Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
ce57572
docs(blog): update enterprise (#8002)
icecrasher321 Sep 19, 2026
5eece6e
improvement(knowledge): skip redundant document resurrection writes (…
waleedlatif1 Sep 19, 2026
5cb88fd
fix(file-search): skip base64-dominated files and redact query errors…
waleedlatif1 Sep 19, 2026
f76aca1
feat(files): workspace file version history over the v2 API, CLI, and…
waleedlatif1 Sep 19, 2026
d96c991
improvement(knowledge): remember a caller's saturated search reach (#…
waleedlatif1 Sep 19, 2026
6892dd7
fix(knowledge): keep Slack searchable while its member crawl runs (#8…
waleedlatif1 Sep 19, 2026
eaa9ff0
improvement(knowledge): rank organization keyword search with Tin (#8…
waleedlatif1 Sep 19, 2026
d9e8c4a
fix(files): file version history follow-ups (#8010)
waleedlatif1 Sep 19, 2026
be70351
fix(slack-search): reuse manifest installation in setup (#8013)
TheodoreSpeaks Sep 19, 2026
6aabeb3
fix(file-search): bound chunk inserts by trigram work (#8011)
icecrasher321 Sep 19, 2026
5414fb9
refactor(ui): reuse EMCN icons for simple product glyphs (#8016)
BillLeoutsakosvl346 Sep 19, 2026
14994dc
fix(ui): use defined status and interaction color tokens (#8012)
BillLeoutsakosvl346 Sep 19, 2026
bb263f8
refactor(ui): share image upload preview tiles (#8015)
BillLeoutsakosvl346 Sep 19, 2026
8bda182
feat(google-calendar): add RSVP operation to respond to invitations (…
waleedlatif1 Sep 19, 2026
c448b87
refactor(ui): reuse EMCN chips for AI controls (#8020)
BillLeoutsakosvl346 Sep 19, 2026
96ab25e
fix(chat): return 403 for inactive chats without writing an execution…
waleedlatif1 Sep 19, 2026
baca4bf
fix(api): refuse workspace keys and enforce personal_api_key.use on v…
waleedlatif1 Sep 19, 2026
d5df6f6
fix(sso): require a session to list SSO providers (#8023)
waleedlatif1 Sep 19, 2026
f444c8f
improvement(ui): use existing 12px and 13px text tokens (#8036)
BillLeoutsakosvl346 Sep 19, 2026
6b46f69
fix(self-hosting): stop publishing Postgres and require POSTGRES_PASS…
waleedlatif1 Sep 19, 2026
c45e8b5
fix(realtime): validate cursor and selection presence payloads (#8041)
waleedlatif1 Sep 19, 2026
0d9e256
fix(copilot): stop returning generate_api_key plaintext on the in-ban…
waleedlatif1 Sep 19, 2026
ed282d6
fix(settings): align credential groups with organization rollout (#8043)
waleedlatif1 Sep 20, 2026
4e72b2b
feat(memory): preserve Agent tool history with bounded context (#8003)
icecrasher321 Sep 20, 2026
3868bf9
improvement(copilot): refuse approval-gated tools on the in-band lane…
waleedlatif1 Sep 20, 2026
a854709
feat(confluence): index PowerPoint and Excel attachments (#8050)
mzxchandra Sep 20, 2026
ac24c87
fix(ui): align editor subblocks and combobox styling (#8049)
waleedlatif1 Sep 20, 2026
6e62541
improvement(ui): share sidebar row action buttons (#8047)
BillLeoutsakosvl346 Sep 20, 2026
526e385
improvement(ui): centralize tab strip action geometry (#8037)
BillLeoutsakosvl346 Sep 20, 2026
8b5109f
improvement(ui): reuse chip inputs for remaining settings fields (#8030)
BillLeoutsakosvl346 Sep 20, 2026
04096b6
fix(ui): align remaining editor dropdown styling (#8051)
waleedlatif1 Sep 20, 2026
812f130
improvement(utils): share escapeRegExp, compareStrings and isRecordLi…
waleedlatif1 Sep 20, 2026
4dd929a
improvement(utils): adopt toRecord and toRecordOrNull over inline rec…
waleedlatif1 Sep 20, 2026
a4730ea
refactor(ui): share log and enrichment details panels (#8026)
BillLeoutsakosvl346 Sep 20, 2026
83fd36a
fix(mcp): let the read tool carry a request body (#8054)
waleedlatif1 Sep 20, 2026
6d5f280
improvement(utils): add toArray and the scalar payload coercions (#8055)
waleedlatif1 Sep 20, 2026
7689dcc
feat(files): surface file versions in the File block and logs, with c…
waleedlatif1 Sep 20, 2026
751887f
fix(knowledge): retry the Tin projection after a database refuses the…
waleedlatif1 Sep 20, 2026
9573ecc
improvement(knowledge): resolve connector and member state once per s…
waleedlatif1 Sep 20, 2026
a2c22f2
fix(knowledge): run the projection source/ACL backfill in the backgro…
waleedlatif1 Sep 20, 2026
753cb4f
docs(library): update agentic-ai-coding-tools-what-they-are-and-how-t…
icecrasher321 Sep 20, 2026
08ef5a9
docs(library): update openai-vs-n8n-vs-sim (#8062)
icecrasher321 Sep 20, 2026
a41ef97
docs(library): update best-zapier-alternatives (#8063)
icecrasher321 Sep 20, 2026
7093409
fix(knowledge): apply the source and date filters inside a resolved s…
waleedlatif1 Sep 20, 2026
bc97b72
feat(library): AI coding-agent benchmark: a reproducible test of debu…
icecrasher321 Sep 20, 2026
ea31ca7
improvement(knowledge): page search results, take a custom date windo…
waleedlatif1 Sep 20, 2026
5457698
improvement(knowledge): warm the search projection after its backfill…
waleedlatif1 Sep 21, 2026
bd0311e
improvement(ui): reuse shared product status pages (#8089)
BillLeoutsakosvl346 Sep 21, 2026
e144647
docs(library): update openai-vs-n8n-vs-sim (#8094)
icecrasher321 Sep 21, 2026
4548165
docs(library): update best-zapier-alternatives (#8095)
icecrasher321 Sep 21, 2026
081dd7c
docs(library): update agentic-ai-coding-tools-what-they-are-and-how-t…
icecrasher321 Sep 21, 2026
3f4c101
fix(files,realtime): issue a revision on revert and stop resurrecting…
waleedlatif1 Sep 21, 2026
27a8603
improvement(knowledge): rank the vector page on the projection and ad…
waleedlatif1 Sep 21, 2026
d5061d5
improvement(knowledge): read the source card with the result (#8099)
waleedlatif1 Sep 21, 2026
bc2f641
improvement(knowledge): score the page on the original vectors, resol…
waleedlatif1 Sep 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .claude/rules/global.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ Use shared helpers from `@sim/utils` instead of writing inline implementations:
- `structuredClone(value)` — built-in deep clone, no import needed. Never write `JSON.parse(JSON.stringify(obj))`
- `omit(obj, keys)` from `@sim/utils/object` — remove keys from object
- `filterUndefined(obj)` from `@sim/utils/object` — strip undefined-valued keys. Never write `Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined))`
- `isRecordLike(value)` from `@sim/utils/object` — indexable-object guard. Never redeclare `typeof value === 'object' && value !== null && !Array.isArray(value)`
- `toRecord(value)` / `toRecordOrNull(value)` / `toArray(value)` from `@sim/utils/object` — coerce an untyped payload value to a record or array. Never inline `isRecordLike(v) ? v : {}` or `Array.isArray(v) ? v : []`. Where the source is already typed, keep the inline `Array.isArray` check: it narrows, while `toArray` asserts
- `toStringOrNull(value)` / `toNumberOrNull(value)` / `toBooleanOrNull(value)` from `@sim/utils/coerce` — read one scalar out of an untyped payload. Never declare a local one-liner that is byte-identical to one of these (`asString`, `getString`, `nullableString`, …). Keep a local helper that differs: one returning `undefined` rather than `null` changes the wire shape, and one adding `Number.isFinite` or a string parse is a stricter check these deliberately omit
- `truncate(str, maxLength, suffix?)` from `@sim/utils/string` — safe string truncation with ellipsis
- `escapeRegExp(value)` from `@sim/utils/string` — escape regex metacharacters. Never inline `replace(/[.*+?^${}()|[\]\\]/g, '\\$&')`
- `compareStrings(left, right)` from `@sim/utils/string` — code-unit string comparator for hashes, fingerprints, and values compared across processes. Never `localeCompare` there
- `backoffWithJitter(attempt, retryAfterMs, options?)` from `@sim/utils/retry` — exponential backoff with jitter
- `parseRetryAfter(header)` from `@sim/utils/retry` — parse HTTP `Retry-After` header to milliseconds

Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/sim-imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ paths:

```typescript
// ✓ Good
import { Chip } from '@sim/emcn'
import { useWorkflowStore } from '@/stores/workflows/store'
import { Button } from '@/components/ui/button'

// ✗ Bad
import { useWorkflowStore } from '../../../stores/workflows/store'
Expand Down
5 changes: 5 additions & 0 deletions .cursor/rules/global.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ Use shared helpers from `@sim/utils` instead of writing inline implementations:
- `structuredClone(value)` — built-in deep clone, no import needed. Never write `JSON.parse(JSON.stringify(obj))`
- `omit(obj, keys)` from `@sim/utils/object` — remove keys from object
- `filterUndefined(obj)` from `@sim/utils/object` — strip undefined-valued keys. Never write `Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined))`
- `isRecordLike(value)` from `@sim/utils/object` — indexable-object guard. Never redeclare `typeof value === 'object' && value !== null && !Array.isArray(value)`
- `toRecord(value)` / `toRecordOrNull(value)` / `toArray(value)` from `@sim/utils/object` — coerce an untyped payload value to a record or array. Never inline `isRecordLike(v) ? v : {}` or `Array.isArray(v) ? v : []`. Where the source is already typed, keep the inline `Array.isArray` check: it narrows, while `toArray` asserts
- `toStringOrNull(value)` / `toNumberOrNull(value)` / `toBooleanOrNull(value)` from `@sim/utils/coerce` — read one scalar out of an untyped payload. Never declare a local one-liner that is byte-identical to one of these (`asString`, `getString`, `nullableString`, …). Keep a local helper that differs: one returning `undefined` rather than `null` changes the wire shape, and one adding `Number.isFinite` or a string parse is a stricter check these deliberately omit
- `truncate(str, maxLength, suffix?)` from `@sim/utils/string` — safe string truncation with ellipsis
- `escapeRegExp(value)` from `@sim/utils/string` — escape regex metacharacters. Never inline `replace(/[.*+?^${}()|[\]\\]/g, '\\$&')`
- `compareStrings(left, right)` from `@sim/utils/string` — code-unit string comparator for hashes, fingerprints, and values compared across processes. Never `localeCompare` there
- `backoffWithJitter(attempt, retryAfterMs, options?)` from `@sim/utils/retry` — exponential backoff with jitter
- `parseRetryAfter(header)` from `@sim/utils/retry` — parse HTTP `Retry-After` header to milliseconds

Expand Down
2 changes: 1 addition & 1 deletion .cursor/rules/sim-imports.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ globs: ["apps/sim/**/*.ts","apps/sim/**/*.tsx"]

```typescript
// ✓ Good
import { Chip } from '@sim/emcn'
import { useWorkflowStore } from '@/stores/workflows/store'
import { Button } from '@/components/ui/button'

// ✗ Bad
import { useWorkflowStore } from '../../../stores/workflows/store'
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/test-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,18 @@ jobs:
KNOWLEDGE_ACL_TEST_DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/sim_auth_scim
run: bunx vitest run --mode integration lib/workspace-files/search/dispatcher.integration.ts

- name: Verify workspace file version history on PostgreSQL 17
working-directory: apps/sim
env:
KNOWLEDGE_ACL_TEST_DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/sim_auth_scim
run: bunx vitest run --mode integration lib/uploads/contexts/workspace/__integration__/file-versions.integration.ts

- name: Verify file search trigram estimate against pg_trgm
working-directory: apps/sim
env:
KNOWLEDGE_ACL_TEST_DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/sim_auth_scim
run: bunx vitest run --mode integration lib/workspace-files/search/index-plan.integration.ts

- name: Verify SCIM and administration over real HTTP
working-directory: apps/sim
env:
Expand Down Expand Up @@ -219,6 +231,8 @@ jobs:
bunx vitest run
lib/table/rows/secret-provenance.postgres.test.ts
lib/memory/message-provenance.postgres.test.ts
lib/memory/conversation-store.postgres.test.ts
lib/memory/summary-store.postgres.test.ts
executor/handlers/agent/memory-harness.postgres.test.ts

- name: Verify Search vector projection upgrade in PostgreSQL
Expand All @@ -229,6 +243,7 @@ jobs:
bunx vitest run
script-migrations/0016_backfill_search_vectors.postgres.test.ts
script-migrations/0018_repair_workspace_file_content_revision.postgres.test.ts
script-migrations/0019_tin_keyword_projection.postgres.test.ts

- name: Verify Search progress, pagination, and outbox scheduling in PostgreSQL
working-directory: apps/sim
Expand All @@ -246,6 +261,8 @@ jobs:
lib/knowledge/__integration__/stored-document-recovery.integration.ts
lib/knowledge/__integration__/connector-partition-work.integration.ts
lib/knowledge/__integration__/listing-continuation.integration.ts
lib/knowledge/__integration__/member-scope-renewal.integration.ts
lib/knowledge/__integration__/slack-empty-threads.integration.ts
lib/knowledge/__integration__/kb-block-search.integration.ts
lib/core/outbox/service.integration.ts
lib/knowledge/__integration__/connector-upload.integration.ts
Expand Down
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ You are a professional software engineer. All code must follow best practices: a
- `getErrorMessage(e, fallback?)` from `@sim/utils/errors` — extract message string from unknown caught value; never write `e instanceof Error ? e.message : 'fallback'`
- `structuredClone(value)` — built-in deep clone; never `JSON.parse(JSON.stringify(...))`
- `omit(obj, keys)` / `filterUndefined(obj)` from `@sim/utils/object` — object trimming; never `Object.fromEntries(Object.entries(...).filter(...))`
- `isRecordLike(value)` from `@sim/utils/object` — never redeclare `typeof value === 'object' && value !== null && !Array.isArray(value)`
- `toRecord(value)` / `toRecordOrNull(value)` / `toArray(value)` from `@sim/utils/object` — coerce an untyped payload value to a record or array; never inline `isRecordLike(v) ? v : {}` or `Array.isArray(v) ? v : []`. Where the source is already typed, keep the inline `Array.isArray` check: it narrows, while `toArray` asserts
- `toStringOrNull(value)` / `toNumberOrNull(value)` / `toBooleanOrNull(value)` from `@sim/utils/coerce` — read one scalar out of an untyped payload; never declare a local one-liner byte-identical to one of these. Keep a local helper that differs: `undefined` instead of `null` changes the wire shape, and a `Number.isFinite` or string-parse variant is a stricter check these omit
- `truncate(str, maxLength, suffix?)` from `@sim/utils/string` — never inline slice + ellipsis
- `escapeRegExp(value)` from `@sim/utils/string` — never inline `replace(/[.*+?^${}()|[\]\\]/g, '\\$&')`
- `compareStrings(left, right)` from `@sim/utils/string` — code-unit ordering for hashes, fingerprints, and cross-process comparisons; never `localeCompare` there
- `backoffWithJitter(attempt, retryAfterMs, options?)` / `parseRetryAfter(header)` from `@sim/utils/retry` — shared retry pacing; never reimplement exponential backoff inline
- **Deployment flags in the browser**: client code inside a workspace, organization, or standalone settings surface reads `hosted`, `billingEnabled`, `chatEnabled`, and the enterprise feature set through `useDeploymentShape()` (components) or `getDeploymentShape()` (block conditions, stores, helpers) from `@/lib/core/config/deployment-shape`, never `isHosted`/`isBillingEnabled`/... from `env-flags`. The constants freeze at module init from the root layout's `NEXT_PUBLIC_*` transport, which Next's bare 404 shell and `global-error` never emit; the reader is seeded from the server-resolved workspace host context, organization layout, or standalone settings layout instead. Server code keeps reading `env-flags`
- **Package Manager**: Use `bun` and `bunx`, not `npm` and `npx`
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<p align="center">
<a href="https://deepwiki.com/simstudioai/sim" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/Ask-DeepWiki-E6E6E6?labelColor=C3C3C3&color=E6E6E6" alt="Ask DeepWiki"></a>
<a href="https://cursor.com/link/prompt?text=Help%20me%20set%20up%20Sim%20locally.%20Follow%20these%20steps%3A%0A%0A1.%20First%2C%20verify%20Docker%20is%20installed%20and%20running%3A%0A%20%20%20docker%20--version%0A%20%20%20docker%20info%0A%0A2.%20Clone%20the%20repository%3A%0A%20%20%20git%20clone%20https%3A%2F%2Fgithub.com%2Fsimstudioai%2Fsim.git%0A%20%20%20cd%20sim%0A%0A3.%20Generate%20required%20secrets%20%28the%20stack%20will%20not%20start%20without%20them%29%3A%0A%20%20%20cat%20%3E%20.env%20%3C%3C%20EOF%0A%20%20%20BETTER_AUTH_SECRET%3D%24%28openssl%20rand%20-hex%2032%29%0A%20%20%20ENCRYPTION_KEY%3D%24%28openssl%20rand%20-hex%2032%29%0A%20%20%20INTERNAL_API_SECRET%3D%24%28openssl%20rand%20-hex%2032%29%0A%20%20%20CRON_SECRET%3D%24%28openssl%20rand%20-hex%2032%29%0A%20%20%20EOF%0A%0A4.%20Start%20the%20services%20with%20Docker%20Compose%3A%0A%20%20%20docker%20compose%20-f%20docker-compose.prod.yml%20up%20-d%0A%0A4.%20Wait%20for%20all%20containers%20to%20be%20healthy%20(this%20may%20take%201-2%20minutes)%3A%0A%20%20%20docker%20compose%20-f%20docker-compose.prod.yml%20ps%0A%0A5.%20Verify%20the%20app%20is%20accessible%20at%20http%3A%2F%2Flocalhost%3A3000%0A%0AIf%20there%20are%20any%20errors%2C%20help%20me%20troubleshoot%20them.%20Common%20issues%3A%0A-%20Port%203000%2C%203002%2C%20or%205432%20already%20in%20use%0A-%20Docker%20not%20running%0A-%20Insufficient%20memory%20(needs%2012GB%2B%20RAM)%0A%0AFor%20local%20AI%20models%20with%20Ollama%2C%20use%20this%20instead%20of%20step%203%3A%0A%20%20%20docker%20compose%20-f%20docker-compose.ollama.yml%20--profile%20setup%20up%20-d"><img src="https://img.shields.io/badge/Set%20Up%20with-Cursor-E6E6E6?logo=cursor&logoColor=1A1A1A&labelColor=C3C3C3&color=E6E6E6" alt="Set Up with Cursor"></a>
<a href="https://cursor.com/link/prompt?text=Help%20me%20set%20up%20Sim%20locally.%20Follow%20these%20steps%3A%0A%0A1.%20First%2C%20verify%20Docker%20is%20installed%20and%20running%3A%0A%20%20%20docker%20--version%0A%20%20%20docker%20info%0A%0A2.%20Clone%20the%20repository%3A%0A%20%20%20git%20clone%20https%3A%2F%2Fgithub.com%2Fsimstudioai%2Fsim.git%0A%20%20%20cd%20sim%0A%0A3.%20Generate%20required%20secrets%20%28the%20stack%20will%20not%20start%20without%20them%29%3A%0A%20%20%20cat%20%3E%20.env%20%3C%3C%20EOF%0A%20%20%20BETTER_AUTH_SECRET%3D%24%28openssl%20rand%20-hex%2032%29%0A%20%20%20ENCRYPTION_KEY%3D%24%28openssl%20rand%20-hex%2032%29%0A%20%20%20INTERNAL_API_SECRET%3D%24%28openssl%20rand%20-hex%2032%29%0A%20%20%20CRON_SECRET%3D%24%28openssl%20rand%20-hex%2032%29%0A%20%20%20POSTGRES_PASSWORD%3D%24%28openssl%20rand%20-hex%2024%29%0A%20%20%20EOF%0A%0A4.%20Start%20the%20services%20with%20Docker%20Compose%3A%0A%20%20%20docker%20compose%20-f%20docker-compose.prod.yml%20up%20-d%0A%0A4.%20Wait%20for%20all%20containers%20to%20be%20healthy%20(this%20may%20take%201-2%20minutes)%3A%0A%20%20%20docker%20compose%20-f%20docker-compose.prod.yml%20ps%0A%0A5.%20Verify%20the%20app%20is%20accessible%20at%20http%3A%2F%2Flocalhost%3A3000%0A%0AIf%20there%20are%20any%20errors%2C%20help%20me%20troubleshoot%20them.%20Common%20issues%3A%0A-%20Port%203000%20or%203002%20already%20in%20use%0A-%20Docker%20not%20running%0A-%20Insufficient%20memory%20(needs%2012GB%2B%20RAM)%0A%0AFor%20local%20AI%20models%20with%20Ollama%2C%20use%20this%20instead%20of%20step%203%3A%0A%20%20%20docker%20compose%20-f%20docker-compose.ollama.yml%20--profile%20setup%20up%20-d"><img src="https://img.shields.io/badge/Set%20Up%20with-Cursor-E6E6E6?logo=cursor&logoColor=1A1A1A&labelColor=C3C3C3&color=E6E6E6" alt="Set Up with Cursor"></a>
</p>

<p align="center">
Expand Down
6 changes: 3 additions & 3 deletions apps/desktop/src/main/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
type TerminalToolArgs,
} from '@sim/terminal-protocol'
import { getErrorMessage } from '@sim/utils/errors'
import { isRecordLike } from '@sim/utils/object'
import { isRecordLike, toRecord } from '@sim/utils/object'
import { PASTE_LIMITS, utf8ByteLength } from '@sim/utils/paste'
import type { BrowserWindow, IpcMainEvent, IpcMainInvokeEvent, WebContents } from 'electron'
import { clipboard, ipcMain, shell } from 'electron'
Expand Down Expand Up @@ -856,7 +856,7 @@ export function registerIpcHandlers(deps: IpcDeps): void {
) {
return { ok: false, error: `Unknown browser tool: ${String(tool)}` }
}
const toolParams = isRecordLike(params) ? params : {}
const toolParams = toRecord(params)
return executeTool(
scope,
tool,
Expand Down Expand Up @@ -1532,7 +1532,7 @@ export function registerIpcHandlers(deps: IpcDeps): void {
) {
return { ok: false, error: `Unknown terminal tool: ${String(tool)}` }
}
const call = isRecordLike(params) ? params : {}
const call = toRecord(params)
if (!isTerminalOperation(call.operation)) {
return { ok: false, error: `Unknown terminal operation: ${String(call.operation)}` }
}
Expand Down
3 changes: 2 additions & 1 deletion apps/desktop/src/main/local-filesystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from '@sim/desktop-bridge/local-filesystem-limits'
import { generateId } from '@sim/utils/id'
import { isRecordLike } from '@sim/utils/object'
import { escapeRegExp } from '@sim/utils/string'
import { app, dialog, shell } from 'electron'
import micromatch from 'micromatch'
import safeRegex from 'safe-regex2'
Expand Down Expand Up @@ -1114,7 +1115,7 @@ export class LocalFilesystemService {
regex =
rawPattern !== undefined
? new RegExp(expression, ignoreCase ? 'i' : '')
: new RegExp(expression.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), ignoreCase ? 'i' : '')
: new RegExp(escapeRegExp(expression), ignoreCase ? 'i' : '')
} catch {
// An empty result set would tell the model the string appears nowhere in
// the user's files — a factual claim it will act on, when in truth the
Expand Down
Loading
Loading