@caupulican/pi-adaptative 0.85.0 → 0.85.3

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 (88) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/bundled-resources/runtimes/pi-shell-engine/arithmetic.py +364 -0
  3. package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +2 -1
  4. package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +16 -0
  5. package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +137 -14
  6. package/dist/bundled-resources/runtimes/pi-shell-engine/nodes.py +23 -2
  7. package/dist/bundled-resources/runtimes/pi-shell-engine/parser.py +134 -6
  8. package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +25 -2
  9. package/dist/core/agent-session.d.ts.map +1 -1
  10. package/dist/core/agent-session.js +8 -0
  11. package/dist/core/agent-session.js.map +1 -1
  12. package/dist/core/compaction-controller.d.ts +2 -0
  13. package/dist/core/compaction-controller.d.ts.map +1 -1
  14. package/dist/core/compaction-controller.js +35 -13
  15. package/dist/core/compaction-controller.js.map +1 -1
  16. package/dist/core/failure-corpus.d.ts +26 -1
  17. package/dist/core/failure-corpus.d.ts.map +1 -1
  18. package/dist/core/failure-corpus.js +17 -0
  19. package/dist/core/failure-corpus.js.map +1 -1
  20. package/dist/core/model-tool-protocol.d.ts +3 -2
  21. package/dist/core/model-tool-protocol.d.ts.map +1 -1
  22. package/dist/core/model-tool-protocol.js +5 -1
  23. package/dist/core/model-tool-protocol.js.map +1 -1
  24. package/dist/core/models/runtime-process.d.ts +7 -1
  25. package/dist/core/models/runtime-process.d.ts.map +1 -1
  26. package/dist/core/models/runtime-process.js +4 -2
  27. package/dist/core/models/runtime-process.js.map +1 -1
  28. package/dist/core/process-matrix/runtime.js +43 -11
  29. package/dist/core/process-matrix/runtime.js.map +1 -1
  30. package/dist/core/resource-loader.d.ts +2 -0
  31. package/dist/core/resource-loader.d.ts.map +1 -1
  32. package/dist/core/resource-loader.js +18 -6
  33. package/dist/core/resource-loader.js.map +1 -1
  34. package/dist/core/tool-recovery-log-records.d.ts +33 -1
  35. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  36. package/dist/core/tool-recovery-log-records.js +59 -12
  37. package/dist/core/tool-recovery-log-records.js.map +1 -1
  38. package/dist/core/tool-recovery-logger.d.ts +12 -1
  39. package/dist/core/tool-recovery-logger.d.ts.map +1 -1
  40. package/dist/core/tool-recovery-logger.js +24 -1
  41. package/dist/core/tool-recovery-logger.js.map +1 -1
  42. package/dist/core/tool-repair-health.d.ts.map +1 -1
  43. package/dist/core/tool-repair-health.js +6 -0
  44. package/dist/core/tool-repair-health.js.map +1 -1
  45. package/dist/core/tools/bash.d.ts +2 -2
  46. package/dist/core/tools/bash.d.ts.map +1 -1
  47. package/dist/core/tools/bash.js +2 -2
  48. package/dist/core/tools/bash.js.map +1 -1
  49. package/dist/core/tools/find.d.ts +2 -1
  50. package/dist/core/tools/find.d.ts.map +1 -1
  51. package/dist/core/tools/find.js +2 -6
  52. package/dist/core/tools/find.js.map +1 -1
  53. package/dist/core/tools/grep.d.ts +2 -1
  54. package/dist/core/tools/grep.d.ts.map +1 -1
  55. package/dist/core/tools/grep.js +2 -6
  56. package/dist/core/tools/grep.js.map +1 -1
  57. package/dist/core/tools/managed-search-tool.d.ts +8 -0
  58. package/dist/core/tools/managed-search-tool.d.ts.map +1 -0
  59. package/dist/core/tools/managed-search-tool.js +10 -0
  60. package/dist/core/tools/managed-search-tool.js.map +1 -0
  61. package/dist/core/tools/shell-command-parser.d.ts +4 -3
  62. package/dist/core/tools/shell-command-parser.d.ts.map +1 -1
  63. package/dist/core/tools/shell-command-parser.js +32 -7
  64. package/dist/core/tools/shell-command-parser.js.map +1 -1
  65. package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
  66. package/dist/core/tools/shell-contract-router.js +23 -1
  67. package/dist/core/tools/shell-contract-router.js.map +1 -1
  68. package/dist/core/tools/windows-shell-engine.js +1 -1
  69. package/dist/core/tools/windows-shell-engine.js.map +1 -1
  70. package/dist/utils/paths.js +1 -1
  71. package/dist/utils/paths.js.map +1 -1
  72. package/dist/utils/tools-manager.d.ts +18 -1
  73. package/dist/utils/tools-manager.d.ts.map +1 -1
  74. package/dist/utils/tools-manager.js +73 -43
  75. package/dist/utils/tools-manager.js.map +1 -1
  76. package/docs/models.md +1 -1
  77. package/docs/settings.md +1 -1
  78. package/docs/tool-repair.md +3 -3
  79. package/docs/windows.md +7 -5
  80. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  81. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  82. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  83. package/examples/extensions/sandbox/package-lock.json +2 -2
  84. package/examples/extensions/sandbox/package.json +1 -1
  85. package/examples/extensions/with-deps/package-lock.json +2 -2
  86. package/examples/extensions/with-deps/package.json +1 -1
  87. package/npm-shrinkwrap.json +12 -12
  88. package/package.json +4 -4
@@ -5,6 +5,7 @@ import type { ArtifactStore } from "../context/context-artifacts.ts";
5
5
  import { type BroadQueryTracker } from "../context/tool-output-packer.ts";
6
6
  import type { ToolDefinition } from "../extensions/types.ts";
7
7
  import { type FffSearchBackend } from "./fff-search-backend.ts";
8
+ import { type ManagedSearchToolOptions } from "./managed-search-tool.ts";
8
9
  import type { SearchRouter } from "./search-router.ts";
