@mastra/code-sdk 1.15.0-alpha.1 → 1.15.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/acp/agent.d.ts.map +1 -1
  2. package/dist/acp/agent.js +1 -1
  3. package/dist/acp/agent.js.map +1 -1
  4. package/dist/acp/event-mapper.d.ts.map +1 -1
  5. package/dist/acp/event-mapper.js +1 -1
  6. package/dist/acp/event-mapper.js.map +1 -1
  7. package/dist/agent-connections/signal-provider.d.ts +1 -1
  8. package/dist/agent-connections/signal-provider.d.ts.map +1 -1
  9. package/dist/agent-connections/signal-provider.js.map +1 -1
  10. package/dist/agent-connections/state-processor.d.ts +2 -2
  11. package/dist/agent-connections/state-processor.d.ts.map +1 -1
  12. package/dist/agent-connections/state-processor.js.map +1 -1
  13. package/dist/agent-connections/thread-state.d.ts +1 -1
  14. package/dist/agent-connections/thread-state.d.ts.map +1 -1
  15. package/dist/agent-connections/thread-state.js.map +1 -1
  16. package/dist/agent-connections/tools.d.ts.map +1 -1
  17. package/dist/agent-connections/tools.js +1 -1
  18. package/dist/agent-connections/tools.js.map +1 -1
  19. package/dist/agents/background-completion.d.ts +15 -2
  20. package/dist/agents/background-completion.d.ts.map +1 -1
  21. package/dist/agents/background-completion.js +19 -2
  22. package/dist/agents/background-completion.js.map +1 -1
  23. package/dist/agents/credential-resolver.d.ts +6 -0
  24. package/dist/agents/credential-resolver.d.ts.map +1 -1
  25. package/dist/agents/credential-resolver.js +13 -4
  26. package/dist/agents/credential-resolver.js.map +1 -1
  27. package/dist/agents/memory.d.ts.map +1 -1
  28. package/dist/agents/memory.js +1 -1
  29. package/dist/agents/memory.js.map +1 -1
  30. package/dist/agents/sandbox-filesystem.d.ts +32 -10
  31. package/dist/agents/sandbox-filesystem.d.ts.map +1 -1
  32. package/dist/agents/sandbox-filesystem.js +208 -66
  33. package/dist/agents/sandbox-filesystem.js.map +1 -1
  34. package/dist/agents/workspace.d.ts.map +1 -1
  35. package/dist/agents/workspace.js +1 -0
  36. package/dist/agents/workspace.js.map +1 -1
  37. package/dist/experimental-agent.d.ts +1 -1
  38. package/dist/experimental-agent.d.ts.map +1 -1
  39. package/dist/experimental-agent.js.map +1 -1
  40. package/dist/factory/client.d.ts +41 -0
  41. package/dist/factory/client.d.ts.map +1 -0
  42. package/dist/factory/client.js +98 -0
  43. package/dist/factory/client.js.map +1 -0
  44. package/dist/factory/remote-controller.d.ts +34 -0
  45. package/dist/factory/remote-controller.d.ts.map +1 -0
  46. package/dist/factory/remote-controller.js +43 -0
  47. package/dist/factory/remote-controller.js.map +1 -0
  48. package/dist/factory/remote-session.d.ts +210 -0
  49. package/dist/factory/remote-session.d.ts.map +1 -0
  50. package/dist/factory/remote-session.js +420 -0
  51. package/dist/factory/remote-session.js.map +1 -0
  52. package/dist/headless/cli.d.ts +7 -0
  53. package/dist/headless/cli.d.ts.map +1 -1
  54. package/dist/headless/cli.js +19 -3
  55. package/dist/headless/cli.js.map +1 -1
  56. package/dist/headless/flags.d.ts.map +1 -1
  57. package/dist/headless/flags.js +2 -1
  58. package/dist/headless/flags.js.map +1 -1
  59. package/dist/headless/format.d.ts +2 -0
  60. package/dist/headless/format.d.ts.map +1 -1
  61. package/dist/headless/format.js +13 -1
  62. package/dist/headless/format.js.map +1 -1
  63. package/dist/headless/run-mc.d.ts.map +1 -1
  64. package/dist/headless/run-mc.js +48 -20
  65. package/dist/headless/run-mc.js.map +1 -1
  66. package/dist/index.d.ts +22 -1
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +69 -25
  69. package/dist/index.js.map +1 -1
  70. package/dist/onboarding/pack-activation.d.ts +2 -11
  71. package/dist/onboarding/pack-activation.d.ts.map +1 -1
  72. package/dist/onboarding/pack-activation.js.map +1 -1
  73. package/dist/onboarding/settings.d.ts +18 -0
  74. package/dist/onboarding/settings.d.ts.map +1 -1
  75. package/dist/onboarding/settings.js +28 -3
  76. package/dist/onboarding/settings.js.map +1 -1
  77. package/dist/platform/index.d.ts +74 -0
  78. package/dist/platform/index.d.ts.map +1 -0
  79. package/dist/platform/index.js +200 -0
  80. package/dist/platform/index.js.map +1 -0
  81. package/dist/process-memory-diagnostics.d.ts +2 -1
  82. package/dist/process-memory-diagnostics.d.ts.map +1 -1
  83. package/dist/process-memory-diagnostics.js.map +1 -1
  84. package/dist/providers/model-ids.d.ts +1 -0
  85. package/dist/providers/model-ids.d.ts.map +1 -1
  86. package/dist/providers/model-ids.js +6 -4
  87. package/dist/providers/model-ids.js.map +1 -1
  88. package/dist/tools/web-search.d.ts +1 -1
  89. package/dist/tools/web-search.d.ts.map +1 -1
  90. package/dist/tools/web-search.js.map +1 -1
  91. package/dist/tools/workflows/create-workflow.d.ts.map +1 -1
  92. package/dist/tools/workflows/create-workflow.js +5 -1
  93. package/dist/tools/workflows/create-workflow.js.map +1 -1
  94. package/dist/utils/local-observability.d.ts +19 -0
  95. package/dist/utils/local-observability.d.ts.map +1 -0
  96. package/dist/utils/local-observability.js +57 -0
  97. package/dist/utils/local-observability.js.map +1 -0
  98. package/dist/utils/notification-dispatch.d.ts +27 -12
  99. package/dist/utils/notification-dispatch.d.ts.map +1 -1
  100. package/dist/utils/notification-dispatch.js +46 -24
  101. package/dist/utils/notification-dispatch.js.map +1 -1
  102. package/dist/utils/signals-pubsub.d.ts +5 -3
  103. package/dist/utils/signals-pubsub.d.ts.map +1 -1
  104. package/dist/utils/signals-pubsub.js +8 -6
  105. package/dist/utils/signals-pubsub.js.map +1 -1
  106. package/dist/utils/wake-session.d.ts +44 -0
  107. package/dist/utils/wake-session.d.ts.map +1 -0
  108. package/dist/utils/wake-session.js +86 -0
  109. package/dist/utils/wake-session.js.map +1 -0
  110. package/dist/workflows/register-primitives.js +4 -1
  111. package/dist/workflows/register-primitives.js.map +1 -1
  112. package/package.json +23 -23
