@astralyn/pi 1.0.4 → 1.1.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 (332) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/bundle/chunks/{anthropic-messages-YIOJIMVL.js → anthropic-messages-3K3DWVY6.js} +1 -1
  3. package/dist/bundle/chunks/anthropic.js +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-LDW4FGAQ.js → azure-openai-responses-CH74HGP4.js} +1 -1
  5. package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
  6. package/dist/bundle/chunks/{chunk-UCXU7KLO.js → chunk-3MMB5I7J.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-GIG5IHES.js → chunk-5KJH3GGH.js} +1 -1
  8. package/dist/bundle/chunks/chunk-6VYRLG5F.js +2 -0
  9. package/dist/bundle/chunks/{chunk-73WG7F7N.js → chunk-C2ARIVS3.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-23OTKHCH.js → chunk-D3XW5X3Z.js} +490 -260
  11. package/dist/bundle/chunks/{chunk-IFELM7MW.js → chunk-EJEOEBSJ.js} +1 -1
  12. package/dist/bundle/chunks/chunk-H35KWBT5.js +11 -0
  13. package/dist/bundle/chunks/chunk-KAC2YPTW.js +2 -0
  14. package/dist/bundle/chunks/chunk-MAC4N3BW.js +2 -0
  15. package/dist/bundle/chunks/chunk-QLU3LESZ.js +2 -0
  16. package/dist/bundle/chunks/{chunk-A6ALEEY5.js → chunk-TEAAYBTS.js} +1 -1
  17. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-XO45ZT3V.js +2 -0
  18. package/dist/bundle/chunks/codemode-worker.js +101 -5
  19. package/dist/bundle/chunks/github-copilot.js +1 -1
  20. package/dist/bundle/chunks/{google-generative-ai-S5A5IBU4.js → google-generative-ai-VVO64ZRQ.js} +1 -1
  21. package/dist/bundle/chunks/{google-vertex-UBRQFDB4.js → google-vertex-LKS5NUHA.js} +1 -1
  22. package/dist/bundle/chunks/image-resize-worker.js +1 -1
  23. package/dist/bundle/chunks/{llama-cpp-classify-R7DQLTQN.js → llama-cpp-classify-H3IZDR5O.js} +2 -2
  24. package/dist/bundle/chunks/{mistral-conversations-A2N5FSOV.js → mistral-conversations-NJUOG4ET.js} +2 -2
  25. package/dist/bundle/chunks/openai-chatgpt.js +1 -1
  26. package/dist/bundle/chunks/{openai-codex-responses-Q6JHCWLE.js → openai-codex-responses-TZWBTTYM.js} +2 -2
  27. package/dist/bundle/chunks/openai-codex.js +1 -1
  28. package/dist/bundle/chunks/{openai-completions-H4VMO7AU.js → openai-completions-7HTTU6FH.js} +1 -1
  29. package/dist/bundle/chunks/openai-decisions-776H4VDZ.js +5 -0
  30. package/dist/bundle/chunks/{openai-responses-G4PGNM2H.js → openai-responses-7A6BAQ5X.js} +1 -1
  31. package/dist/bundle/chunks/{openrouter-images-YP3YVB54.js → openrouter-images-TDLJV5N4.js} +1 -1
  32. package/dist/bundle/chunks/{pi-messages-HZZ7GEEW.js → pi-messages-ZXNERWJG.js} +1 -1
  33. package/dist/bundle/chunks/typesafe-system-one-2DQLG4R2.js +2 -0
  34. package/dist/bundle/chunks/{virtual-modules-IJTAY26N.js → virtual-modules-2NHGQRS6.js} +1 -1
  35. package/dist/bundle/cli.js +1 -1
  36. package/dist/bundle/index.js +1 -1
  37. package/dist/bundle/rpc-entry.js +1 -1
  38. package/dist/cli/args.d.ts +2 -1
  39. package/dist/cli/args.d.ts.map +1 -1
  40. package/dist/cli/args.js +24 -5
  41. package/dist/cli/args.js.map +1 -1
  42. package/dist/core/agent-session.d.ts +38 -10
  43. package/dist/core/agent-session.d.ts.map +1 -1
  44. package/dist/core/agent-session.js +190 -186
  45. package/dist/core/agent-session.js.map +1 -1
  46. package/dist/core/bash-executor.d.ts.map +1 -1
  47. package/dist/core/bash-executor.js +40 -45
  48. package/dist/core/bash-executor.js.map +1 -1
  49. package/dist/core/context-snapshot.d.ts +4 -1
  50. package/dist/core/context-snapshot.d.ts.map +1 -1
  51. package/dist/core/context-snapshot.js +45 -0
  52. package/dist/core/context-snapshot.js.map +1 -1
  53. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  54. package/dist/core/export-html/tool-renderer.js +2 -0
  55. package/dist/core/export-html/tool-renderer.js.map +1 -1
  56. package/dist/core/extensions/types.d.ts +13 -0
  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/mcp-servers.d.ts +8 -0
  60. package/dist/core/mcp-servers.d.ts.map +1 -1
  61. package/dist/core/mcp-servers.js +30 -7
  62. package/dist/core/mcp-servers.js.map +1 -1
  63. package/dist/core/model-runtime.d.ts.map +1 -1
  64. package/dist/core/model-runtime.js +2 -1
  65. package/dist/core/model-runtime.js.map +1 -1
  66. package/dist/core/nested-tool-calls.d.ts +1 -0
  67. package/dist/core/nested-tool-calls.d.ts.map +1 -1
  68. package/dist/core/nested-tool-calls.js +1 -0
  69. package/dist/core/nested-tool-calls.js.map +1 -1
  70. package/dist/core/resource-loader.d.ts +3 -0
  71. package/dist/core/resource-loader.d.ts.map +1 -1
  72. package/dist/core/resource-loader.js +3 -3
  73. package/dist/core/resource-loader.js.map +1 -1
  74. package/dist/core/sdk.d.ts +13 -4
  75. package/dist/core/sdk.d.ts.map +1 -1
  76. package/dist/core/sdk.js +19 -6
  77. package/dist/core/sdk.js.map +1 -1
  78. package/dist/core/settings-manager.d.ts +13 -0
  79. package/dist/core/settings-manager.d.ts.map +1 -1
  80. package/dist/core/settings-manager.js +37 -13
  81. package/dist/core/settings-manager.js.map +1 -1
  82. package/dist/core/skills.d.ts +4 -1
  83. package/dist/core/skills.d.ts.map +1 -1
  84. package/dist/core/skills.js +6 -1
  85. package/dist/core/skills.js.map +1 -1
  86. package/dist/core/system-prompt.d.ts +6 -0
  87. package/dist/core/system-prompt.d.ts.map +1 -1
  88. package/dist/core/system-prompt.js +9 -4
  89. package/dist/core/system-prompt.js.map +1 -1
  90. package/dist/core/tasks/session.d.ts +9 -0
  91. package/dist/core/tasks/session.d.ts.map +1 -1
  92. package/dist/core/tasks/session.js +21 -0
  93. package/dist/core/tasks/session.js.map +1 -1
  94. package/dist/core/tools/read.d.ts +13 -0
  95. package/dist/core/tools/read.d.ts.map +1 -1
  96. package/dist/core/tools/read.js +18 -1
  97. package/dist/core/tools/read.js.map +1 -1
  98. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  99. package/dist/core/tools/renderers/bash.js +8 -3
  100. package/dist/core/tools/renderers/bash.js.map +1 -1
  101. package/dist/core/tools/renderers/edit.js +1 -1
  102. package/dist/core/tools/renderers/edit.js.map +1 -1
  103. package/dist/extensions/codemode/execute.d.ts.map +1 -1
  104. package/dist/extensions/codemode/execute.js +65 -8
  105. package/dist/extensions/codemode/execute.js.map +1 -1
  106. package/dist/extensions/codemode/index.d.ts.map +1 -1
  107. package/dist/extensions/codemode/index.js +1 -0
  108. package/dist/extensions/codemode/index.js.map +1 -1
  109. package/dist/extensions/codemode/tool.d.ts +9 -2
  110. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  111. package/dist/extensions/codemode/tool.js +14 -6
  112. package/dist/extensions/codemode/tool.js.map +1 -1
  113. package/dist/extensions/index.js +2 -2
  114. package/dist/extensions/index.js.map +1 -1
  115. package/dist/extensions/llama/provider.d.ts.map +1 -1
  116. package/dist/extensions/llama/provider.js +34 -11
  117. package/dist/extensions/llama/provider.js.map +1 -1
  118. package/dist/extensions/mcp/cli.js +17 -23
  119. package/dist/extensions/mcp/cli.js.map +1 -1
  120. package/dist/extensions/mcp/index.d.ts.map +1 -1
  121. package/dist/extensions/mcp/index.js +165 -64
  122. package/dist/extensions/mcp/index.js.map +1 -1
  123. package/dist/extensions/mcp/oauth.d.ts +5 -3
  124. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  125. package/dist/extensions/mcp/oauth.js +36 -10
  126. package/dist/extensions/mcp/oauth.js.map +1 -1
  127. package/dist/extensions/mcp/resources.d.ts +3 -4
  128. package/dist/extensions/mcp/resources.d.ts.map +1 -1
  129. package/dist/extensions/mcp/resources.js +3 -4
  130. package/dist/extensions/mcp/resources.js.map +1 -1
  131. package/dist/extensions/mcp/runtime.d.ts +4 -1
  132. package/dist/extensions/mcp/runtime.d.ts.map +1 -1
  133. package/dist/extensions/mcp/runtime.js +22 -5
  134. package/dist/extensions/mcp/runtime.js.map +1 -1
  135. package/dist/extensions/mcp/tools.d.ts +2 -1
  136. package/dist/extensions/mcp/tools.d.ts.map +1 -1
  137. package/dist/extensions/mcp/tools.js +2 -1
  138. package/dist/extensions/mcp/tools.js.map +1 -1
  139. package/dist/extensions/mcp/ui.d.ts +3 -3
  140. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  141. package/dist/extensions/mcp/ui.js +10 -2
  142. package/dist/extensions/mcp/ui.js.map +1 -1
  143. package/dist/extensions/search/code-search.d.ts +29 -0
  144. package/dist/extensions/search/code-search.d.ts.map +1 -0
  145. package/dist/extensions/search/code-search.js +120 -0
  146. package/dist/extensions/search/code-search.js.map +1 -0
  147. package/dist/extensions/search/command.d.ts +5 -0
  148. package/dist/extensions/search/command.d.ts.map +1 -0
  149. package/dist/extensions/search/command.js +69 -0
  150. package/dist/extensions/search/command.js.map +1 -0
  151. package/dist/extensions/search/credential.d.ts +25 -0
  152. package/dist/extensions/search/credential.d.ts.map +1 -0
  153. package/dist/extensions/search/credential.js +117 -0
  154. package/dist/extensions/search/credential.js.map +1 -0
  155. package/dist/extensions/search/devin.d.ts +34 -0
  156. package/dist/extensions/search/devin.d.ts.map +1 -0
  157. package/dist/extensions/search/devin.js +210 -0
  158. package/dist/extensions/search/devin.js.map +1 -0
  159. package/dist/extensions/search/index.d.ts +5 -0
  160. package/dist/extensions/search/index.d.ts.map +1 -0
  161. package/dist/extensions/search/index.js +110 -0
  162. package/dist/extensions/search/index.js.map +1 -0
  163. package/dist/extensions/search/panel.d.ts +53 -0
  164. package/dist/extensions/search/panel.d.ts.map +1 -0
  165. package/dist/extensions/search/panel.js +157 -0
  166. package/dist/extensions/search/panel.js.map +1 -0
  167. package/dist/extensions/search/prompt.d.ts +14 -0
  168. package/dist/extensions/search/prompt.d.ts.map +1 -0
  169. package/dist/extensions/search/prompt.js +221 -0
  170. package/dist/extensions/search/prompt.js.map +1 -0
  171. package/dist/extensions/search/render.d.ts +28 -0
  172. package/dist/extensions/search/render.d.ts.map +1 -0
  173. package/dist/extensions/search/render.js +86 -0
  174. package/dist/extensions/search/render.js.map +1 -0
  175. package/dist/extensions/search/workspace.d.ts +38 -0
  176. package/dist/extensions/search/workspace.d.ts.map +1 -0
  177. package/dist/extensions/search/workspace.js +245 -0
  178. package/dist/extensions/search/workspace.js.map +1 -0
  179. package/dist/main.d.ts.map +1 -1
  180. package/dist/main.js +1 -0
  181. package/dist/main.js.map +1 -1
  182. package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
  183. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  184. package/dist/modes/interactive/components/bash-execution.js +14 -14
  185. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  186. package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
  187. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  188. package/dist/modes/interactive/components/branch-summary-message.js +5 -2
  189. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  190. package/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -1
  191. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  192. package/dist/modes/interactive/components/compaction-summary-message.js +5 -2
  193. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  194. package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
  195. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  196. package/dist/modes/interactive/components/custom-entry.js +7 -2
  197. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  198. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  199. package/dist/modes/interactive/components/custom-message.js +1 -0
  200. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  201. package/dist/modes/interactive/components/settings-selector.js +1 -1
  202. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  203. package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
  204. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  205. package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
  206. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  207. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  208. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  209. package/dist/modes/interactive/interactive-mode.js +52 -59
  210. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  211. package/dist/modes/interactive/program-status-reporter.d.ts +34 -0
  212. package/dist/modes/interactive/program-status-reporter.d.ts.map +1 -0
  213. package/dist/modes/interactive/program-status-reporter.js +107 -0
  214. package/dist/modes/interactive/program-status-reporter.js.map +1 -0
  215. package/dist/modes/interactive/tasks/host-hooks.d.ts +14 -0
  216. package/dist/modes/interactive/tasks/host-hooks.d.ts.map +1 -0
  217. package/dist/modes/interactive/tasks/host-hooks.js +31 -0
  218. package/dist/modes/interactive/tasks/host-hooks.js.map +1 -0
  219. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  220. package/dist/modes/interactive/theme/theme.js +1 -0
  221. package/dist/modes/interactive/theme/theme.js.map +1 -1
  222. package/dist/modes/interactive/tool-view/tool-execution.d.ts +5 -0
  223. package/dist/modes/interactive/tool-view/tool-execution.d.ts.map +1 -1
  224. package/dist/modes/interactive/tool-view/tool-execution.js +7 -0
  225. package/dist/modes/interactive/tool-view/tool-execution.js.map +1 -1
  226. package/dist/package-manager-cli.d.ts.map +1 -1
  227. package/dist/package-manager-cli.js +24 -0
  228. package/dist/package-manager-cli.js.map +1 -1
  229. package/dist/utils/ansi.d.ts +8 -0
  230. package/dist/utils/ansi.d.ts.map +1 -1
  231. package/dist/utils/ansi.js +30 -11
  232. package/dist/utils/ansi.js.map +1 -1
  233. package/dist/utils/clipboard.d.ts.map +1 -1
  234. package/dist/utils/clipboard.js +12 -11
  235. package/dist/utils/clipboard.js.map +1 -1
  236. package/dist/utils/image-resize-core.d.ts +12 -0
  237. package/dist/utils/image-resize-core.d.ts.map +1 -1
  238. package/dist/utils/image-resize-core.js +5 -0
  239. package/dist/utils/image-resize-core.js.map +1 -1
  240. package/dist/utils/image-resize-worker.js +3 -2
  241. package/dist/utils/image-resize-worker.js.map +1 -1
  242. package/dist/utils/image-resize.d.ts.map +1 -1
  243. package/dist/utils/image-resize.js +9 -10
  244. package/dist/utils/image-resize.js.map +1 -1
  245. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  246. package/dist/utils/syntax-highlight.js +6 -1
  247. package/dist/utils/syntax-highlight.js.map +1 -1
  248. package/docs/bundled/README.md +1 -1
  249. package/docs/bundled/extensions/provider.md +1 -1
  250. package/docs/bundled/extensions/question.md +1 -1
  251. package/docs/bundled/extensions/search.md +50 -0
  252. package/docs/bundled/extensions/statusline.md +15 -41
  253. package/docs/codemode.md +26 -5
  254. package/docs/docs.json +0 -4
  255. package/docs/environment-variables.md +1 -0
  256. package/docs/extensions.md +6 -2
  257. package/docs/json.md +2 -2
  258. package/docs/llama-cpp.md +8 -1
  259. package/docs/mcp.md +3 -1
  260. package/docs/models.md +4 -1
  261. package/docs/providers.md +17 -0
  262. package/docs/rpc.md +6 -3
  263. package/docs/session-format.md +1 -0
  264. package/docs/settings.md +4 -4
  265. package/docs/terminal-setup.md +14 -0
  266. package/docs/usage.md +19 -5
  267. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  268. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  269. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  270. package/examples/extensions/gondolin/package-lock.json +2 -2
  271. package/examples/extensions/gondolin/package.json +1 -1
  272. package/examples/extensions/sandbox/package-lock.json +2 -2
  273. package/examples/extensions/sandbox/package.json +1 -1
  274. package/examples/extensions/with-deps/package-lock.json +2 -2
  275. package/examples/extensions/with-deps/package.json +1 -1
  276. package/npm-shrinkwrap.json +54 -54
  277. package/package.json +13 -11
  278. package/dist/bundle/chunks/chunk-57XI7YJH.js +0 -2
  279. package/dist/bundle/chunks/chunk-JI4WGISU.js +0 -2
  280. package/dist/bundle/chunks/chunk-TCQ4HHQD.js +0 -2
  281. package/dist/bundle/chunks/chunk-TXJO4AJ7.js +0 -11
  282. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-OWU5SM6J.js +0 -2
  283. package/dist/bundle/chunks/typesafe-system-one-KYKKNU3E.js +0 -2
  284. package/dist/extensions/web-search/auth.d.ts +0 -12
  285. package/dist/extensions/web-search/auth.d.ts.map +0 -1
  286. package/dist/extensions/web-search/auth.js +0 -90
  287. package/dist/extensions/web-search/auth.js.map +0 -1
  288. package/dist/extensions/web-search/constants.d.ts +0 -13
  289. package/dist/extensions/web-search/constants.d.ts.map +0 -1
  290. package/dist/extensions/web-search/constants.js +0 -26
  291. package/dist/extensions/web-search/constants.js.map +0 -1
  292. package/dist/extensions/web-search/execute.d.ts +0 -9
  293. package/dist/extensions/web-search/execute.d.ts.map +0 -1
  294. package/dist/extensions/web-search/execute.js +0 -96
  295. package/dist/extensions/web-search/execute.js.map +0 -1
  296. package/dist/extensions/web-search/format.d.ts +0 -21
  297. package/dist/extensions/web-search/format.d.ts.map +0 -1
  298. package/dist/extensions/web-search/format.js +0 -117
  299. package/dist/extensions/web-search/format.js.map +0 -1
  300. package/dist/extensions/web-search/index.d.ts +0 -6
  301. package/dist/extensions/web-search/index.d.ts.map +0 -1
  302. package/dist/extensions/web-search/index.js +0 -50
  303. package/dist/extensions/web-search/index.js.map +0 -1
  304. package/dist/extensions/web-search/providers/deepseek.d.ts +0 -13
  305. package/dist/extensions/web-search/providers/deepseek.d.ts.map +0 -1
  306. package/dist/extensions/web-search/providers/deepseek.js +0 -110
  307. package/dist/extensions/web-search/providers/deepseek.js.map +0 -1
  308. package/dist/extensions/web-search/providers/http.d.ts +0 -4
  309. package/dist/extensions/web-search/providers/http.d.ts.map +0 -1
  310. package/dist/extensions/web-search/providers/http.js +0 -42
  311. package/dist/extensions/web-search/providers/http.js.map +0 -1
  312. package/dist/extensions/web-search/providers/minimax.d.ts +0 -12
  313. package/dist/extensions/web-search/providers/minimax.d.ts.map +0 -1
  314. package/dist/extensions/web-search/providers/minimax.js +0 -61
  315. package/dist/extensions/web-search/providers/minimax.js.map +0 -1
  316. package/dist/extensions/web-search/render.d.ts +0 -15
  317. package/dist/extensions/web-search/render.d.ts.map +0 -1
  318. package/dist/extensions/web-search/render.js +0 -142
  319. package/dist/extensions/web-search/render.js.map +0 -1
  320. package/dist/extensions/web-search/results.d.ts +0 -35
  321. package/dist/extensions/web-search/results.d.ts.map +0 -1
  322. package/dist/extensions/web-search/results.js +0 -167
  323. package/dist/extensions/web-search/results.js.map +0 -1
  324. package/dist/extensions/web-search/schema.d.ts +0 -10
  325. package/dist/extensions/web-search/schema.d.ts.map +0 -1
  326. package/dist/extensions/web-search/schema.js +0 -36
  327. package/dist/extensions/web-search/schema.js.map +0 -1
  328. package/dist/extensions/web-search/types.d.ts +0 -51
  329. package/dist/extensions/web-search/types.d.ts.map +0 -1
  330. package/dist/extensions/web-search/types.js +0 -5
  331. package/dist/extensions/web-search/types.js.map +0 -1
  332. package/docs/bundled/extensions/web-search.md +0 -46