9
10
  declare const grepSchema: Type.TObject<{
10
11
  pattern: Type.TString;
@@ -35,7 +36,7 @@ export interface GrepOperations {
35
36
  /** Read file contents for context lines */
36
37
  readFile: (absolutePath: string) => Promise<string> | string;
37
38
  }
38
- export interface GrepToolOptions {
39
+ export interface GrepToolOptions extends ManagedSearchToolOptions {
39
40
  /** Custom operations for grep. Default: local filesystem plus routed FFF/rg search */
40
41
  operations?: GrepOperations;
41
42
  /** FFF backend for resident indexed search. Set false to force ripgrep fallback. */
@@ -1 +1 @@
1
- {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAIN,KAAK,gBAAgB,EAErB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EACN,KAAK,iBAAiB,EAKtB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAGN,KAAK,gBAAgB,EAGrB,MAAM,yBAAyB,CAAC;AAUjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,QAAA,MAAM,UAAU;;;;;;;;EAYd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAKtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,mEAAmE;IACnE,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAClE,2CAA2C;IAC3C,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC7D;AAOD,MAAM,WAAW,eAAe;IAC/B,sFAAsF;IACtF,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,oFAAoF;IACpF,GAAG,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC;IAC/B,qFAAqF;IACrF,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,yFAAyF;IACzF,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAwPD,wBAAsB,UAAU,CAAC,OAAO,EAAE;IACzC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAAG,SAAS,CAAC,CA8ClE;AAED,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAuShE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG"}
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"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"}
@@ -5,9 +5,9 @@ import { spawn } from "child_process";
5
5
  import path from "path";
6
6
  import { Type } from "typebox";
7
7
  import { waitForChildProcessWithTermination } from "../../utils/child-process.js";
8
- import { ensureTool } from "../../utils/tools-manager.js";
9
8
  import { broadQueryInvalidationNote, formatArtifactNotice, normalizeBroadQueryKey, packToolOutput, } from "../context/tool-output-packer.js";
10
9
  import { hasGitignoreInTree, resolveRoutedFffFinder, } from "./fff-search-backend.js";
10
+ import { resolveManagedSearchTool } from "./managed-search-tool.js";
11
11
  import { resolveToCwd } from "./path-utils.js";
12
12
  import { formatCollapsibleToolResult, invalidArgText, renderTextComponent, shortenPath, str, toolTextResult, } from "./render-utils.js";
13
13
  import { resolveSearchToolRuntime } from "./search-tool-runtime.js";
@@ -337,11 +337,7 @@ export function createGrepToolDefinition(cwd, options) {
337
337
  return;
338
338
  }
339
339
  }
340
- const rgPath = await ensureTool("rg", true);
341
- if (!rgPath) {
342
- settle(() => reject(new Error("ripgrep (rg) is not available and could not be downloaded")));
343
- return;
344
- }
340
+ const rgPath = await resolveManagedSearchTool("rg", options?.managedToolResolver);
345
341
  const fileCache = new Map();
346
342
  const getFileLines = async (filePath) => {
347
343
  let lines = fileCache.get(filePath);
@@ -1 +1 @@
1
- {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile as fsReadFile, stat as fsStat } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateLine,\n} from \"@caupulican/pi-agent-core/node\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { waitForChildProcessWithTermination } from \"../../utils/child-process.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ArtifactStore } from \"../context/context-artifacts.ts\";\nimport {\n\ttype BroadQueryTracker,\n\tbroadQueryInvalidationNote,\n\tformatArtifactNotice,\n\tnormalizeBroadQueryKey,\n\tpackToolOutput,\n} from \"../context/tool-output-packer.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport {\n\ttype FffGrepMatch,\n\ttype FffGrepResult,\n\ttype FffSearchBackend,\n\thasGitignoreInTree,\n\tresolveRoutedFffFinder,\n} from \"./fff-search-backend.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatCollapsibleToolResult,\n\tinvalidArgText,\n\trenderTextComponent,\n\tshortenPath,\n\tstr,\n\ttoolTextResult,\n} from \"./render-utils.ts\";\nimport type { SearchRouter } from \"./search-router.ts\";\nimport { resolveSearchToolRuntime } from \"./search-tool-runtime.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\nconst GREP_PROCESS_TIMEOUT_MS = 5 * 60_000;\nconst GREP_PROCESS_KILL_GRACE_MS = 1_000;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n\t/** Set only when output was packed to an artifact; see tool-output-packer.ts. */\n\tartifactId?: string;\n\t/** Set when this exact query has repeatedly produced broad/truncated results. */\n\tinvalidationCandidate?: boolean;\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: async (p) => (await fsStat(p)).isDirectory(),\n\treadFile: (p) => fsReadFile(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus routed FFF/rg search */\n\toperations?: GrepOperations;\n\t/** FFF backend for resident indexed search. Set false to force ripgrep fallback. */\n\tfff?: FffSearchBackend | false;\n\t/** Pure router that selects FFF or rg from request filters and environment facts. */\n\tsearchRouter?: SearchRouter;\n\t/**\n\t * Opt-in artifact store for first-capture-then-bound output packing (Phase 3). When\n\t * omitted (the default), behavior is byte-for-byte unchanged from before this option\n\t * existed: output is truncated the same way, just never artifact-backed.\n\t */\n\tartifactStore?: ArtifactStore;\n\t/** Opt-in tracker for repeated-broad-query \"do not repeat\" signals. Also default-off. */\n\tbroadQueryTracker?: BroadQueryTracker;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: Theme,\n\tcwd: string,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\", cwd) : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\treturn formatCollapsibleToolResult({\n\t\tresult,\n\t\toptions,\n\t\ttheme,\n\t\tshowImages,\n\t\tcollapsedLineLimit: 15,\n\t\twarnings: (details) => {\n\t\t\tconst warnings: string[] = [];\n\t\t\tif (details?.matchLimitReached) warnings.push(`${details.matchLimitReached} matches limit`);\n\t\t\tif (details?.truncation?.truncated) {\n\t\t\t\twarnings.push(`${formatSize(details.truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\t\t}\n\t\t\tif (details?.linesTruncated) warnings.push(\"some lines truncated\");\n\t\t\treturn warnings;\n\t\t},\n\t});\n}\n\nfunction globConstraintForFff(glob: string | undefined): string {\n\tif (!glob) return \"\";\n\tif (glob.includes(\"/\") || glob.startsWith(\"**/\")) return glob;\n\treturn `**/${glob}`;\n}\n\nfunction fffGrepQuery(options: {\n\tpattern: string;\n\tglob?: string;\n\tisDirectory: boolean;\n\tsearchPathRelativeToCwd: string;\n}): string | undefined {\n\tconst parts: string[] = [];\n\tif (options.searchPathRelativeToCwd) {\n\t\tparts.push(options.isDirectory ? `${options.searchPathRelativeToCwd}/` : options.searchPathRelativeToCwd);\n\t}\n\tparts.push(globConstraintForFff(options.glob));\n\tparts.push(options.pattern);\n\treturn parts.filter(Boolean).join(\" \");\n}\n\nfunction fffDisplayPath(\n\tmatch: FffGrepMatch,\n\toptions: { isDirectory: boolean; searchPathRelativeToCwd: string },\n): string | undefined {\n\tconst relativePath = match.relativePath.replaceAll(\"\\\\\", \"/\");\n\tif (!options.searchPathRelativeToCwd) return relativePath;\n\tif (!options.isDirectory) {\n\t\treturn relativePath === options.searchPathRelativeToCwd ? path.posix.basename(relativePath) : undefined;\n\t}\n\tconst prefix = `${options.searchPathRelativeToCwd}/`;\n\tif (!relativePath.startsWith(prefix)) return undefined;\n\treturn relativePath.slice(prefix.length);\n}\n\nfunction appendFffMatchLines(options: {\n\tmatch: FffGrepMatch;\n\toutputLines: string[];\n\tlinesTruncated: { value: boolean };\n\tcontextValue: number;\n}): void {\n\tconst before = options.match.contextBefore ?? [];\n\tfor (let i = 0; i < before.length; i++) {\n\t\tconst lineNumber = options.match.lineNumber - before.length + i;\n\t\tconst { text, wasTruncated } = truncateLine(before[i] ?? \"\");\n\t\tif (wasTruncated) options.linesTruncated.value = true;\n\t\toptions.outputLines.push(` ${lineNumber}- ${text}`);\n\t}\n\n\tconst { text, wasTruncated } = truncateLine(options.match.lineContent.replace(/\\r/g, \"\"));\n\tif (wasTruncated) options.linesTruncated.value = true;\n\toptions.outputLines.push(` ${options.match.lineNumber}: ${text}`);\n\n\tif (options.contextValue === 0) return;\n\tconst after = options.match.contextAfter ?? [];\n\tfor (let i = 0; i < after.length; i++) {\n\t\tconst lineNumber = options.match.lineNumber + 1 + i;\n\t\tconst { text: contextText, wasTruncated: contextWasTruncated } = truncateLine(after[i] ?? \"\");\n\t\tif (contextWasTruncated) options.linesTruncated.value = true;\n\t\toptions.outputLines.push(` ${lineNumber}- ${contextText}`);\n\t}\n}\n\n/**\n * Shared \"measure -> pack -> notices\" tail for both the FFF and ripgrep result paths:\n * first-capture the raw output to an artifact if it's oversized and a store was provided\n * (Phase 3 tool-output-artifacts.md boundary rule), then append the same match-limit/\n * byte-limit/line-truncation/broad-query notices either path already produced.\n */\nfunction packGrepOutput(options: {\n\trawOutput: string;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\tpattern: string;\n\trawPath?: string;\n\tglob?: string;\n\tmatchLimitReached: number | false;\n\tlinesTruncated: boolean;\n}): { text: string; details: GrepToolDetails } {\n\tconst packed = packToolOutput(\n\t\t{\n\t\t\ttoolName: \"grep\",\n\t\t\tpath: options.rawPath,\n\t\t\trawContent: options.rawOutput,\n\t\t\t// No line limit here because the match limit already caps rows; only the byte\n\t\t\t// cap should apply, matching the pre-Slice-B truncateHead call exactly.\n\t\t\ttruncation: { maxLines: Number.MAX_SAFE_INTEGER },\n\t\t},\n\t\toptions.artifactStore,\n\t\toptions.toolCallId,\n\t);\n\tlet output = packed.content;\n\tconst details: GrepToolDetails = {};\n\n\tconst notices: string[] = [];\n\tif (packed.artifactId) {\n\t\tnotices.push(formatArtifactNotice(packed.artifactId));\n\t\tdetails.artifactId = packed.artifactId;\n\t}\n\tif (options.matchLimitReached) {\n\t\tnotices.push(\n\t\t\t`${options.matchLimitReached} matches limit reached. Use limit=${options.matchLimitReached * 2} for more, or refine pattern`,\n\t\t);\n\t\tdetails.matchLimitReached = options.matchLimitReached;\n\t}\n\tif (packed.truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t// Drop the duplicated bounded-preview text: it's already in the message's own\n\t\t// content, and re-including it here can push `details` past\n\t\t// MAX_RETAINED_TOOL_RESULT_DETAILS_BYTES (message-retention.ts), which replaces\n\t\t// the *entire* details object with a stub -- silently losing artifactId and every\n\t\t// other field alongside it. This is load-bearing beyond just the retention budget:\n\t\t// agent-session.ts's _releaseGcPackedArtifactReferences() reads artifactId back off\n\t\t// this same canonical message at eviction time (potentially many turns later), so\n\t\t// keeping `details` small here is what keeps that release path working at all. If\n\t\t// this field ever grows a large addition again, add a regression proving artifactId\n\t\t// survives compactToolResultDetailsForRetention (see\n\t\t// test/suite/agent-session-artifact-lifecycle.test.ts), not just a details-size check.\n\t\tdetails.truncation = { ...packed.truncation, content: \"\" };\n\t}\n\tif (options.linesTruncated) {\n\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n\t\tdetails.linesTruncated = true;\n\t}\n\tif (options.matchLimitReached || packed.truncation.truncated) {\n\t\tconst note = broadQueryInvalidationNote(\n\t\t\toptions.broadQueryTracker,\n\t\t\tnormalizeBroadQueryKey({\n\t\t\t\ttoolName: \"grep\",\n\t\t\t\tpattern: options.pattern,\n\t\t\t\tpath: options.rawPath,\n\t\t\t\tglob: options.glob,\n\t\t\t}),\n\t\t\t`grep \"${options.pattern}\" in ${options.rawPath ?? \".\"}`,\n\t\t);\n\t\tif (note) {\n\t\t\tnotices.push(note);\n\t\t\tdetails.invalidationCandidate = true;\n\t\t}\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn { text: output, details };\n}\n\nfunction formatFffGrepResult(options: {\n\tresult: FffGrepResult;\n\tisDirectory: boolean;\n\tsearchPathRelativeToCwd: string;\n\teffectiveLimit: number;\n\tcontextValue: number;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\tpattern: string;\n\trawPath?: string;\n\tglob?: string;\n}): { text: string; details: GrepToolDetails } {\n\tif (options.result.items.length === 0) return { text: \"No matches found\", details: {} };\n\n\tconst outputLines: string[] = [];\n\tconst linesTruncated = { value: false };\n\tconst resultLimitReached =\n\t\toptions.result.items.length > options.effectiveLimit || Boolean(options.result.nextCursor);\n\tconst displayedMatches = resultLimitReached\n\t\t? options.result.items.slice(0, options.effectiveLimit)\n\t\t: options.result.items;\n\tlet currentPath = \"\";\n\tfor (const match of displayedMatches) {\n\t\tconst displayPath = fffDisplayPath(match, options);\n\t\tif (!displayPath) continue;\n\t\tif (displayPath !== currentPath) {\n\t\t\tcurrentPath = displayPath;\n\t\t\toutputLines.push(`${displayPath}:`);\n\t\t}\n\t\tappendFffMatchLines({\n\t\t\tmatch,\n\t\t\toutputLines,\n\t\t\tlinesTruncated,\n\t\t\tcontextValue: options.contextValue,\n\t\t});\n\t}\n\n\tif (outputLines.length === 0) return { text: \"No matches found\", details: {} };\n\tconst rawOutput = outputLines.join(\"\\n\");\n\treturn packGrepOutput({\n\t\trawOutput,\n\t\ttoolCallId: options.toolCallId,\n\t\tartifactStore: options.artifactStore,\n\t\tbroadQueryTracker: options.broadQueryTracker,\n\t\tpattern: options.pattern,\n\t\trawPath: options.rawPath,\n\t\tglob: options.glob,\n\t\tmatchLimitReached: resultLimitReached ? options.effectiveLimit : false,\n\t\tlinesTruncated: linesTruncated.value,\n\t});\n}\n\nexport async function tryFffGrep(options: {\n\tbackend: FffSearchBackend;\n\trouter: SearchRouter;\n\tcwd: string;\n\tsearchPath: string;\n\tpattern: string;\n\tglob?: string;\n\tignoreCase?: boolean;\n\tliteral?: boolean;\n\tcontextValue: number;\n\teffectiveLimit: number;\n\tisDirectory: boolean;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\trawPath?: string;\n}): Promise<{ text: string; details: GrepToolDetails } | undefined> {\n\tconst routed = await resolveRoutedFffFinder({\n\t\tbackend: options.backend,\n\t\trouter: options.router,\n\t\ttool: \"grep\",\n\t\tcwd: options.cwd,\n\t\tsearchPath: options.searchPath,\n\t\tglob: Boolean(options.glob),\n\t\tignoreCase: Boolean(options.ignoreCase),\n\t\tlimit: options.effectiveLimit,\n\t\treadGitignoreInTree: () => (options.isDirectory ? hasGitignoreInTree(options.searchPath) : false),\n\t});\n\tif (!routed) return undefined;\n\tconst { finder, searchPathRelativeToCwd } = routed;\n\n\tconst query = fffGrepQuery({\n\t\tpattern: options.pattern,\n\t\tglob: options.glob,\n\t\tisDirectory: options.isDirectory,\n\t\tsearchPathRelativeToCwd,\n\t});\n\tif (!query) return undefined;\n\n\tconst probeLimit = options.effectiveLimit + 1;\n\tconst result = finder.grep(query, {\n\t\tmode: options.literal ? \"plain\" : \"regex\",\n\t\tsmartCase: false,\n\t\tmaxMatchesPerFile: probeLimit,\n\t\tbeforeContext: options.contextValue,\n\t\tafterContext: options.contextValue,\n\t\tpageSize: probeLimit,\n\t});\n\tif (!result.ok || result.value.regexFallbackError) return undefined;\n\treturn formatFffGrepResult({\n\t\tresult: result.value,\n\t\tisDirectory: options.isDirectory,\n\t\tsearchPathRelativeToCwd,\n\t\teffectiveLimit: options.effectiveLimit,\n\t\tcontextValue: options.contextValue,\n\t\ttoolCallId: options.toolCallId,\n\t\tartifactStore: options.artifactStore,\n\t\tbroadQueryTracker: options.broadQueryTracker,\n\t\tpattern: options.pattern,\n\t\trawPath: options.rawPath,\n\t\tglob: options.glob,\n\t});\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst search = resolveSearchToolRuntime(options);\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tpromptGuidelines: [\n\t\t\t\"Scope grep to the narrowest known root and glob; discover candidate paths first instead of repeatedly scanning an entire repository, home directory, or filesystem.\",\n\t\t],\n\t\tparameters: grepSchema,\n\t\ttoolGroup: \"explore\",\n\t\tasync execute(\n\t\t\ttoolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = search.operations ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (!search.operations && search.fffBackend) {\n\t\t\t\t\t\t\tconst fffResult = await tryFffGrep({\n\t\t\t\t\t\t\t\tbackend: search.fffBackend,\n\t\t\t\t\t\t\t\trouter: search.searchRouter,\n\t\t\t\t\t\t\t\tcwd,\n\t\t\t\t\t\t\t\tsearchPath,\n\t\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\t\tglob,\n\t\t\t\t\t\t\t\tignoreCase,\n\t\t\t\t\t\t\t\tliteral,\n\t\t\t\t\t\t\t\tcontextValue,\n\t\t\t\t\t\t\t\teffectiveLimit,\n\t\t\t\t\t\t\t\tisDirectory,\n\t\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\t\tartifactStore: search.artifactStore,\n\t\t\t\t\t\t\t\tbroadQueryTracker: search.broadQueryTracker,\n\t\t\t\t\t\t\t\trawPath: searchDir,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (fffResult) {\n\t\t\t\t\t\t\t\tsettle(() => resolve(toolTextResult(fffResult)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rgPath = await ensureTool(\"rg\", true);\n\t\t\t\t\t\tif (!rgPath) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"ripgrep (rg) is not available and could not be downloaded\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, {\n\t\t\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst terminationController = new AbortController();\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (dueToLimit) killedDueToLimit = true;\n\t\t\t\t\t\t\tterminationController.abort();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (signal?.aborted) onAbort();\n\t\t\t\t\t\telse signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [`${relativePath}:${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${relativePath}:${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${relativePath}-${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchLimitReached) return;\n\t\t\t\t\t\t\tlet event: any;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.type === \"match\") {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tif (matchCount > effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (filePath && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst terminal = await waitForChildProcessWithTermination(child, {\n\t\t\t\t\t\t\tsignal: terminationController.signal,\n\t\t\t\t\t\t\ttimeoutMs: GREP_PROCESS_TIMEOUT_MS,\n\t\t\t\t\t\t\tkillGraceMs: GREP_PROCESS_KILL_GRACE_MS,\n\t\t\t\t\t\t}).finally(cleanup);\n\t\t\t\t\t\tconst code = terminal.code;\n\t\t\t\t\t\tif (terminal.reason === \"timeout\") {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`ripgrep timed out after ${GREP_PROCESS_TIMEOUT_MS}ms`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Format matches after streaming finishes so custom readFile() backends can be async.\n\t\t\t\t\t\tconst fileGroups = new Map<string, string[]>();\n\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\tconst relativePath = formatPath(match.filePath);\n\t\t\t\t\t\t\tif (!fileGroups.has(relativePath)) {\n\t\t\t\t\t\t\t\tfileGroups.set(relativePath, []);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst group = fileGroups.get(relativePath)!;\n\n\t\t\t\t\t\t\tif (contextValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\tconst sanitized = match.lineText.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\").replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tgroup.push(` ${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\tfor (const line of block) {\n\t\t\t\t\t\t\t\t\tif (line.startsWith(`${relativePath}:`)) {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line.slice(relativePath.length + 1)}`);\n\t\t\t\t\t\t\t\t\t} else if (line.startsWith(`${relativePath}-`)) {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line.slice(relativePath.length + 1)}`);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line}`);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (const [relativePath, lines] of fileGroups) {\n\t\t\t\t\t\t\toutputLines.push(`${relativePath}:`);\n\t\t\t\t\t\t\tlet lastLine = \"\";\n\t\t\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\t\t\tif (line === lastLine) continue;\n\t\t\t\t\t\t\t\toutputLines.push(line);\n\t\t\t\t\t\t\t\tlastLine = line;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t// Measure -> pack (artifact-backed if oversized and a store was provided) -> notices.\n\t\t\t\t\t\t// There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\tconst { text: output, details } = packGrepOutput({\n\t\t\t\t\t\t\trawOutput,\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\tartifactStore: search.artifactStore,\n\t\t\t\t\t\t\tbroadQueryTracker: search.broadQueryTracker,\n\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\trawPath: searchDir,\n\t\t\t\t\t\t\tglob,\n\t\t\t\t\t\t\tmatchLimitReached: matchLimitReached ? effectiveLimit : false,\n\t\t\t\t\t\t\tlinesTruncated,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tsettle(() => resolve(toolTextResult({ text: output, details })));\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\treturn renderTextComponent(context.lastComponent, formatGrepCall(args, theme, context.cwd));\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\treturn renderTextComponent(\n\t\t\t\tcontext.lastComponent,\n\t\t\t\tformatGrepResult(result as Parameters<typeof formatGrepResult>[0], options, theme, context.showImages),\n\t\t\t);\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile as fsReadFile, stat as fsStat } from \"node:fs/promises\";\nimport { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateLine,\n} from \"@caupulican/pi-agent-core/node\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { waitForChildProcessWithTermination } from \"../../utils/child-process.ts\";\nimport type { ArtifactStore } from \"../context/context-artifacts.ts\";\nimport {\n\ttype BroadQueryTracker,\n\tbroadQueryInvalidationNote,\n\tformatArtifactNotice,\n\tnormalizeBroadQueryKey,\n\tpackToolOutput,\n} from \"../context/tool-output-packer.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport {\n\ttype FffGrepMatch,\n\ttype FffGrepResult,\n\ttype FffSearchBackend,\n\thasGitignoreInTree,\n\tresolveRoutedFffFinder,\n} from \"./fff-search-backend.ts\";\nimport { type ManagedSearchToolOptions, resolveManagedSearchTool } from \"./managed-search-tool.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatCollapsibleToolResult,\n\tinvalidArgText,\n\trenderTextComponent,\n\tshortenPath,\n\tstr,\n\ttoolTextResult,\n} from \"./render-utils.ts\";\nimport type { SearchRouter } from \"./search-router.ts\";\nimport { resolveSearchToolRuntime } from \"./search-tool-runtime.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\nconst GREP_PROCESS_TIMEOUT_MS = 5 * 60_000;\nconst GREP_PROCESS_KILL_GRACE_MS = 1_000;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n\t/** Set only when output was packed to an artifact; see tool-output-packer.ts. */\n\tartifactId?: string;\n\t/** Set when this exact query has repeatedly produced broad/truncated results. */\n\tinvalidationCandidate?: boolean;\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: async (p) => (await fsStat(p)).isDirectory(),\n\treadFile: (p) => fsReadFile(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions extends ManagedSearchToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus routed FFF/rg search */\n\toperations?: GrepOperations;\n\t/** FFF backend for resident indexed search. Set false to force ripgrep fallback. */\n\tfff?: FffSearchBackend | false;\n\t/** Pure router that selects FFF or rg from request filters and environment facts. */\n\tsearchRouter?: SearchRouter;\n\t/**\n\t * Opt-in artifact store for first-capture-then-bound output packing (Phase 3). When\n\t * omitted (the default), behavior is byte-for-byte unchanged from before this option\n\t * existed: output is truncated the same way, just never artifact-backed.\n\t */\n\tartifactStore?: ArtifactStore;\n\t/** Opt-in tracker for repeated-broad-query \"do not repeat\" signals. Also default-off. */\n\tbroadQueryTracker?: BroadQueryTracker;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: Theme,\n\tcwd: string,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\", cwd) : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\treturn formatCollapsibleToolResult({\n\t\tresult,\n\t\toptions,\n\t\ttheme,\n\t\tshowImages,\n\t\tcollapsedLineLimit: 15,\n\t\twarnings: (details) => {\n\t\t\tconst warnings: string[] = [];\n\t\t\tif (details?.matchLimitReached) warnings.push(`${details.matchLimitReached} matches limit`);\n\t\t\tif (details?.truncation?.truncated) {\n\t\t\t\twarnings.push(`${formatSize(details.truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\t\t}\n\t\t\tif (details?.linesTruncated) warnings.push(\"some lines truncated\");\n\t\t\treturn warnings;\n\t\t},\n\t});\n}\n\nfunction globConstraintForFff(glob: string | undefined): string {\n\tif (!glob) return \"\";\n\tif (glob.includes(\"/\") || glob.startsWith(\"**/\")) return glob;\n\treturn `**/${glob}`;\n}\n\nfunction fffGrepQuery(options: {\n\tpattern: string;\n\tglob?: string;\n\tisDirectory: boolean;\n\tsearchPathRelativeToCwd: string;\n}): string | undefined {\n\tconst parts: string[] = [];\n\tif (options.searchPathRelativeToCwd) {\n\t\tparts.push(options.isDirectory ? `${options.searchPathRelativeToCwd}/` : options.searchPathRelativeToCwd);\n\t}\n\tparts.push(globConstraintForFff(options.glob));\n\tparts.push(options.pattern);\n\treturn parts.filter(Boolean).join(\" \");\n}\n\nfunction fffDisplayPath(\n\tmatch: FffGrepMatch,\n\toptions: { isDirectory: boolean; searchPathRelativeToCwd: string },\n): string | undefined {\n\tconst relativePath = match.relativePath.replaceAll(\"\\\\\", \"/\");\n\tif (!options.searchPathRelativeToCwd) return relativePath;\n\tif (!options.isDirectory) {\n\t\treturn relativePath === options.searchPathRelativeToCwd ? path.posix.basename(relativePath) : undefined;\n\t}\n\tconst prefix = `${options.searchPathRelativeToCwd}/`;\n\tif (!relativePath.startsWith(prefix)) return undefined;\n\treturn relativePath.slice(prefix.length);\n}\n\nfunction appendFffMatchLines(options: {\n\tmatch: FffGrepMatch;\n\toutputLines: string[];\n\tlinesTruncated: { value: boolean };\n\tcontextValue: number;\n}): void {\n\tconst before = options.match.contextBefore ?? [];\n\tfor (let i = 0; i < before.length; i++) {\n\t\tconst lineNumber = options.match.lineNumber - before.length + i;\n\t\tconst { text, wasTruncated } = truncateLine(before[i] ?? \"\");\n\t\tif (wasTruncated) options.linesTruncated.value = true;\n\t\toptions.outputLines.push(` ${lineNumber}- ${text}`);\n\t}\n\n\tconst { text, wasTruncated } = truncateLine(options.match.lineContent.replace(/\\r/g, \"\"));\n\tif (wasTruncated) options.linesTruncated.value = true;\n\toptions.outputLines.push(` ${options.match.lineNumber}: ${text}`);\n\n\tif (options.contextValue === 0) return;\n\tconst after = options.match.contextAfter ?? [];\n\tfor (let i = 0; i < after.length; i++) {\n\t\tconst lineNumber = options.match.lineNumber + 1 + i;\n\t\tconst { text: contextText, wasTruncated: contextWasTruncated } = truncateLine(after[i] ?? \"\");\n\t\tif (contextWasTruncated) options.linesTruncated.value = true;\n\t\toptions.outputLines.push(` ${lineNumber}- ${contextText}`);\n\t}\n}\n\n/**\n * Shared \"measure -> pack -> notices\" tail for both the FFF and ripgrep result paths:\n * first-capture the raw output to an artifact if it's oversized and a store was provided\n * (Phase 3 tool-output-artifacts.md boundary rule), then append the same match-limit/\n * byte-limit/line-truncation/broad-query notices either path already produced.\n */\nfunction packGrepOutput(options: {\n\trawOutput: string;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\tpattern: string;\n\trawPath?: string;\n\tglob?: string;\n\tmatchLimitReached: number | false;\n\tlinesTruncated: boolean;\n}): { text: string; details: GrepToolDetails } {\n\tconst packed = packToolOutput(\n\t\t{\n\t\t\ttoolName: \"grep\",\n\t\t\tpath: options.rawPath,\n\t\t\trawContent: options.rawOutput,\n\t\t\t// No line limit here because the match limit already caps rows; only the byte\n\t\t\t// cap should apply, matching the pre-Slice-B truncateHead call exactly.\n\t\t\ttruncation: { maxLines: Number.MAX_SAFE_INTEGER },\n\t\t},\n\t\toptions.artifactStore,\n\t\toptions.toolCallId,\n\t);\n\tlet output = packed.content;\n\tconst details: GrepToolDetails = {};\n\n\tconst notices: string[] = [];\n\tif (packed.artifactId) {\n\t\tnotices.push(formatArtifactNotice(packed.artifactId));\n\t\tdetails.artifactId = packed.artifactId;\n\t}\n\tif (options.matchLimitReached) {\n\t\tnotices.push(\n\t\t\t`${options.matchLimitReached} matches limit reached. Use limit=${options.matchLimitReached * 2} for more, or refine pattern`,\n\t\t);\n\t\tdetails.matchLimitReached = options.matchLimitReached;\n\t}\n\tif (packed.truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t// Drop the duplicated bounded-preview text: it's already in the message's own\n\t\t// content, and re-including it here can push `details` past\n\t\t// MAX_RETAINED_TOOL_RESULT_DETAILS_BYTES (message-retention.ts), which replaces\n\t\t// the *entire* details object with a stub -- silently losing artifactId and every\n\t\t// other field alongside it. This is load-bearing beyond just the retention budget:\n\t\t// agent-session.ts's _releaseGcPackedArtifactReferences() reads artifactId back off\n\t\t// this same canonical message at eviction time (potentially many turns later), so\n\t\t// keeping `details` small here is what keeps that release path working at all. If\n\t\t// this field ever grows a large addition again, add a regression proving artifactId\n\t\t// survives compactToolResultDetailsForRetention (see\n\t\t// test/suite/agent-session-artifact-lifecycle.test.ts), not just a details-size check.\n\t\tdetails.truncation = { ...packed.truncation, content: \"\" };\n\t}\n\tif (options.linesTruncated) {\n\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);\n\t\tdetails.linesTruncated = true;\n\t}\n\tif (options.matchLimitReached || packed.truncation.truncated) {\n\t\tconst note = broadQueryInvalidationNote(\n\t\t\toptions.broadQueryTracker,\n\t\t\tnormalizeBroadQueryKey({\n\t\t\t\ttoolName: \"grep\",\n\t\t\t\tpattern: options.pattern,\n\t\t\t\tpath: options.rawPath,\n\t\t\t\tglob: options.glob,\n\t\t\t}),\n\t\t\t`grep \"${options.pattern}\" in ${options.rawPath ?? \".\"}`,\n\t\t);\n\t\tif (note) {\n\t\t\tnotices.push(note);\n\t\t\tdetails.invalidationCandidate = true;\n\t\t}\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn { text: output, details };\n}\n\nfunction formatFffGrepResult(options: {\n\tresult: FffGrepResult;\n\tisDirectory: boolean;\n\tsearchPathRelativeToCwd: string;\n\teffectiveLimit: number;\n\tcontextValue: number;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\tpattern: string;\n\trawPath?: string;\n\tglob?: string;\n}): { text: string; details: GrepToolDetails } {\n\tif (options.result.items.length === 0) return { text: \"No matches found\", details: {} };\n\n\tconst outputLines: string[] = [];\n\tconst linesTruncated = { value: false };\n\tconst resultLimitReached =\n\t\toptions.result.items.length > options.effectiveLimit || Boolean(options.result.nextCursor);\n\tconst displayedMatches = resultLimitReached\n\t\t? options.result.items.slice(0, options.effectiveLimit)\n\t\t: options.result.items;\n\tlet currentPath = \"\";\n\tfor (const match of displayedMatches) {\n\t\tconst displayPath = fffDisplayPath(match, options);\n\t\tif (!displayPath) continue;\n\t\tif (displayPath !== currentPath) {\n\t\t\tcurrentPath = displayPath;\n\t\t\toutputLines.push(`${displayPath}:`);\n\t\t}\n\t\tappendFffMatchLines({\n\t\t\tmatch,\n\t\t\toutputLines,\n\t\t\tlinesTruncated,\n\t\t\tcontextValue: options.contextValue,\n\t\t});\n\t}\n\n\tif (outputLines.length === 0) return { text: \"No matches found\", details: {} };\n\tconst rawOutput = outputLines.join(\"\\n\");\n\treturn packGrepOutput({\n\t\trawOutput,\n\t\ttoolCallId: options.toolCallId,\n\t\tartifactStore: options.artifactStore,\n\t\tbroadQueryTracker: options.broadQueryTracker,\n\t\tpattern: options.pattern,\n\t\trawPath: options.rawPath,\n\t\tglob: options.glob,\n\t\tmatchLimitReached: resultLimitReached ? options.effectiveLimit : false,\n\t\tlinesTruncated: linesTruncated.value,\n\t});\n}\n\nexport async function tryFffGrep(options: {\n\tbackend: FffSearchBackend;\n\trouter: SearchRouter;\n\tcwd: string;\n\tsearchPath: string;\n\tpattern: string;\n\tglob?: string;\n\tignoreCase?: boolean;\n\tliteral?: boolean;\n\tcontextValue: number;\n\teffectiveLimit: number;\n\tisDirectory: boolean;\n\ttoolCallId: string;\n\tartifactStore?: ArtifactStore;\n\tbroadQueryTracker?: BroadQueryTracker;\n\trawPath?: string;\n}): Promise<{ text: string; details: GrepToolDetails } | undefined> {\n\tconst routed = await resolveRoutedFffFinder({\n\t\tbackend: options.backend,\n\t\trouter: options.router,\n\t\ttool: \"grep\",\n\t\tcwd: options.cwd,\n\t\tsearchPath: options.searchPath,\n\t\tglob: Boolean(options.glob),\n\t\tignoreCase: Boolean(options.ignoreCase),\n\t\tlimit: options.effectiveLimit,\n\t\treadGitignoreInTree: () => (options.isDirectory ? hasGitignoreInTree(options.searchPath) : false),\n\t});\n\tif (!routed) return undefined;\n\tconst { finder, searchPathRelativeToCwd } = routed;\n\n\tconst query = fffGrepQuery({\n\t\tpattern: options.pattern,\n\t\tglob: options.glob,\n\t\tisDirectory: options.isDirectory,\n\t\tsearchPathRelativeToCwd,\n\t});\n\tif (!query) return undefined;\n\n\tconst probeLimit = options.effectiveLimit + 1;\n\tconst result = finder.grep(query, {\n\t\tmode: options.literal ? \"plain\" : \"regex\",\n\t\tsmartCase: false,\n\t\tmaxMatchesPerFile: probeLimit,\n\t\tbeforeContext: options.contextValue,\n\t\tafterContext: options.contextValue,\n\t\tpageSize: probeLimit,\n\t});\n\tif (!result.ok || result.value.regexFallbackError) return undefined;\n\treturn formatFffGrepResult({\n\t\tresult: result.value,\n\t\tisDirectory: options.isDirectory,\n\t\tsearchPathRelativeToCwd,\n\t\teffectiveLimit: options.effectiveLimit,\n\t\tcontextValue: options.contextValue,\n\t\ttoolCallId: options.toolCallId,\n\t\tartifactStore: options.artifactStore,\n\t\tbroadQueryTracker: options.broadQueryTracker,\n\t\tpattern: options.pattern,\n\t\trawPath: options.rawPath,\n\t\tglob: options.glob,\n\t});\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst search = resolveSearchToolRuntime(options);\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tpromptGuidelines: [\n\t\t\t\"Scope grep to the narrowest known root and glob; discover candidate paths first instead of repeatedly scanning an entire repository, home directory, or filesystem.\",\n\t\t],\n\t\tparameters: grepSchema,\n\t\ttoolGroup: \"explore\",\n\t\tasync execute(\n\t\t\ttoolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = search.operations ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (!search.operations && search.fffBackend) {\n\t\t\t\t\t\t\tconst fffResult = await tryFffGrep({\n\t\t\t\t\t\t\t\tbackend: search.fffBackend,\n\t\t\t\t\t\t\t\trouter: search.searchRouter,\n\t\t\t\t\t\t\t\tcwd,\n\t\t\t\t\t\t\t\tsearchPath,\n\t\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\t\tglob,\n\t\t\t\t\t\t\t\tignoreCase,\n\t\t\t\t\t\t\t\tliteral,\n\t\t\t\t\t\t\t\tcontextValue,\n\t\t\t\t\t\t\t\teffectiveLimit,\n\t\t\t\t\t\t\t\tisDirectory,\n\t\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\t\tartifactStore: search.artifactStore,\n\t\t\t\t\t\t\t\tbroadQueryTracker: search.broadQueryTracker,\n\t\t\t\t\t\t\t\trawPath: searchDir,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (fffResult) {\n\t\t\t\t\t\t\t\tsettle(() => resolve(toolTextResult(fffResult)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rgPath = await resolveManagedSearchTool(\"rg\", options?.managedToolResolver);\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, {\n\t\t\t\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst terminationController = new AbortController();\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (dueToLimit) killedDueToLimit = true;\n\t\t\t\t\t\t\tterminationController.abort();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (signal?.aborted) onAbort();\n\t\t\t\t\t\telse signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [`${relativePath}:${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${relativePath}:${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${relativePath}-${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchLimitReached) return;\n\t\t\t\t\t\t\tlet event: any;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.type === \"match\") {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tif (matchCount > effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (filePath && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst terminal = await waitForChildProcessWithTermination(child, {\n\t\t\t\t\t\t\tsignal: terminationController.signal,\n\t\t\t\t\t\t\ttimeoutMs: GREP_PROCESS_TIMEOUT_MS,\n\t\t\t\t\t\t\tkillGraceMs: GREP_PROCESS_KILL_GRACE_MS,\n\t\t\t\t\t\t}).finally(cleanup);\n\t\t\t\t\t\tconst code = terminal.code;\n\t\t\t\t\t\tif (terminal.reason === \"timeout\") {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`ripgrep timed out after ${GREP_PROCESS_TIMEOUT_MS}ms`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Format matches after streaming finishes so custom readFile() backends can be async.\n\t\t\t\t\t\tconst fileGroups = new Map<string, string[]>();\n\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\tconst relativePath = formatPath(match.filePath);\n\t\t\t\t\t\t\tif (!fileGroups.has(relativePath)) {\n\t\t\t\t\t\t\t\tfileGroups.set(relativePath, []);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst group = fileGroups.get(relativePath)!;\n\n\t\t\t\t\t\t\tif (contextValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\tconst sanitized = match.lineText.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\").replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tgroup.push(` ${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\tfor (const line of block) {\n\t\t\t\t\t\t\t\t\tif (line.startsWith(`${relativePath}:`)) {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line.slice(relativePath.length + 1)}`);\n\t\t\t\t\t\t\t\t\t} else if (line.startsWith(`${relativePath}-`)) {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line.slice(relativePath.length + 1)}`);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tgroup.push(` ${line}`);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (const [relativePath, lines] of fileGroups) {\n\t\t\t\t\t\t\toutputLines.push(`${relativePath}:`);\n\t\t\t\t\t\t\tlet lastLine = \"\";\n\t\t\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\t\t\tif (line === lastLine) continue;\n\t\t\t\t\t\t\t\toutputLines.push(line);\n\t\t\t\t\t\t\t\tlastLine = line;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t// Measure -> pack (artifact-backed if oversized and a store was provided) -> notices.\n\t\t\t\t\t\t// There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\tconst { text: output, details } = packGrepOutput({\n\t\t\t\t\t\t\trawOutput,\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\tartifactStore: search.artifactStore,\n\t\t\t\t\t\t\tbroadQueryTracker: search.broadQueryTracker,\n\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\trawPath: searchDir,\n\t\t\t\t\t\t\tglob,\n\t\t\t\t\t\t\tmatchLimitReached: matchLimitReached ? effectiveLimit : false,\n\t\t\t\t\t\t\tlinesTruncated,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tsettle(() => resolve(toolTextResult({ text: output, details })));\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\treturn renderTextComponent(context.lastComponent, formatGrepCall(args, theme, context.cwd));\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\treturn renderTextComponent(\n\t\t\t\tcontext.lastComponent,\n\t\t\t\tformatGrepResult(result as Parameters<typeof formatGrepResult>[0], options, theme, context.showImages),\n\t\t\t);\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import { type ManagedToolName, type ManagedToolResolver } from "../../utils/tools-manager.ts";
2
+ export interface ManagedSearchToolOptions {
3
+ /** Managed-tool provisioning adapter. Defaults to Pi's diagnostic-preserving resolver. */
4
+ managedToolResolver?: ManagedToolResolver;
5
+ }
6
+ /** One provisioning boundary shared by local search tools; unavailable results always retain their cause. */
7
+ export declare function resolveManagedSearchTool(tool: ManagedToolName, resolver?: ManagedToolResolver): Promise<string>;
8
+ //# sourceMappingURL=managed-search-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-search-tool.d.ts","sourceRoot":"","sources":["../../../src/core/tools/managed-search-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,WAAW,wBAAwB;IACxC,0FAA0F;IAC1F,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC1C;AAED,6GAA6G;AAC7G,wBAAsB,wBAAwB,CAC7C,IAAI,EAAE,eAAe,EACrB,QAAQ,GAAE,mBAA+C,GACvD,OAAO,CAAC,MAAM,CAAC,CAMjB"}
@@ -0,0 +1,10 @@
1
+ import { ensureToolWithDiagnostics, formatManagedToolProvisioningFailure, } from "../../utils/tools-manager.js";
2
+ /** One provisioning boundary shared by local search tools; unavailable results always retain their cause. */
3
+ export async function resolveManagedSearchTool(tool, resolver = ensureToolWithDiagnostics) {
4
+ const resolution = await resolver(tool, true);
5
+ if (resolution.status === "unavailable") {
6
+ throw new Error(formatManagedToolProvisioningFailure(tool, resolution));
7
+ }
8
+ return resolution.path;
9
+ }
10
+ //# sourceMappingURL=managed-search-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-search-tool.js","sourceRoot":"","sources":["../../../src/core/tools/managed-search-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,yBAAyB,EACzB,oCAAoC,GAGpC,MAAM,8BAA8B,CAAC;AAOtC,6GAA6G;AAC7G,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC7C,IAAqB,EACrB,QAAQ,GAAwB,yBAAyB;IAEzD,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9C,IAAI,UAAU,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,CAAC;AACxB,CAAC","sourcesContent":["import {\n\tensureToolWithDiagnostics,\n\tformatManagedToolProvisioningFailure,\n\ttype ManagedToolName,\n\ttype ManagedToolResolver,\n} from \"../../utils/tools-manager.ts\";\n\nexport interface ManagedSearchToolOptions {\n\t/** Managed-tool provisioning adapter. Defaults to Pi's diagnostic-preserving resolver. */\n\tmanagedToolResolver?: ManagedToolResolver;\n}\n\n/** One provisioning boundary shared by local search tools; unavailable results always retain their cause. */\nexport async function resolveManagedSearchTool(\n\ttool: ManagedToolName,\n\tresolver: ManagedToolResolver = ensureToolWithDiagnostics,\n): Promise<string> {\n\tconst resolution = await resolver(tool, true);\n\tif (resolution.status === \"unavailable\") {\n\t\tthrow new Error(formatManagedToolProvisioningFailure(tool, resolution));\n\t}\n\treturn resolution.path;\n}\n"]}
@@ -3,14 +3,15 @@ export interface ShellToken {
3
3
  kind: ShellTokenKind;
4
4
  value: string;
5
5
  }
6
+ export type ShellCommandDialect = "posix" | "powershell";
6
7
  /** Tokenize one simple command while preserving the pre-existing quote/escape contract. */
7
- export declare function tokenizeCommand(command: string): string[] | null;
8
+ export declare function tokenizeCommand(command: string, dialect?: ShellCommandDialect): string[] | null;
8
9
  /** Tokenize a shell command and expose quote-aware command boundaries and redirects. */
9
- export declare function tokenizeShellCommand(command: string): ShellToken[] | null;
10
+ export declare function tokenizeShellCommand(command: string, dialect?: ShellCommandDialect): ShellToken[] | null;
10
11
  export interface ParsedCommand {
11
12
  envVars: Record<string, string>;
12
13
  coreCommandTokens: string[];
13
14
  }
14
- export declare function parseCommandPrefixes(command: string): ParsedCommand | null;
15
+ export declare function parseCommandPrefixes(command: string, dialect?: ShellCommandDialect): ParsedCommand | null;
15
16
  export declare function isComplexShellCommand(command: string): boolean;
16
17
  //# sourceMappingURL=shell-command-parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shell-command-parser.d.ts","sourceRoot":"","sources":["../../../src/core/tools/shell-command-parser.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,CAAC;AAEtE,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACd;AA0FD,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAEhE;AAED,wFAAwF;AACxF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,IAAI,CAEzE;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAgB1E;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE9D"}
1
+ {"version":3,"file":"shell-command-parser.d.ts","sourceRoot":"","sources":["../../../src/core/tools/shell-command-parser.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,CAAC;AAEtE,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACd;AAOD,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,YAAY,CAAC;AAiHzD,2FAA2F;AAC3F,wBAAgB,eAAe,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAkD,GACzD,MAAM,EAAE,GAAG,IAAI,CAEjB;AAED,wFAAwF;AACxF,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAkD,GACzD,UAAU,EAAE,GAAG,IAAI,CAErB;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAkD,GACzD,aAAa,GAAG,IAAI,CAgBtB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE9D"}
@@ -1,3 +1,10 @@
1
+ function defaultShellCommandDialect() {
2
+ // Pi exposes Bash-like source on every platform. Native PowerShell callers opt in explicitly.
3
+ return "posix";
4
+ }
5
+ function hasWindowsPathPrefix(value) {
6
+ return /^[A-Za-z]:/u.test(value) || value.startsWith("\\\\");
7
+ }
1
8
  function pushArgument(tokens, current) {
2
9
  if (current.length > 0)
3
10
  tokens.push({ kind: "arg", value: current });
@@ -10,12 +17,30 @@ function tokenize(input, options) {
10
17
  let escaped = false;
11
18
  for (let index = 0; index < input.length; index++) {
12
19
  const char = input[index];
20
+ const next = input[index + 1];
13
21
  if (escaped) {
14
22
  current += char;
15
23
  escaped = false;
16
24
  continue;
17
25
  }
18
- if (char === "\\" && quote !== "'") {
26
+ if (options.dialect === "powershell" && char === "`" && quote !== "'") {
27
+ escaped = true;
28
+ continue;
29
+ }
30
+ if (options.dialect === "posix" && char === "\\" && quote !== "'") {
31
+ if (hasWindowsPathPrefix(current)) {
32
+ current += char;
33
+ continue;
34
+ }
35
+ if (current === "" && next === "\\") {
36
+ current = "\\\\";
37
+ index++;
38
+ continue;
39
+ }
40
+ if (quote === '"' && next !== undefined && !'"$`\\'.includes(next)) {
41
+ current += char;
42
+ continue;
43
+ }
19
44
  escaped = true;
20
45
  continue;
21
46
  }
@@ -84,15 +109,15 @@ function tokenize(input, options) {
84
109
  return tokens;
85
110
  }
86
111
  /** Tokenize one simple command while preserving the pre-existing quote/escape contract. */
87
- export function tokenizeCommand(command) {
88
- return tokenize(command, { operators: false })?.map((token) => token.value) ?? null;
112
+ export function tokenizeCommand(command, dialect = defaultShellCommandDialect()) {
113
+ return tokenize(command, { operators: false, dialect })?.map((token) => token.value) ?? null;
89
114
  }
90
115
  /** Tokenize a shell command and expose quote-aware command boundaries and redirects. */
91
- export function tokenizeShellCommand(command) {
92
- return tokenize(command, { operators: true });
116
+ export function tokenizeShellCommand(command, dialect = defaultShellCommandDialect()) {
117
+ return tokenize(command, { operators: true, dialect });
93
118
  }
94
- export function parseCommandPrefixes(command) {
95
- const tokens = tokenizeCommand(command);
119
+ export function parseCommandPrefixes(command, dialect = defaultShellCommandDialect()) {
120
+ const tokens = tokenizeCommand(command, dialect);
96
121
  if (!tokens || tokens.length === 0)
97
122
  return null;
98
123
  const envVars = {};
@@ -1 +1 @@
1
- {"version":3,"file":"shell-command-parser.js","sourceRoot":"","sources":["../../../src/core/tools/shell-command-parser.ts"],"names":[],"mappings":"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","sourcesContent":["export type ShellTokenKind = \"arg\" | \"operator\" | \"pipe\" | \"redirect\";\n\nexport interface ShellToken {\n\tkind: ShellTokenKind;\n\tvalue: string;\n}\n\ninterface TokenizeOptions {\n\toperators: boolean;\n}\n\nfunction pushArgument(tokens: ShellToken[], current: string): string {\n\tif (current.length > 0) tokens.push({ kind: \"arg\", value: current });\n\treturn \"\";\n}\n\nfunction tokenize(input: string, options: TokenizeOptions): ShellToken[] | null {\n\tconst tokens: ShellToken[] = [];\n\tlet current = \"\";\n\tlet quote: \"'\" | '\"' | undefined;\n\tlet escaped = false;\n\n\tfor (let index = 0; index < input.length; index++) {\n\t\tconst char = input[index];\n\t\tif (escaped) {\n\t\t\tcurrent += char;\n\t\t\tescaped = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\\\" && quote !== \"'\") {\n\t\t\tescaped = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote) {\n\t\t\tif (char === quote) quote = undefined;\n\t\t\telse current += char;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\tquote = char;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (options.operators && (char === \"|\" || char === \"&\" || char === \";\" || char === \"\\n\" || char === \"\\r\")) {\n\t\t\tcurrent = pushArgument(tokens, current);\n\t\t\tif (char === \"|\" && input[index + 1] === \"&\") {\n\t\t\t\ttokens.push({ kind: \"pipe\", value: \"|&\" });\n\t\t\t\tindex++;\n\t\t\t} else if ((char === \"|\" || char === \"&\") && input[index + 1] === char) {\n\t\t\t\ttokens.push({ kind: \"operator\", value: `${char}${char}` });\n\t\t\t\tindex++;\n\t\t\t} else if (char === \"|\") {\n\t\t\t\ttokens.push({ kind: \"pipe\", value: char });\n\t\t\t} else {\n\t\t\t\ttokens.push({ kind: \"operator\", value: char });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (options.operators && (char === \">\" || char === \"<\")) {\n\t\t\tlet fileDescriptor = \"\";\n\t\t\tif (char === \">\" && /^\\d+$/u.test(current)) {\n\t\t\t\tfileDescriptor = current;\n\t\t\t\tcurrent = \"\";\n\t\t\t} else {\n\t\t\t\tcurrent = pushArgument(tokens, current);\n\t\t\t}\n\t\t\tlet value = `${fileDescriptor}${char}`;\n\t\t\tif (input[index + 1] === char) {\n\t\t\t\tvalue += char;\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\tif (input[index + 1] === \"&\") {\n\t\t\t\tvalue += \"&\";\n\t\t\t\tindex++;\n\t\t\t\twhile (index + 1 < input.length && /[\\d-]/u.test(input[index + 1])) {\n\t\t\t\t\tvalue += input[++index];\n\t\t\t\t}\n\t\t\t}\n\t\t\ttokens.push({ kind: \"redirect\", value });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/\\s/u.test(char)) {\n\t\t\tcurrent = pushArgument(tokens, current);\n\t\t\tcontinue;\n\t\t}\n\t\tcurrent += char;\n\t}\n\n\tif (quote || escaped) return null;\n\tpushArgument(tokens, current);\n\treturn tokens;\n}\n\n/** Tokenize one simple command while preserving the pre-existing quote/escape contract. */\nexport function tokenizeCommand(command: string): string[] | null {\n\treturn tokenize(command, { operators: false })?.map((token) => token.value) ?? null;\n}\n\n/** Tokenize a shell command and expose quote-aware command boundaries and redirects. */\nexport function tokenizeShellCommand(command: string): ShellToken[] | null {\n\treturn tokenize(command, { operators: true });\n}\n\nexport interface ParsedCommand {\n\tenvVars: Record<string, string>;\n\tcoreCommandTokens: string[];\n}\n\nexport function parseCommandPrefixes(command: string): ParsedCommand | null {\n\tconst tokens = tokenizeCommand(command);\n\tif (!tokens || tokens.length === 0) return null;\n\n\tconst envVars: Record<string, string> = {};\n\tlet index = 0;\n\tconst envPattern = /^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$/u;\n\n\twhile (index < tokens.length) {\n\t\tconst match = tokens[index].match(envPattern);\n\t\tif (!match) break;\n\t\tenvVars[match[1]] = match[2];\n\t\tindex++;\n\t}\n\n\treturn { envVars, coreCommandTokens: tokens.slice(index) };\n}\n\nexport function isComplexShellCommand(command: string): boolean {\n\treturn /[|><&;\\n\\r$`()*?[\\]#]/u.test(command);\n}\n"]}
1
+ {"version":3,"file":"shell-command-parser.js","sourceRoot":"","sources":["../../../src/core/tools/shell-command-parser.ts"],"names":[],"mappings":"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","sourcesContent":["export type ShellTokenKind = \"arg\" | \"operator\" | \"pipe\" | \"redirect\";\n\nexport interface ShellToken {\n\tkind: ShellTokenKind;\n\tvalue: string;\n}\n\ninterface TokenizeOptions {\n\toperators: boolean;\n\tdialect: ShellCommandDialect;\n}\n\nexport type ShellCommandDialect = \"posix\" | \"powershell\";\n\nfunction defaultShellCommandDialect(): ShellCommandDialect {\n\t// Pi exposes Bash-like source on every platform. Native PowerShell callers opt in explicitly.\n\treturn \"posix\";\n}\n\nfunction hasWindowsPathPrefix(value: string): boolean {\n\treturn /^[A-Za-z]:/u.test(value) || value.startsWith(\"\\\\\\\\\");\n}\n\nfunction pushArgument(tokens: ShellToken[], current: string): string {\n\tif (current.length > 0) tokens.push({ kind: \"arg\", value: current });\n\treturn \"\";\n}\n\nfunction tokenize(input: string, options: TokenizeOptions): ShellToken[] | null {\n\tconst tokens: ShellToken[] = [];\n\tlet current = \"\";\n\tlet quote: \"'\" | '\"' | undefined;\n\tlet escaped = false;\n\n\tfor (let index = 0; index < input.length; index++) {\n\t\tconst char = input[index];\n\t\tconst next = input[index + 1];\n\t\tif (escaped) {\n\t\t\tcurrent += char;\n\t\t\tescaped = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (options.dialect === \"powershell\" && char === \"`\" && quote !== \"'\") {\n\t\t\tescaped = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (options.dialect === \"posix\" && char === \"\\\\\" && quote !== \"'\") {\n\t\t\tif (hasWindowsPathPrefix(current)) {\n\t\t\t\tcurrent += char;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (current === \"\" && next === \"\\\\\") {\n\t\t\t\tcurrent = \"\\\\\\\\\";\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (quote === '\"' && next !== undefined && !'\"$`\\\\'.includes(next)) {\n\t\t\t\tcurrent += char;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tescaped = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote) {\n\t\t\tif (char === quote) quote = undefined;\n\t\t\telse current += char;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\tquote = char;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (options.operators && (char === \"|\" || char === \"&\" || char === \";\" || char === \"\\n\" || char === \"\\r\")) {\n\t\t\tcurrent = pushArgument(tokens, current);\n\t\t\tif (char === \"|\" && input[index + 1] === \"&\") {\n\t\t\t\ttokens.push({ kind: \"pipe\", value: \"|&\" });\n\t\t\t\tindex++;\n\t\t\t} else if ((char === \"|\" || char === \"&\") && input[index + 1] === char) {\n\t\t\t\ttokens.push({ kind: \"operator\", value: `${char}${char}` });\n\t\t\t\tindex++;\n\t\t\t} else if (char === \"|\") {\n\t\t\t\ttokens.push({ kind: \"pipe\", value: char });\n\t\t\t} else {\n\t\t\t\ttokens.push({ kind: \"operator\", value: char });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (options.operators && (char === \">\" || char === \"<\")) {\n\t\t\tlet fileDescriptor = \"\";\n\t\t\tif (char === \">\" && /^\\d+$/u.test(current)) {\n\t\t\t\tfileDescriptor = current;\n\t\t\t\tcurrent = \"\";\n\t\t\t} else {\n\t\t\t\tcurrent = pushArgument(tokens, current);\n\t\t\t}\n\t\t\tlet value = `${fileDescriptor}${char}`;\n\t\t\tif (input[index + 1] === char) {\n\t\t\t\tvalue += char;\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\tif (input[index + 1] === \"&\") {\n\t\t\t\tvalue += \"&\";\n\t\t\t\tindex++;\n\t\t\t\twhile (index + 1 < input.length && /[\\d-]/u.test(input[index + 1])) {\n\t\t\t\t\tvalue += input[++index];\n\t\t\t\t}\n\t\t\t}\n\t\t\ttokens.push({ kind: \"redirect\", value });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/\\s/u.test(char)) {\n\t\t\tcurrent = pushArgument(tokens, current);\n\t\t\tcontinue;\n\t\t}\n\t\tcurrent += char;\n\t}\n\n\tif (quote || escaped) return null;\n\tpushArgument(tokens, current);\n\treturn tokens;\n}\n\n/** Tokenize one simple command while preserving the pre-existing quote/escape contract. */\nexport function tokenizeCommand(\n\tcommand: string,\n\tdialect: ShellCommandDialect = defaultShellCommandDialect(),\n): string[] | null {\n\treturn tokenize(command, { operators: false, dialect })?.map((token) => token.value) ?? null;\n}\n\n/** Tokenize a shell command and expose quote-aware command boundaries and redirects. */\nexport function tokenizeShellCommand(\n\tcommand: string,\n\tdialect: ShellCommandDialect = defaultShellCommandDialect(),\n): ShellToken[] | null {\n\treturn tokenize(command, { operators: true, dialect });\n}\n\nexport interface ParsedCommand {\n\tenvVars: Record<string, string>;\n\tcoreCommandTokens: string[];\n}\n\nexport function parseCommandPrefixes(\n\tcommand: string,\n\tdialect: ShellCommandDialect = defaultShellCommandDialect(),\n): ParsedCommand | null {\n\tconst tokens = tokenizeCommand(command, dialect);\n\tif (!tokens || tokens.length === 0) return null;\n\n\tconst envVars: Record<string, string> = {};\n\tlet index = 0;\n\tconst envPattern = /^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$/u;\n\n\twhile (index < tokens.length) {\n\t\tconst match = tokens[index].match(envPattern);\n\t\tif (!match) break;\n\t\tenvVars[match[1]] = match[2];\n\t\tindex++;\n\t}\n\n\treturn { envVars, coreCommandTokens: tokens.slice(index) };\n}\n\nexport function isComplexShellCommand(command: string): boolean {\n\treturn /[|><&;\\n\\r$`()*?[\\]#]/u.test(command);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"shell-contract-router.d.ts","sourceRoot":"","sources":["../../../src/core/tools/shell-contract-router.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC3B;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAuS1C,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAClC,kBAAkB,CAiEpB"}
1
+ {"version":3,"file":"shell-contract-router.d.ts","sourceRoot":"","sources":["../../../src/core/tools/shell-contract-router.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC3B;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAqT1C,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAClC,kBAAkB,CAwEpB"}
@@ -1,4 +1,18 @@
1
- const ENGINE_OWNED_BUILTINS = new Set(["cd", "export", "unset", "exit"]);
1
+ const ENGINE_OWNED_BUILTINS = new Set(["cd", "export", "unset", "exit", "break", "continue"]);
2
+ const ENGINE_ONLY_BUILTINS = new Set([
3
+ "printf",
4
+ "basename",
5
+ "dirname",
6
+ "test",
7
+ "[",
8
+ "sed",
9
+ "wc",
10
+ "sort",
11
+ "uniq",
12
+ "cut",
13
+ "tr",
14
+ "xargs",
15
+ ]);
2
16
  const BLOCKED_NESTED_SHELLS = new Set([
3
17
  "bash",
4
18
  "sh",
@@ -328,6 +342,14 @@ export function routeShellContract(command, platform = process.platform, options
328
342
  };
329
343
  }
330
344
  }
345
+ if (ENGINE_ONLY_BUILTINS.has(commandName)) {
346
+ if (pythonEngine)
347
+ return { kind: "python-engine", command };
348
+ return {
349
+ kind: "unsupported",
350
+ error: `The Bash-like '${argv[0]}' builtin requires the Windows Python shell engine. Enable windowsShell.pythonEngine to use it portably.`,
351
+ };
352
+ }
331
353
  if (BLOCKED_NESTED_SHELLS.has(commandName)) {
332
354
  const powershellGuidance = ["powershell", "powershell.exe", "pwsh", "pwsh.exe"].includes(commandName)
333
355
  ? " Invoke the .ps1 path directly with its arguments, without powershell.exe -File or pwsh -File."