@astralyn/pi 1.1.0 → 1.3.0

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 (290) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/dist/bundle/chunks/anthropic-messages-MSB6JBS2.js +6 -0
  3. package/dist/bundle/chunks/{azure-openai-responses-CH74HGP4.js → azure-openai-responses-ATZ757I2.js} +1 -1
  4. package/dist/bundle/chunks/bedrock-converse-stream.js +14 -11
  5. package/dist/bundle/chunks/{chunk-H35KWBT5.js → chunk-4XZYHGVN.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-MAC4N3BW.js → chunk-7UBIBLPN.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-KAC2YPTW.js → chunk-J75WV3FL.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-EJEOEBSJ.js → chunk-KSCGI7JW.js} +2 -2
  9. package/dist/bundle/chunks/chunk-LUYFHZ6W.js +11 -0
  10. package/dist/bundle/chunks/{chunk-TEAAYBTS.js → chunk-NM2KGRFS.js} +1 -1
  11. package/dist/bundle/chunks/chunk-Q74S7ILH.js +2 -0
  12. package/dist/bundle/chunks/{chunk-QLU3LESZ.js → chunk-QDDSFJ35.js} +1 -1
  13. package/dist/bundle/chunks/{chunk-D3XW5X3Z.js → chunk-R2KES7LS.js} +175 -244
  14. package/dist/bundle/chunks/{chunk-5B3S5DVL.js → chunk-SA2AQYEI.js} +5 -2
  15. package/dist/bundle/chunks/{chunk-C2ARIVS3.js → chunk-YHRHHXFG.js} +1 -1
  16. package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-XO45ZT3V.js → cloudflare-workers-ai-system-one-HGOVFZDC.js} +1 -1
  17. package/dist/bundle/chunks/codemode-worker.js +17 -9
  18. package/dist/bundle/chunks/github-copilot.js +1 -1
  19. package/dist/bundle/chunks/{google-generative-ai-VVO64ZRQ.js → google-generative-ai-QRLQ4MCJ.js} +1 -1
  20. package/dist/bundle/chunks/{google-vertex-LKS5NUHA.js → google-vertex-L3T6EGTL.js} +1 -1
  21. package/dist/bundle/chunks/mistral-conversations-6E6SS3WF.js +5 -0
  22. package/dist/bundle/chunks/openai-codex-responses-4GUO76XJ.js +10 -0
  23. package/dist/bundle/chunks/{openai-completions-7HTTU6FH.js → openai-completions-O4TKZCIM.js} +1 -1
  24. package/dist/bundle/chunks/{openai-decisions-776H4VDZ.js → openai-decisions-TVCDIPZX.js} +1 -1
  25. package/dist/bundle/chunks/openai-responses-VBQKJFNO.js +3 -0
  26. package/dist/bundle/chunks/{pi-messages-ZXNERWJG.js → pi-messages-3POWZ43C.js} +1 -1
  27. package/dist/bundle/chunks/{typesafe-system-one-2DQLG4R2.js → typesafe-system-one-LWPJYTJP.js} +1 -1
  28. package/dist/bundle/chunks/{virtual-modules-2NHGQRS6.js → virtual-modules-TG53AOL4.js} +1 -1
  29. package/dist/bundle/cli.js +1 -1
  30. package/dist/bundle/index.js +1 -1
  31. package/dist/bundle/rpc-entry.js +1 -1
  32. package/dist/cli/credential-print.d.ts.map +1 -1
  33. package/dist/cli/credential-print.js +4 -4
  34. package/dist/cli/credential-print.js.map +1 -1
  35. package/dist/core/agent-session.d.ts +18 -3
  36. package/dist/core/agent-session.d.ts.map +1 -1
  37. package/dist/core/agent-session.js +98 -62
  38. package/dist/core/agent-session.js.map +1 -1
  39. package/dist/core/auth-storage.d.ts.map +1 -1
  40. package/dist/core/auth-storage.js +20 -13
  41. package/dist/core/auth-storage.js.map +1 -1
  42. package/dist/core/bug-report.d.ts +9 -1
  43. package/dist/core/bug-report.d.ts.map +1 -1
  44. package/dist/core/compaction/utils.d.ts +6 -0
  45. package/dist/core/compaction/utils.d.ts.map +1 -1
  46. package/dist/core/compaction/utils.js +7 -8
  47. package/dist/core/compaction/utils.js.map +1 -1
  48. package/dist/core/export-html/template.js +21 -16
  49. package/dist/core/extensions/index.d.ts +1 -1
  50. package/dist/core/extensions/index.d.ts.map +1 -1
  51. package/dist/core/extensions/index.js.map +1 -1
  52. package/dist/core/extensions/runner.d.ts +4 -2
  53. package/dist/core/extensions/runner.d.ts.map +1 -1
  54. package/dist/core/extensions/runner.js +2 -3
  55. package/dist/core/extensions/runner.js.map +1 -1
  56. package/dist/core/extensions/types.d.ts +31 -7
  57. package/dist/core/extensions/types.d.ts.map +1 -1
  58. package/dist/core/extensions/types.js.map +1 -1
  59. package/dist/core/key-id-schema.d.ts +6 -0
  60. package/dist/core/key-id-schema.d.ts.map +1 -0
  61. package/dist/core/key-id-schema.js +16 -0
  62. package/dist/core/key-id-schema.js.map +1 -0
  63. package/dist/core/keybinding-registry.d.ts +4 -3
  64. package/dist/core/keybinding-registry.d.ts.map +1 -1
  65. package/dist/core/keybinding-registry.js +4 -3
  66. package/dist/core/keybinding-registry.js.map +1 -1
  67. package/dist/core/keybindings-schema.d.ts +4 -0
  68. package/dist/core/keybindings-schema.d.ts.map +1 -0
  69. package/dist/core/keybindings-schema.js +16 -0
  70. package/dist/core/keybindings-schema.js.map +1 -0
  71. package/dist/core/keybindings.d.ts +258 -81
  72. package/dist/core/keybindings.d.ts.map +1 -1
  73. package/dist/core/keybindings.js +27 -24
  74. package/dist/core/keybindings.js.map +1 -1
  75. package/dist/core/model-config.d.ts +729 -180
  76. package/dist/core/model-config.d.ts.map +1 -1
  77. package/dist/core/model-config.js +18 -179
  78. package/dist/core/model-config.js.map +1 -1
  79. package/dist/core/model-resolver.d.ts +56 -43
  80. package/dist/core/model-resolver.d.ts.map +1 -1
  81. package/dist/core/model-resolver.js +247 -352
  82. package/dist/core/model-resolver.js.map +1 -1
  83. package/dist/core/model-runtime.d.ts.map +1 -1
  84. package/dist/core/model-runtime.js +11 -6
  85. package/dist/core/model-runtime.js.map +1 -1
  86. package/dist/core/package-manager.d.ts.map +1 -1
  87. package/dist/core/package-manager.js +3 -3
  88. package/dist/core/package-manager.js.map +1 -1
  89. package/dist/core/project-trust.d.ts.map +1 -1
  90. package/dist/core/project-trust.js +2 -1
  91. package/dist/core/project-trust.js.map +1 -1
  92. package/dist/core/prompt-templates.d.ts.map +1 -1
  93. package/dist/core/prompt-templates.js +7 -2
  94. package/dist/core/prompt-templates.js.map +1 -1
  95. package/dist/core/remote-catalog-provider.d.ts +12 -1
  96. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  97. package/dist/core/remote-catalog-provider.js +82 -24
  98. package/dist/core/remote-catalog-provider.js.map +1 -1
  99. package/dist/core/resource-loader.d.ts.map +1 -1
  100. package/dist/core/resource-loader.js +7 -2
  101. package/dist/core/resource-loader.js.map +1 -1
  102. package/dist/core/settings-defaults.d.ts +66 -0
  103. package/dist/core/settings-defaults.d.ts.map +1 -0
  104. package/dist/core/settings-defaults.js +67 -0
  105. package/dist/core/settings-defaults.js.map +1 -0
  106. package/dist/core/settings-manager.d.ts +6 -149
  107. package/dist/core/settings-manager.d.ts.map +1 -1
  108. package/dist/core/settings-manager.js +59 -44
  109. package/dist/core/settings-manager.js.map +1 -1
  110. package/dist/core/settings-schema.d.ts +233 -0
  111. package/dist/core/settings-schema.d.ts.map +1 -0
  112. package/dist/core/settings-schema.js +298 -0
  113. package/dist/core/settings-schema.js.map +1 -0
  114. package/dist/core/slash-commands.js +1 -1
  115. package/dist/core/slash-commands.js.map +1 -1
  116. package/dist/core/tools/render-utils.d.ts +20 -0
  117. package/dist/core/tools/render-utils.d.ts.map +1 -1
  118. package/dist/core/tools/render-utils.js +67 -0
  119. package/dist/core/tools/render-utils.js.map +1 -1
  120. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  121. package/dist/core/tools/renderers/bash.js +21 -50
  122. package/dist/core/tools/renderers/bash.js.map +1 -1
  123. package/dist/core/tools/renderers/read.d.ts.map +1 -1
  124. package/dist/core/tools/renderers/read.js +7 -11
  125. package/dist/core/tools/renderers/read.js.map +1 -1
  126. package/dist/extensions/btw/keybindings.d.ts +2 -2
  127. package/dist/extensions/btw/keybindings.d.ts.map +1 -1
  128. package/dist/extensions/btw/keybindings.js.map +1 -1
  129. package/dist/extensions/codemode/execute.d.ts.map +1 -1
  130. package/dist/extensions/codemode/execute.js +76 -45
  131. package/dist/extensions/codemode/execute.js.map +1 -1
  132. package/dist/extensions/codemode/index.d.ts.map +1 -1
  133. package/dist/extensions/codemode/index.js +3 -7
  134. package/dist/extensions/codemode/index.js.map +1 -1
  135. package/dist/extensions/codemode/renderer.d.ts +2 -2
  136. package/dist/extensions/codemode/renderer.d.ts.map +1 -1
  137. package/dist/extensions/codemode/renderer.js +9 -3
  138. package/dist/extensions/codemode/renderer.js.map +1 -1
  139. package/dist/extensions/codemode/tool.d.ts +6 -12
  140. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  141. package/dist/extensions/codemode/tool.js +44 -32
  142. package/dist/extensions/codemode/tool.js.map +1 -1
  143. package/dist/extensions/list-keybindings.d.ts +2 -2
  144. package/dist/extensions/list-keybindings.d.ts.map +1 -1
  145. package/dist/extensions/list-keybindings.js.map +1 -1
  146. package/dist/extensions/mcp/cli.js +5 -8
  147. package/dist/extensions/mcp/cli.js.map +1 -1
  148. package/dist/extensions/mcp/index.d.ts.map +1 -1
  149. package/dist/extensions/mcp/index.js +25 -34
  150. package/dist/extensions/mcp/index.js.map +1 -1
  151. package/dist/extensions/mcp/resources.d.ts +0 -6
  152. package/dist/extensions/mcp/resources.d.ts.map +1 -1
  153. package/dist/extensions/mcp/resources.js +1 -1
  154. package/dist/extensions/mcp/resources.js.map +1 -1
  155. package/dist/extensions/mcp/runtime.d.ts +3 -6
  156. package/dist/extensions/mcp/runtime.d.ts.map +1 -1
  157. package/dist/extensions/mcp/runtime.js +4 -39
  158. package/dist/extensions/mcp/runtime.js.map +1 -1
  159. package/dist/extensions/mcp/tools.d.ts +2 -3
  160. package/dist/extensions/mcp/tools.d.ts.map +1 -1
  161. package/dist/extensions/mcp/tools.js +62 -6
  162. package/dist/extensions/mcp/tools.js.map +1 -1
  163. package/dist/extensions/provider/keybindings.d.ts +2 -2
  164. package/dist/extensions/provider/keybindings.d.ts.map +1 -1
  165. package/dist/extensions/provider/keybindings.js.map +1 -1
  166. package/dist/extensions/search/code-search.d.ts +0 -2
  167. package/dist/extensions/search/code-search.d.ts.map +1 -1
  168. package/dist/extensions/search/code-search.js +2 -2
  169. package/dist/extensions/search/code-search.js.map +1 -1
  170. package/dist/extensions/search/command.js +2 -2
  171. package/dist/extensions/search/command.js.map +1 -1
  172. package/dist/extensions/search/index.d.ts.map +1 -1
  173. package/dist/extensions/search/index.js +14 -11
  174. package/dist/extensions/search/index.js.map +1 -1
  175. package/dist/extensions/search/workspace.d.ts +11 -10
  176. package/dist/extensions/search/workspace.d.ts.map +1 -1
  177. package/dist/extensions/search/workspace.js +259 -141
  178. package/dist/extensions/search/workspace.js.map +1 -1
  179. package/dist/extensions/tool-search/index.d.ts.map +1 -1
  180. package/dist/extensions/tool-search/index.js +1 -6
  181. package/dist/extensions/tool-search/index.js.map +1 -1
  182. package/dist/extensions/tool-search/tool.d.ts +0 -2
  183. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  184. package/dist/extensions/tool-search/tool.js +2 -4
  185. package/dist/extensions/tool-search/tool.js.map +1 -1
  186. package/dist/index.d.ts +2 -1
  187. package/dist/index.d.ts.map +1 -1
  188. package/dist/index.js +1 -0
  189. package/dist/index.js.map +1 -1
  190. package/dist/main.d.ts.map +1 -1
  191. package/dist/main.js +4 -3
  192. package/dist/main.js.map +1 -1
  193. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  194. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  195. package/dist/modes/interactive/components/settings-selector.js +13 -2
  196. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  197. package/dist/modes/interactive/components/status-indicator.d.ts +1 -1
  198. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  199. package/dist/modes/interactive/components/status-indicator.js +2 -2
  200. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  201. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/tree-selector.js +2 -9
  203. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  204. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  205. package/dist/modes/interactive/interactive-mode.js +20 -8
  206. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  207. package/dist/modes/interactive/session-share.d.ts.map +1 -1
  208. package/dist/modes/interactive/session-share.js +9 -2
  209. package/dist/modes/interactive/session-share.js.map +1 -1
  210. package/dist/modes/interactive/tasks/layout.d.ts +2 -0
  211. package/dist/modes/interactive/tasks/layout.d.ts.map +1 -1
  212. package/dist/modes/interactive/tasks/layout.js +32 -6
  213. package/dist/modes/interactive/tasks/layout.js.map +1 -1
  214. package/dist/modes/interactive/tasks/manager.d.ts.map +1 -1
  215. package/dist/modes/interactive/tasks/manager.js +20 -2
  216. package/dist/modes/interactive/tasks/manager.js.map +1 -1
  217. package/dist/modes/interactive/theme/dark.json +1 -1
  218. package/dist/modes/interactive/theme/light.json +1 -1
  219. package/dist/modes/interactive/theme/theme-schema.d.ts +28 -0
  220. package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  221. package/dist/modes/interactive/theme/theme-schema.js +105 -0
  222. package/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  223. package/dist/modes/interactive/theme/theme-tokens.d.ts +257 -0
  224. package/dist/modes/interactive/theme/theme-tokens.d.ts.map +1 -0
  225. package/dist/modes/interactive/theme/theme-tokens.js +94 -0
  226. package/dist/modes/interactive/theme/theme-tokens.js.map +1 -0
  227. package/dist/modes/interactive/theme/theme.d.ts +13 -16
  228. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  229. package/dist/modes/interactive/theme/theme.js +23 -31
  230. package/dist/modes/interactive/theme/theme.js.map +1 -1
  231. package/dist/modes/print-mode.d.ts.map +1 -1
  232. package/dist/modes/print-mode.js +4 -0
  233. package/dist/modes/print-mode.js.map +1 -1
  234. package/dist/utils/clipboard.d.ts.map +1 -1
  235. package/dist/utils/clipboard.js +6 -1
  236. package/dist/utils/clipboard.js.map +1 -1
  237. package/docs/bundled/extensions/search.md +2 -1
  238. package/docs/bundled/tasks.md +1 -1
  239. package/docs/codemode.md +2 -1
  240. package/docs/compaction.md +2 -2
  241. package/docs/development.md +0 -13
  242. package/docs/docs.json +12 -0
  243. package/docs/environment-variables.md +2 -3
  244. package/docs/extensions.md +11 -5
  245. package/docs/keybindings.md +1 -0
  246. package/docs/llama-cpp.md +1 -1
  247. package/docs/mcp.md +1 -1
  248. package/docs/models.md +1 -0
  249. package/docs/nvidia-rtx-llama-cpp.md +96 -0
  250. package/docs/providers.md +17 -1
  251. package/docs/sdk.md +0 -27
  252. package/docs/sessions.md +1 -1
  253. package/docs/settings.md +4 -3
  254. package/docs/themes.md +4 -2
  255. package/docs/tui.md +1 -1
  256. package/docs/usage.md +7 -5
  257. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  258. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  259. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  260. package/examples/extensions/dynamic-resources/dynamic.json +1 -1
  261. package/examples/extensions/gondolin/package-lock.json +2 -2
  262. package/examples/extensions/gondolin/package.json +1 -1
  263. package/examples/extensions/minimal-mode.ts +4 -5
  264. package/examples/extensions/overlay-test.ts +2 -2
  265. package/examples/extensions/plan-mode/index.ts +6 -2
  266. package/examples/extensions/sandbox/package-lock.json +2 -2
  267. package/examples/extensions/sandbox/package.json +1 -1
  268. package/examples/extensions/with-deps/package-lock.json +2 -2
  269. package/examples/extensions/with-deps/package.json +1 -1
  270. package/npm-shrinkwrap.json +151 -199
  271. package/package.json +8 -20
  272. package/schemas/keybindings.schema.json +453 -0
  273. package/schemas/models.schema.json +1157 -0
  274. package/schemas/settings.schema.json +800 -0
  275. package/schemas/theme.schema.json +365 -0
  276. package/dist/bundle/chunks/anthropic-messages-3K3DWVY6.js +0 -6
  277. package/dist/bundle/chunks/chunk-3MMB5I7J.js +0 -11
  278. package/dist/bundle/chunks/mistral-conversations-NJUOG4ET.js +0 -5
  279. package/dist/bundle/chunks/openai-codex-responses-TZWBTTYM.js +0 -10
  280. package/dist/bundle/chunks/openai-responses-7A6BAQ5X.js +0 -3
  281. package/dist/modes/interactive/theme/theme-json.d.ts +0 -85
  282. package/dist/modes/interactive/theme/theme-json.d.ts.map +0 -1
  283. package/dist/modes/interactive/theme/theme-json.js +0 -132
  284. package/dist/modes/interactive/theme/theme-json.js.map +0 -1
  285. package/dist/modes/interactive/theme/theme-schema.json +0 -361
  286. package/examples/plugins/pi-example-plugin/README.md +0 -38
  287. package/examples/plugins/pi-example-plugin/package.json +0 -10
  288. package/examples/plugins/pi-example-plugin/src/contract.ts +0 -13
  289. package/examples/plugins/pi-example-plugin/src/session.ts +0 -24
  290. package/examples/plugins/pi-example-plugin/src/tui.ts +0 -31
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/extensions/mcp/tools.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Adapts MCP tools to pi tool definitions.\n *\n * Results map onto pi's model-facing content (text and images). Text over 20KB keeps its start and\n * end with the middle cut out, like Codex does, and the full text is saved to a temp file the model\n * can read. Binary resources other than images are saved to temp files too, and resource links name\n * the `read_mcp_resource` tool. Codemode scripts receive the whole `CallToolResult` without `_meta`\n * (`content` blocks as sent by the server, `structuredContent`, `isError`), never truncated: it is\n * the tool's `structuredContent`, and every MCP tool declares a `CallToolResult` output schema. MCP\n * errors (`isError`) are error results for the model, but scripts still resolve to the result.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { ImageContent, JsonValue, TextContent } from \"@earendil-works/pi-ai\";\nimport {\n\ttype CallToolResult,\n\ttype ContentBlock,\n\ttype McpRequestOptions,\n\ttype Tool as McpTool,\n\ttoLlmContent,\n} from \"@earendil-works/pi-mcp\";\nimport { Container, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport type { TSchema } from \"typebox\";\nimport type {\n\tToolAnnotations,\n\tToolDefinition,\n\tToolExposure,\n\tToolNamespace,\n\tToolRenderers,\n} from \"../../core/extensions/types.ts\";\nimport { READ_MCP_RESOURCE_TOOL } from \"../../core/mcp-servers.ts\";\nimport { formatToolCallWithArgs, getTextOutput, replaceTabs } from \"../../core/tools/render-utils.ts\";\nimport { formatSize, truncateMiddle } from \"../../core/tools/truncate.ts\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { VisualLinePreview } from \"../../modes/interactive/components/visual-truncate.ts\";\nimport { writeOutputFile } from \"../../utils/output-files.ts\";\nimport type { McpExposure } from \"./config.ts\";\n\n/**\n * Tool exposure of an MCP exposure. `codemode` and `deferred` both leave tools out of the codemode\n * description; they differ only in which tool the MCP extension activates to reach them.\n */\nexport function toToolExposure(exposure: McpExposure): ToolExposure {\n\treturn exposure === \"codemode\" ? \"deferred\" : exposure;\n}\n\n/** Provider tool names are limited to 64 characters of `[A-Za-z0-9_-]`. */\nconst MAX_TOOL_NAME_LENGTH = 64;\n/** Model-facing text of an MCP result beyond this is cut in the middle. */\nexport const MCP_OUTPUT_MAX_BYTES = 20 * 1024;\n/** Visual (wrapped) result lines shown before the output is expanded. */\nconst OUTPUT_PREVIEW_LINES = 5;\n/** Tool that reads the resources named by resource links. */\nexport { READ_MCP_RESOURCE_TOOL };\n\nexport interface McpToolDetails {\n\tserver: string;\n\ttool: string;\n\t/** Temp file with the full text output, when the model-facing text was truncated. */\n\tfullOutputPath?: string;\n}\n\n/**\n * Saves the full text of a truncated result, or a binary resource, and returns the file path.\n * `extension` includes the dot, for example `.txt`.\n */\nexport type McpOutputSaver = (data: string | Uint8Array, extension: string) => Promise<string>;\n\nexport function saveToTempFile(data: string | Uint8Array, extension: string): Promise<string> {\n\treturn writeOutputFile(\"pi-mcp\", extension, data);\n}\n\nexport interface McpToolCaller {\n\tcallTool(name: string, args: Record<string, unknown>, options: McpRequestOptions): Promise<CallToolResult>;\n}\n\n/**\n * `mcp__<server>__<tool>`, sanitized and shortened with a hash suffix when too long. Like Codex,\n * everything but `[A-Za-z0-9_]` becomes `_`, so the name is also the identifier codemode scripts\n * call it by. `isTaken` reports names used by a different MCP tool: sanitizing can map two tools to\n * one name (`a-b` and `a_b`), which then get the hash suffix.\n */\nexport function createMcpToolName(\n\tserver: string,\n\ttool: string,\n\tisTaken: (name: string) => boolean = () => false,\n): string {\n\tconst name = `mcp__${server}__${tool}`.replace(/[^A-Za-z0-9_]/g, \"_\");\n\tif (name.length <= MAX_TOOL_NAME_LENGTH && !isTaken(name)) return name;\n\tconst hash = createHash(\"sha256\").update(`${server}\\0${tool}`).digest(\"hex\").slice(0, 8);\n\treturn `${name.slice(0, MAX_TOOL_NAME_LENGTH - hash.length - 1)}_${hash}`;\n}\n\nfunction textOf(content: readonly (TextContent | ImageContent)[]): string {\n\treturn content\n\t\t.filter((block): block is TextContent => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\\n\");\n}\n\n/**\n * Output schema of every MCP tool: the `CallToolResult` scripts receive, with the tool's own output\n * schema as `structuredContent`. Codemode detects this shape to render `CallToolResult<T>`\n * declarations.\n */\nexport function createMcpResultSchema(structuredContentSchema: Record<string, unknown> | undefined): TSchema {\n\treturn {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tcontent: { type: \"array\", items: { type: \"object\" } },\n\t\t\t...(structuredContentSchema ? { structuredContent: structuredContentSchema } : {}),\n\t\t\tisError: { type: \"boolean\" },\n\t\t\t_meta: { type: \"object\" },\n\t\t},\n\t\trequired: [\"content\"],\n\t} as unknown as TSchema;\n}\n\n/**\n * Keep model-facing text within {@link MCP_OUTPUT_MAX_BYTES}. Longer text becomes one text block in\n * Codex's truncation format, followed by the path of the file with the full text; images follow it.\n */\nexport async function limitMcpContent(\n\tcontent: (TextContent | ImageContent)[],\n\tsaveOutput: McpOutputSaver = saveToTempFile,\n): Promise<{ content: (TextContent | ImageContent)[]; fullOutputPath?: string }> {\n\tconst combined = textOf(content);\n\tconst truncation = truncateMiddle(combined, MCP_OUTPUT_MAX_BYTES);\n\tif (!truncation.truncated) return { content };\n\tlet fullOutputPath: string | undefined;\n\tlet where: string;\n\ttry {\n\t\tfullOutputPath = await saveOutput(combined, \".txt\");\n\t\twhere = `[Full output: ${fullOutputPath} (read it with offset/limit)]`;\n\t} catch (error) {\n\t\twhere = `[Could not save the full output: ${error instanceof Error ? error.message : String(error)}]`;\n\t}\n\tconst tokens = Math.ceil(truncation.totalBytes / 4);\n\tconst text = `Warning: truncated output (original token count: ${tokens})\\nTotal output lines: ${truncation.totalLines}\\n\\n${truncation.content}\\n\\n${where}`;\n\treturn {\n\t\tcontent: [{ type: \"text\", text }, ...content.filter((block) => block.type === \"image\")],\n\t\t...(fullOutputPath ? { fullOutputPath } : {}),\n\t};\n}\n\nexport interface ConvertMcpResultOptions {\n\t/** Saves truncated text and binary resources. Default: a temp file. */\n\tsaveOutput?: McpOutputSaver;\n\t/** Whether the server's resources can be read with `read_mcp_resource`, which resource links then name. */\n\treadableResources?: boolean;\n}\n\n/** File extension for a saved binary resource: the one its URI ends in, else `.bin`. */\nfunction extensionOf(uri: string): string {\n\tconst path = URL.canParse(uri) ? new URL(uri).pathname : uri;\n\treturn /\\.[A-Za-z0-9]{1,8}$/.exec(path)?.[0] ?? \".bin\";\n}\n\n/** Blobs of these types are shown as text. */\nfunction isTextMimeType(mimeType: string | undefined): boolean {\n\tif (!mimeType) return false;\n\tconst type = mimeType.split(\";\", 1)[0].trim().toLowerCase();\n\treturn type.startsWith(\"text/\") || type === \"application/json\" || type.endsWith(\"+json\") || type.endsWith(\"+xml\");\n}\n\n/** Model-facing content of one block of `server`'s result. */\nasync function blockToContent(\n\tserver: string,\n\tblock: ContentBlock,\n\toptions: ConvertMcpResultOptions,\n): Promise<(TextContent | ImageContent)[]> {\n\tif (block.type === \"resource_link\") {\n\t\tconst details = [block.mimeType, block.size === undefined ? undefined : formatSize(block.size)].filter(Boolean);\n\t\tconst read = options.readableResources ? `. Read it with ${READ_MCP_RESOURCE_TOOL} (server \"${server}\")` : \"\";\n\t\tconst description = block.description ? `: ${block.description}` : \"\";\n\t\treturn [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `[Resource ${block.uri} \"${block.title ?? block.name}\"${details.length > 0 ? ` (${details.join(\", \")})` : \"\"}${description}${read}]`,\n\t\t\t},\n\t\t];\n\t}\n\tif (block.type === \"resource\" && \"blob\" in block.resource && !block.resource.mimeType?.startsWith(\"image/\")) {\n\t\tconst { uri, mimeType, blob } = block.resource;\n\t\tconst data = Buffer.from(blob, \"base64\");\n\t\tif (isTextMimeType(mimeType)) return [{ type: \"text\", text: data.toString(\"utf8\") }];\n\t\tconst kind = `${mimeType ?? \"unknown type\"}, ${formatSize(data.length)}`;\n\t\ttry {\n\t\t\tconst path = await (options.saveOutput ?? saveToTempFile)(data, extensionOf(uri));\n\t\t\treturn [{ type: \"text\", text: `[Binary resource ${uri} (${kind}) saved to ${path}]` }];\n\t\t} catch (error) {\n\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\treturn [{ type: \"text\", text: `[Binary resource ${uri} (${kind}) could not be saved: ${reason}]` }];\n\t\t}\n\t}\n\treturn toLlmContent({ content: [block] });\n}\n\n/** Model-facing content of `server`'s content blocks, before the output limit. */\nexport async function toModelContent(\n\tserver: string,\n\tblocks: readonly ContentBlock[],\n\toptions: ConvertMcpResultOptions = {},\n): Promise<(TextContent | ImageContent)[]> {\n\treturn (await Promise.all(blocks.map((block) => blockToContent(server, block, options)))).flat();\n}\n\n/** Convert an MCP result. `isError` results become error results that keep the structured result. */\nexport async function convertMcpResult(\n\tserver: string,\n\ttool: string,\n\tresult: CallToolResult,\n\toptions: ConvertMcpResultOptions = {},\n): Promise<AgentToolResult<McpToolDetails>> {\n\t// Without content blocks, toLlmContent falls back to the structured content as JSON.\n\tconst converted: (TextContent | ImageContent)[] =\n\t\tresult.content.length > 0 ? await toModelContent(server, result.content, options) : toLlmContent(result);\n\tif (result.isError && textOf(converted) === \"\") {\n\t\tconverted.push({ type: \"text\", text: `MCP tool ${server}/${tool} returned an error` });\n\t}\n\tconst { content, fullOutputPath } = await limitMcpContent(converted, options.saveOutput);\n\tconst { _meta: _ignored, ...scriptResult } = result;\n\treturn {\n\t\tcontent,\n\t\tdetails: { server, tool, ...(fullOutputPath ? { fullOutputPath } : {}) },\n\t\tstructuredContent: scriptResult as unknown as JsonValue,\n\t\t...(result.isError ? { isError: true } : {}),\n\t};\n}\n\n/**\n * Tool input schemas must be objects. MCP servers may omit `type`, and some providers reject object\n * schemas without `properties`.\n */\nfunction toParameters(schema: Record<string, unknown>): TSchema {\n\treturn {\n\t\t...schema,\n\t\ttype: schema.type ?? \"object\",\n\t\t...(schema.properties === undefined ? { properties: {} } : {}),\n\t} as unknown as TSchema;\n}\n\nconst ANNOTATION_HINTS = [\"readOnlyHint\", \"destructiveHint\", \"idempotentHint\", \"openWorldHint\"] as const;\n\n/** The boolean hints of an MCP tool's annotations, or undefined when it has none. */\nfunction toToolAnnotations(tool: McpTool): ToolAnnotations | undefined {\n\tconst annotations: ToolAnnotations = {};\n\tfor (const hint of ANNOTATION_HINTS) {\n\t\tconst value = tool.annotations?.[hint];\n\t\tif (typeof value === \"boolean\") annotations[hint] = value;\n\t}\n\treturn Object.keys(annotations).length > 0 ? annotations : undefined;\n}\n\nexport function createMcpToolDefinition(options: {\n\tserver: string;\n\ttool: McpTool;\n\tname: string;\n\texposure: McpExposure;\n\tnamespace: ToolNamespace;\n\ttimeoutMs: number;\n\tgetClient: () => Promise<McpToolCaller>;\n\t/** Whether `read_mcp_resource` can read the server's resources. */\n\treadableResources?: () => boolean;\n}): ToolDefinition<TSchema, McpToolDetails> {\n\tconst { server, tool } = options;\n\tconst title = tool.title ?? tool.annotations?.title;\n\tconst annotations = toToolAnnotations(tool);\n\tconst label = `${server}/${tool.name}`;\n\treturn {\n\t\tname: options.name,\n\t\tlabel,\n\t\tdescription: tool.description?.trim() || title || `MCP tool ${tool.name} from server ${server}`,\n\t\tparameters: toParameters(tool.inputSchema),\n\t\toutputSchema: createMcpResultSchema(tool.outputSchema),\n\t\texposure: toToolExposure(options.exposure),\n\t\tnamespace: options.namespace,\n\t\t...(annotations ? { annotations } : {}),\n\t\t...createMcpToolRenderers(label),\n\t\tasync execute(_toolCallId, params, signal, onUpdate) {\n\t\t\tconst client = await options.getClient();\n\t\t\tconst result = await client.callTool(tool.name, (params ?? {}) as Record<string, unknown>, {\n\t\t\t\tsignal,\n\t\t\t\ttimeoutMs: options.timeoutMs,\n\t\t\t\tonProgress: (progress) => {\n\t\t\t\t\tconst total = progress.total === undefined ? \"\" : `/${progress.total}`;\n\t\t\t\t\tconst text = progress.message ?? `Progress ${progress.progress}${total}`;\n\t\t\t\t\tonUpdate?.({ content: [{ type: \"text\", text }], details: { server, tool: tool.name } });\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn convertMcpResult(server, tool.name, result, { readableResources: options.readableResources?.() });\n\t\t},\n\t};\n}\n\n/** Renderers of calls to an MCP tool, labeled `server/tool`, also used before the tool is registered. */\nexport function createMcpToolRenderers(label: string): ToolRenderers {\n\treturn {\n\t\trenderCall(args, theme, context) {\n\t\t\tconst component = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\tcomponent.setText(formatToolCallWithArgs(label, args, theme, context.expanded));\n\t\t\treturn component;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\tcomponent.clear();\n\t\t\tconst output = getTextOutput(result, context.showImages).trim();\n\t\t\tif (!output) return component;\n\t\t\tconst color = context.isError ? \"error\" : \"toolOutput\";\n\t\t\tconst styled = replaceTabs(output)\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((line) => theme.fg(color, line))\n\t\t\t\t.join(\"\\n\");\n\t\t\tcomponent.addChild(new Spacer(1));\n\t\t\tif (options.expanded) {\n\t\t\t\tcomponent.addChild(new Text(styled, 0, 0));\n\t\t\t} else {\n\t\t\t\t// Limit wrapped lines, not logical ones: MCP results are often one long JSON line.\n\t\t\t\tcomponent.addChild(\n\t\t\t\t\tnew VisualLinePreview({\n\t\t\t\t\t\ttext: styled,\n\t\t\t\t\t\tmaxVisualLines: OUTPUT_PREVIEW_LINES,\n\t\t\t\t\t\tkeep: \"start\",\n\t\t\t\t\t\tformatHint: (hidden) =>\n\t\t\t\t\t\t\t`${theme.fg(\"muted\", `... (${hidden} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tconst fullOutputPath = (result.details as McpToolDetails | undefined)?.fullOutputPath;\n\t\t\t\tif (fullOutputPath) component.addChild(new Text(theme.fg(\"muted\", `Full output: ${fullOutputPath}`), 0, 0));\n\t\t\t}\n\t\t\treturn component;\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/extensions/mcp/tools.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Adapts MCP tools to pi tool definitions.\n *\n * Results map onto pi's model-facing content (text and images). Text over 20KB keeps its start and\n * end with the middle cut out, like Codex does, and the full text is saved to a temp file the model\n * can read. Binary resources other than images are saved to temp files too, and resource links name\n * the `read_mcp_resource` tool. Codemode scripts receive the whole `CallToolResult` without `_meta`\n * (`content` blocks as sent by the server, `structuredContent`, `isError`), never truncated: it is\n * the tool's `structuredContent`, and every MCP tool declares a `CallToolResult` output schema. MCP\n * errors (`isError`) are error results for the model, but scripts still resolve to the result.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { ImageContent, JsonValue, TextContent } from \"@earendil-works/pi-ai\";\nimport {\n\ttype CallToolResult,\n\ttype ContentBlock,\n\ttype McpRequestOptions,\n\ttype Tool as McpTool,\n\ttoLlmContent,\n} from \"@earendil-works/pi-mcp\";\nimport { Container, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport type { TSchema } from \"typebox\";\nimport type {\n\tToolAnnotations,\n\tToolDefinition,\n\tToolExposure,\n\tToolNamespace,\n\tToolRenderers,\n} from \"../../core/extensions/types.ts\";\nimport { READ_MCP_RESOURCE_TOOL } from \"../../core/mcp-servers.ts\";\nimport { formatToolCallWithArgs, getTextOutput, replaceTabs } from \"../../core/tools/render-utils.ts\";\nimport { formatSize, truncateMiddle } from \"../../core/tools/truncate.ts\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { VisualLinePreview } from \"../../modes/interactive/components/visual-truncate.ts\";\nimport { writeOutputFile } from \"../../utils/output-files.ts\";\nimport type { McpExposure } from \"./config.ts\";\n\n/**\n * Tool exposure of an MCP exposure. `codemode` and `deferred` both leave tools out of the codemode\n * description; they differ only in which tool the MCP extension activates to reach them.\n */\nexport function toToolExposure(exposure: McpExposure): ToolExposure {\n\treturn exposure === \"codemode\" ? \"deferred\" : exposure;\n}\n\n/** Provider tool names are limited to 64 characters of `[A-Za-z0-9_-]`. */\nconst MAX_TOOL_NAME_LENGTH = 64;\n/** Model-facing text of an MCP result beyond this is cut in the middle. */\nexport const MCP_OUTPUT_MAX_BYTES = 20 * 1024;\n/** Visual (wrapped) result lines shown before the output is expanded. */\nconst OUTPUT_PREVIEW_LINES = 5;\n/** Tool that reads the resources named by resource links. */\nexport { READ_MCP_RESOURCE_TOOL };\n\nexport interface McpToolDetails {\n\tserver: string;\n\ttool: string;\n\t/** Temp file with the full text output, when the model-facing text was truncated. */\n\tfullOutputPath?: string;\n}\n\n/**\n * Saves the full text of a truncated result, or a binary resource, and returns the file path.\n * `extension` includes the dot, for example `.txt`.\n */\nexport type McpOutputSaver = (data: string | Uint8Array, extension: string) => Promise<string>;\n\nexport function saveToTempFile(data: string | Uint8Array, extension: string): Promise<string> {\n\treturn writeOutputFile(\"pi-mcp\", extension, data);\n}\n\nexport interface McpToolCaller {\n\tcallTool(name: string, args: Record<string, unknown>, options: McpRequestOptions): Promise<CallToolResult>;\n}\n\n/**\n * `mcp__<server>__<tool>`, sanitized and shortened with a hash suffix when too long. Like Codex,\n * everything but `[A-Za-z0-9_]` becomes `_`, so the name is also the identifier codemode scripts\n * call it by. `isTaken` reports names used by a different MCP tool: sanitizing can map two tools to\n * one name (`a-b` and `a_b`), which then get the hash suffix.\n */\nexport function createMcpToolName(\n\tserver: string,\n\ttool: string,\n\tisTaken: (name: string) => boolean = () => false,\n): string {\n\tconst name = `mcp__${server}__${tool}`.replace(/[^A-Za-z0-9_]/g, \"_\");\n\tif (name.length <= MAX_TOOL_NAME_LENGTH && !isTaken(name)) return name;\n\tconst hash = createHash(\"sha256\").update(`${server}\\0${tool}`).digest(\"hex\").slice(0, 8);\n\treturn `${name.slice(0, MAX_TOOL_NAME_LENGTH - hash.length - 1)}_${hash}`;\n}\n\nfunction textOf(content: readonly (TextContent | ImageContent)[]): string {\n\treturn content\n\t\t.filter((block): block is TextContent => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\\n\");\n}\n\n/**\n * MCP content blocks as one compact type with the fields of text and image blocks, which scripts\n * read most (`image(block)` takes an image block as is). Rendered into every MCP tool's declaration.\n */\nconst CONTENT_BLOCK_SCHEMA = {\n\ttype: \"object\",\n\tproperties: {\n\t\ttype: { enum: [\"text\", \"image\", \"audio\", \"resource_link\", \"resource\"] },\n\t\ttext: { type: \"string\" },\n\t\tdata: { type: \"string\" },\n\t\tmimeType: { type: \"string\" },\n\t},\n\trequired: [\"type\"],\n\tadditionalProperties: true,\n};\n\n/** Keywords whose values are data, so a `$ref` key in them is not a reference. */\nconst SCHEMA_DATA_KEYWORDS: ReadonlySet<string> = new Set([\"const\", \"enum\", \"default\", \"examples\"]);\n/** Keywords whose values map names to schemas, so their keys are names, not keywords. */\nconst SCHEMA_MAP_KEYWORDS: ReadonlySet<string> = new Set([\n\t\"properties\",\n\t\"patternProperties\",\n\t\"dependentSchemas\",\n\t\"dependencies\",\n\t\"$defs\",\n\t\"definitions\",\n]);\n\n/**\n * `schema` as a subschema at the JSON pointer `pointer` (`#/properties/structuredContent`) of\n * another schema: its local references (`#`, `#/$defs/Item`) are rewritten to point below\n * `pointer`, so they resolve to the same subschemas as before.\n */\nfunction relocateSchema(schema: unknown, pointer: string): unknown {\n\tif (Array.isArray(schema)) return schema.map((item) => relocateSchema(item, pointer));\n\tif (typeof schema !== \"object\" || schema === null) return schema;\n\tconst relocated: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(schema)) {\n\t\tif (key === \"$ref\" && typeof value === \"string\" && (value === \"#\" || value.startsWith(\"#/\"))) {\n\t\t\trelocated[key] = `${pointer}${value.slice(1)}`;\n\t\t} else if (SCHEMA_DATA_KEYWORDS.has(key)) {\n\t\t\trelocated[key] = value;\n\t\t} else if (SCHEMA_MAP_KEYWORDS.has(key) && typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n\t\t\trelocated[key] = Object.fromEntries(\n\t\t\t\tObject.entries(value).map(([name, subschema]) => [name, relocateSchema(subschema, pointer)]),\n\t\t\t);\n\t\t} else {\n\t\t\trelocated[key] = relocateSchema(value, pointer);\n\t\t}\n\t}\n\treturn relocated;\n}\n\n/**\n * Output schema of every MCP tool: the `CallToolResult` scripts receive (without `_meta`, which\n * {@link convertMcpResult} drops), with the tool's own output schema as `structuredContent`.\n */\nexport function createMcpResultSchema(structuredContentSchema: Record<string, unknown> | undefined): TSchema {\n\treturn {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tcontent: { type: \"array\", items: CONTENT_BLOCK_SCHEMA },\n\t\t\t// Servers may send structured content without declaring a schema for it, and it may be any JSON value.\n\t\t\tstructuredContent: structuredContentSchema\n\t\t\t\t? relocateSchema(structuredContentSchema, \"#/properties/structuredContent\")\n\t\t\t\t: {},\n\t\t\tisError: { type: \"boolean\" },\n\t\t},\n\t\trequired: [\"content\"],\n\t\t// Fields newer protocol versions add.\n\t\tadditionalProperties: true,\n\t} as unknown as TSchema;\n}\n\n/**\n * Keep model-facing text within {@link MCP_OUTPUT_MAX_BYTES}. Longer text becomes one text block in\n * Codex's truncation format, followed by the path of the file with the full text; images follow it.\n */\nexport async function limitMcpContent(\n\tcontent: (TextContent | ImageContent)[],\n\tsaveOutput: McpOutputSaver = saveToTempFile,\n): Promise<{ content: (TextContent | ImageContent)[]; fullOutputPath?: string }> {\n\tconst combined = textOf(content);\n\tconst truncation = truncateMiddle(combined, MCP_OUTPUT_MAX_BYTES);\n\tif (!truncation.truncated) return { content };\n\tlet fullOutputPath: string | undefined;\n\tlet where: string;\n\ttry {\n\t\tfullOutputPath = await saveOutput(combined, \".txt\");\n\t\twhere = `[Full output: ${fullOutputPath} (read it with offset/limit)]`;\n\t} catch (error) {\n\t\twhere = `[Could not save the full output: ${error instanceof Error ? error.message : String(error)}]`;\n\t}\n\tconst tokens = Math.ceil(truncation.totalBytes / 4);\n\tconst text = `Warning: truncated output (original token count: ${tokens})\\nTotal output lines: ${truncation.totalLines}\\n\\n${truncation.content}\\n\\n${where}`;\n\treturn {\n\t\tcontent: [{ type: \"text\", text }, ...content.filter((block) => block.type === \"image\")],\n\t\t...(fullOutputPath ? { fullOutputPath } : {}),\n\t};\n}\n\nexport interface ConvertMcpResultOptions {\n\t/** Saves truncated text and binary resources. Default: a temp file. */\n\tsaveOutput?: McpOutputSaver;\n\t/** Whether the server's resources can be read with `read_mcp_resource`, which resource links then name. */\n\treadableResources?: boolean;\n}\n\n/** File extension for a saved binary resource: the one its URI ends in, else `.bin`. */\nfunction extensionOf(uri: string): string {\n\tconst path = URL.canParse(uri) ? new URL(uri).pathname : uri;\n\treturn /\\.[A-Za-z0-9]{1,8}$/.exec(path)?.[0] ?? \".bin\";\n}\n\n/** Blobs of these types are shown as text. */\nfunction isTextMimeType(mimeType: string | undefined): boolean {\n\tif (!mimeType) return false;\n\tconst type = mimeType.split(\";\", 1)[0].trim().toLowerCase();\n\treturn type.startsWith(\"text/\") || type === \"application/json\" || type.endsWith(\"+json\") || type.endsWith(\"+xml\");\n}\n\n/** Model-facing content of one block of `server`'s result. */\nasync function blockToContent(\n\tserver: string,\n\tblock: ContentBlock,\n\toptions: ConvertMcpResultOptions,\n): Promise<(TextContent | ImageContent)[]> {\n\tif (block.type === \"resource_link\") {\n\t\tconst details = [block.mimeType, block.size === undefined ? undefined : formatSize(block.size)].filter(Boolean);\n\t\tconst read = options.readableResources ? `. Read it with ${READ_MCP_RESOURCE_TOOL} (server \"${server}\")` : \"\";\n\t\tconst description = block.description ? `: ${block.description}` : \"\";\n\t\treturn [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `[Resource ${block.uri} \"${block.title ?? block.name}\"${details.length > 0 ? ` (${details.join(\", \")})` : \"\"}${description}${read}]`,\n\t\t\t},\n\t\t];\n\t}\n\tif (block.type === \"resource\" && \"blob\" in block.resource && !block.resource.mimeType?.startsWith(\"image/\")) {\n\t\tconst { uri, mimeType, blob } = block.resource;\n\t\tconst data = Buffer.from(blob, \"base64\");\n\t\tif (isTextMimeType(mimeType)) return [{ type: \"text\", text: data.toString(\"utf8\") }];\n\t\tconst kind = `${mimeType ?? \"unknown type\"}, ${formatSize(data.length)}`;\n\t\ttry {\n\t\t\tconst path = await (options.saveOutput ?? saveToTempFile)(data, extensionOf(uri));\n\t\t\treturn [{ type: \"text\", text: `[Binary resource ${uri} (${kind}) saved to ${path}]` }];\n\t\t} catch (error) {\n\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\treturn [{ type: \"text\", text: `[Binary resource ${uri} (${kind}) could not be saved: ${reason}]` }];\n\t\t}\n\t}\n\treturn toLlmContent({ content: [block] });\n}\n\n/** Model-facing content of `server`'s content blocks, before the output limit. */\nexport async function toModelContent(\n\tserver: string,\n\tblocks: readonly ContentBlock[],\n\toptions: ConvertMcpResultOptions = {},\n): Promise<(TextContent | ImageContent)[]> {\n\treturn (await Promise.all(blocks.map((block) => blockToContent(server, block, options)))).flat();\n}\n\n/** Convert an MCP result. `isError` results become error results that keep the structured result. */\nexport async function convertMcpResult(\n\tserver: string,\n\ttool: string,\n\tresult: CallToolResult,\n\toptions: ConvertMcpResultOptions = {},\n): Promise<AgentToolResult<McpToolDetails>> {\n\t// Without content blocks, toLlmContent falls back to the structured content as JSON.\n\tconst converted: (TextContent | ImageContent)[] =\n\t\tresult.content.length > 0 ? await toModelContent(server, result.content, options) : toLlmContent(result);\n\tif (result.isError && textOf(converted) === \"\") {\n\t\tconverted.push({ type: \"text\", text: `MCP tool ${server}/${tool} returned an error` });\n\t}\n\tconst { content, fullOutputPath } = await limitMcpContent(converted, options.saveOutput);\n\tconst { _meta: _ignored, ...scriptResult } = result;\n\treturn {\n\t\tcontent,\n\t\tdetails: { server, tool, ...(fullOutputPath ? { fullOutputPath } : {}) },\n\t\tstructuredContent: scriptResult as unknown as JsonValue,\n\t\t...(result.isError ? { isError: true } : {}),\n\t};\n}\n\n/**\n * Tool input schemas must be objects. MCP servers may omit `type`, and some providers reject object\n * schemas without `properties`.\n */\nfunction toParameters(schema: Record<string, unknown>): TSchema {\n\treturn {\n\t\t...schema,\n\t\ttype: schema.type ?? \"object\",\n\t\t...(schema.properties === undefined ? { properties: {} } : {}),\n\t} as unknown as TSchema;\n}\n\nconst ANNOTATION_HINTS = [\"readOnlyHint\", \"destructiveHint\", \"idempotentHint\", \"openWorldHint\"] as const;\n\n/** The boolean hints of an MCP tool's annotations, or undefined when it has none. */\nfunction toToolAnnotations(tool: McpTool): ToolAnnotations | undefined {\n\tconst annotations: ToolAnnotations = {};\n\tfor (const hint of ANNOTATION_HINTS) {\n\t\tconst value = tool.annotations?.[hint];\n\t\tif (typeof value === \"boolean\") annotations[hint] = value;\n\t}\n\treturn Object.keys(annotations).length > 0 ? annotations : undefined;\n}\n\nexport function createMcpToolDefinition(options: {\n\tserver: string;\n\ttool: McpTool;\n\tname: string;\n\texposure: McpExposure;\n\tnamespace: ToolNamespace;\n\ttimeoutMs: number;\n\tgetClient: () => Promise<McpToolCaller>;\n\t/** Whether `read_mcp_resource` can read the server's resources. */\n\treadableResources?: () => boolean;\n}): ToolDefinition<TSchema, McpToolDetails> {\n\tconst { server, tool } = options;\n\tconst title = tool.title ?? tool.annotations?.title;\n\tconst annotations = toToolAnnotations(tool);\n\tconst label = `${server}/${tool.name}`;\n\treturn {\n\t\tname: options.name,\n\t\tlabel,\n\t\tdescription: tool.description?.trim() || title || `MCP tool ${tool.name} from server ${server}`,\n\t\tparameters: toParameters(tool.inputSchema),\n\t\toutputSchema: createMcpResultSchema(tool.outputSchema),\n\t\texposure: toToolExposure(options.exposure),\n\t\tnamespace: options.namespace,\n\t\t...(annotations ? { annotations } : {}),\n\t\t...createMcpToolRenderers(label),\n\t\tasync execute(_toolCallId, params, signal, onUpdate) {\n\t\t\tconst client = await options.getClient();\n\t\t\tconst result = await client.callTool(tool.name, (params ?? {}) as Record<string, unknown>, {\n\t\t\t\tsignal,\n\t\t\t\ttimeoutMs: options.timeoutMs,\n\t\t\t\tonProgress: (progress) => {\n\t\t\t\t\tconst total = progress.total === undefined ? \"\" : `/${progress.total}`;\n\t\t\t\t\tconst text = progress.message ?? `Progress ${progress.progress}${total}`;\n\t\t\t\t\tonUpdate?.({ content: [{ type: \"text\", text }], details: { server, tool: tool.name } });\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn convertMcpResult(server, tool.name, result, { readableResources: options.readableResources?.() });\n\t\t},\n\t};\n}\n\n/** Renderers of calls to an MCP tool, labeled `server/tool`, also used before the tool is registered. */\nexport function createMcpToolRenderers(label: string): ToolRenderers {\n\treturn {\n\t\trenderCall(args, theme, context) {\n\t\t\tconst component = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\tcomponent.setText(formatToolCallWithArgs(label, args, theme, context.expanded));\n\t\t\treturn component;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\t\tcomponent.clear();\n\t\t\tconst output = getTextOutput(result, context.showImages).trim();\n\t\t\tif (!output) return component;\n\t\t\tconst color = context.isError ? \"error\" : \"toolOutput\";\n\t\t\tconst styled = replaceTabs(output)\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((line) => theme.fg(color, line))\n\t\t\t\t.join(\"\\n\");\n\t\t\tcomponent.addChild(new Spacer(1));\n\t\t\tif (options.expanded) {\n\t\t\t\tcomponent.addChild(new Text(styled, 0, 0));\n\t\t\t} else {\n\t\t\t\t// Limit wrapped lines, not logical ones: MCP results are often one long JSON line.\n\t\t\t\tcomponent.addChild(\n\t\t\t\t\tnew VisualLinePreview({\n\t\t\t\t\t\ttext: styled,\n\t\t\t\t\t\tmaxVisualLines: OUTPUT_PREVIEW_LINES,\n\t\t\t\t\t\tkeep: \"start\",\n\t\t\t\t\t\tformatHint: (hidden) =>\n\t\t\t\t\t\t\t`${theme.fg(\"muted\", `... (${hidden} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")}${theme.fg(\"muted\", \")\")}`,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tconst fullOutputPath = (result.details as McpToolDetails | undefined)?.fullOutputPath;\n\t\t\t\tif (fullOutputPath) component.addChild(new Text(theme.fg(\"muted\", `Full output: ${fullOutputPath}`), 0, 0));\n\t\t\t}\n\t\t\treturn component;\n\t\t},\n\t};\n}\n"]}
@@ -1,5 +1,5 @@
1
- declare module "../../core/keybindings.ts" {
2
- interface AppKeybindings {
1
+ declare module "@earendil-works/pi-tui" {
2
+ interface Keybindings {
3
3
  "app.provider.switchPaneLeft": true;
4
4
  "app.provider.switchPaneRight": true;
5
5
  "app.provider.removeEntry": true;
@@ -1 +1 @@
1
- {"version":3,"file":"keybindings.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/keybindings.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,2BAA2B,CAAC;IAC1C,UAAU,cAAc;QACvB,6BAA6B,EAAE,IAAI,CAAC;QACpC,8BAA8B,EAAE,IAAI,CAAC;QACrC,0BAA0B,EAAE,IAAI,CAAC;KACjC;CACD"}
1
+ {"version":3,"file":"keybindings.d.ts","sourceRoot":"","sources":["../../../src/extensions/provider/keybindings.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,wBAAwB,CAAC;IACvC,UAAU,WAAW;QACpB,6BAA6B,EAAE,IAAI,CAAC;QACpC,8BAA8B,EAAE,IAAI,CAAC;QACrC,0BAA0B,EAAE,IAAI,CAAC;KACjC;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"keybindings.js","sourceRoot":"","sources":["../../../src/extensions/provider/keybindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAUjE,uBAAuB,EAAE,CAAC;AAC1B,mBAAmB,CAAC;IACnB,6BAA6B,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,gCAAgC,EAAE;IACrG,8BAA8B,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,iCAAiC,EAAE;IACxG,0BAA0B,EAAE;QAC3B,WAAW,EAAE,QAAQ;QACrB,WAAW,EAAE,2DAA2D;KACxE;CACD,CAAC,CAAC","sourcesContent":["import { registerKeybindings } from \"../../core/keybinding-registry.ts\";\nimport { registerListKeybindings } from \"../list-keybindings.ts\";\n\ndeclare module \"../../core/keybindings.ts\" {\n\tinterface AppKeybindings {\n\t\t\"app.provider.switchPaneLeft\": true;\n\t\t\"app.provider.switchPaneRight\": true;\n\t\t\"app.provider.removeEntry\": true;\n\t}\n}\n\nregisterListKeybindings();\nregisterKeybindings({\n\t\"app.provider.switchPaneLeft\": { defaultKeys: \"left\", description: \"/provider: focus the left pane\" },\n\t\"app.provider.switchPaneRight\": { defaultKeys: \"right\", description: \"/provider: focus the right pane\" },\n\t\"app.provider.removeEntry\": {\n\t\tdefaultKeys: \"ctrl+x\",\n\t\tdescription: \"/provider: remove the selected compat or dictionary entry\",\n\t},\n});\n"]}
1
+ {"version":3,"file":"keybindings.js","sourceRoot":"","sources":["../../../src/extensions/provider/keybindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAUjE,uBAAuB,EAAE,CAAC;AAC1B,mBAAmB,CAAC;IACnB,6BAA6B,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,gCAAgC,EAAE;IACrG,8BAA8B,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,iCAAiC,EAAE;IACxG,0BAA0B,EAAE;QAC3B,WAAW,EAAE,QAAQ;QACrB,WAAW,EAAE,2DAA2D;KACxE;CACD,CAAC,CAAC","sourcesContent":["import { registerKeybindings } from \"../../core/keybinding-registry.ts\";\nimport { registerListKeybindings } from \"../list-keybindings.ts\";\n\ndeclare module \"@earendil-works/pi-tui\" {\n\tinterface Keybindings {\n\t\t\"app.provider.switchPaneLeft\": true;\n\t\t\"app.provider.switchPaneRight\": true;\n\t\t\"app.provider.removeEntry\": true;\n\t}\n}\n\nregisterListKeybindings();\nregisterKeybindings({\n\t\"app.provider.switchPaneLeft\": { defaultKeys: \"left\", description: \"/provider: focus the left pane\" },\n\t\"app.provider.switchPaneRight\": { defaultKeys: \"right\", description: \"/provider: focus the right pane\" },\n\t\"app.provider.removeEntry\": {\n\t\tdefaultKeys: \"ctrl+x\",\n\t\tdescription: \"/provider: remove the selected compat or dictionary entry\",\n\t},\n});\n"]}
@@ -12,8 +12,6 @@ export interface CodeSearchOptions {
12
12
  cwd: string;
13
13
  signal?: AbortSignal;
14
14
  onProgress?: (message: string) => void;
15
- /** Test seam for the local `rg` backend. */
16
- workspace?: Workspace;
17
15
  }
18
16
  export declare function codeSearch(options: CodeSearchOptions): Promise<CodeLocation[]>;
19
17
  export interface ToolCall {
@@ -1 +1 @@
1
- {"version":3,"file":"code-search.d.ts","sourceRoot":"","sources":["../../../src/extensions/search/code-search.ts"],"names":[],"mappings":"AAmBA,OAAO,EAA8B,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvE,MAAM,WAAW,YAAY;IAC5B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,4CAA4C;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAgDpF;AAED,MAAM,WAAW,QAAQ;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAED,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAa3D;AAyBD,yGAAyG;AACzG,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAc1F;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,CAOjE"}
1
+ {"version":3,"file":"code-search.d.ts","sourceRoot":"","sources":["../../../src/extensions/search/code-search.ts"],"names":[],"mappings":"AAmBA,OAAO,EAA8B,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvE,MAAM,WAAW,YAAY;IAC5B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAgDpF;AAED,MAAM,WAAW,QAAQ;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAED,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAa3D;AAyBD,yGAAyG;AACzG,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAc1F;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,CAOjE"}
@@ -13,8 +13,8 @@ import { VIRTUAL_ROOT, Workspace } from "./workspace.js";
13
13
  export async function codeSearch(options) {
14
14
  const { apiKey, query, signal } = options;
15
15
  const progress = options.onProgress ?? (() => { });
16
- const workspace = options.workspace ?? new Workspace(options.root);
17
- const map = workspace.repoMap();
16
+ const workspace = new Workspace(options.root);
17
+ const map = await workspace.repoMap(signal);
18
18
  const messages = [
19
19
  { role: "system", content: SYSTEM_PROMPT },
20
20
  {
@@ -1 +1 @@
1
- {"version":3,"file":"code-search.js","sourceRoot":"","sources":["../../../src/extensions/search/code-search.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAoB,IAAI,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,SAAS,EACT,eAAe,EACf,aAAa,EACb,gBAAgB,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAgB,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAoBvE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAA0B;IAC1D,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC1C,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAkB;QAC/B,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE;QAC1C;YACC,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,sBAAsB,KAAK,yBAAyB,GAAG,CAAC,KAAK,IAAI,YAAY,mBAAmB,GAAG,CAAC,IAAI,UAAU;SAC3H;KACD,CAAC;IAEF,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,SAAS,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QAClD,IAAI,IAAI,KAAK,SAAS,GAAG,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QACnF,QAAQ,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,mBAAmB,IAAI,IAAI,SAAS,IAAI,CAAC,CAAC;QACjG,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAElC,IAAI,IAAI,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,IAAI,EAAE,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;YACjG,SAAS;QACV,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;aACjC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACrC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;aACvD,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;QACzB,QAAQ,CAAC,WAAW,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,WAAW,IAAI,IAAI,SAAS,IAAI,CAAC,CAAC;QAC/G,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,IAAI,CAAC,GAAG,CACP,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,MAAM,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAY,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CACrG,CACD,CAAC;QACF,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CACZ;YACC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACnE,EACD,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CACvD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC;AAQD,yGAAyG;AACzG,MAAM,UAAU,aAAa,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACxE,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,4FAA4F;IAC5F,KAAK,MAAM,SAAS,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAY,CAAC;YAC9C,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9D,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,IAA+B,EAAE,CAAC;YACxG,CAAC;QACF,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAChC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;iBACf,IAAI,CAAC,KAAK,GAAG;gBAAE,QAAQ,GAAG,KAAK,CAAC;QACtC,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG;YAAE,QAAQ,GAAG,IAAI,CAAC;aACjC,IAAI,CAAC,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;aACvB,IAAI,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,wFAAwF;AACxF,SAAS,UAAU,CAAC,IAAY;IAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,kCAAkC,EAAE,SAAS,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,OAAO,GAAG,mDAAmD,CAAC;AACpE,MAAM,QAAQ,GAAG,0CAA0C,CAAC;AAE5D,yGAAyG;AACzG,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,SAAoB,EAAE,GAAW;IACzE,MAAM,SAAS,GAAmB,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,EAAE,AAAD,EAAG,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,SAAS,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,GAAG;YACpD,MAAM,EAAE,CAAC,GAAG,IAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;iBACnC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,EAAoB,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;iBACvE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;SAC7B,CAAC,CAAC;QACH,IAAI,SAAS,CAAC,MAAM,KAAK,WAAW;YAAE,MAAM;IAC7C,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAyB;IACxD,IAAI,CAAC,SAAS,CAAC,MAAM;QACpB,OAAO,0FAA0F,CAAC;IACnG,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAC1B,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9G,CAAC;IACF,OAAO,GAAG,SAAS,CAAC,MAAM,cAAc,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,wCAAwC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACrJ,CAAC","sourcesContent":["/**\n * code_search: Devin's SWE-grep model plans, this process executes.\n *\n * Each round sends the transcript to Devin, which replies with one tool call: `restricted_exec`\n * (up to eight rg/readfile/tree commands, run locally by `Workspace`) or `answer` (an `<ANSWER>`\n * document of files and line ranges). After `MAX_TURNS` rounds the answer is demanded.\n */\nimport { randomUUID } from \"node:crypto\";\nimport { relative } from \"node:path\";\nimport { type ChatMessage, chat } from \"./devin.ts\";\nimport {\n\tFORCE_ANSWER,\n\tMAX_COMMANDS,\n\tMAX_RESULTS,\n\tMAX_TURNS,\n\tRETRY_TOOL_CALL,\n\tSYSTEM_PROMPT,\n\tTOOL_DEFINITIONS,\n} from \"./prompt.ts\";\nimport { type Command, VIRTUAL_ROOT, Workspace } from \"./workspace.ts\";\n\nexport interface CodeLocation {\n\t/** Relative to the session's working directory. */\n\tpath: string;\n\tranges: Array<[number, number]>;\n}\n\nexport interface CodeSearchOptions {\n\tapiKey: string;\n\tquery: string;\n\t/** Directory to search; already confined to the working directory by the caller. */\n\troot: string;\n\tcwd: string;\n\tsignal?: AbortSignal;\n\tonProgress?: (message: string) => void;\n\t/** Test seam for the local `rg` backend. */\n\tworkspace?: Workspace;\n}\n\nexport async function codeSearch(options: CodeSearchOptions): Promise<CodeLocation[]> {\n\tconst { apiKey, query, signal } = options;\n\tconst progress = options.onProgress ?? (() => {});\n\tconst workspace = options.workspace ?? new Workspace(options.root);\n\tconst map = workspace.repoMap();\n\tconst messages: ChatMessage[] = [\n\t\t{ role: \"system\", content: SYSTEM_PROMPT },\n\t\t{\n\t\t\trole: \"user\",\n\t\t\tcontent: `Problem Statement: ${query}\\n\\nRepo Map (tree -L ${map.depth} ${VIRTUAL_ROOT}):\\n\\`\\`\\`text\\n${map.tree}\\n\\`\\`\\``,\n\t\t},\n\t];\n\n\tfor (let turn = 1; turn <= MAX_TURNS + 1; turn++) {\n\t\tif (turn === MAX_TURNS + 1) messages.push({ role: \"user\", content: FORCE_ANSWER });\n\t\tprogress(turn > MAX_TURNS ? \"Collecting the answer…\" : `Planning (round ${turn}/${MAX_TURNS})…`);\n\t\tconst reply = await chat(apiKey, messages, TOOL_DEFINITIONS, signal);\n\t\tconst call = parseToolCall(reply);\n\n\t\tif (call?.name === \"answer\") {\n\t\t\treturn parseAnswer(String(call.args.answer ?? \"\"), workspace, options.cwd);\n\t\t}\n\t\tif (call?.name !== \"restricted_exec\") {\n\t\t\tmessages.push({ role: \"assistant\", content: reply }, { role: \"user\", content: RETRY_TOOL_CALL });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst keys = Object.keys(call.args)\n\t\t\t.filter((k) => /^command\\d+$/.test(k))\n\t\t\t.sort((a, b) => Number(a.slice(7)) - Number(b.slice(7)))\n\t\t\t.slice(0, MAX_COMMANDS);\n\t\tprogress(`Running ${keys.length} ${keys.length === 1 ? \"command\" : \"commands\"} (round ${turn}/${MAX_TURNS})…`);\n\t\tconst results = await Promise.all(\n\t\t\tkeys.map(\n\t\t\t\tasync (k) => `<${k}_result>\\n${await workspace.run(call.args[k] as Command, signal)}\\n</${k}_result>`,\n\t\t\t),\n\t\t);\n\t\tconst id = randomUUID();\n\t\tmessages.push(\n\t\t\t{\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: call.thinking,\n\t\t\t\tcall: { id, name: call.name, arguments: JSON.stringify(call.args) },\n\t\t\t},\n\t\t\t{ role: \"tool\", content: results.join(\"\"), callId: id },\n\t\t);\n\t}\n\treturn [];\n}\n\nexport interface ToolCall {\n\tthinking: string;\n\tname: string;\n\targs: Record<string, unknown>;\n}\n\n/** `thinking[TOOL_CALLS]name[ARGS]{json}`. The JSON is the first balanced object, repaired if needed. */\nexport function parseToolCall(text: string): ToolCall | null {\n\tconst m = text.match(/\\[TOOL_CALLS\\]\\s*(\\w+)\\s*\\[ARGS\\]\\s*(\\{[\\s\\S]*)/);\n\tif (!m) return null;\n\t// Repair before scanning: a stray key quote would otherwise end the scan inside a \"string\".\n\tfor (const candidate of [firstObject(m[2]!), firstObject(repairKeys(m[2]!))]) {\n\t\ttry {\n\t\t\tconst args = JSON.parse(candidate) as unknown;\n\t\t\tif (args && typeof args === \"object\" && !Array.isArray(args)) {\n\t\t\t\treturn { thinking: text.slice(0, m.index).trim(), name: m[1]!, args: args as Record<string, unknown> };\n\t\t\t}\n\t\t} catch {}\n\t}\n\treturn null;\n}\n\nfunction firstObject(text: string): string {\n\tlet depth = 0;\n\tlet inString = false;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tconst c = text[i];\n\t\tif (inString) {\n\t\t\tif (c === \"\\\\\") i++;\n\t\t\telse if (c === '\"') inString = false;\n\t\t} else if (c === '\"') inString = true;\n\t\telse if (c === \"{\") depth++;\n\t\telse if (c === \"}\" && --depth === 0) return text.slice(0, i + 1);\n\t}\n\treturn text;\n}\n\n/** The planner sometimes drops a key's quotes, as in `,exclude\":[]` or `{path:\"…\"}`. */\nfunction repairKeys(json: string): string {\n\treturn json.replace(/([{,]\\s*)\"?([A-Za-z_]\\w*)\"?\\s*:/g, '$1\"$2\":');\n}\n\nconst FILE_RE = /<file\\s+path=([\"'])(.+?)\\1\\s*>([\\s\\S]*?)<\\/file>/g;\nconst RANGE_RE = /<range>\\s*(\\d+)\\s*-\\s*(\\d+)\\s*<\\/range>/g;\n\n/** The files of an `<ANSWER>`, each re-checked against the workspace; anything outside it is dropped. */\nexport function parseAnswer(xml: string, workspace: Workspace, cwd: string): CodeLocation[] {\n\tconst locations: CodeLocation[] = [];\n\tfor (const [, , path, body] of xml.matchAll(FILE_RE)) {\n\t\tconst real = workspace.toReal(path);\n\t\tif (!real) continue;\n\t\tlocations.push({\n\t\t\tpath: relative(cwd, real).replace(/\\\\/g, \"/\") || \".\",\n\t\t\tranges: [...body!.matchAll(RANGE_RE)]\n\t\t\t\t.map(([, start, end]): [number, number] => [Number(start), Number(end)])\n\t\t\t\t.sort((a, b) => a[0] - b[0]),\n\t\t});\n\t\tif (locations.length === MAX_RESULTS) break;\n\t}\n\treturn locations;\n}\n\nexport function formatLocations(locations: CodeLocation[]): string {\n\tif (!locations.length)\n\t\treturn \"No relevant code found. Try a narrower behavioral query, or grep for a known identifier.\";\n\tconst lines = locations.map(\n\t\t({ path, ranges }) => `${path}${ranges.length ? ` (${ranges.map(([s, e]) => `L${s}-${e}`).join(\", \")})` : \"\"}`,\n\t);\n\treturn `${locations.length} candidate ${locations.length === 1 ? \"location\" : \"locations\"}; read them before relying on them:\\n${lines.join(\"\\n\")}`;\n}\n"]}
1
+ {"version":3,"file":"code-search.js","sourceRoot":"","sources":["../../../src/extensions/search/code-search.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * code_search: Devin's SWE-grep model plans, this process executes.\n *\n * Each round sends the transcript to Devin, which replies with one tool call: `restricted_exec`\n * (up to eight rg/readfile/tree commands, run locally by `Workspace`) or `answer` (an `<ANSWER>`\n * document of files and line ranges). After `MAX_TURNS` rounds the answer is demanded.\n */\nimport { randomUUID } from \"node:crypto\";\nimport { relative } from \"node:path\";\nimport { type ChatMessage, chat } from \"./devin.ts\";\nimport {\n\tFORCE_ANSWER,\n\tMAX_COMMANDS,\n\tMAX_RESULTS,\n\tMAX_TURNS,\n\tRETRY_TOOL_CALL,\n\tSYSTEM_PROMPT,\n\tTOOL_DEFINITIONS,\n} from \"./prompt.ts\";\nimport { type Command, VIRTUAL_ROOT, Workspace } from \"./workspace.ts\";\n\nexport interface CodeLocation {\n\t/** Relative to the session's working directory. */\n\tpath: string;\n\tranges: Array<[number, number]>;\n}\n\nexport interface CodeSearchOptions {\n\tapiKey: string;\n\tquery: string;\n\t/** Directory to search; already confined to the working directory by the caller. */\n\troot: string;\n\tcwd: string;\n\tsignal?: AbortSignal;\n\tonProgress?: (message: string) => void;\n}\n\nexport async function codeSearch(options: CodeSearchOptions): Promise<CodeLocation[]> {\n\tconst { apiKey, query, signal } = options;\n\tconst progress = options.onProgress ?? (() => {});\n\tconst workspace = new Workspace(options.root);\n\tconst map = await workspace.repoMap(signal);\n\tconst messages: ChatMessage[] = [\n\t\t{ role: \"system\", content: SYSTEM_PROMPT },\n\t\t{\n\t\t\trole: \"user\",\n\t\t\tcontent: `Problem Statement: ${query}\\n\\nRepo Map (tree -L ${map.depth} ${VIRTUAL_ROOT}):\\n\\`\\`\\`text\\n${map.tree}\\n\\`\\`\\``,\n\t\t},\n\t];\n\n\tfor (let turn = 1; turn <= MAX_TURNS + 1; turn++) {\n\t\tif (turn === MAX_TURNS + 1) messages.push({ role: \"user\", content: FORCE_ANSWER });\n\t\tprogress(turn > MAX_TURNS ? \"Collecting the answer…\" : `Planning (round ${turn}/${MAX_TURNS})…`);\n\t\tconst reply = await chat(apiKey, messages, TOOL_DEFINITIONS, signal);\n\t\tconst call = parseToolCall(reply);\n\n\t\tif (call?.name === \"answer\") {\n\t\t\treturn parseAnswer(String(call.args.answer ?? \"\"), workspace, options.cwd);\n\t\t}\n\t\tif (call?.name !== \"restricted_exec\") {\n\t\t\tmessages.push({ role: \"assistant\", content: reply }, { role: \"user\", content: RETRY_TOOL_CALL });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst keys = Object.keys(call.args)\n\t\t\t.filter((k) => /^command\\d+$/.test(k))\n\t\t\t.sort((a, b) => Number(a.slice(7)) - Number(b.slice(7)))\n\t\t\t.slice(0, MAX_COMMANDS);\n\t\tprogress(`Running ${keys.length} ${keys.length === 1 ? \"command\" : \"commands\"} (round ${turn}/${MAX_TURNS})…`);\n\t\tconst results = await Promise.all(\n\t\t\tkeys.map(\n\t\t\t\tasync (k) => `<${k}_result>\\n${await workspace.run(call.args[k] as Command, signal)}\\n</${k}_result>`,\n\t\t\t),\n\t\t);\n\t\tconst id = randomUUID();\n\t\tmessages.push(\n\t\t\t{\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: call.thinking,\n\t\t\t\tcall: { id, name: call.name, arguments: JSON.stringify(call.args) },\n\t\t\t},\n\t\t\t{ role: \"tool\", content: results.join(\"\"), callId: id },\n\t\t);\n\t}\n\treturn [];\n}\n\nexport interface ToolCall {\n\tthinking: string;\n\tname: string;\n\targs: Record<string, unknown>;\n}\n\n/** `thinking[TOOL_CALLS]name[ARGS]{json}`. The JSON is the first balanced object, repaired if needed. */\nexport function parseToolCall(text: string): ToolCall | null {\n\tconst m = text.match(/\\[TOOL_CALLS\\]\\s*(\\w+)\\s*\\[ARGS\\]\\s*(\\{[\\s\\S]*)/);\n\tif (!m) return null;\n\t// Repair before scanning: a stray key quote would otherwise end the scan inside a \"string\".\n\tfor (const candidate of [firstObject(m[2]!), firstObject(repairKeys(m[2]!))]) {\n\t\ttry {\n\t\t\tconst args = JSON.parse(candidate) as unknown;\n\t\t\tif (args && typeof args === \"object\" && !Array.isArray(args)) {\n\t\t\t\treturn { thinking: text.slice(0, m.index).trim(), name: m[1]!, args: args as Record<string, unknown> };\n\t\t\t}\n\t\t} catch {}\n\t}\n\treturn null;\n}\n\nfunction firstObject(text: string): string {\n\tlet depth = 0;\n\tlet inString = false;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tconst c = text[i];\n\t\tif (inString) {\n\t\t\tif (c === \"\\\\\") i++;\n\t\t\telse if (c === '\"') inString = false;\n\t\t} else if (c === '\"') inString = true;\n\t\telse if (c === \"{\") depth++;\n\t\telse if (c === \"}\" && --depth === 0) return text.slice(0, i + 1);\n\t}\n\treturn text;\n}\n\n/** The planner sometimes drops a key's quotes, as in `,exclude\":[]` or `{path:\"…\"}`. */\nfunction repairKeys(json: string): string {\n\treturn json.replace(/([{,]\\s*)\"?([A-Za-z_]\\w*)\"?\\s*:/g, '$1\"$2\":');\n}\n\nconst FILE_RE = /<file\\s+path=([\"'])(.+?)\\1\\s*>([\\s\\S]*?)<\\/file>/g;\nconst RANGE_RE = /<range>\\s*(\\d+)\\s*-\\s*(\\d+)\\s*<\\/range>/g;\n\n/** The files of an `<ANSWER>`, each re-checked against the workspace; anything outside it is dropped. */\nexport function parseAnswer(xml: string, workspace: Workspace, cwd: string): CodeLocation[] {\n\tconst locations: CodeLocation[] = [];\n\tfor (const [, , path, body] of xml.matchAll(FILE_RE)) {\n\t\tconst real = workspace.toReal(path);\n\t\tif (!real) continue;\n\t\tlocations.push({\n\t\t\tpath: relative(cwd, real).replace(/\\\\/g, \"/\") || \".\",\n\t\t\tranges: [...body!.matchAll(RANGE_RE)]\n\t\t\t\t.map(([, start, end]): [number, number] => [Number(start), Number(end)])\n\t\t\t\t.sort((a, b) => a[0] - b[0]),\n\t\t});\n\t\tif (locations.length === MAX_RESULTS) break;\n\t}\n\treturn locations;\n}\n\nexport function formatLocations(locations: CodeLocation[]): string {\n\tif (!locations.length)\n\t\treturn \"No relevant code found. Try a narrower behavioral query, or grep for a known identifier.\";\n\tconst lines = locations.map(\n\t\t({ path, ranges }) => `${path}${ranges.length ? ` (${ranges.map(([s, e]) => `L${s}-${e}`).join(\", \")})` : \"\"}`,\n\t);\n\treturn `${locations.length} candidate ${locations.length === 1 ? \"location\" : \"locations\"}; read them before relying on them:\\n${lines.join(\"\\n\")}`;\n}\n"]}
@@ -58,8 +58,8 @@ export function registerSearchCommand(pi) {
58
58
  if (!ctx.hasUI) {
59
59
  const credential = getCredential();
60
60
  ctx.ui.notify(credential
61
- ? `Devin Search: signed in ($credential.source === "env" ? ENV_KEY : credentialPath()).`
62
- : `Devin Search: not signed in. Run /search interactively, or set $ENV_KEY.`, credential ? "info" : "warning");
61
+ ? `Devin Search: signed in (${credential.source === "env" ? ENV_KEY : credentialPath()}).`
62
+ : `Devin Search: not signed in. Run /search interactively, or set ${ENV_KEY}.`, credential ? "info" : "warning");
63
63
  return;
64
64
  }
65
65
  await ctx.ui.custom((tui, theme, keybindings, done) => new SearchPanel(tui, theme, keybindings, accountActions(pi), () => done()));
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/extensions/search/command.ts"],"names":[],"mappings":"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","sourcesContent":["/** `/search` and the tool activation that follows the account state. */\nimport { homedir } from \"node:os\";\nimport type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { openBrowser } from \"../../utils/open-browser.ts\";\nimport {\n\tcreateSignIn,\n\tcredentialPath,\n\tdeleteCredential,\n\tENV_KEY,\n\texchangeCode,\n\tgetCredential,\n\tlooksLikeToken,\n\tsaveCredential,\n\ttoApiKey,\n} from \"./credential.ts\";\nimport { webSearch } from \"./devin.ts\";\nimport { type PanelActions, SearchPanel } from \"./panel.ts\";\n\n/** `~/.pi/agent/search-auth.json` rather than the full home path, so panel rows stay short. */\nfunction displayPath(path: string): string {\n\tconst home = homedir();\n\treturn path.startsWith(home) ? `~${path.slice(home.length).replace(/\\\\/g, \"/\")}` : path;\n}\n\nconst TOOL_NAMES = [\"code_search\", \"web_search\"];\n\n/** Deactivate both tools when no credential exists; `activate` re-enables them after a sign-in. */\nexport function syncTools(pi: ExtensionAPI, activate = false): void {\n\tconst active = pi.getActiveTools();\n\tif (!getCredential()) {\n\t\tconst next = active.filter((name) => !TOOL_NAMES.includes(name));\n\t\tif (next.length !== active.length) pi.setActiveTools(next);\n\t} else if (activate) {\n\t\tconst missing = TOOL_NAMES.filter((name) => !active.includes(name));\n\t\tif (missing.length) pi.setActiveTools([...active, ...missing]);\n\t}\n}\n\nfunction accountActions(pi: ExtensionAPI): PanelActions {\n\t/** One cheap authenticated call, so a bad token fails here rather than at the model's first search. */\n\tconst verifyAndSave = async (token: string) => {\n\t\tawait webSearch(toApiKey(token), \"Devin\", 1);\n\t\tsaveCredential(token);\n\t\tsyncTools(pi, true);\n\t};\n\treturn {\n\t\tstate() {\n\t\t\tconst source = getCredential()?.source;\n\t\t\treturn { source, location: source === \"env\" ? ENV_KEY : displayPath(credentialPath()) };\n\t\t},\n\t\tstartSignIn() {\n\t\t\tconst attempt = createSignIn();\n\t\t\topenBrowser(attempt.url);\n\t\t\treturn {\n\t\t\t\turl: attempt.url,\n\t\t\t\tcomplete: async (input) =>\n\t\t\t\t\tverifyAndSave(looksLikeToken(input) ? input : await exchangeCode(attempt, input)),\n\t\t\t};\n\t\t},\n\t\tsaveToken: verifyAndSave,\n\t\tsignOut() {\n\t\t\tdeleteCredential();\n\t\t\tsyncTools(pi);\n\t\t},\n\t};\n}\n\nexport function registerSearchCommand(pi: ExtensionAPI): void {\n\tpi.registerCommand(\"search\", {\n\t\tdescription: \"Sign in to Devin for code_search and web_search\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tif (!ctx.hasUI) {\n\t\t\t\tconst credential = getCredential();\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\tcredential\n\t\t\t\t\t\t? `Devin Search: signed in ($credential.source === \"env\" ? ENV_KEY : credentialPath()).`\n\t\t\t\t\t\t: `Devin Search: not signed in. Run /search interactively, or set $ENV_KEY.`,\n\t\t\t\t\tcredential ? \"info\" : \"warning\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait ctx.ui.custom<void>(\n\t\t\t\t(tui, theme, keybindings, done) =>\n\t\t\t\t\tnew SearchPanel(tui, theme, keybindings, accountActions(pi), () => done()),\n\t\t\t);\n\t\t},\n\t});\n}\n"]}
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/extensions/search/command.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACN,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,OAAO,EACP,YAAY,EACZ,aAAa,EACb,cAAc,EACd,cAAc,EACd,QAAQ,GACR,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAqB,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,+FAA+F;AAC/F,SAAS,WAAW,CAAC,IAAY;IAChC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;AAEjD,mGAAmG;AACnG,MAAM,UAAU,SAAS,CAAC,EAAgB,EAAE,QAAQ,GAAG,KAAK;IAC3D,MAAM,MAAM,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC;IACnC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;YAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;SAAM,IAAI,QAAQ,EAAE,CAAC;QACrB,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACpE,IAAI,OAAO,CAAC,MAAM;YAAE,EAAE,CAAC,cAAc,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;AACF,CAAC;AAED,SAAS,cAAc,CAAC,EAAgB;IACvC,uGAAuG;IACvG,MAAM,aAAa,GAAG,KAAK,EAAE,KAAa,EAAE,EAAE;QAC7C,MAAM,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QAC7C,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACrB,CAAC,CAAC;IACF,OAAO;QACN,KAAK;YACJ,MAAM,MAAM,GAAG,aAAa,EAAE,EAAE,MAAM,CAAC;YACvC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC;QACzF,CAAC;QACD,WAAW;YACV,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;YAC/B,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACzB,OAAO;gBACN,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CACzB,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;aAClF,CAAC;QACH,CAAC;QACD,SAAS,EAAE,aAAa;QACxB,OAAO;YACN,gBAAgB,EAAE,CAAC;YACnB,SAAS,CAAC,EAAE,CAAC,CAAC;QACf,CAAC;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EAAgB;IACrD,EAAE,CAAC,eAAe,CAAC,QAAQ,EAAE;QAC5B,WAAW,EAAE,iDAAiD;QAC9D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC7B,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;gBAChB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;gBACnC,GAAG,CAAC,EAAE,CAAC,MAAM,CACZ,UAAU;oBACT,CAAC,CAAC,4BAA4B,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,EAAE,IAAI;oBAC1F,CAAC,CAAC,kEAAkE,OAAO,GAAG,EAC/E,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAC/B,CAAC;gBACF,OAAO;YACR,CAAC;YACD,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAClB,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,CACjC,IAAI,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAC3E,CAAC;QACH,CAAC;KACD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/** `/search` and the tool activation that follows the account state. */\nimport { homedir } from \"node:os\";\nimport type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { openBrowser } from \"../../utils/open-browser.ts\";\nimport {\n\tcreateSignIn,\n\tcredentialPath,\n\tdeleteCredential,\n\tENV_KEY,\n\texchangeCode,\n\tgetCredential,\n\tlooksLikeToken,\n\tsaveCredential,\n\ttoApiKey,\n} from \"./credential.ts\";\nimport { webSearch } from \"./devin.ts\";\nimport { type PanelActions, SearchPanel } from \"./panel.ts\";\n\n/** `~/.pi/agent/search-auth.json` rather than the full home path, so panel rows stay short. */\nfunction displayPath(path: string): string {\n\tconst home = homedir();\n\treturn path.startsWith(home) ? `~${path.slice(home.length).replace(/\\\\/g, \"/\")}` : path;\n}\n\nconst TOOL_NAMES = [\"code_search\", \"web_search\"];\n\n/** Deactivate both tools when no credential exists; `activate` re-enables them after a sign-in. */\nexport function syncTools(pi: ExtensionAPI, activate = false): void {\n\tconst active = pi.getActiveTools();\n\tif (!getCredential()) {\n\t\tconst next = active.filter((name) => !TOOL_NAMES.includes(name));\n\t\tif (next.length !== active.length) pi.setActiveTools(next);\n\t} else if (activate) {\n\t\tconst missing = TOOL_NAMES.filter((name) => !active.includes(name));\n\t\tif (missing.length) pi.setActiveTools([...active, ...missing]);\n\t}\n}\n\nfunction accountActions(pi: ExtensionAPI): PanelActions {\n\t/** One cheap authenticated call, so a bad token fails here rather than at the model's first search. */\n\tconst verifyAndSave = async (token: string) => {\n\t\tawait webSearch(toApiKey(token), \"Devin\", 1);\n\t\tsaveCredential(token);\n\t\tsyncTools(pi, true);\n\t};\n\treturn {\n\t\tstate() {\n\t\t\tconst source = getCredential()?.source;\n\t\t\treturn { source, location: source === \"env\" ? ENV_KEY : displayPath(credentialPath()) };\n\t\t},\n\t\tstartSignIn() {\n\t\t\tconst attempt = createSignIn();\n\t\t\topenBrowser(attempt.url);\n\t\t\treturn {\n\t\t\t\turl: attempt.url,\n\t\t\t\tcomplete: async (input) =>\n\t\t\t\t\tverifyAndSave(looksLikeToken(input) ? input : await exchangeCode(attempt, input)),\n\t\t\t};\n\t\t},\n\t\tsaveToken: verifyAndSave,\n\t\tsignOut() {\n\t\t\tdeleteCredential();\n\t\t\tsyncTools(pi);\n\t\t},\n\t};\n}\n\nexport function registerSearchCommand(pi: ExtensionAPI): void {\n\tpi.registerCommand(\"search\", {\n\t\tdescription: \"Sign in to Devin for code_search and web_search\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tif (!ctx.hasUI) {\n\t\t\t\tconst credential = getCredential();\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\tcredential\n\t\t\t\t\t\t? `Devin Search: signed in (${credential.source === \"env\" ? ENV_KEY : credentialPath()}).`\n\t\t\t\t\t\t: `Devin Search: not signed in. Run /search interactively, or set ${ENV_KEY}.`,\n\t\t\t\t\tcredential ? \"info\" : \"warning\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait ctx.ui.custom<void>(\n\t\t\t\t(tui, theme, keybindings, done) =>\n\t\t\t\t\tnew SearchPanel(tui, theme, keybindings, accountActions(pi), () => done()),\n\t\t\t);\n\t\t},\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/search/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAKnE,OAAO,EAAkB,KAAK,SAAS,EAAa,MAAM,YAAY,CAAC;AA8CvE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,CAW5E;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA2DrD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/search/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAKnE,OAAO,EAAkB,KAAK,SAAS,EAAa,MAAM,YAAY,CAAC;AA8CvE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,CAW5E;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA8DrD"}
@@ -58,14 +58,12 @@ export default function search(pi) {
58
58
  pi.registerTool({
59
59
  name: "code_search",
60
60
  label: "Code Search",
61
- description: "Find where behavior lives in the local repository by describing it, powered by Devin's SWE-grep agent. " +
62
- "Use it when the relevant files are unknown: exploration, tracing a flow or bug, planning a change in " +
63
- "unfamiliar code. Returns candidate files with line ranges — a reading list to verify with read or grep. " +
64
- "For known paths, exact symbols, or literal strings, use find, grep, or read directly.",
65
- promptSnippet: "Locate unknown local code by describing behavior; verify results with read",
61
+ description: "Find where behavior lives in the local repository from a description of it. " +
62
+ "Returns candidate files with line ranges.",
63
+ promptSnippet: "Find code by describing its behavior",
66
64
  promptGuidelines: [
67
- "Use `code_search` first when you do not know which files implement a behavior; use grep/find for exact names and literals.",
68
- "Treat `code_search` results as a reading list: read the returned ranges before editing.",
65
+ "Use `code_search` when you cannot name the file or symbol you need; use `read`, `grep`, or `find` when you can.",
66
+ "Read the returned ranges before editing; the locations are candidates, not answers.",
69
67
  ],
70
68
  parameters: CodeSearchParams,
71
69
  renderCall: renderCodeSearchCall,
@@ -85,13 +83,18 @@ export default function search(pi) {
85
83
  return { content: [{ type: "text", text: formatLocations(locations) }], details: { locations } };
86
84
  },
87
85
  });
86
+ // Pi's system prompt carries no date, so models otherwise search with their training year.
87
+ const currentMonth = new Date().toLocaleDateString("en-US", { month: "long", year: "numeric" });
88
88
  pi.registerTool({
89
89
  name: "web_search",
90
90
  label: "Web Search",
91
- description: "Search the live web through Devin. Use it for facts outside the repository: library and API docs, error " +
92
- "messages, release notes, current versions. Returns titles, URLs, and query-relevant page excerpts.",
93
- promptSnippet: "Live web search: external docs, errors, releases, current facts",
94
- promptGuidelines: ["Use `web_search` instead of guessing for version-, release-, or date-sensitive facts."],
91
+ description: "Search the live web for current information. Returns titles, URLs, and the page excerpts that match the query.",
92
+ promptSnippet: "Search the live web for current information",
93
+ promptGuidelines: [
94
+ "Use `web_search` for information beyond your knowledge cutoff.",
95
+ `It is ${currentMonth}; put this year in \`web_search\` queries for recent releases, versions, or events, not the year your training data suggests.`,
96
+ "When an answer relies on `web_search` results, cite each result you used as a markdown link: [Title](URL).",
97
+ ],
95
98
  parameters: WebSearchParams,
96
99
  renderCall: renderWebSearchCall,
97
100
  renderResult: renderWebSearchResult,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/search/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Devin Search: `code_search` and `web_search`, both authenticated by one Devin sign-in.\n *\n * Both tools stay registered so `/tools` and old transcripts know them; a session without a\n * credential starts with them inactive, and signing in or out through `/search` toggles them.\n */\nimport { resolve } from \"node:path\";\nimport { type Static, Type } from \"typebox\";\nimport type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { truncateHead } from \"../../core/tools/truncate.ts\";\nimport { codeSearch, formatLocations } from \"./code-search.ts\";\nimport { registerSearchCommand, syncTools } from \"./command.ts\";\nimport { getCredential } from \"./credential.ts\";\nimport { DevinAuthError, type WebResult, webSearch } from \"./devin.ts\";\nimport {\n\ttype CodeSearchDetails,\n\trenderCodeSearchCall,\n\trenderCodeSearchResult,\n\trenderWebSearchCall,\n\trenderWebSearchResult,\n\ttype WebSearchDetails,\n} from \"./render.ts\";\nimport { isInside } from \"./workspace.ts\";\n\nconst WEB_EXCERPT_MAX_CHARS = 1500;\n\nconst CodeSearchParams = Type.Object({\n\tquery: Type.String({\n\t\tdescription:\n\t\t\t\"Natural-language description of the behavior, flow, error, or concept to locate, in concise English. Keep identifiers, API names, and error text verbatim. Not for a bare symbol, filename, or literal.\",\n\t}),\n\tpath: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Subdirectory to search, relative to or inside the working directory. Defaults to the working directory.\",\n\t\t}),\n\t),\n});\n\nconst WebSearchParams = Type.Object({\n\tquery: Type.String({\n\t\tdescription: \"Web search query. Be specific: product names, versions, exact error text. English matches best.\",\n\t}),\n\tmax_results: Type.Optional(Type.Integer({ minimum: 1, maximum: 10, description: \"Results to return (default 5).\" })),\n});\n\nconst SIGN_IN_HINT = \"Ask the user to run /search to sign in to Devin.\";\n\n/** Run a Devin call with the current credential; credential failures tell the model what fixes them. */\nasync function withDevin<T>(run: (apiKey: string) => Promise<T>): Promise<T> {\n\tconst credential = getCredential();\n\tif (!credential) throw new Error(`Devin Search is not signed in. ${SIGN_IN_HINT}`);\n\ttry {\n\t\treturn await run(credential.apiKey);\n\t} catch (error) {\n\t\tthrow error instanceof DevinAuthError ? new Error(`${error.message} ${SIGN_IN_HINT}`) : error;\n\t}\n}\n\nexport function formatWebResults(query: string, results: WebResult[]): string {\n\tif (!results.length) return `No web results for \"${query}\".`;\n\tconst blocks = results.map((r, i) => {\n\t\tconst lines = [`${i + 1}. ${r.title ?? r.url}`, ` ${r.url}`];\n\t\tif (r.summary) {\n\t\t\tconst excerpt = r.summary.replace(/\\n\\s*\\n+/g, \"\\n\").trim();\n\t\t\tlines.push(excerpt.length > WEB_EXCERPT_MAX_CHARS ? `${excerpt.slice(0, WEB_EXCERPT_MAX_CHARS)}…` : excerpt);\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t});\n\treturn truncateHead(`Web results for \"${query}\":\\n\\n${blocks.join(\"\\n\\n\")}`).content;\n}\n\nexport default function search(pi: ExtensionAPI): void {\n\tpi.registerTool<typeof CodeSearchParams, CodeSearchDetails>({\n\t\tname: \"code_search\",\n\t\tlabel: \"Code Search\",\n\t\tdescription:\n\t\t\t\"Find where behavior lives in the local repository by describing it, powered by Devin's SWE-grep agent. \" +\n\t\t\t\"Use it when the relevant files are unknown: exploration, tracing a flow or bug, planning a change in \" +\n\t\t\t\"unfamiliar code. Returns candidate files with line ranges — a reading list to verify with read or grep. \" +\n\t\t\t\"For known paths, exact symbols, or literal strings, use find, grep, or read directly.\",\n\t\tpromptSnippet: \"Locate unknown local code by describing behavior; verify results with read\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use `code_search` first when you do not know which files implement a behavior; use grep/find for exact names and literals.\",\n\t\t\t\"Treat `code_search` results as a reading list: read the returned ranges before editing.\",\n\t\t],\n\t\tparameters: CodeSearchParams,\n\t\trenderCall: renderCodeSearchCall,\n\t\trenderResult: renderCodeSearchResult,\n\n\t\tasync execute(_toolCallId, params: Static<typeof CodeSearchParams>, signal, onUpdate, ctx) {\n\t\t\tconst root = resolve(ctx.cwd, params.path ?? \".\");\n\t\t\tif (!isInside(ctx.cwd, root)) throw new Error(`path must be inside the working directory (${ctx.cwd}).`);\n\t\t\tconst locations = await withDevin((apiKey) =>\n\t\t\t\tcodeSearch({\n\t\t\t\t\tapiKey,\n\t\t\t\t\tquery: params.query.trim(),\n\t\t\t\t\troot,\n\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\tsignal,\n\t\t\t\t\tonProgress: (text) => onUpdate?.({ content: [{ type: \"text\", text }], details: { locations: [] } }),\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn { content: [{ type: \"text\", text: formatLocations(locations) }], details: { locations } };\n\t\t},\n\t});\n\n\tpi.registerTool<typeof WebSearchParams, WebSearchDetails>({\n\t\tname: \"web_search\",\n\t\tlabel: \"Web Search\",\n\t\tdescription:\n\t\t\t\"Search the live web through Devin. Use it for facts outside the repository: library and API docs, error \" +\n\t\t\t\"messages, release notes, current versions. Returns titles, URLs, and query-relevant page excerpts.\",\n\t\tpromptSnippet: \"Live web search: external docs, errors, releases, current facts\",\n\t\tpromptGuidelines: [\"Use `web_search` instead of guessing for version-, release-, or date-sensitive facts.\"],\n\t\tparameters: WebSearchParams,\n\t\trenderCall: renderWebSearchCall,\n\t\trenderResult: renderWebSearchResult,\n\n\t\tasync execute(_toolCallId, params: Static<typeof WebSearchParams>, signal) {\n\t\t\tconst query = params.query.trim();\n\t\t\tconst results = await withDevin((apiKey) => webSearch(apiKey, query, params.max_results ?? 5, signal));\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: formatWebResults(query, results) }],\n\t\t\t\tdetails: { results: results.map(({ url, title }) => ({ url, title })) },\n\t\t\t};\n\t\t},\n\t});\n\n\tregisterSearchCommand(pi);\n\tpi.on(\"session_start\", async () => syncTools(pi));\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/search/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Devin Search: `code_search` and `web_search`, both authenticated by one Devin sign-in.\n *\n * Both tools stay registered so `/tools` and old transcripts know them; a session without a\n * credential starts with them inactive, and signing in or out through `/search` toggles them.\n */\nimport { resolve } from \"node:path\";\nimport { type Static, Type } from \"typebox\";\nimport type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { truncateHead } from \"../../core/tools/truncate.ts\";\nimport { codeSearch, formatLocations } from \"./code-search.ts\";\nimport { registerSearchCommand, syncTools } from \"./command.ts\";\nimport { getCredential } from \"./credential.ts\";\nimport { DevinAuthError, type WebResult, webSearch } from \"./devin.ts\";\nimport {\n\ttype CodeSearchDetails,\n\trenderCodeSearchCall,\n\trenderCodeSearchResult,\n\trenderWebSearchCall,\n\trenderWebSearchResult,\n\ttype WebSearchDetails,\n} from \"./render.ts\";\nimport { isInside } from \"./workspace.ts\";\n\nconst WEB_EXCERPT_MAX_CHARS = 1500;\n\nconst CodeSearchParams = Type.Object({\n\tquery: Type.String({\n\t\tdescription:\n\t\t\t\"Natural-language description of the behavior, flow, error, or concept to locate, in concise English. Keep identifiers, API names, and error text verbatim. Not for a bare symbol, filename, or literal.\",\n\t}),\n\tpath: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Subdirectory to search, relative to or inside the working directory. Defaults to the working directory.\",\n\t\t}),\n\t),\n});\n\nconst WebSearchParams = Type.Object({\n\tquery: Type.String({\n\t\tdescription: \"Web search query. Be specific: product names, versions, exact error text. English matches best.\",\n\t}),\n\tmax_results: Type.Optional(Type.Integer({ minimum: 1, maximum: 10, description: \"Results to return (default 5).\" })),\n});\n\nconst SIGN_IN_HINT = \"Ask the user to run /search to sign in to Devin.\";\n\n/** Run a Devin call with the current credential; credential failures tell the model what fixes them. */\nasync function withDevin<T>(run: (apiKey: string) => Promise<T>): Promise<T> {\n\tconst credential = getCredential();\n\tif (!credential) throw new Error(`Devin Search is not signed in. ${SIGN_IN_HINT}`);\n\ttry {\n\t\treturn await run(credential.apiKey);\n\t} catch (error) {\n\t\tthrow error instanceof DevinAuthError ? new Error(`${error.message} ${SIGN_IN_HINT}`) : error;\n\t}\n}\n\nexport function formatWebResults(query: string, results: WebResult[]): string {\n\tif (!results.length) return `No web results for \"${query}\".`;\n\tconst blocks = results.map((r, i) => {\n\t\tconst lines = [`${i + 1}. ${r.title ?? r.url}`, ` ${r.url}`];\n\t\tif (r.summary) {\n\t\t\tconst excerpt = r.summary.replace(/\\n\\s*\\n+/g, \"\\n\").trim();\n\t\t\tlines.push(excerpt.length > WEB_EXCERPT_MAX_CHARS ? `${excerpt.slice(0, WEB_EXCERPT_MAX_CHARS)}…` : excerpt);\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t});\n\treturn truncateHead(`Web results for \"${query}\":\\n\\n${blocks.join(\"\\n\\n\")}`).content;\n}\n\nexport default function search(pi: ExtensionAPI): void {\n\tpi.registerTool<typeof CodeSearchParams, CodeSearchDetails>({\n\t\tname: \"code_search\",\n\t\tlabel: \"Code Search\",\n\t\tdescription:\n\t\t\t\"Find where behavior lives in the local repository from a description of it. \" +\n\t\t\t\"Returns candidate files with line ranges.\",\n\t\tpromptSnippet: \"Find code by describing its behavior\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use `code_search` when you cannot name the file or symbol you need; use `read`, `grep`, or `find` when you can.\",\n\t\t\t\"Read the returned ranges before editing; the locations are candidates, not answers.\",\n\t\t],\n\t\tparameters: CodeSearchParams,\n\t\trenderCall: renderCodeSearchCall,\n\t\trenderResult: renderCodeSearchResult,\n\n\t\tasync execute(_toolCallId, params: Static<typeof CodeSearchParams>, signal, onUpdate, ctx) {\n\t\t\tconst root = resolve(ctx.cwd, params.path ?? \".\");\n\t\t\tif (!isInside(ctx.cwd, root)) throw new Error(`path must be inside the working directory (${ctx.cwd}).`);\n\t\t\tconst locations = await withDevin((apiKey) =>\n\t\t\t\tcodeSearch({\n\t\t\t\t\tapiKey,\n\t\t\t\t\tquery: params.query.trim(),\n\t\t\t\t\troot,\n\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\tsignal,\n\t\t\t\t\tonProgress: (text) => onUpdate?.({ content: [{ type: \"text\", text }], details: { locations: [] } }),\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn { content: [{ type: \"text\", text: formatLocations(locations) }], details: { locations } };\n\t\t},\n\t});\n\n\t// Pi's system prompt carries no date, so models otherwise search with their training year.\n\tconst currentMonth = new Date().toLocaleDateString(\"en-US\", { month: \"long\", year: \"numeric\" });\n\tpi.registerTool<typeof WebSearchParams, WebSearchDetails>({\n\t\tname: \"web_search\",\n\t\tlabel: \"Web Search\",\n\t\tdescription:\n\t\t\t\"Search the live web for current information. Returns titles, URLs, and the page excerpts that match the query.\",\n\t\tpromptSnippet: \"Search the live web for current information\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use `web_search` for information beyond your knowledge cutoff.\",\n\t\t\t`It is ${currentMonth}; put this year in \\`web_search\\` queries for recent releases, versions, or events, not the year your training data suggests.`,\n\t\t\t\"When an answer relies on `web_search` results, cite each result you used as a markdown link: [Title](URL).\",\n\t\t],\n\t\tparameters: WebSearchParams,\n\t\trenderCall: renderWebSearchCall,\n\t\trenderResult: renderWebSearchResult,\n\n\t\tasync execute(_toolCallId, params: Static<typeof WebSearchParams>, signal) {\n\t\t\tconst query = params.query.trim();\n\t\t\tconst results = await withDevin((apiKey) => webSearch(apiKey, query, params.max_results ?? 5, signal));\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: formatWebResults(query, results) }],\n\t\t\t\tdetails: { results: results.map(({ url, title }) => ({ url, title })) },\n\t\t\t};\n\t\t},\n\t});\n\n\tregisterSearchCommand(pi);\n\tpi.on(\"session_start\", async () => syncTools(pi));\n}\n"]}
@@ -1,8 +1,4 @@
1
1
  export declare const VIRTUAL_ROOT = "/codebase";
2
- /** `rg` backend: pattern, directory or file, optional glob → `path:line: text` lines. */
3
- export type Grep = (pattern: string, path: string, glob: string | undefined, signal?: AbortSignal) => Promise<string>;
4
- /** Pi's own grep tool: gitignore-aware, with its bundled ripgrep. It takes one glob, so only the first include applies. */
5
- export declare function piGrep(root: string): Grep;
6
2
  /** Whether `path` lies inside `root`, both as written and after following symlinks. */
7
3
  export declare function isInside(root: string, path: string): boolean;
8
4
  export interface Command {
@@ -10,6 +6,7 @@ export interface Command {
10
6
  pattern?: unknown;
11
7
  path?: unknown;
12
8
  include?: unknown;
9
+ exclude?: unknown;
13
10
  file?: unknown;
14
11
  start_line?: unknown;
15
12
  end_line?: unknown;
@@ -17,22 +14,26 @@ export interface Command {
17
14
  }
18
15
  export declare class Workspace {
19
16
  readonly root: string;
20
- private readonly grep;
21
- private readonly noise;
22
- constructor(root: string, grep?: Grep);
17
+ private index?;
18
+ constructor(root: string);
23
19
  contains(path: string): boolean;
24
20
  /** `/codebase/src/a.ts` or `src/a.ts` → an absolute path inside the root, or null. */
25
21
  toReal(virtual: unknown): string | null;
26
22
  toVirtual(real: string): string;
23
+ /** Every file rg would search, listed once per search; tree, readfile, and rg targets all check against it. */
24
+ private files;
25
+ /** A model-named path that rg would see, or the error string to return in its place. */
26
+ private find;
27
27
  /** The deepest tree of the root, up to three levels, that fits the map budget. */
28
- repoMap(): {
28
+ repoMap(signal?: AbortSignal): Promise<{
29
29
  depth: number;
30
30
  tree: string;
31
- };
31
+ }>;
32
32
  run(command: Command, signal?: AbortSignal): Promise<string>;
33
33
  private rg;
34
+ /** A numbered slice of a text file, headed by its length and ending with where to continue. */
34
35
  private readfile;
36
+ /** The requested depth of a directory, or the deepest one that fits the result cap. */
35
37
  private tree;
36
- private renderTree;
37
38
  }
38
39
  //# sourceMappingURL=workspace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/extensions/search/workspace.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,YAAY,cAAc,CAAC;AA6BxC,yFAAyF;AACzF,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtH,2HAA2H;AAC3H,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAWzC;AAwBD,uFAAuF;AACvF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAG5D;AAWD,MAAM,WAAW,OAAO;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,SAAS;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBAExB,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,IAAmB;IAMnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,sFAAsF;IACtF,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAgBvC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAK/B,kFAAkF;IAClF,OAAO,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAQpC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;YAapD,EAAE;IA2BhB,OAAO,CAAC,QAAQ;IAqBhB,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,UAAU;CA0BlB"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/extensions/search/workspace.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,YAAY,cAAc,CAAC;AAwIxC,uFAAuF;AACvF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAG5D;AAqBD,MAAM,WAAW,OAAO;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,SAAS;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,KAAK,CAAC,CAAiB;gBAEnB,IAAI,EAAE,MAAM;IAIxB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,sFAAsF;IACtF,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAgBvC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI/B,+GAA+G;IAC/G,OAAO,CAAC,KAAK;IA2Bb,wFAAwF;YAC1E,IAAI;IAiBlB,kFAAkF;IAC5E,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IASvE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;YAiBpD,EAAE;IAiChB,+FAA+F;YACjF,QAAQ;IAuBtB,uFAAuF;YACzE,IAAI;CAWlB"}