@@ -0,0 +1,245 @@
1
+ /**
2
+ * The local side of code_search: the planner runs remotely and names commands against a virtual
3
+ * `/codebase`; this module executes them read-only, confined to one directory.
4
+ *
5
+ * Security boundary: every model-supplied path must resolve inside the root, both lexically and
6
+ * after following symlinks. Only `rg`, `readfile`, and `tree` exist; there is no shell and no write.
7
+ */
8
+ import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
9
+ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
10
+ import { createGrepToolDefinition } from "../../core/tools/grep.js";
11
+ export const VIRTUAL_ROOT = "/codebase";
12
+ /** Per-command result cap. Results are sent back to Devin, whose request limit is ~320KB. */
13
+ const RESULT_MAX_LINES = 40;
14
+ const LINE_MAX_CHARS = 200;
15
+ /** The repo map's share of that limit; deeper trees fall back to shallower ones until they fit. */
16
+ const MAP_MAX_BYTES = 64 * 1024;
17
+ const MAP_MAX_DEPTH = 3;
18
+ const NOISE_DIRS = [
19
+ ".git",
20
+ "node_modules",
21
+ "dist",
22
+ "build",
23
+ "out",
24
+ "target",
25
+ "coverage",
26
+ ".venv",
27
+ "venv",
28
+ "__pycache__",
29
+ ".cache",
30
+ ".next",
31
+ ".nuxt",
32
+ ".turbo",
33
+ ".idea",
34
+ "vendor",
35
+ "third_party",
36
+ ];
37
+ /** Pi's own grep tool: gitignore-aware, with its bundled ripgrep. It takes one glob, so only the first include applies. */
38
+ export function piGrep(root) {
39
+ const tool = createGrepToolDefinition(root);
40
+ const execute = tool.execute;
41
+ return async (pattern, path, glob, signal) => {
42
+ const result = await execute("code_search", { pattern, path, glob, limit: RESULT_MAX_LINES }, signal);
43
+ return result.content?.find((c) => c.type === "text")?.text ?? "";
44
+ };
45
+ }
46
+ function within(base, path) {
47
+ const rel = relative(base, path);
48
+ return rel === "" || (!rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel));
49
+ }
50
+ /** realpath of the longest existing prefix, so a not-yet-existing path still resolves through symlinks. */
51
+ function realpathOf(path) {
52
+ let current = resolve(path);
53
+ const tail = [];
54
+ while (!existsSync(current)) {
55
+ const parent = dirname(current);
56
+ if (parent === current)
57
+ return resolve(path);
58
+ tail.unshift(basename(current));
59
+ current = parent;
60
+ }
61
+ try {
62
+ return resolve(realpathSync(current), ...tail);
63
+ }
64
+ catch {
65
+ return resolve(path);
66
+ }
67
+ }
68
+ /** Whether `path` lies inside `root`, both as written and after following symlinks. */
69
+ export function isInside(root, path) {
70
+ const abs = resolve(path);
71
+ return within(resolve(root), abs) && within(realpathOf(root), realpathOf(abs));
72
+ }
73
+ function capLines(text) {
74
+ const lines = text.split("\n");
75
+ const kept = lines
76
+ .slice(0, RESULT_MAX_LINES)
77
+ .map((l) => (l.length > LINE_MAX_CHARS ? l.slice(0, LINE_MAX_CHARS) : l));
78
+ if (lines.length > RESULT_MAX_LINES)
79
+ kept.push(`... (${lines.length - RESULT_MAX_LINES} more lines)`);
80
+ return kept.join("\n");
81
+ }
82
+ export class Workspace {
83
+ constructor(root, grep = piGrep(root)) {
84
+ this.root = resolve(root);
85
+ this.grep = grep;
86
+ this.noise = new Set([...NOISE_DIRS, ...gitignoredNames(this.root)]);
87
+ }
88
+ contains(path) {
89
+ return isInside(this.root, path);
90
+ }
91
+ /** `/codebase/src/a.ts` or `src/a.ts` → an absolute path inside the root, or null. */
92
+ toReal(virtual) {
93
+ if (typeof virtual !== "string" || !virtual)
94
+ return null;
95
+ const normalized = virtual.replace(/\\/g, "/");
96
+ let rel;
97
+ if (normalized === VIRTUAL_ROOT || normalized.startsWith(`${VIRTUAL_ROOT}/`)) {
98
+ rel = normalized.slice(VIRTUAL_ROOT.length);
99
+ }
100
+ else if (isAbsolute(virtual) || normalized.startsWith("/") || /^[a-zA-Z]:/.test(normalized)) {
101
+ // A drive-letter path is another drive on Windows and a stray filename elsewhere; refuse it everywhere.
102
+ return null;
103
+ }
104
+ else {
105
+ rel = normalized;
106
+ }
107
+ const candidate = resolve(this.root, rel.replace(/^\/+/, ""));
108
+ return this.contains(candidate) ? candidate : null;
109
+ }
110
+ toVirtual(real) {
111
+ const rel = relative(this.root, real).split(sep).join("/");
112
+ return rel ? `${VIRTUAL_ROOT}/${rel}` : VIRTUAL_ROOT;
113
+ }
114
+ /** The deepest tree of the root, up to three levels, that fits the map budget. */
115
+ repoMap() {
116
+ for (let depth = MAP_MAX_DEPTH; depth > 1; depth--) {
117
+ const tree = this.renderTree(this.root, depth);
118
+ if (Buffer.byteLength(tree) <= MAP_MAX_BYTES)
119
+ return { depth, tree };
120
+ }
121
+ return { depth: 1, tree: this.renderTree(this.root, 1).slice(0, MAP_MAX_BYTES / 4) };
122
+ }
123
+ async run(command, signal) {
124
+ switch (command?.type) {
125
+ case "rg":
126
+ return this.rg(command, signal);
127
+ case "readfile":
128
+ return this.readfile(command);
129
+ case "tree":
130
+ return this.tree(command);
131
+ default:
132
+ return `Error: unknown command type '${String(command?.type)}'; use rg, readfile, or tree`;
133
+ }
134
+ }
135
+ async rg(command, signal) {
136
+ if (typeof command.pattern !== "string" || !command.pattern)
137
+ return "Error: missing pattern";
138
+ const real = this.toReal(command.path ?? VIRTUAL_ROOT);
139
+ if (!real)
140
+ return `Error: path outside project root: ${String(command.path)}`;
141
+ if (!existsSync(real))
142
+ return `Error: path does not exist: ${String(command.path)}`;
143
+ const include = Array.isArray(command.include) && typeof command.include[0] === "string" ? command.include[0] : undefined;
144
+ let raw;
145
+ try {
146
+ raw = await this.grep(command.pattern, real, include, signal);
147
+ }
148
+ catch (e) {
149
+ return `Error: ${e instanceof Error ? e.message : String(e)}`;
150
+ }
151
+ // Pi's grep prints paths relative to the searched directory, or the bare file name for a file.
152
+ const isFile = statSync(real).isFile();
153
+ const base = this.toVirtual(real);
154
+ const remapped = raw
155
+ .split("\n")
156
+ .map((line) => {
157
+ const m = line.match(/^(.+?):(\d+):(.*)$/);
158
+ if (!m)
159
+ return line;
160
+ return `${isFile ? base : `${base}/${m[1].replace(/\\/g, "/")}`}:${m[2]}:${m[3]}`;
161
+ })
162
+ .join("\n");
163
+ return capLines(remapped.trim() || "(no matches)");
164
+ }
165
+ readfile(command) {
166
+ const real = this.toReal(command.file);
167
+ if (!real)
168
+ return `Error: path outside project root: ${String(command.file)}`;
169
+ let content;
170
+ try {
171
+ if (!statSync(real).isFile())
172
+ return `Error: not a file: ${String(command.file)}`;
173
+ content = readFileSync(real, "utf-8");
174
+ }
175
+ catch {
176
+ return `Error: file not found: ${String(command.file)}`;
177
+ }
178
+ const lines = content.split("\n");
179
+ const start = Math.max(1, Number(command.start_line) || 1);
180
+ const end = Math.min(lines.length, Number(command.end_line) || lines.length);
181
+ return capLines(lines
182
+ .slice(start - 1, end)
183
+ .map((line, i) => `${start + i}:${line}`)
184
+ .join("\n"));
185
+ }
186
+ tree(command) {
187
+ const real = this.toReal(command.path ?? VIRTUAL_ROOT);
188
+ if (!real)
189
+ return `Error: path outside project root: ${String(command.path)}`;
190
+ try {
191
+ if (!statSync(real).isDirectory())
192
+ return `Error: not a directory: ${String(command.path)}`;
193
+ }
194
+ catch {
195
+ return `Error: directory not found: ${String(command.path)}`;
196
+ }
197
+ const levels = Math.min(Math.max(Number(command.levels) || 2, 1), 4);
198
+ return capLines(this.renderTree(real, levels));
199
+ }
200
+ renderTree(dir, maxDepth) {
201
+ const lines = [this.toVirtual(dir)];
202
+ const walk = (current, depth, prefix) => {
203
+ if (depth >= maxDepth)
204
+ return;
205
+ let entries;
206
+ try {
207
+ entries = readdirSync(current)
208
+ .filter((name) => !this.noise.has(name))
209
+ .sort();
210
+ }
211
+ catch {
212
+ return;
213
+ }
214
+ entries.forEach((name, i) => {
215
+ const last = i === entries.length - 1;
216
+ lines.push(`${prefix}${last ? "└── " : "├── "}${name}`);
217
+ const path = join(current, name);
218
+ let isDir = false;
219
+ try {
220
+ isDir = statSync(path).isDirectory() && this.contains(path);
221
+ }
222
+ catch { }
223
+ if (isDir)
224
+ walk(path, depth + 1, `${prefix}${last ? " " : "│ "}`);
225
+ });
226
+ };
227
+ walk(dir, 0, "");
228
+ return lines.join("\n");
229
+ }
230
+ }
231
+ /** Plain directory names from `.gitignore`; patterns with slashes or globs are left to grep. */
232
+ function gitignoredNames(root) {
233
+ let text;
234
+ try {
235
+ text = readFileSync(join(root, ".gitignore"), "utf-8");
236
+ }
237
+ catch {
238
+ return [];
239
+ }
240
+ return text
241
+ .split("\n")
242
+ .map((line) => line.trim().replace(/^\/+|\/+$/g, ""))
243
+ .filter((name) => name && !name.startsWith("#") && !name.startsWith("!") && !/[/*?[\]]/.test(name));
244
+ }
245
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/extensions/search/workspace.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The local side of code_search: the planner runs remotely and names commands against a virtual\n * `/codebase`; this module executes them read-only, confined to one directory.\n *\n * Security boundary: every model-supplied path must resolve inside the root, both lexically and\n * after following symlinks. Only `rg`, `readfile`, and `tree` exist; there is no shell and no write.\n */\nimport { existsSync, readdirSync, readFileSync, realpathSync, statSync } from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport { createGrepToolDefinition } from \"../../core/tools/grep.ts\";\n\nexport const VIRTUAL_ROOT = \"/codebase\";\n\n/** Per-command result cap. Results are sent back to Devin, whose request limit is ~320KB. */\nconst RESULT_MAX_LINES = 40;\nconst LINE_MAX_CHARS = 200;\n/** The repo map's share of that limit; deeper trees fall back to shallower ones until they fit. */\nconst MAP_MAX_BYTES = 64 * 1024;\nconst MAP_MAX_DEPTH = 3;\n\nconst NOISE_DIRS = [\n\t\".git\",\n\t\"node_modules\",\n\t\"dist\",\n\t\"build\",\n\t\"out\",\n\t\"target\",\n\t\"coverage\",\n\t\".venv\",\n\t\"venv\",\n\t\"__pycache__\",\n\t\".cache\",\n\t\".next\",\n\t\".nuxt\",\n\t\".turbo\",\n\t\".idea\",\n\t\"vendor\",\n\t\"third_party\",\n];\n\n/** `rg` backend: pattern, directory or file, optional glob → `path:line: text` lines. */\nexport type Grep = (pattern: string, path: string, glob: string | undefined, signal?: AbortSignal) => Promise<string>;\n\n/** Pi's own grep tool: gitignore-aware, with its bundled ripgrep. It takes one glob, so only the first include applies. */\nexport function piGrep(root: string): Grep {\n\tconst tool = createGrepToolDefinition(root);\n\tconst execute = tool.execute as unknown as (\n\t\tid: string,\n\t\tparams: { pattern: string; path: string; glob?: string; limit: number },\n\t\tsignal?: AbortSignal,\n\t) => Promise<{ content?: Array<{ type?: string; text?: string }> }>;\n\treturn async (pattern, path, glob, signal) => {\n\t\tconst result = await execute(\"code_search\", { pattern, path, glob, limit: RESULT_MAX_LINES }, signal);\n\t\treturn result.content?.find((c) => c.type === \"text\")?.text ?? \"\";\n\t};\n}\n\nfunction within(base: string, path: string): boolean {\n\tconst rel = relative(base, path);\n\treturn rel === \"\" || (!rel.startsWith(`..${sep}`) && rel !== \"..\" && !isAbsolute(rel));\n}\n\n/** realpath of the longest existing prefix, so a not-yet-existing path still resolves through symlinks. */\nfunction realpathOf(path: string): string {\n\tlet current = resolve(path);\n\tconst tail: string[] = [];\n\twhile (!existsSync(current)) {\n\t\tconst parent = dirname(current);\n\t\tif (parent === current) return resolve(path);\n\t\ttail.unshift(basename(current));\n\t\tcurrent = parent;\n\t}\n\ttry {\n\t\treturn resolve(realpathSync(current), ...tail);\n\t} catch {\n\t\treturn resolve(path);\n\t}\n}\n\n/** Whether `path` lies inside `root`, both as written and after following symlinks. */\nexport function isInside(root: string, path: string): boolean {\n\tconst abs = resolve(path);\n\treturn within(resolve(root), abs) && within(realpathOf(root), realpathOf(abs));\n}\n\nfunction capLines(text: string): string {\n\tconst lines = text.split(\"\\n\");\n\tconst kept = lines\n\t\t.slice(0, RESULT_MAX_LINES)\n\t\t.map((l) => (l.length > LINE_MAX_CHARS ? l.slice(0, LINE_MAX_CHARS) : l));\n\tif (lines.length > RESULT_MAX_LINES) kept.push(`... (${lines.length - RESULT_MAX_LINES} more lines)`);\n\treturn kept.join(\"\\n\");\n}\n\nexport interface Command {\n\ttype?: unknown;\n\tpattern?: unknown;\n\tpath?: unknown;\n\tinclude?: unknown;\n\tfile?: unknown;\n\tstart_line?: unknown;\n\tend_line?: unknown;\n\tlevels?: unknown;\n}\n\nexport class Workspace {\n\treadonly root: string;\n\tprivate readonly grep: Grep;\n\tprivate readonly noise: Set<string>;\n\n\tconstructor(root: string, grep: Grep = piGrep(root)) {\n\t\tthis.root = resolve(root);\n\t\tthis.grep = grep;\n\t\tthis.noise = new Set([...NOISE_DIRS, ...gitignoredNames(this.root)]);\n\t}\n\n\tcontains(path: string): boolean {\n\t\treturn isInside(this.root, path);\n\t}\n\n\t/** `/codebase/src/a.ts` or `src/a.ts` → an absolute path inside the root, or null. */\n\ttoReal(virtual: unknown): string | null {\n\t\tif (typeof virtual !== \"string\" || !virtual) return null;\n\t\tconst normalized = virtual.replace(/\\\\/g, \"/\");\n\t\tlet rel: string;\n\t\tif (normalized === VIRTUAL_ROOT || normalized.startsWith(`${VIRTUAL_ROOT}/`)) {\n\t\t\trel = normalized.slice(VIRTUAL_ROOT.length);\n\t\t} else if (isAbsolute(virtual) || normalized.startsWith(\"/\") || /^[a-zA-Z]:/.test(normalized)) {\n\t\t\t// A drive-letter path is another drive on Windows and a stray filename elsewhere; refuse it everywhere.\n\t\t\treturn null;\n\t\t} else {\n\t\t\trel = normalized;\n\t\t}\n\t\tconst candidate = resolve(this.root, rel.replace(/^\\/+/, \"\"));\n\t\treturn this.contains(candidate) ? candidate : null;\n\t}\n\n\ttoVirtual(real: string): string {\n\t\tconst rel = relative(this.root, real).split(sep).join(\"/\");\n\t\treturn rel ? `${VIRTUAL_ROOT}/${rel}` : VIRTUAL_ROOT;\n\t}\n\n\t/** The deepest tree of the root, up to three levels, that fits the map budget. */\n\trepoMap(): { depth: number; tree: string } {\n\t\tfor (let depth = MAP_MAX_DEPTH; depth > 1; depth--) {\n\t\t\tconst tree = this.renderTree(this.root, depth);\n\t\t\tif (Buffer.byteLength(tree) <= MAP_MAX_BYTES) return { depth, tree };\n\t\t}\n\t\treturn { depth: 1, tree: this.renderTree(this.root, 1).slice(0, MAP_MAX_BYTES / 4) };\n\t}\n\n\tasync run(command: Command, signal?: AbortSignal): Promise<string> {\n\t\tswitch (command?.type) {\n\t\t\tcase \"rg\":\n\t\t\t\treturn this.rg(command, signal);\n\t\t\tcase \"readfile\":\n\t\t\t\treturn this.readfile(command);\n\t\t\tcase \"tree\":\n\t\t\t\treturn this.tree(command);\n\t\t\tdefault:\n\t\t\t\treturn `Error: unknown command type '${String(command?.type)}'; use rg, readfile, or tree`;\n\t\t}\n\t}\n\n\tprivate async rg(command: Command, signal?: AbortSignal): Promise<string> {\n\t\tif (typeof command.pattern !== \"string\" || !command.pattern) return \"Error: missing pattern\";\n\t\tconst real = this.toReal(command.path ?? VIRTUAL_ROOT);\n\t\tif (!real) return `Error: path outside project root: ${String(command.path)}`;\n\t\tif (!existsSync(real)) return `Error: path does not exist: ${String(command.path)}`;\n\t\tconst include =\n\t\t\tArray.isArray(command.include) && typeof command.include[0] === \"string\" ? command.include[0] : undefined;\n\t\tlet raw: string;\n\t\ttry {\n\t\t\traw = await this.grep(command.pattern, real, include, signal);\n\t\t} catch (e) {\n\t\t\treturn `Error: ${e instanceof Error ? e.message : String(e)}`;\n\t\t}\n\t\t// Pi's grep prints paths relative to the searched directory, or the bare file name for a file.\n\t\tconst isFile = statSync(real).isFile();\n\t\tconst base = this.toVirtual(real);\n\t\tconst remapped = raw\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => {\n\t\t\t\tconst m = line.match(/^(.+?):(\\d+):(.*)$/);\n\t\t\t\tif (!m) return line;\n\t\t\t\treturn `${isFile ? base : `${base}/${m[1]!.replace(/\\\\/g, \"/\")}`}:${m[2]}:${m[3]}`;\n\t\t\t})\n\t\t\t.join(\"\\n\");\n\t\treturn capLines(remapped.trim() || \"(no matches)\");\n\t}\n\n\tprivate readfile(command: Command): string {\n\t\tconst real = this.toReal(command.file);\n\t\tif (!real) return `Error: path outside project root: ${String(command.file)}`;\n\t\tlet content: string;\n\t\ttry {\n\t\t\tif (!statSync(real).isFile()) return `Error: not a file: ${String(command.file)}`;\n\t\t\tcontent = readFileSync(real, \"utf-8\");\n\t\t} catch {\n\t\t\treturn `Error: file not found: ${String(command.file)}`;\n\t\t}\n\t\tconst lines = content.split(\"\\n\");\n\t\tconst start = Math.max(1, Number(command.start_line) || 1);\n\t\tconst end = Math.min(lines.length, Number(command.end_line) || lines.length);\n\t\treturn capLines(\n\t\t\tlines\n\t\t\t\t.slice(start - 1, end)\n\t\t\t\t.map((line, i) => `${start + i}:${line}`)\n\t\t\t\t.join(\"\\n\"),\n\t\t);\n\t}\n\n\tprivate tree(command: Command): string {\n\t\tconst real = this.toReal(command.path ?? VIRTUAL_ROOT);\n\t\tif (!real) return `Error: path outside project root: ${String(command.path)}`;\n\t\ttry {\n\t\t\tif (!statSync(real).isDirectory()) return `Error: not a directory: ${String(command.path)}`;\n\t\t} catch {\n\t\t\treturn `Error: directory not found: ${String(command.path)}`;\n\t\t}\n\t\tconst levels = Math.min(Math.max(Number(command.levels) || 2, 1), 4);\n\t\treturn capLines(this.renderTree(real, levels));\n\t}\n\n\tprivate renderTree(dir: string, maxDepth: number): string {\n\t\tconst lines = [this.toVirtual(dir)];\n\t\tconst walk = (current: string, depth: number, prefix: string): void => {\n\t\t\tif (depth >= maxDepth) return;\n\t\t\tlet entries: string[];\n\t\t\ttry {\n\t\t\t\tentries = readdirSync(current)\n\t\t\t\t\t.filter((name) => !this.noise.has(name))\n\t\t\t\t\t.sort();\n\t\t\t} catch {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tentries.forEach((name, i) => {\n\t\t\t\tconst last = i === entries.length - 1;\n\t\t\t\tlines.push(`${prefix}${last ? \"└── \" : \"├── \"}${name}`);\n\t\t\t\tconst path = join(current, name);\n\t\t\t\tlet isDir = false;\n\t\t\t\ttry {\n\t\t\t\t\tisDir = statSync(path).isDirectory() && this.contains(path);\n\t\t\t\t} catch {}\n\t\t\t\tif (isDir) walk(path, depth + 1, `${prefix}${last ? \" \" : \"│ \"}`);\n\t\t\t});\n\t\t};\n\t\twalk(dir, 0, \"\");\n\t\treturn lines.join(\"\\n\");\n\t}\n}\n\n/** Plain directory names from `.gitignore`; patterns with slashes or globs are left to grep. */\nfunction gitignoredNames(root: string): string[] {\n\tlet text: string;\n\ttry {\n\t\ttext = readFileSync(join(root, \".gitignore\"), \"utf-8\");\n\t} catch {\n\t\treturn [];\n\t}\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trim().replace(/^\\/+|\\/+$/g, \"\"))\n\t\t.filter((name) => name && !name.startsWith(\"#\") && !name.startsWith(\"!\") && !/[/*?[\\]]/.test(name));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,KAAK,IAAI,EAAyD,MAAM,eAAe,CAAC;AAkCjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAalE,OAAO,EAAwB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAyS7D,wBAAsB,oBAAoB,CACzC,MAAM,EAAE,IAAI,EACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,eAAe,EAAE,eAAe,GAC9B,OAAO,CAAC,cAAc,CAAC,CAsFzB;AAwHD,MAAM,WAAW,WAAW;IAC3B,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;CACvC;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,iBAya/D"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,KAAK,IAAI,EAAyD,MAAM,eAAe,CAAC;AAkCjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAalE,OAAO,EAAwB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAyS7D,wBAAsB,oBAAoB,CACzC,MAAM,EAAE,IAAI,EACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,eAAe,EAAE,eAAe,GAC9B,OAAO,CAAC,cAAc,CAAC,CAsFzB;AAwHD,MAAM,WAAW,WAAW;IAC3B,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;CACvC;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,iBA0a/D"}
package/dist/main.js CHANGED
@@ -631,6 +631,7 @@ export async function main(args, options) {
631
631
  additionalPromptTemplatePaths: resolvedPromptTemplatePaths,
632
632
  additionalThemePaths: resolvedThemePaths,
633
633
  noExtensions: parsed.noExtensions,
634
+ disabledBuiltinExtensions: parsed.noMcp ? ["mcp"] : undefined,
634
635
  noSkills: parsed.noSkills,
635
636
  noPromptTemplates: parsed.noPromptTemplates,
636
637
  noThemes: parsed.noThemes,