@@ -116,19 +116,20 @@ export declare class SandboxFilesystem implements WorkspaceFilesystem {
116
116
  */
117
117
  walk(path: string, options?: WalkOptions): Promise<WalkEntry[]>;
118
118
  /**
119
- * Content search executed inside the sandbox in one command. Prefers
120
- * ripgrep (`rg --json`) when installed; otherwise falls back to
121
- * `grep -rnE`. Patterns the ERE fallback can't express (PCRE-style classes,
122
- * word boundaries, lookarounds, non-greedy quantifiers) throw
123
- * {@link UnsupportedGrepPatternError} so callers use their host-side walk.
119
+ * Content search executed inside the sandbox in one command, using the best
120
+ * engine the sandbox has: ripgrep, then GNU grep (with git choosing files
121
+ * inside repositories), then POSIX `grep -rnE`. Patterns the grep engines
122
+ * can't express (PCRE-style classes, word boundaries, lookarounds,
123
+ * non-greedy quantifiers) throw {@link UnsupportedGrepPatternError} so
124
+ * callers use their host-side walk.
124
125
  *
125
- * Callers are expected to apply their own gitignore/hidden/glob filtering
126
- * to the returned paths; both engines run with ignore rules disabled so
127
- * results are a superset of what any host-side filter would keep.
126
+ * ripgrep and GNU grep apply every `.gitignore` in the tree, relative to the
127
+ * directory that holds it, and skip `node_modules` unless the search path
128
+ * is inside one. Callers still apply their own hidden/glob filtering.
128
129
  */
129
130
  grep(options: FilesystemGrepOptions): Promise<FilesystemGrepResult[]>;
130
- private rgCheck;
131
- private hasRipgrep;
131
+ private toolsCheck;
132
+ private searchTools;
132
133
  private grepWithRipgrep;
133
134
  private parseRipgrepJson;
134
135
  /**
@@ -138,6 +139,27 @@ export declare class SandboxFilesystem implements WorkspaceFilesystem {
138
139
  * POSIX bracket classes, GNU word anchors) must fall back to the host walk.
139
140
  */
140
141
  private static readonly ERE_UNSUPPORTED;
142
+ /**
143
+ * Escapes that `grep -P` (PCRE) and JS RegExp (without the `u` flag) both
144
+ * accept but read differently, e.g. `\A` is "start of subject" in PCRE and
145
+ * a literal `A` in JS, plus POSIX bracket classes. PCRE-only syntax that JS
146
+ * rejects (inline flags, possessive quantifiers, atomic groups) already
147
+ * fails the JS compile below.
148
+ */
149
+ private static readonly PCRE_UNSUPPORTED;
150
+ /** Reject patterns grep can't run with the same meaning as JS; return the JS regex used for columns. */
151
+ private static grepRegex;
152
+ /**
153
+ * GNU grep without ripgrep. Inside a git checkout, `git grep` picks the
154
+ * files (tracked plus untracked, every `.gitignore` applied) and GNU grep
155
+ * prints them with context. Outside a checkout (e.g. a multi-repo root),
156
+ * each child repository is searched the same way and plain grep covers the
157
+ * remaining files, skipping `node_modules`. `--null` ends each file name
158
+ * with NUL, so match (`N:`) and context (`N-`) lines parse unambiguously.
159
+ * When grep and git support it, patterns run as PCRE (`-P`), so `\d`,
160
+ * `\w`, `\s`, `\b`, and lookarounds don't need the host walk.
161
+ */
162
+ private grepWithGnuGrep;
141
163
  private grepWithPosixGrep;
142
164
  private applyTotalCap;
143
165
  exists(path: string): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-filesystem.d.ts","sourceRoot":"","sources":["../../src/agents/sandbox-filesystem.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sandbox-filesystem.d.ts","sourceRoot":"","sources":["../../src/agents/sandbox-filesystem.ts"],"names":[],"mappings":"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"}
@@ -25,10 +25,69 @@ const EXIT_EXISTS = 22;
25
25
  const EXIT_NOT_DIRECTORY = 23;
26
26
  /** Default per-command deadline so a hung sandbox can't block file tools forever. */
27
27
  const COMMAND_TIMEOUT_MS = 3e4;
28
+ /**
29
+ * Explain why a native grep command failed so callers can tell a timeout or
30
+ * broken toolchain apart from a pattern the engine cannot express.
31
+ */
32
+ function describeGrepFailure(result) {
33
+ if (result.exitCode === 124) return `timed out after ${COMMAND_TIMEOUT_MS / 1e3}s`;
34
+ const stderrLine = result.stderr.split("\n").map((line) => line.trim()).find(Boolean);
35
+ const detail = stderrLine ? `: ${stderrLine.length > 200 ? `${stderrLine.slice(0, 200)}…` : stderrLine}` : "";
36
+ return `exit code ${result.exitCode}${detail}`;
37
+ }
28
38
  /** Single-quote a string for safe POSIX shell interpolation. */
29
39
  function shellQuote(value) {
30
40
  return `'${value.replace(/'/g, `'\\''`)}'`;
31
41
  }
42
+ /** One command that reports which search tools the sandbox has, one name per line. */
43
+ const SEARCH_TOOLS_PROBE = "command -v rg >/dev/null 2>&1 && echo rg; grep --version 2>/dev/null | head -n 1 | grep -q 'GNU grep' && echo gnu-grep; printf 'a1\\n' | grep -qP '\\d(?=)' 2>/dev/null && echo grep-pcre; if command -v git >/dev/null 2>&1; then echo git; d=$(mktemp -d 2>/dev/null) && { (cd \"$d\" && git init -q && printf 'a1\\n' >f && git grep -q --untracked -P -e '\\d(?=)') >/dev/null 2>&1 && echo git-pcre; rm -rf \"$d\"; }; fi; true";
44
+ function isInsideNodeModules(path) {
45
+ return path.split("/").includes("node_modules");
46
+ }
47
+ function fileLines(files, filePath) {
48
+ let state = files.get(filePath);
49
+ if (!state) {
50
+ state = {
51
+ matches: [],
52
+ linesByNumber: /* @__PURE__ */ new Map()
53
+ };
54
+ files.set(filePath, state);
55
+ }
56
+ return state;
57
+ }
58
+ /** Turn per-file lines into results relative to `abs`, attaching before/after context. */
59
+ function toGrepResults(files, abs, contextLines) {
60
+ const results = [];
61
+ for (const [filePath, state] of files) {
62
+ if (state.matches.length === 0) continue;
63
+ const rel = posix.relative(abs, filePath) || posix.basename(filePath);
64
+ const matches = state.matches.map((match) => {
65
+ if (contextLines <= 0) return match;
66
+ const before = [];
67
+ for (let n = match.line - 1; n >= Math.max(1, match.line - contextLines); n--) {
68
+ const text = state.linesByNumber.get(n);
69
+ if (text === void 0) break;
70
+ before.unshift(text);
71
+ }
72
+ const after = [];
73
+ for (let n = match.line + 1; n <= match.line + contextLines; n++) {
74
+ const text = state.linesByNumber.get(n);
75
+ if (text === void 0) break;
76
+ after.push(text);
77
+ }
78
+ return {
79
+ ...match,
80
+ before,
81
+ after
82
+ };
83
+ });
84
+ results.push({
85
+ path: rel,
86
+ matches
87
+ });
88
+ }
89
+ return results;
90
+ }
32
91
  function isFileContentString(content) {
33
92
  return typeof content === "string";
34
93
  }
@@ -319,8 +378,11 @@ var SandboxFilesystem = class SandboxFilesystem {
319
378
  const abs = await this.resolveAsync(path);
320
379
  await this.assertContainedRealpath(abs, path);
321
380
  const maxDepth = options?.maxDepth !== void 0 && Number.isFinite(options.maxDepth) ? `-maxdepth ${Math.max(0, Math.floor(options.maxDepth))} ` : "";
322
- const hiddenPrune = options?.includeHidden ? "" : `-name '.*' -prune -o `;
323
- const script = `root=${shellQuote(abs)}\n[ -e "$root" ] || [ -L "$root" ] || exit ${EXIT_NOT_FOUND}\n[ -d "$root" ] || exit ${EXIT_NOT_DIRECTORY}\nfind "$root" -mindepth 1 ${maxDepth}${hiddenPrune}-print 2>/dev/null | while IFS= read -r f; do if [ -L "$f" ]; then if [ -d "$f" ]; then t=D; else t=F; fi; printf '%s\\t%s\\t%s\\n' "$t" "$f" "$(readlink "$f")"; elif [ -d "$f" ]; then printf 'd\\t%s\\n' "$f"; else printf 'f\\t%s\\n' "$f"; fi; done`;
381
+ const keepGitignore = options?.includeGitignoreFiles ? `! \\( -type f -name .gitignore \\) ` : "";
382
+ const hiddenPrune = options?.includeHidden ? "" : `\\( -name '.*' ${keepGitignore}\\) -prune -o `;
383
+ const skipNames = options?.skipDirectoryNames?.filter(Boolean) ?? [];
384
+ const skipPrune = skipNames.length ? `\\( -type d \\( ${skipNames.map((name) => `-name ${shellQuote(name)}`).join(" -o ")} \\) \\) -prune -o ` : "";
385
+ const script = `root=${shellQuote(abs)}\n[ -e "$root" ] || [ -L "$root" ] || exit ${EXIT_NOT_FOUND}\n[ -d "$root" ] || exit ${EXIT_NOT_DIRECTORY}\nfind "$root" -mindepth 1 ${maxDepth}${hiddenPrune}${skipPrune}-print 2>/dev/null | while IFS= read -r f; do if [ -L "$f" ]; then if [ -d "$f" ]; then t=D; else t=F; fi; printf '%s\\t%s\\t%s\\n' "$t" "$f" "$(readlink "$f")"; elif [ -d "$f" ]; then printf 'd\\t%s\\n' "$f"; else printf 'f\\t%s\\n' "$f"; fi; done`;
324
386
  const result = await this.exec(script);
325
387
  if (result.exitCode === EXIT_NOT_FOUND) throw new DirectoryNotFoundError(path);
326
388
  if (result.exitCode === EXIT_NOT_DIRECTORY) throw new NotDirectoryError(path);
@@ -356,31 +418,53 @@ var SandboxFilesystem = class SandboxFilesystem {
356
418
  return entries;
357
419
  }
358
420
  /**
359
- * Content search executed inside the sandbox in one command. Prefers
360
- * ripgrep (`rg --json`) when installed; otherwise falls back to
361
- * `grep -rnE`. Patterns the ERE fallback can't express (PCRE-style classes,
362
- * word boundaries, lookarounds, non-greedy quantifiers) throw
363
- * {@link UnsupportedGrepPatternError} so callers use their host-side walk.
421
+ * Content search executed inside the sandbox in one command, using the best
422
+ * engine the sandbox has: ripgrep, then GNU grep (with git choosing files
423
+ * inside repositories), then POSIX `grep -rnE`. Patterns the grep engines
424
+ * can't express (PCRE-style classes, word boundaries, lookarounds,
425
+ * non-greedy quantifiers) throw {@link UnsupportedGrepPatternError} so
426
+ * callers use their host-side walk.
364
427
  *
365
- * Callers are expected to apply their own gitignore/hidden/glob filtering
366
- * to the returned paths; both engines run with ignore rules disabled so
367
- * results are a superset of what any host-side filter would keep.
428
+ * ripgrep and GNU grep apply every `.gitignore` in the tree, relative to the
429
+ * directory that holds it, and skip `node_modules` unless the search path
430
+ * is inside one. Callers still apply their own hidden/glob filtering.
368
431
  */
369
432
  async grep(options) {
370
433
  const abs = await this.resolveAsync(options.path);
371
434
  await this.assertContainedRealpath(abs, options.path);
372
- if (await this.hasRipgrep()) return this.grepWithRipgrep(abs, options);
435
+ const tools = await this.searchTools();
436
+ if (tools.rg) return this.grepWithRipgrep(abs, options);
437
+ if (tools.gnuGrep) return this.grepWithGnuGrep(abs, options, tools);
373
438
  return this.grepWithPosixGrep(abs, options);
374
439
  }
375
- rgCheck;
376
- hasRipgrep() {
377
- this.rgCheck ??= this.exec("command -v rg >/dev/null 2>&1").then((r) => r.exitCode === 0, () => false);
378
- return this.rgCheck;
440
+ toolsCheck;
441
+ searchTools() {
442
+ const check = this.toolsCheck ??= this.exec(SEARCH_TOOLS_PROBE).then((result) => {
443
+ if (result.exitCode !== 0) throw new Error(`search tool probe exited with ${result.exitCode}`);
444
+ const found = new Set(result.stdout.split("\n").map((line) => line.trim()));
445
+ const git = found.has("git");
446
+ return {
447
+ rg: found.has("rg"),
448
+ gnuGrep: found.has("gnu-grep"),
449
+ git,
450
+ pcre: found.has("grep-pcre") && (!git || found.has("git-pcre"))
451
+ };
452
+ });
453
+ return check.catch(() => {
454
+ if (this.toolsCheck === check) this.toolsCheck = void 0;
455
+ return {
456
+ rg: false,
457
+ gnuGrep: false,
458
+ git: false,
459
+ pcre: false
460
+ };
461
+ });
379
462
  }
380
463
  async grepWithRipgrep(abs, options) {
381
464
  const args = [
382
- "rg --json --no-ignore --hidden",
465
+ "rg --json --hidden --no-require-git",
383
466
  `-g ${shellQuote("!.git/**")}`,
467
+ isInsideNodeModules(abs) ? "" : `-g ${shellQuote("!**/node_modules/**")}`,
384
468
  options.caseSensitive ? "" : "-i",
385
469
  options.maxCountPerFile !== void 0 ? `-m ${Math.max(1, Math.floor(options.maxCountPerFile))}` : "",
386
470
  options.contextLines ? `-C ${Math.max(0, Math.floor(options.contextLines))}` : "",
@@ -390,7 +474,7 @@ var SandboxFilesystem = class SandboxFilesystem {
390
474
  const result = await this.exec(args);
391
475
  if (result.exitCode === 1) return [];
392
476
  const results = this.parseRipgrepJson(result.stdout, abs, options);
393
- if (result.exitCode !== 0 && results.length === 0) throw new UnsupportedGrepPatternError(options.pattern);
477
+ if (result.exitCode !== 0 && results.length === 0) throw new UnsupportedGrepPatternError(options.pattern, describeGrepFailure(result));
394
478
  return results;
395
479
  }
396
480
  parseRipgrepJson(stdout, abs, options) {
@@ -407,14 +491,7 @@ var SandboxFilesystem = class SandboxFilesystem {
407
491
  const filePath = event.data?.path?.text;
408
492
  const lineNumber = event.data?.line_number;
409
493
  if (!filePath || !lineNumber) continue;
410
- let state = files.get(filePath);
411
- if (!state) {
412
- state = {
413
- matches: [],
414
- linesByNumber: /* @__PURE__ */ new Map()
415
- };
416
- files.set(filePath, state);
417
- }
494
+ const state = fileLines(files, filePath);
418
495
  const text = (event.data?.lines?.text ?? "").replace(/\r?\n$/, "");
419
496
  state.linesByNumber.set(lineNumber, text);
420
497
  if (event.type === "match") {
@@ -423,42 +500,11 @@ var SandboxFilesystem = class SandboxFilesystem {
423
500
  state.matches.push({
424
501
  line: lineNumber,
425
502
  column,
426
- text,
427
- lineNumber
503
+ text
428
504
  });
429
505
  }
430
506
  }
431
- const contextLines = options.contextLines ?? 0;
432
- const results = [];
433
- for (const [filePath, state] of files) {
434
- if (state.matches.length === 0) continue;
435
- const rel = posix.relative(abs, filePath) || posix.basename(filePath);
436
- const matches = state.matches.map(({ lineNumber, ...match }) => {
437
- if (contextLines <= 0) return match;
438
- const before = [];
439
- for (let n = lineNumber - 1; n >= Math.max(1, lineNumber - contextLines); n--) {
440
- const t = state.linesByNumber.get(n);
441
- if (t === void 0) break;
442
- before.unshift(t);
443
- }
444
- const after = [];
445
- for (let n = lineNumber + 1; n <= lineNumber + contextLines; n++) {
446
- const t = state.linesByNumber.get(n);
447
- if (t === void 0) break;
448
- after.push(t);
449
- }
450
- return {
451
- ...match,
452
- before,
453
- after
454
- };
455
- });
456
- results.push({
457
- path: rel,
458
- matches
459
- });
460
- }
461
- return this.applyTotalCap(results, options.maxTotalMatches);
507
+ return this.applyTotalCap(toGrepResults(files, abs, options.contextLines ?? 0), options.maxTotalMatches);
462
508
  }
463
509
  /**
464
510
  * Patterns whose meaning differs between POSIX ERE and JS RegExp. The grep
@@ -467,17 +513,113 @@ var SandboxFilesystem = class SandboxFilesystem {
467
513
  * POSIX bracket classes, GNU word anchors) must fall back to the host walk.
468
514
  */
469
515
  static ERE_UNSUPPORTED = /\\[dDwWsSbB<>]|\(\?|[*+?}]\?|\[:[a-z]+:\]/;
470
- async grepWithPosixGrep(abs, options) {
471
- if (SandboxFilesystem.ERE_UNSUPPORTED.test(options.pattern)) throw new UnsupportedGrepPatternError(options.pattern);
472
- let jsRegex;
516
+ /**
517
+ * Escapes that `grep -P` (PCRE) and JS RegExp (without the `u` flag) both
518
+ * accept but read differently, e.g. `\A` is "start of subject" in PCRE and
519
+ * a literal `A` in JS, plus POSIX bracket classes. PCRE-only syntax that JS
520
+ * rejects (inline flags, possessive quantifiers, atomic groups) already
521
+ * fails the JS compile below.
522
+ */
523
+ static PCRE_UNSUPPORTED = /\\[AzZGKQEhHvVRXNCpPe]|\[:[a-z]+:\]/;
524
+ /** Reject patterns grep can't run with the same meaning as JS; return the JS regex used for columns. */
525
+ static grepRegex(options, pcre = false) {
526
+ if (pcre ? SandboxFilesystem.PCRE_UNSUPPORTED.test(options.pattern) : SandboxFilesystem.ERE_UNSUPPORTED.test(options.pattern)) throw new UnsupportedGrepPatternError(options.pattern, pcre ? "grep -P reads this syntax differently from JavaScript" : "POSIX ERE cannot express this syntax");
473
527
  try {
474
- jsRegex = new RegExp(options.pattern, options.caseSensitive ? "" : "i");
528
+ return new RegExp(options.pattern, options.caseSensitive ? "" : "i");
475
529
  } catch {
476
- throw new UnsupportedGrepPatternError(options.pattern);
530
+ throw new UnsupportedGrepPatternError(options.pattern, "invalid regular expression");
531
+ }
532
+ }
533
+ /**
534
+ * GNU grep without ripgrep. Inside a git checkout, `git grep` picks the
535
+ * files (tracked plus untracked, every `.gitignore` applied) and GNU grep
536
+ * prints them with context. Outside a checkout (e.g. a multi-repo root),
537
+ * each child repository is searched the same way and plain grep covers the
538
+ * remaining files, skipping `node_modules`. `--null` ends each file name
539
+ * with NUL, so match (`N:`) and context (`N-`) lines parse unambiguously.
540
+ * When grep and git support it, patterns run as PCRE (`-P`), so `\d`,
541
+ * `\w`, `\s`, `\b`, and lookarounds don't need the host walk.
542
+ */
543
+ async grepWithGnuGrep(abs, options, tools) {
544
+ const hasGit = tools.git;
545
+ const mode = tools.pcre ? "-P" : "-E";
546
+ const jsRegex = SandboxFilesystem.grepRegex(options, tools.pcre);
547
+ const contextLines = Math.max(0, Math.floor(options.contextLines ?? 0));
548
+ const grepFlags = [
549
+ `-HnI${mode.slice(1)} --null`,
550
+ options.caseSensitive ? "" : "-i",
551
+ options.maxCountPerFile !== void 0 ? `-m ${Math.max(1, Math.floor(options.maxCountPerFile))}` : "",
552
+ contextLines > 0 ? `-C ${contextLines}` : ""
553
+ ].filter(Boolean).join(" ");
554
+ const skipNodeModules = !isInsideNodeModules(abs);
555
+ const nodeModulesPathspec = skipNodeModules ? ` ${shellQuote(":(exclude,glob)**/node_modules/**")}` : "";
556
+ const pruneNames = skipNodeModules ? "-name .git -o -name node_modules" : "-name .git";
557
+ const script = [
558
+ `pat=${shellQuote(options.pattern)}`,
559
+ `root=${shellQuote(abs)}`,
560
+ `grep ${mode} -e "$pat" </dev/null >/dev/null 2>&1`,
561
+ "if [ $? -eq 2 ]; then echo \"grep: invalid regular expression\" >&2; exit 2; fi",
562
+ "tmp=$(mktemp -d) || exit 1",
563
+ `trap 'rm -rf "$tmp"' EXIT`,
564
+ `search_files() { xargs -0 -r grep ${grepFlags} -e "$pat" -- 2>/dev/null; }`,
565
+ "search_repo() {",
566
+ ` git -C "$1" grep -l -z -I --untracked ${options.caseSensitive ? "" : "-i "}${mode} -e "$pat" -- .${nodeModulesPathspec} >"$tmp/files" 2>/dev/null`,
567
+ " [ $? -gt 1 ] && return 1",
568
+ ` printf '\\0%s\\n' "$1"`,
569
+ " (cd \"$1\" && search_files) <\"$tmp/files\"",
570
+ "}",
571
+ ...hasGit ? [
572
+ "if git -C \"$root\" rev-parse --is-inside-work-tree >/dev/null 2>&1 && ! git -C \"$root\" check-ignore -q . 2>/dev/null; then",
573
+ " search_repo \"$root\" && exit 0",
574
+ "fi",
575
+ `find "$root" -mindepth 1 -maxdepth 3 \\( ${skipNodeModules ? "-name node_modules -prune" : "-false"} \\) -o \\( -name .git -prune -print \\) >"$tmp/repos" 2>/dev/null`,
576
+ ": >\"$tmp/done\"",
577
+ "while IFS= read -r g; do",
578
+ " d=${g%/.git}",
579
+ " search_repo \"$d\" && printf '%s\\n' \"$d\" >>\"$tmp/done\"",
580
+ "done <\"$tmp/repos\"",
581
+ "set --",
582
+ "while IFS= read -r d; do set -- \"$@\" -o -path \"$d\"; done <\"$tmp/done\""
583
+ ] : ["set --"],
584
+ `printf '\\0%s\\n' "$root"`,
585
+ `find "$root" -mindepth 1 \\( ${pruneNames} "$@" \\) -prune -o -type f -print0 2>/dev/null | search_files`,
586
+ "exit 0"
587
+ ].join("\n");
588
+ const result = await this.exec(script);
589
+ if (result.exitCode !== 0) throw new UnsupportedGrepPatternError(options.pattern, describeGrepFailure(result));
590
+ const files = /* @__PURE__ */ new Map();
591
+ let base = abs;
592
+ for (const line of result.stdout.split("\n")) {
593
+ if (!line || line === "--") continue;
594
+ if (line.startsWith("\0")) {
595
+ base = line.slice(1);
596
+ continue;
597
+ }
598
+ const nul = line.indexOf("\0");
599
+ if (nul <= 0) continue;
600
+ const parsed = /^(\d+)([:-])(.*)$/s.exec(line.slice(nul + 1));
601
+ if (!parsed) continue;
602
+ const lineNumber = Number(parsed[1]);
603
+ const text = parsed[3];
604
+ const state = fileLines(files, posix.resolve(base, line.slice(0, nul)));
605
+ state.linesByNumber.set(lineNumber, text);
606
+ if (parsed[2] !== ":") continue;
607
+ const column = jsRegex.exec(text)?.index;
608
+ if (column === void 0) throw new UnsupportedGrepPatternError(options.pattern, "POSIX ERE and JS RegExp disagree on this pattern");
609
+ state.matches.push({
610
+ line: lineNumber,
611
+ column,
612
+ text
613
+ });
477
614
  }
478
- if (options.contextLines) throw new UnsupportedGrepPatternError(options.pattern);
615
+ return this.applyTotalCap(toGrepResults(files, abs, contextLines), options.maxTotalMatches);
616
+ }
617
+ async grepWithPosixGrep(abs, options) {
618
+ const jsRegex = SandboxFilesystem.grepRegex(options);
619
+ if (options.contextLines) throw new UnsupportedGrepPatternError(options.pattern, "context lines are not supported by POSIX grep");
479
620
  const args = [
480
621
  "grep -rnIE",
622
+ "--exclude-dir=.git",
481
623
  options.caseSensitive ? "" : "-i",
482
624
  options.maxCountPerFile !== void 0 ? `-m ${Math.max(1, Math.floor(options.maxCountPerFile))}` : "",
483
625
  "--",
@@ -486,7 +628,7 @@ var SandboxFilesystem = class SandboxFilesystem {
486
628
  ].filter(Boolean).join(" ");
487
629
  const result = await this.exec(args);
488
630
  if (result.exitCode === 1) return [];
489
- if (result.exitCode !== 0) throw new UnsupportedGrepPatternError(options.pattern);
631
+ if (result.exitCode !== 0 && !(result.exitCode === 2 && result.stdout.trim())) throw new UnsupportedGrepPatternError(options.pattern, describeGrepFailure(result));
490
632
  const byFile = /* @__PURE__ */ new Map();
491
633
  for (const line of result.stdout.split("\n")) {
492
634
  if (!line) continue;
@@ -495,7 +637,7 @@ var SandboxFilesystem = class SandboxFilesystem {
495
637
  const rel = posix.relative(abs, parsed[1]) || posix.basename(parsed[1]);
496
638
  const text = parsed[3];
497
639
  const column = jsRegex.exec(text)?.index;
498
- if (column === void 0) throw new UnsupportedGrepPatternError(options.pattern);
640
+ if (column === void 0) throw new UnsupportedGrepPatternError(options.pattern, "POSIX ERE and JS RegExp disagree on this pattern");
499
641
  let matches = byFile.get(rel);
500
642
  if (!matches) {
501
643
  matches = [];