@cjhyy/code-shell-core 0.5.0-rc.1 → 0.6.0-rc.1

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 (528) hide show
  1. package/README.md +13 -10
  2. package/dist/agent/agent-definition-registry.d.ts +21 -3
  3. package/dist/agent/agent-definition-registry.js +49 -18
  4. package/dist/agent/agent-definition.d.ts +32 -0
  5. package/dist/agent/agent-definition.js +49 -4
  6. package/dist/arena/arena.js +11 -12
  7. package/dist/arena/context/context-tools.js +47 -6
  8. package/dist/arena/context/within-root.d.ts +7 -0
  9. package/dist/arena/context/within-root.js +15 -0
  10. package/dist/arena/iterate/phases/argue.js +8 -2
  11. package/dist/arena/iterate/phases/revise.js +1 -1
  12. package/dist/arena/iterate/phases/tournament.js +3 -3
  13. package/dist/arena/ledger.js +9 -1
  14. package/dist/arena/phases/adjudication.js +1 -4
  15. package/dist/arena/phases/build-consensus.js +1 -4
  16. package/dist/arena/phases/cross-review.js +2 -8
  17. package/dist/arena/phases/debate-rounds.js +1 -4
  18. package/dist/arena/phases/participant-research.js +1 -4
  19. package/dist/arena/phases/planning-detail-expansion.js +8 -10
  20. package/dist/arena/planner.js +0 -1
  21. package/dist/arena/providers/docs.d.ts +1 -0
  22. package/dist/arena/providers/docs.js +5 -2
  23. package/dist/arena/providers/repo.d.ts +1 -0
  24. package/dist/arena/providers/repo.js +5 -2
  25. package/dist/arena/strategies/utils.d.ts +1 -4
  26. package/dist/arena/strategies/utils.js +7 -51
  27. package/dist/arena/transitions.d.ts +7 -2
  28. package/dist/arena/transitions.js +9 -4
  29. package/dist/arena/types.d.ts +8 -2
  30. package/dist/automation/cron-expr.d.ts +41 -0
  31. package/dist/automation/cron-expr.js +169 -0
  32. package/dist/automation/index.d.ts +41 -0
  33. package/dist/automation/index.js +39 -0
  34. package/dist/automation/runner.d.ts +84 -0
  35. package/dist/automation/runner.js +92 -0
  36. package/dist/automation/scheduler.d.ts +194 -0
  37. package/dist/automation/scheduler.js +623 -0
  38. package/dist/automation/store.d.ts +39 -0
  39. package/dist/automation/store.js +122 -0
  40. package/dist/automation/write-policy.d.ts +34 -0
  41. package/dist/automation/write-policy.js +113 -0
  42. package/dist/automation/write-run.d.ts +51 -0
  43. package/dist/automation/write-run.js +38 -0
  44. package/dist/capability-control/disabled-lists.d.ts +25 -0
  45. package/dist/capability-control/disabled-lists.js +57 -0
  46. package/dist/capability-control/index.d.ts +5 -0
  47. package/dist/capability-control/index.js +3 -0
  48. package/dist/capability-control/overlay.d.ts +64 -0
  49. package/dist/capability-control/overlay.js +116 -0
  50. package/dist/capability-control/project.d.ts +65 -0
  51. package/dist/capability-control/project.js +147 -0
  52. package/dist/capability-control/service.d.ts +70 -0
  53. package/dist/capability-control/service.js +147 -0
  54. package/dist/capability-control/types.d.ts +62 -0
  55. package/dist/capability-control/types.js +17 -0
  56. package/dist/cc-orchestrator/agent-adapter.d.ts +50 -0
  57. package/dist/cc-orchestrator/agent-adapter.js +133 -0
  58. package/dist/cc-orchestrator/cc-capability.d.ts +19 -0
  59. package/dist/cc-orchestrator/cc-capability.js +53 -0
  60. package/dist/cc-orchestrator/codex-session-discovery.d.ts +24 -0
  61. package/dist/cc-orchestrator/codex-session-discovery.js +191 -0
  62. package/dist/cc-orchestrator/codex-session-history.d.ts +25 -0
  63. package/dist/cc-orchestrator/codex-session-history.js +187 -0
  64. package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
  65. package/dist/cc-orchestrator/external-agent-changes.js +214 -0
  66. package/dist/cc-orchestrator/external-agent-driver.d.ts +18 -0
  67. package/dist/cc-orchestrator/external-agent-driver.js +69 -0
  68. package/dist/cc-orchestrator/index.d.ts +8 -0
  69. package/dist/cc-orchestrator/index.js +8 -0
  70. package/dist/cc-orchestrator/relevance-judge.d.ts +15 -0
  71. package/dist/cc-orchestrator/relevance-judge.js +29 -0
  72. package/dist/cc-orchestrator/session-discovery.d.ts +46 -0
  73. package/dist/cc-orchestrator/session-discovery.js +125 -0
  74. package/dist/cc-orchestrator/session-history.d.ts +19 -0
  75. package/dist/cc-orchestrator/session-history.js +67 -0
  76. package/dist/cli/agent-server-stdio.d.ts +26 -1
  77. package/dist/cli/agent-server-stdio.js +221 -28
  78. package/dist/cli/agent-server-tcp.d.ts +20 -0
  79. package/dist/cli/agent-server-tcp.js +134 -0
  80. package/dist/cli/graceful-shutdown.d.ts +27 -0
  81. package/dist/cli/graceful-shutdown.js +30 -0
  82. package/dist/context/compaction.d.ts +56 -0
  83. package/dist/context/compaction.js +209 -15
  84. package/dist/context/manager.d.ts +0 -20
  85. package/dist/context/manager.js +25 -41
  86. package/dist/cost-tracker.js +5 -61
  87. package/dist/credentials/cipher.d.ts +49 -0
  88. package/dist/credentials/cipher.js +45 -0
  89. package/dist/credentials/cookie-jar.d.ts +24 -0
  90. package/dist/credentials/cookie-jar.js +40 -0
  91. package/dist/credentials/index.d.ts +7 -0
  92. package/dist/credentials/index.js +5 -0
  93. package/dist/credentials/inject-credential-tool.d.ts +20 -0
  94. package/dist/credentials/inject-credential-tool.js +130 -0
  95. package/dist/credentials/store.d.ts +72 -0
  96. package/dist/credentials/store.js +184 -0
  97. package/dist/credentials/types.d.ts +56 -0
  98. package/dist/credentials/use-credential-tool.d.ts +29 -0
  99. package/dist/credentials/use-credential-tool.js +205 -0
  100. package/dist/credentials/use-gate.d.ts +56 -0
  101. package/dist/credentials/use-gate.js +52 -0
  102. package/dist/cron/cron-runtime.d.ts +2 -0
  103. package/dist/cron/cron-runtime.js +2 -0
  104. package/dist/cron/cron-store.d.ts +2 -0
  105. package/dist/cron/cron-store.js +2 -0
  106. package/dist/cron/scheduler.d.ts +5 -32
  107. package/dist/cron/scheduler.js +5 -113
  108. package/dist/data/model-metadata.d.ts +77 -0
  109. package/dist/data/model-metadata.js +56 -0
  110. package/dist/data/model-metadata.json +216 -0
  111. package/dist/data/openrouter-models.d.ts +18 -7
  112. package/dist/data/openrouter-models.js +35 -8
  113. package/dist/data/openrouter-sync.js +1 -1
  114. package/dist/engine/aux-key.d.ts +10 -0
  115. package/dist/engine/aux-key.js +11 -0
  116. package/dist/engine/dynamic-tool-defs.d.ts +19 -0
  117. package/dist/engine/dynamic-tool-defs.js +36 -0
  118. package/dist/engine/engine.d.ts +431 -108
  119. package/dist/engine/engine.js +1630 -279
  120. package/dist/engine/friendly-error.d.ts +18 -0
  121. package/dist/engine/friendly-error.js +63 -0
  122. package/dist/engine/goal.d.ts +187 -0
  123. package/dist/engine/goal.js +196 -0
  124. package/dist/engine/image-compression.d.ts +81 -0
  125. package/dist/engine/image-compression.js +186 -0
  126. package/dist/engine/image-policy.d.ts +165 -0
  127. package/dist/engine/image-policy.js +189 -0
  128. package/dist/engine/model-connections-pool.d.ts +17 -0
  129. package/dist/engine/model-connections-pool.js +66 -0
  130. package/dist/engine/model-facade.d.ts +10 -0
  131. package/dist/engine/model-facade.js +25 -0
  132. package/dist/engine/patch-orphaned-tools.js +3 -0
  133. package/dist/engine/reactive-threshold.d.ts +13 -0
  134. package/dist/engine/reactive-threshold.js +17 -0
  135. package/dist/engine/resolve-llm-config.d.ts +16 -0
  136. package/dist/engine/resolve-llm-config.js +44 -0
  137. package/dist/engine/runtime.js +9 -1
  138. package/dist/engine/sandbox-cache-key.d.ts +10 -0
  139. package/dist/engine/sandbox-cache-key.js +9 -0
  140. package/dist/engine/sandbox-config.d.ts +31 -0
  141. package/dist/engine/sandbox-config.js +38 -0
  142. package/dist/engine/session-title.d.ts +13 -0
  143. package/dist/engine/session-title.js +34 -0
  144. package/dist/engine/session-usage.d.ts +19 -0
  145. package/dist/engine/session-usage.js +25 -0
  146. package/dist/engine/steer-queue.d.ts +32 -0
  147. package/dist/engine/steer-queue.js +26 -0
  148. package/dist/engine/streaming-tool-queue.d.ts +12 -0
  149. package/dist/engine/streaming-tool-queue.js +50 -10
  150. package/dist/engine/turn-loop.d.ts +94 -9
  151. package/dist/engine/turn-loop.js +775 -342
  152. package/dist/engine/types.d.ts +175 -0
  153. package/dist/engine/types.js +13 -0
  154. package/dist/external-agents/config.d.ts +2 -0
  155. package/dist/external-agents/config.js +15 -0
  156. package/dist/external-agents/types.d.ts +31 -0
  157. package/dist/external-agents/types.js +1 -0
  158. package/dist/git/parse-log.d.ts +13 -0
  159. package/dist/git/parse-log.js +21 -0
  160. package/dist/git/utils.d.ts +8 -6
  161. package/dist/git/utils.js +62 -26
  162. package/dist/git/worktree.d.ts +48 -0
  163. package/dist/git/worktree.js +111 -20
  164. package/dist/hooks/events.d.ts +23 -1
  165. package/dist/hooks/goal-stop-hook.d.ts +58 -0
  166. package/dist/hooks/goal-stop-hook.js +279 -0
  167. package/dist/hooks/hook-output.d.ts +33 -0
  168. package/dist/hooks/hook-output.js +79 -0
  169. package/dist/hooks/registry.d.ts +15 -0
  170. package/dist/hooks/registry.js +57 -1
  171. package/dist/hooks/shell-runner.d.ts +2 -0
  172. package/dist/hooks/shell-runner.js +48 -18
  173. package/dist/index.d.ts +79 -11
  174. package/dist/index.js +89 -6
  175. package/dist/llm/capabilities/param-specs.d.ts +14 -0
  176. package/dist/llm/capabilities/param-specs.js +62 -0
  177. package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
  178. package/dist/llm/capabilities/reasoning-control.js +38 -0
  179. package/dist/llm/capabilities/rules.js +37 -3
  180. package/dist/llm/capabilities/types.d.ts +32 -2
  181. package/dist/llm/clamp-max-tokens.d.ts +11 -0
  182. package/dist/llm/clamp-max-tokens.js +17 -0
  183. package/dist/llm/client-base.d.ts +69 -5
  184. package/dist/llm/client-base.js +185 -25
  185. package/dist/llm/client-factory.d.ts +3 -3
  186. package/dist/llm/client-factory.js +2 -2
  187. package/dist/llm/model-cache.js +4 -2
  188. package/dist/llm/model-pool.d.ts +29 -11
  189. package/dist/llm/model-pool.js +36 -20
  190. package/dist/llm/provider-auth.d.ts +41 -0
  191. package/dist/llm/provider-auth.js +76 -0
  192. package/dist/llm/provider-catalog.d.ts +6 -2
  193. package/dist/llm/providers/anthropic.d.ts +32 -2
  194. package/dist/llm/providers/anthropic.js +207 -18
  195. package/dist/llm/providers/openai.d.ts +47 -2
  196. package/dist/llm/providers/openai.js +478 -71
  197. package/dist/llm/reasoning-setting.d.ts +51 -0
  198. package/dist/llm/reasoning-setting.js +40 -0
  199. package/dist/llm/stop-reason.d.ts +13 -0
  200. package/dist/llm/stop-reason.js +21 -0
  201. package/dist/llm/stream-watchdog.js +5 -1
  202. package/dist/llm/strip-vision.d.ts +32 -0
  203. package/dist/llm/strip-vision.js +94 -0
  204. package/dist/llm/token-counter.js +9 -2
  205. package/dist/llm/types.d.ts +9 -6
  206. package/dist/logging/logger.js +18 -4
  207. package/dist/logging/sanitize-messages.d.ts +10 -0
  208. package/dist/logging/sanitize-messages.js +112 -0
  209. package/dist/lsp/client.js +28 -8
  210. package/dist/lsp/manager.d.ts +1 -1
  211. package/dist/lsp/manager.js +42 -11
  212. package/dist/lsp/root-path.d.ts +9 -0
  213. package/dist/lsp/root-path.js +12 -0
  214. package/dist/model-catalog/builtin.d.ts +12 -0
  215. package/dist/model-catalog/builtin.js +407 -0
  216. package/dist/model-catalog/gen-connections.d.ts +20 -0
  217. package/dist/model-catalog/gen-connections.js +28 -0
  218. package/dist/model-catalog/index.d.ts +41 -0
  219. package/dist/model-catalog/index.js +90 -0
  220. package/dist/model-catalog/params.d.ts +20 -0
  221. package/dist/model-catalog/params.js +45 -0
  222. package/dist/model-catalog/resolve.d.ts +48 -0
  223. package/dist/model-catalog/resolve.js +33 -0
  224. package/dist/model-catalog/save-entry.d.ts +32 -0
  225. package/dist/model-catalog/save-entry.js +104 -0
  226. package/dist/model-catalog/types.d.ts +561 -0
  227. package/dist/model-catalog/types.js +93 -0
  228. package/dist/model-catalog/upsert.d.ts +9 -0
  229. package/dist/model-catalog/upsert.js +8 -0
  230. package/dist/onboarding.d.ts +12 -82
  231. package/dist/onboarding.js +75 -333
  232. package/dist/plugins/gitOps.d.ts +53 -0
  233. package/dist/plugins/gitOps.js +130 -5
  234. package/dist/plugins/installer/checkUpdate.d.ts +16 -0
  235. package/dist/plugins/installer/checkUpdate.js +32 -0
  236. package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
  237. package/dist/plugins/installer/codex/convertAgents.js +55 -0
  238. package/dist/plugins/installer/codex/convertCommands.d.ts +19 -0
  239. package/dist/plugins/installer/codex/convertCommands.js +46 -0
  240. package/dist/plugins/installer/codex/convertMcp.d.ts +11 -0
  241. package/dist/plugins/installer/codex/convertMcp.js +85 -0
  242. package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
  243. package/dist/plugins/installer/codex/convertSkills.js +33 -0
  244. package/dist/plugins/installer/detectFormat.d.ts +2 -0
  245. package/dist/plugins/installer/detectFormat.js +6 -0
  246. package/dist/plugins/installer/install.d.ts +7 -0
  247. package/dist/plugins/installer/install.js +123 -0
  248. package/dist/plugins/installer/installFromArchive.d.ts +43 -0
  249. package/dist/plugins/installer/installFromArchive.js +134 -0
  250. package/dist/plugins/installer/installFromSource.d.ts +13 -0
  251. package/dist/plugins/installer/installFromSource.js +51 -0
  252. package/dist/plugins/installer/list.d.ts +9 -0
  253. package/dist/plugins/installer/list.js +30 -0
  254. package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
  255. package/dist/plugins/installer/loadPluginAgents.js +27 -0
  256. package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
  257. package/dist/plugins/installer/loadPluginMcp.js +107 -0
  258. package/dist/plugins/installer/parseSource.d.ts +20 -0
  259. package/dist/plugins/installer/parseSource.js +74 -0
  260. package/dist/plugins/installer/paths.d.ts +5 -0
  261. package/dist/plugins/installer/paths.js +25 -0
  262. package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
  263. package/dist/plugins/installer/pruneDisabled.js +73 -0
  264. package/dist/plugins/installer/types.d.ts +52 -0
  265. package/dist/plugins/installer/types.js +28 -0
  266. package/dist/plugins/installer/uninstall.d.ts +2 -0
  267. package/dist/plugins/installer/uninstall.js +18 -0
  268. package/dist/plugins/installer/unzip.d.ts +14 -0
  269. package/dist/plugins/installer/unzip.js +82 -0
  270. package/dist/plugins/installer/update.d.ts +28 -0
  271. package/dist/plugins/installer/update.js +97 -0
  272. package/dist/plugins/loadPluginHooks.d.ts +54 -1
  273. package/dist/plugins/loadPluginHooks.js +83 -1
  274. package/dist/plugins/marketplaceManager.d.ts +15 -1
  275. package/dist/plugins/marketplaceManager.js +58 -4
  276. package/dist/plugins/pluginCommandHook.js +34 -14
  277. package/dist/plugins/pluginContent.d.ts +30 -0
  278. package/dist/plugins/pluginContent.js +83 -0
  279. package/dist/plugins/pluginInstaller.d.ts +34 -0
  280. package/dist/plugins/pluginInstaller.js +168 -35
  281. package/dist/plugins/schemas.js +41 -6
  282. package/dist/plugins/types.d.ts +10 -0
  283. package/dist/preset/index.d.ts +7 -1
  284. package/dist/preset/index.js +112 -6
  285. package/dist/product/types.d.ts +1 -1
  286. package/dist/prompt/composer.d.ts +31 -0
  287. package/dist/prompt/composer.js +95 -25
  288. package/dist/prompt/instruction-scanner.js +5 -3
  289. package/dist/prompt/section-loader.js +1 -0
  290. package/dist/prompt/sections/base.md +1 -0
  291. package/dist/prompt/sections/browser.md +10 -0
  292. package/dist/prompt/sections/coding.md +4 -0
  293. package/dist/prompt/sections/orchestration.md +8 -0
  294. package/dist/protocol/chat-session-manager.d.ts +15 -2
  295. package/dist/protocol/chat-session-manager.js +46 -0
  296. package/dist/protocol/chat-session.d.ts +82 -0
  297. package/dist/protocol/chat-session.js +121 -1
  298. package/dist/protocol/client.d.ts +27 -0
  299. package/dist/protocol/client.js +38 -0
  300. package/dist/protocol/redact.d.ts +50 -0
  301. package/dist/protocol/redact.js +71 -0
  302. package/dist/protocol/server.d.ts +153 -2
  303. package/dist/protocol/server.js +807 -39
  304. package/dist/protocol/tcp-transport.d.ts +45 -0
  305. package/dist/protocol/tcp-transport.js +74 -0
  306. package/dist/protocol/transport.js +3 -2
  307. package/dist/protocol/types.d.ts +69 -0
  308. package/dist/protocol/types.js +22 -0
  309. package/dist/quota/credentials.d.ts +3 -0
  310. package/dist/quota/credentials.js +80 -0
  311. package/dist/quota/index.d.ts +36 -0
  312. package/dist/quota/index.js +155 -0
  313. package/dist/quota/types.d.ts +48 -0
  314. package/dist/quota/types.js +13 -0
  315. package/dist/remote/bridge.d.ts +11 -2
  316. package/dist/remote/bridge.js +61 -33
  317. package/dist/review/review-prompt.d.ts +28 -0
  318. package/dist/review/review-prompt.js +81 -0
  319. package/dist/run/ArtifactTracker.js +5 -4
  320. package/dist/run/EngineRunner.d.ts +27 -1
  321. package/dist/run/EngineRunner.js +46 -8
  322. package/dist/run/FileRunStore.js +40 -11
  323. package/dist/run/RunApprovalBackend.js +25 -5
  324. package/dist/run/RunLock.d.ts +28 -2
  325. package/dist/run/RunLock.js +49 -7
  326. package/dist/run/RunManager.d.ts +12 -0
  327. package/dist/run/RunManager.js +86 -3
  328. package/dist/run/RunQueue.d.ts +1 -0
  329. package/dist/run/RunQueue.js +8 -2
  330. package/dist/run/factory.d.ts +8 -1
  331. package/dist/run/factory.js +1 -0
  332. package/dist/run/index.d.ts +2 -2
  333. package/dist/run/index.js +1 -1
  334. package/dist/run/redirect-target.d.ts +7 -0
  335. package/dist/run/redirect-target.js +13 -0
  336. package/dist/run/types.js +1 -1
  337. package/dist/runtime/background-shell.d.ts +139 -0
  338. package/dist/runtime/background-shell.js +495 -0
  339. package/dist/runtime/output-clean.d.ts +24 -0
  340. package/dist/runtime/output-clean.js +41 -0
  341. package/dist/runtime/ring-file.d.ts +64 -0
  342. package/dist/runtime/ring-file.js +174 -0
  343. package/dist/runtime/safe-spawn.js +15 -34
  344. package/dist/runtime/spawn-common.d.ts +148 -0
  345. package/dist/runtime/spawn-common.js +303 -0
  346. package/dist/runtime/truncate-output.d.ts +22 -0
  347. package/dist/runtime/truncate-output.js +49 -0
  348. package/dist/runtime/utf8-cut.d.ts +11 -0
  349. package/dist/runtime/utf8-cut.js +23 -0
  350. package/dist/services/auto-dream.d.ts +4 -0
  351. package/dist/services/auto-dream.js +26 -26
  352. package/dist/services/browser-open.d.ts +13 -0
  353. package/dist/services/browser-open.js +16 -0
  354. package/dist/services/diagnostics.d.ts +1 -2
  355. package/dist/services/diagnostics.js +12 -7
  356. package/dist/services/dream-consolidation.d.ts +57 -0
  357. package/dist/services/dream-consolidation.js +151 -0
  358. package/dist/services/extract-memories.d.ts +14 -1
  359. package/dist/services/extract-memories.js +45 -6
  360. package/dist/services/memory-orchestrator.d.ts +21 -0
  361. package/dist/services/memory-orchestrator.js +125 -32
  362. package/dist/services/notifier.d.ts +8 -0
  363. package/dist/services/notifier.js +39 -25
  364. package/dist/services/oauth.js +5 -7
  365. package/dist/services/session-memory-sort.d.ts +8 -0
  366. package/dist/services/session-memory-sort.js +9 -0
  367. package/dist/services/session-memory.js +30 -19
  368. package/dist/session/file-history.d.ts +124 -1
  369. package/dist/session/file-history.js +232 -9
  370. package/dist/session/memory.d.ts +116 -2
  371. package/dist/session/memory.js +250 -28
  372. package/dist/session/session-manager.d.ts +63 -1
  373. package/dist/session/session-manager.js +186 -5
  374. package/dist/session/simple-diff.d.ts +23 -0
  375. package/dist/session/simple-diff.js +84 -0
  376. package/dist/session/transcript.d.ts +25 -1
  377. package/dist/session/transcript.js +35 -2
  378. package/dist/session/undo-target.d.ts +67 -0
  379. package/dist/session/undo-target.js +144 -0
  380. package/dist/settings/disk-defaults.d.ts +42 -0
  381. package/dist/settings/disk-defaults.js +33 -0
  382. package/dist/settings/feature-flags.d.ts +64 -0
  383. package/dist/settings/feature-flags.js +61 -0
  384. package/dist/settings/manager.d.ts +101 -1
  385. package/dist/settings/manager.js +345 -15
  386. package/dist/settings/migrate-config.d.ts +45 -0
  387. package/dist/settings/migrate-config.js +125 -0
  388. package/dist/settings/personalization.d.ts +19 -0
  389. package/dist/settings/personalization.js +7 -0
  390. package/dist/settings/schema-export.d.ts +25 -0
  391. package/dist/settings/schema-export.js +38 -0
  392. package/dist/settings/schema.d.ts +1827 -396
  393. package/dist/settings/schema.js +361 -81
  394. package/dist/skills/scanner.d.ts +9 -0
  395. package/dist/skills/scanner.js +30 -2
  396. package/dist/stt/resolve-transcribe.d.ts +31 -0
  397. package/dist/stt/resolve-transcribe.js +108 -0
  398. package/dist/stt/transcribe.d.ts +51 -0
  399. package/dist/stt/transcribe.js +65 -0
  400. package/dist/tool-system/browser-bridge.d.ts +226 -0
  401. package/dist/tool-system/browser-bridge.js +163 -0
  402. package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
  403. package/dist/tool-system/builtin/add-marketplace.js +76 -0
  404. package/dist/tool-system/builtin/agent-heartbeat.d.ts +49 -0
  405. package/dist/tool-system/builtin/agent-heartbeat.js +89 -0
  406. package/dist/tool-system/builtin/agent-notifications.d.ts +12 -3
  407. package/dist/tool-system/builtin/agent-notifications.js +9 -3
  408. package/dist/tool-system/builtin/agent-output-file.d.ts +38 -0
  409. package/dist/tool-system/builtin/agent-output-file.js +72 -0
  410. package/dist/tool-system/builtin/agent-registry.d.ts +23 -0
  411. package/dist/tool-system/builtin/agent-registry.js +16 -4
  412. package/dist/tool-system/builtin/agent.d.ts +50 -11
  413. package/dist/tool-system/builtin/agent.js +576 -73
  414. package/dist/tool-system/builtin/apply-patch/applier.js +66 -8
  415. package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +10 -0
  416. package/dist/tool-system/builtin/apply-patch/backup-targets.js +30 -0
  417. package/dist/tool-system/builtin/apply-patch/index.js +7 -3
  418. package/dist/tool-system/builtin/arena.js +6 -7
  419. package/dist/tool-system/builtin/background-jobs.d.ts +76 -0
  420. package/dist/tool-system/builtin/background-jobs.js +124 -0
  421. package/dist/tool-system/builtin/background-shell-tools.d.ts +20 -0
  422. package/dist/tool-system/builtin/background-shell-tools.js +108 -0
  423. package/dist/tool-system/builtin/background-work.d.ts +67 -0
  424. package/dist/tool-system/builtin/background-work.js +86 -0
  425. package/dist/tool-system/builtin/bash-output-style.d.ts +32 -0
  426. package/dist/tool-system/builtin/bash-output-style.js +40 -0
  427. package/dist/tool-system/builtin/bash.d.ts +5 -2
  428. package/dist/tool-system/builtin/bash.js +98 -62
  429. package/dist/tool-system/builtin/browser-tools.d.ts +33 -0
  430. package/dist/tool-system/builtin/browser-tools.js +312 -0
  431. package/dist/tool-system/builtin/cancel-goal.d.ts +31 -0
  432. package/dist/tool-system/builtin/cancel-goal.js +64 -0
  433. package/dist/tool-system/builtin/check-quota.d.ts +15 -0
  434. package/dist/tool-system/builtin/check-quota.js +34 -0
  435. package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
  436. package/dist/tool-system/builtin/complete-goal.js +45 -0
  437. package/dist/tool-system/builtin/config.js +7 -0
  438. package/dist/tool-system/builtin/cron.d.ts +7 -0
  439. package/dist/tool-system/builtin/cron.js +105 -9
  440. package/dist/tool-system/builtin/drive-claude-code.d.ts +30 -0
  441. package/dist/tool-system/builtin/drive-claude-code.js +157 -0
  442. package/dist/tool-system/builtin/edit-model-catalog.d.ts +3 -0
  443. package/dist/tool-system/builtin/edit-model-catalog.js +94 -0
  444. package/dist/tool-system/builtin/edit.d.ts +2 -1
  445. package/dist/tool-system/builtin/edit.js +21 -12
  446. package/dist/tool-system/builtin/eol.d.ts +29 -0
  447. package/dist/tool-system/builtin/eol.js +37 -0
  448. package/dist/tool-system/builtin/file-cache.d.ts +6 -0
  449. package/dist/tool-system/builtin/file-cache.js +8 -0
  450. package/dist/tool-system/builtin/generate-image.d.ts +60 -0
  451. package/dist/tool-system/builtin/generate-image.js +374 -0
  452. package/dist/tool-system/builtin/generate-video.d.ts +55 -0
  453. package/dist/tool-system/builtin/generate-video.js +361 -0
  454. package/dist/tool-system/builtin/grep.js +6 -2
  455. package/dist/tool-system/builtin/image-providers.d.ts +86 -0
  456. package/dist/tool-system/builtin/image-providers.js +190 -0
  457. package/dist/tool-system/builtin/image-uploader.d.ts +33 -0
  458. package/dist/tool-system/builtin/image-uploader.js +74 -0
  459. package/dist/tool-system/builtin/index.d.ts +24 -1
  460. package/dist/tool-system/builtin/index.js +310 -25
  461. package/dist/tool-system/builtin/mcp-tools.js +23 -3
  462. package/dist/tool-system/builtin/memory.js +45 -7
  463. package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
  464. package/dist/tool-system/builtin/notebook-edit.js +1 -1
  465. package/dist/tool-system/builtin/powershell.js +4 -1
  466. package/dist/tool-system/builtin/read.d.ts +2 -1
  467. package/dist/tool-system/builtin/read.js +11 -3
  468. package/dist/tool-system/builtin/repl.js +4 -1
  469. package/dist/tool-system/builtin/skill.js +9 -0
  470. package/dist/tool-system/builtin/sleep.js +12 -5
  471. package/dist/tool-system/builtin/task.js +4 -1
  472. package/dist/tool-system/builtin/tool-search.js +25 -7
  473. package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
  474. package/dist/tool-system/builtin/update-automation-memory.js +60 -0
  475. package/dist/tool-system/builtin/video-providers.d.ts +154 -0
  476. package/dist/tool-system/builtin/video-providers.js +235 -0
  477. package/dist/tool-system/builtin/view-image.d.ts +18 -0
  478. package/dist/tool-system/builtin/view-image.js +96 -0
  479. package/dist/tool-system/builtin/web-fetch.js +12 -2
  480. package/dist/tool-system/builtin/web-search.d.ts +4 -1
  481. package/dist/tool-system/builtin/web-search.js +57 -10
  482. package/dist/tool-system/builtin/worktree.d.ts +2 -1
  483. package/dist/tool-system/builtin/worktree.js +31 -4
  484. package/dist/tool-system/builtin/write.d.ts +2 -1
  485. package/dist/tool-system/builtin/write.js +1 -1
  486. package/dist/tool-system/context.d.ts +166 -6
  487. package/dist/tool-system/executor.d.ts +3 -2
  488. package/dist/tool-system/executor.js +197 -119
  489. package/dist/tool-system/investigation-guard.d.ts +4 -1
  490. package/dist/tool-system/investigation-guard.js +20 -4
  491. package/dist/tool-system/mcp-manager.d.ts +78 -16
  492. package/dist/tool-system/mcp-manager.js +357 -28
  493. package/dist/tool-system/path-policy.d.ts +99 -0
  494. package/dist/tool-system/path-policy.js +578 -0
  495. package/dist/tool-system/permission.d.ts +36 -1
  496. package/dist/tool-system/permission.js +322 -117
  497. package/dist/tool-system/plan-mode-allowlist.d.ts +32 -0
  498. package/dist/tool-system/plan-mode-allowlist.js +65 -0
  499. package/dist/tool-system/registry.d.ts +1 -0
  500. package/dist/tool-system/registry.js +26 -1
  501. package/dist/tool-system/sandbox/index.d.ts +8 -0
  502. package/dist/tool-system/sandbox/index.js +7 -2
  503. package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
  504. package/dist/tool-system/validate-tool-metadata.js +63 -0
  505. package/dist/tool-system/validation.d.ts +10 -0
  506. package/dist/tool-system/validation.js +16 -3
  507. package/dist/types.d.ts +301 -15
  508. package/dist/updater.js +20 -9
  509. package/dist/utils/envUtils.d.ts +0 -9
  510. package/dist/utils/envUtils.js +3 -28
  511. package/dist/utils/exec.d.ts +40 -0
  512. package/dist/utils/exec.js +144 -0
  513. package/dist/utils/format.js +4 -2
  514. package/dist/utils/json.d.ts +12 -0
  515. package/dist/utils/json.js +92 -0
  516. package/dist/utils/lockfile.js +9 -2
  517. package/dist/utils/theme.d.ts +7 -1
  518. package/dist/utils/theme.js +5 -3
  519. package/dist/utils/toolDisplay.js +0 -1
  520. package/package.json +14 -7
  521. package/dist/agent/coordinator.d.ts +0 -49
  522. package/dist/agent/coordinator.js +0 -77
  523. package/dist/settings/manager.test.js +0 -73
  524. package/dist/tool-system/builtin/remote-trigger.d.ts +0 -6
  525. package/dist/tool-system/builtin/remote-trigger.js +0 -54
  526. package/dist/tool-system/builtin/send-message.d.ts +0 -6
  527. package/dist/tool-system/builtin/send-message.js +0 -47
  528. /package/dist/{settings/manager.test.d.ts → credentials/types.js} +0 -0
@@ -0,0 +1,235 @@
1
+ /**
2
+ * VideoProvider — adapter interface for text-to-video generation (TODO 7.1).
3
+ *
4
+ * Unlike images (one request → bytes), video generation is asynchronous and
5
+ * long: SUBMIT a job → POLL its status until it finishes → DOWNLOAD the bytes.
6
+ * The interface captures exactly those three steps so the GenerateVideo tool's
7
+ * background polling loop is provider-agnostic, and concrete adapters
8
+ * (Seedance/Kling — filled in once their private API docs are available) only
9
+ * implement submit/poll/download.
10
+ *
11
+ * Credentials are resolved by the tool layer from settings; adapters are pure
12
+ * "creds + request → job lifecycle". `fetch` is injected for testability.
13
+ */
14
+ /**
15
+ * Deterministic in-memory adapter for tests and local dev — no network. Models
16
+ * the three-step lifecycle: submit mints a job; poll returns `running` for the
17
+ * first N calls then `succeeded` (or `failed` after M); download returns the
18
+ * configured bytes. Lets the GenerateVideo background loop be tested end-to-end
19
+ * before any real (Seedance/Kling) adapter exists.
20
+ */
21
+ export class FakeVideoProvider {
22
+ opts;
23
+ kind = "fake";
24
+ polls = new Map();
25
+ counter = 0;
26
+ constructor(opts = {}) {
27
+ this.opts = opts;
28
+ }
29
+ async submit(_req) {
30
+ this.counter += 1;
31
+ const jobId = `fakejob-${this.counter}`;
32
+ this.polls.set(jobId, 0);
33
+ return { ok: true, jobId };
34
+ }
35
+ async poll(req) {
36
+ const n = this.polls.get(req.jobId) ?? 0;
37
+ this.polls.set(req.jobId, n + 1);
38
+ if (this.opts.failAfterPolls !== undefined && n >= this.opts.failAfterPolls) {
39
+ return { ok: true, status: "failed", error: this.opts.failMessage ?? "job failed" };
40
+ }
41
+ if (this.opts.succeedAfterPolls !== undefined && n >= this.opts.succeedAfterPolls) {
42
+ return { ok: true, status: "succeeded" };
43
+ }
44
+ return { ok: true, status: "running" };
45
+ }
46
+ async download(_req) {
47
+ return { ok: true, bytes: Buffer.from(this.opts.bytes ?? "FAKE_VIDEO"), ext: "mp4" };
48
+ }
49
+ }
50
+ /**
51
+ * fal.ai video adapter — submit/poll/download against the fal queue API
52
+ * (https://queue.fal.run). model id selects the underlying model
53
+ * (e.g. fal-ai/kling-video/v3/pro/text-to-video). When `image` is present we
54
+ * switch a `...text-to-video` model to `...image-to-video` and send image_url,
55
+ * so callers only need to pass an image to get i2v.
56
+ *
57
+ * IMPORTANT: fal's status/result URLs use a model-FAMILY prefix
58
+ * (`fal-ai/kling-video/requests/<id>`), NOT the full submit path
59
+ * (`.../v3/pro/text-to-video/requests/<id>` → HTTP 405). So we never
60
+ * reconstruct those URLs; we encode the `status_url` + `response_url` that
61
+ * submit returns into the jobId (`<status_url>|<response_url>`) and use them
62
+ * verbatim in poll/download. Verified against the live API 2026-06-10.
63
+ */
64
+ export class FalVideoProvider {
65
+ fetchImpl;
66
+ kind = "fal";
67
+ constructor(fetchImpl = fetch) {
68
+ this.fetchImpl = fetchImpl;
69
+ }
70
+ /** Effective image list: images[] wins; else single image; else []. */
71
+ imageList(req) {
72
+ if (req.images && req.images.length)
73
+ return req.images;
74
+ if (req.image)
75
+ return [req.image];
76
+ return [];
77
+ }
78
+ /**
79
+ * Does this model family support reference-to-video (multi-image)? Verified
80
+ * 2026-06-10 against the live API: Seedance has it; Kling does NOT (routing a
81
+ * Kling model to `.../reference-to-video` 404s at result fetch). Keep this a
82
+ * conservative allowlist — only families confirmed to expose the endpoint.
83
+ */
84
+ supportsReference(model) {
85
+ return /seedance/i.test(model);
86
+ }
87
+ /** Route model suffix by image count: 0→text, 1→image, ≥2→reference. */
88
+ resolveModel(model, imageCount) {
89
+ const target = imageCount >= 2 ? "reference-to-video" : imageCount === 1 ? "image-to-video" : null;
90
+ if (target && /(text|image|reference)-to-video$/.test(model)) {
91
+ return model.replace(/(text|image|reference)-to-video$/, target);
92
+ }
93
+ return model;
94
+ }
95
+ /** jobId = `${statusUrl}|${responseUrl}` (fal returns both from submit). */
96
+ split(jobId) {
97
+ const idx = jobId.indexOf("|");
98
+ if (idx < 0)
99
+ return { statusUrl: jobId, responseUrl: jobId };
100
+ return { statusUrl: jobId.slice(0, idx), responseUrl: jobId.slice(idx + 1) };
101
+ }
102
+ async submit(req) {
103
+ const base = req.creds.baseUrl.replace(/\/+$/, "");
104
+ const imgs = this.imageList(req);
105
+ const vids = req.videos ?? [];
106
+ // Multi-image OR any reference video needs the reference-to-video endpoint,
107
+ // which only some families (Seedance) expose. Routing e.g. Kling there
108
+ // 404s at result fetch — fail fast with a clear message instead.
109
+ const needsReference = imgs.length >= 2 || vids.length > 0;
110
+ if (needsReference && !this.supportsReference(req.model)) {
111
+ return {
112
+ ok: false,
113
+ error: `model "${req.model}" does not support reference-to-video (multiple images or reference videos). Use a Seedance model, or pass a single image / no video.`,
114
+ };
115
+ }
116
+ // imageCount alone can't express "reference needed"; bump to 2 when a video
117
+ // forces the reference endpoint so resolveModel picks reference-to-video.
118
+ const refImageCount = needsReference ? Math.max(imgs.length, 2) : imgs.length;
119
+ const model = this.resolveModel(req.model, refImageCount);
120
+ const body = { prompt: req.prompt };
121
+ if (imgs.length >= 2)
122
+ body.image_urls = imgs;
123
+ else if (imgs.length === 1)
124
+ body.image_url = imgs[0];
125
+ if (vids.length > 0)
126
+ body.video_urls = vids;
127
+ try {
128
+ const r = await this.fetchImpl(`${base}/${model}`, {
129
+ method: "POST",
130
+ headers: { Authorization: `Key ${req.creds.apiKey}`, "Content-Type": "application/json" },
131
+ body: JSON.stringify(body),
132
+ signal: req.signal,
133
+ });
134
+ if (!r.ok) {
135
+ const t = await r.text().catch(() => "");
136
+ return { ok: false, error: `fal submit failed: HTTP ${r.status} ${t}`.trim() };
137
+ }
138
+ const j = (await r.json());
139
+ if (!j.request_id)
140
+ return { ok: false, error: "fal submit: no request_id in response" };
141
+ // Prefer the URLs fal hands back; fall back to family-prefix reconstruction
142
+ // only if they're absent (defensive — live API always returns them).
143
+ const statusUrl = j.status_url ?? "";
144
+ const responseUrl = j.response_url ?? "";
145
+ if (!statusUrl || !responseUrl) {
146
+ return { ok: false, error: "fal submit: missing status_url/response_url" };
147
+ }
148
+ return { ok: true, jobId: `${statusUrl}|${responseUrl}` };
149
+ }
150
+ catch (err) {
151
+ return { ok: false, error: `fal submit error: ${err.message}` };
152
+ }
153
+ }
154
+ async poll(req) {
155
+ const { statusUrl } = this.split(req.jobId);
156
+ try {
157
+ const r = await this.fetchImpl(statusUrl, {
158
+ method: "GET",
159
+ headers: { Authorization: `Key ${req.creds.apiKey}` },
160
+ signal: req.signal,
161
+ });
162
+ // fal returns 200/202 for valid in-progress/queued states; only treat a
163
+ // hard client/server error (4xx except 202, 5xx) as a transport failure.
164
+ if (!r.ok && r.status !== 202) {
165
+ const t = await r.text().catch(() => "");
166
+ return { ok: false, error: `fal status failed: HTTP ${r.status} ${t}`.trim() };
167
+ }
168
+ const j = (await r.json());
169
+ switch (j.status) {
170
+ case "IN_QUEUE":
171
+ case "IN_PROGRESS":
172
+ return { ok: true, status: "running" };
173
+ case "COMPLETED":
174
+ return { ok: true, status: "succeeded" };
175
+ default:
176
+ return { ok: true, status: "failed", error: `fal status: ${j.status ?? "unknown"}` };
177
+ }
178
+ }
179
+ catch (err) {
180
+ return { ok: false, error: `fal poll error: ${err.message}` };
181
+ }
182
+ }
183
+ async download(req) {
184
+ const { responseUrl } = this.split(req.jobId);
185
+ try {
186
+ // hop 1: result JSON
187
+ const r = await this.fetchImpl(responseUrl, {
188
+ method: "GET",
189
+ headers: { Authorization: `Key ${req.creds.apiKey}` },
190
+ signal: req.signal,
191
+ });
192
+ if (!r.ok) {
193
+ const t = await r.text().catch(() => "");
194
+ return { ok: false, error: `fal result failed: HTTP ${r.status} ${t}`.trim() };
195
+ }
196
+ const j = (await r.json());
197
+ const videoUrl = j.video?.url;
198
+ if (!videoUrl)
199
+ return { ok: false, error: "fal result: no video.url" };
200
+ // hop 2: video bytes
201
+ const vr = await this.fetchImpl(videoUrl, { method: "GET", signal: req.signal });
202
+ if (!vr.ok) {
203
+ return { ok: false, error: `fal video download failed: HTTP ${vr.status}` };
204
+ }
205
+ const buf = new Uint8Array(await vr.arrayBuffer());
206
+ const m = /\.([a-z0-9]{2,4})(?:\?|$)/i.exec(videoUrl);
207
+ const ext = m ? m[1].toLowerCase() : "mp4";
208
+ // Surface the fal-hosted URL so the model can reuse it for video extension
209
+ // (videos[] → video_urls) without re-uploading. Note: signed/expiring.
210
+ return { ok: true, bytes: buf, ext, url: videoUrl };
211
+ }
212
+ catch (err) {
213
+ return { ok: false, error: `fal download error: ${err.message}` };
214
+ }
215
+ }
216
+ }
217
+ /** Default model per video provider kind (filled in with real adapters). */
218
+ export const DEFAULT_VIDEO_MODEL = {
219
+ fal: "fal-ai/kling-video/v3/pro/text-to-video",
220
+ };
221
+ /**
222
+ * Registry of video-provider adapters, keyed by `kind`. Only `fake` exists
223
+ * today (test/dev). Real adapters (seedance, kling) are intentionally absent
224
+ * until their private API contracts are confirmed — see TODO 7.1 块3.
225
+ */
226
+ export function getVideoProvider(kind, fetchImpl = fetch) {
227
+ switch (kind) {
228
+ case "fake":
229
+ return new FakeVideoProvider({ succeedAfterPolls: 0 });
230
+ case "fal":
231
+ return new FalVideoProvider(fetchImpl);
232
+ default:
233
+ return null;
234
+ }
235
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Built-in view_image tool — 把一个本地图片文件以 base64 image ContentBlock
3
+ * 回传进上下文,让 vision 模型「看」它(对照 codex 的 view_image)。
4
+ *
5
+ * 典型用法:模型先写 SVG/Mermaid 并用 shell 转成 PNG,再调 view_image(png)
6
+ * 检查图画对没有(标签是否重叠、文字是否溢出),不对就改源再重转。
7
+ *
8
+ * 三道闸门,避免污染上下文 / 浪费 token:
9
+ * 1. vision gate —— 当前模型不支持视觉时不读文件,只回文字占位。
10
+ * 2. 格式 gate —— 只支持 png/jpeg/gif/webp(provider image 块能吃的);
11
+ * svg/pdf 等回文字提示「先转 PNG」。
12
+ * 3. 大小 gate —— 超过 MAX_BYTES 回文字提示,不读进 base64。
13
+ */
14
+ import type { ToolDefinition } from "../../types.js";
15
+ import type { ToolContext } from "../context.js";
16
+ import type { BuiltinToolResult } from "./index.js";
17
+ export declare const viewImageToolDef: ToolDefinition;
18
+ export declare function viewImageTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<BuiltinToolResult>;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Built-in view_image tool — 把一个本地图片文件以 base64 image ContentBlock
3
+ * 回传进上下文,让 vision 模型「看」它(对照 codex 的 view_image)。
4
+ *
5
+ * 典型用法:模型先写 SVG/Mermaid 并用 shell 转成 PNG,再调 view_image(png)
6
+ * 检查图画对没有(标签是否重叠、文字是否溢出),不对就改源再重转。
7
+ *
8
+ * 三道闸门,避免污染上下文 / 浪费 token:
9
+ * 1. vision gate —— 当前模型不支持视觉时不读文件,只回文字占位。
10
+ * 2. 格式 gate —— 只支持 png/jpeg/gif/webp(provider image 块能吃的);
11
+ * svg/pdf 等回文字提示「先转 PNG」。
12
+ * 3. 大小 gate —— 超过 MAX_BYTES 回文字提示,不读进 base64。
13
+ */
14
+ import { readFile, stat } from "node:fs/promises";
15
+ import { extname, isAbsolute, resolve } from "node:path";
16
+ import { capabilitiesFor } from "../../llm/capabilities/index.js";
17
+ const MAX_BYTES = 5 * 1024 * 1024; // 5MB —— vision 模型按 tile 计 token,大图无益且撑大请求
18
+ const MEDIA_TYPES = {
19
+ ".png": "image/png",
20
+ ".jpg": "image/jpeg",
21
+ ".jpeg": "image/jpeg",
22
+ ".gif": "image/gif",
23
+ ".webp": "image/webp",
24
+ };
25
+ export const viewImageToolDef = {
26
+ name: "view_image",
27
+ description: "Load a local image file into the conversation so you can SEE it (vision). " +
28
+ "Use after generating or rendering an image (e.g. SVG/Mermaid → PNG) to verify it " +
29
+ "looks right — check for overlapping labels, clipped text, wrong layout — then fix the " +
30
+ "source and re-render if needed. Supports PNG/JPEG/GIF/WebP only; convert SVG/PDF to PNG " +
31
+ "first. Requires a vision-capable model; otherwise the image is skipped.",
32
+ inputSchema: {
33
+ type: "object",
34
+ properties: {
35
+ path: {
36
+ type: "string",
37
+ description: "Path to the image file (absolute, or relative to the working directory).",
38
+ },
39
+ },
40
+ required: ["path"],
41
+ },
42
+ };
43
+ export async function viewImageTool(args, ctx) {
44
+ const rawPath = args.path;
45
+ if (typeof rawPath !== "string" || !rawPath.trim()) {
46
+ return "Error: path is required";
47
+ }
48
+ const cwd = ctx?.cwd ?? process.cwd();
49
+ const abs = isAbsolute(rawPath) ? rawPath : resolve(cwd, rawPath);
50
+ // 闸门 1:vision gate —— 不支持视觉就不读文件。
51
+ // 缺 llmConfig 时按「非视觉」处理(fail closed),对齐 DEFAULT_CAPABILITY
52
+ // 的保守姿态:运行时 ToolContext.llmConfig 必有,缺失只发生在测试 / 异常
53
+ // 装配下,此时绝不把 base64 读进上下文。
54
+ const supportsVision = (() => {
55
+ if (!ctx?.llmConfig)
56
+ return false;
57
+ const kind = (ctx.llmConfig.providerKind ?? ctx.llmConfig.provider);
58
+ return capabilitiesFor(kind, ctx.llmConfig.model).supportsVision;
59
+ })();
60
+ if (!supportsVision) {
61
+ return `[图片未加载: ${abs} —— 当前模型不支持视觉输入,已跳过。切换到 vision 模型后再 view_image。]`;
62
+ }
63
+ // 闸门 2:格式 gate
64
+ const ext = extname(abs).toLowerCase();
65
+ const mediaType = MEDIA_TYPES[ext];
66
+ if (!mediaType) {
67
+ return `[图片未加载: ${abs} —— 格式 ${ext || "(无扩展名)"} 不支持视觉预览,请先转成 PNG/JPEG。]`;
68
+ }
69
+ // 闸门 3:大小 gate(读 stat,不读全文件)
70
+ let size;
71
+ try {
72
+ size = (await stat(abs)).size;
73
+ }
74
+ catch (err) {
75
+ return `Error: 无法读取 ${abs}: ${err.message}`;
76
+ }
77
+ if (size > MAX_BYTES) {
78
+ const mb = (size / 1024 / 1024).toFixed(1);
79
+ return `[图片未加载: ${abs} —— 文件过大 (${mb} MB > 5 MB),请先压缩或缩放再 view_image。]`;
80
+ }
81
+ let buf;
82
+ try {
83
+ buf = await readFile(abs);
84
+ }
85
+ catch (err) {
86
+ return `Error: 无法读取 ${abs}: ${err.message}`;
87
+ }
88
+ const data = buf.toString("base64");
89
+ const kb = Math.round(buf.length / 1024);
90
+ return {
91
+ contentBlocks: [
92
+ { type: "image", source: { type: "base64", media_type: mediaType, data } },
93
+ ],
94
+ result: `[已加载图片: ${abs} (${mediaType}, ${kb} KB)]`,
95
+ };
96
+ }
@@ -176,7 +176,12 @@ export async function webFetchTool(args) {
176
176
  catch {
177
177
  return `Error: invalid URL "${url}"`;
178
178
  }
179
- const maxLength = Math.min(args.max_length || DEFAULT_MAX, MAX_OUTPUT);
179
+ // A non-positive max_length must NOT reach `text.slice(0, maxLength)` below
180
+ // with a negative end — JS reads that as "all but the last N", silently
181
+ // returning the WRONG bytes (+ a misleading "truncated" suffix). `|| DEFAULT`
182
+ // only caught 0/NaN, not negatives. Floor to the default page size first.
183
+ const rawMaxLength = args.max_length;
184
+ const maxLength = Math.min(typeof rawMaxLength === "number" && rawMaxLength > 0 ? rawMaxLength : DEFAULT_MAX, MAX_OUTPUT);
180
185
  const rawHeaders = args.headers ?? {};
181
186
  const baseHeaders = {
182
187
  "User-Agent": "Mozilla/5.0 (compatible; code-shell/0.1; +https://github.com/nicepkg/code-shell)",
@@ -192,7 +197,12 @@ export async function webFetchTool(args) {
192
197
  // host, and DNS-resolved IPs against the block lists. fetch() runs
193
198
  // with redirect: "manual" so the runtime cannot silently follow a
194
199
  // redirect into private/loopback/metadata space.
200
+ // Combine the 30s fetch timeout with the run's abort signal (registry injects
201
+ // __signal) so a user Stop cancels an in-flight fetch promptly, not only on
202
+ // the 30s timeout. Timeout alone was the previous behavior.
195
203
  const timeoutSignal = AbortSignal.timeout(30_000);
204
+ const userSignal = args.__signal;
205
+ const fetchSignal = userSignal ? AbortSignal.any([userSignal, timeoutSignal]) : timeoutSignal;
196
206
  let currentUrl = parsed;
197
207
  let currentHeaders = { ...baseHeaders };
198
208
  const originalOrigin = parsed;
@@ -206,7 +216,7 @@ export async function webFetchTool(args) {
206
216
  const res = await fetch(currentUrl, {
207
217
  headers: currentHeaders,
208
218
  redirect: "manual",
209
- signal: timeoutSignal,
219
+ signal: fetchSignal,
210
220
  });
211
221
  // Not a redirect: return body (or HTTP error).
212
222
  if (res.status < 300 || res.status >= 400 || !res.headers.get("location")) {
@@ -21,5 +21,8 @@ export interface ResolvedSearchConfig {
21
21
  * the user where the value came from when debugging.
22
22
  */
23
23
  export declare function resolveSearchConfig(cwd?: string): ResolvedSearchConfig;
24
+ export declare function isWebSearchAvailable(cwd?: string, nowMs?: number): boolean;
24
25
  export declare const webSearchToolDef: ToolDefinition;
25
- export declare function webSearchTool(args: Record<string, unknown>): Promise<string>;
26
+ export declare function webSearchTool(args: Record<string, unknown>, ctx?: {
27
+ cwd?: string;
28
+ }): Promise<string>;
@@ -18,7 +18,11 @@ export function resolveSearchConfig(cwd = process.cwd()) {
18
18
  let settingsKey;
19
19
  let settingsBaseUrl;
20
20
  try {
21
- const merged = new SettingsManager(cwd).get();
21
+ // scope "full" so the USER-level ~/.code-shell/settings.json is read, not
22
+ // just ${cwd}/.code-shell — the search key is typically a personal/global
23
+ // credential. Default "project" scope would miss it (the "No search provider
24
+ // configured" bug, esp. for automation runs rooted at the app dir).
25
+ const merged = new SettingsManager(cwd, "full").get();
22
26
  const search = merged.search ?? {};
23
27
  const p = search.provider;
24
28
  if (p === "serper" || p === "tavily" || p === "searxng")
@@ -68,6 +72,33 @@ export function resolveSearchConfig(cwd = process.cwd()) {
68
72
  return { provider: "searxng", baseUrl: envSearxng, source: "env" };
69
73
  return { provider: "serper", source: "none" };
70
74
  }
75
+ /**
76
+ * Tool-visibility guard: WebSearch is only useful when a search provider is
77
+ * configured. Mirrors the runtime check in the tool itself (source === "none"
78
+ * means no provider).
79
+ *
80
+ * Cached per-cwd with a short TTL: this runs on EVERY message's toolDefs
81
+ * assembly (engine.ts), and resolveSearchConfig reads + parses settings from
82
+ * disk each call. The 1s TTL collapses back-to-back reads while still picking
83
+ * up a newly-configured provider before the user's next message. The execution
84
+ * path (resolveSearchConfig) is intentionally NOT cached — only this boolean.
85
+ */
86
+ const availCache = new Map();
87
+ const AVAIL_TTL_MS = 1000;
88
+ export function isWebSearchAvailable(cwd = process.cwd(), nowMs = Date.now()) {
89
+ const hit = availCache.get(cwd);
90
+ if (hit && nowMs - hit.at < AVAIL_TTL_MS)
91
+ return hit.value;
92
+ let value = false;
93
+ try {
94
+ value = resolveSearchConfig(cwd).source !== "none";
95
+ }
96
+ catch {
97
+ value = false; // unresolved config → treat as unavailable
98
+ }
99
+ availCache.set(cwd, { at: nowMs, value });
100
+ return value;
101
+ }
71
102
  export const webSearchToolDef = {
72
103
  name: "WebSearch",
73
104
  description: "Search the web for information. Returns a list of search results with titles, URLs, and snippets. " +
@@ -84,25 +115,38 @@ export const webSearchToolDef = {
84
115
  required: ["query"],
85
116
  },
86
117
  };
87
- export async function webSearchTool(args) {
118
+ export async function webSearchTool(args, ctx) {
88
119
  const query = args.query;
89
120
  if (!query)
90
121
  return "Error: query is required";
91
- const numResults = Math.min(args.num_results || 10, 20);
92
- const config = resolveSearchConfig();
122
+ // Floor to default on non-positive: a negative num_results would reach
123
+ // `results.slice(0, num)` with a negative end (= all but the last N), silently
124
+ // returning the wrong result set. `|| 10` only caught 0/NaN, not negatives.
125
+ const rawNum = args.num_results;
126
+ const numResults = Math.min(typeof rawNum === "number" && rawNum > 0 ? rawNum : 10, 20);
127
+ // Use the run's cwd (e.g. an automation job's project dir) so per-project
128
+ // settings resolve correctly; falls back to process.cwd() when absent.
129
+ const config = resolveSearchConfig(ctx?.cwd);
93
130
  if (config.source === "none") {
94
131
  return "Error: No search provider configured. Open desktop 设置 → 连接 to add credentials, or set SERPER_API_KEY / TAVILY_API_KEY / SEARXNG_URL.";
95
132
  }
133
+ // A search provider's fetch had NO timeout and NO abort wiring — a hung/slow
134
+ // provider blocked the tool indefinitely and a user Stop couldn't cancel it.
135
+ // Give every provider call a 20s timeout, combined with the run's abort
136
+ // signal (registry injects __signal) so Stop is prompt.
137
+ const userSignal = args.__signal;
138
+ const timeoutSignal = AbortSignal.timeout(20_000);
139
+ const signal = userSignal ? AbortSignal.any([userSignal, timeoutSignal]) : timeoutSignal;
96
140
  try {
97
141
  let results;
98
142
  if (config.provider === "serper" && config.apiKey) {
99
- results = await searchSerper(query, numResults, config.apiKey);
143
+ results = await searchSerper(query, numResults, config.apiKey, signal);
100
144
  }
101
145
  else if (config.provider === "tavily" && config.apiKey) {
102
- results = await searchTavily(query, numResults, config.apiKey);
146
+ results = await searchTavily(query, numResults, config.apiKey, signal);
103
147
  }
104
148
  else if (config.provider === "searxng" && config.baseUrl) {
105
- results = await searchSearXNG(query, numResults, config.baseUrl);
149
+ results = await searchSearXNG(query, numResults, config.baseUrl, signal);
106
150
  }
107
151
  else {
108
152
  return `Error: provider "${config.provider}" missing ${config.provider === "searxng" ? "base URL" : "API key"}`;
@@ -117,7 +161,7 @@ export async function webSearchTool(args) {
117
161
  return `Search error: ${err.message}`;
118
162
  }
119
163
  }
120
- async function searchSerper(query, num, apiKey) {
164
+ async function searchSerper(query, num, apiKey, signal) {
121
165
  const res = await fetch("https://google.serper.dev/search", {
122
166
  method: "POST",
123
167
  headers: {
@@ -125,6 +169,7 @@ async function searchSerper(query, num, apiKey) {
125
169
  "Content-Type": "application/json",
126
170
  },
127
171
  body: JSON.stringify({ q: query, num }),
172
+ signal,
128
173
  });
129
174
  if (!res.ok)
130
175
  throw new Error(`Serper API error: ${res.status} ${res.statusText}`);
@@ -135,7 +180,7 @@ async function searchSerper(query, num, apiKey) {
135
180
  snippet: item.snippet ?? "",
136
181
  }));
137
182
  }
138
- async function searchTavily(query, num, apiKey) {
183
+ async function searchTavily(query, num, apiKey, signal) {
139
184
  const res = await fetch("https://api.tavily.com/search", {
140
185
  method: "POST",
141
186
  headers: { "Content-Type": "application/json" },
@@ -145,6 +190,7 @@ async function searchTavily(query, num, apiKey) {
145
190
  max_results: num,
146
191
  include_answer: false,
147
192
  }),
193
+ signal,
148
194
  });
149
195
  if (!res.ok)
150
196
  throw new Error(`Tavily API error: ${res.status} ${res.statusText}`);
@@ -155,13 +201,14 @@ async function searchTavily(query, num, apiKey) {
155
201
  snippet: item.content ?? "",
156
202
  }));
157
203
  }
158
- async function searchSearXNG(query, num, baseUrl) {
204
+ async function searchSearXNG(query, num, baseUrl, signal) {
159
205
  const url = new URL("/search", baseUrl);
160
206
  url.searchParams.set("q", query);
161
207
  url.searchParams.set("format", "json");
162
208
  url.searchParams.set("pageno", "1");
163
209
  const res = await fetch(url.toString(), {
164
210
  headers: { Accept: "application/json" },
211
+ signal,
165
212
  });
166
213
  if (!res.ok)
167
214
  throw new Error(`SearXNG error: ${res.status} ${res.statusText}`);
@@ -2,9 +2,10 @@
2
2
  * EnterWorktree / ExitWorktree tools — create and manage isolated git worktrees.
3
3
  */
4
4
  import type { ToolDefinition } from "../../types.js";
5
+ import type { ToolContext } from "../context.js";
5
6
  import { type WorktreeSession } from "../../git/worktree.js";
6
7
  export declare function getActiveWorktree(): WorktreeSession | undefined;
7
8
  export declare const enterWorktreeToolDef: ToolDefinition;
8
- export declare function enterWorktreeTool(args: Record<string, unknown>): Promise<string>;
9
+ export declare function enterWorktreeTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
9
10
  export declare const exitWorktreeToolDef: ToolDefinition;
10
11
  export declare function exitWorktreeTool(args: Record<string, unknown>): Promise<string>;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * EnterWorktree / ExitWorktree tools — create and manage isolated git worktrees.
3
3
  */
4
- import { createWorktree, removeWorktree, validateWorktreeSlug, } from "../../git/worktree.js";
4
+ import { createWorktree, removeWorktree, validateWorktreeSlug, selectPlatformScript, runWorktreeSetup, } from "../../git/worktree.js";
5
5
  // Global worktree state
6
6
  let _activeWorktree;
7
7
  export function getActiveWorktree() {
@@ -25,7 +25,7 @@ export const enterWorktreeToolDef = {
25
25
  required: ["slug"],
26
26
  },
27
27
  };
28
- export async function enterWorktreeTool(args) {
28
+ export async function enterWorktreeTool(args, ctx) {
29
29
  const slug = args.slug;
30
30
  if (!slug)
31
31
  return "Error: slug is required";
@@ -41,18 +41,45 @@ export async function enterWorktreeTool(args) {
41
41
  try {
42
42
  // Use a placeholder session ID (the agent should set this properly)
43
43
  const sessionId = args.__sessionId ?? `wt-${Date.now()}`;
44
- const cwd = args.__cwd ?? process.cwd();
44
+ const cwd = args.__cwd ?? ctx?.cwd ?? process.cwd();
45
45
  _activeWorktree = createWorktree(cwd, slug, sessionId);
46
+ // Run the project's localEnvironment.setupScripts once in the new
47
+ // worktree root (Beta decision 2026-06-08: setup belongs to the worktree
48
+ // lifecycle, not the conversation). Failure warns-but-continues — a broken
49
+ // setup script must not strand the agent outside a worktree it just made.
50
+ let setupNote = "";
51
+ const setupScripts = ctx?.engine?.readWorktreeSetupScripts(cwd);
52
+ const script = selectPlatformScript(setupScripts);
53
+ if (script) {
54
+ const setup = await runWorktreeSetup(_activeWorktree.worktreePath, script, {
55
+ sandbox: ctx?.sandbox,
56
+ shellEnv: ctx?.shellEnv,
57
+ signal: ctx?.signal,
58
+ });
59
+ if (setup.ok) {
60
+ setupNote = `\n\nRan setup script (exit 0).${setup.output ? `\n${truncate(setup.output)}` : ""}`;
61
+ }
62
+ else {
63
+ setupNote =
64
+ `\n\n⚠️ Setup script failed (exit ${setup.exitCode ?? "?"}) — continuing anyway. ` +
65
+ `You may need to run setup manually.${setup.output ? `\n${truncate(setup.output)}` : ""}`;
66
+ }
67
+ }
46
68
  return (`Worktree created:\n` +
47
69
  ` Path: ${_activeWorktree.worktreePath}\n` +
48
70
  ` Branch: ${_activeWorktree.worktreeBranch}\n` +
49
71
  ` From: ${_activeWorktree.originalBranch ?? "HEAD"}\n\n` +
50
- `You are now working in an isolated copy. Changes here won't affect the main repo.`);
72
+ `You are now working in an isolated copy. Changes here won't affect the main repo.` +
73
+ setupNote);
51
74
  }
52
75
  catch (err) {
53
76
  return `Error creating worktree: ${err.message}`;
54
77
  }
55
78
  }
79
+ /** Keep setup output from bloating the tool result — head+tail-ish trim. */
80
+ function truncate(s, max = 2000) {
81
+ return s.length <= max ? s : `${s.slice(0, max)}\n…(${s.length - max} more chars)`;
82
+ }
56
83
  export const exitWorktreeToolDef = {
57
84
  name: "ExitWorktree",
58
85
  description: "Exit the current worktree and return to the main working directory. " +
@@ -2,5 +2,6 @@
2
2
  * Built-in Write file tool.
3
3
  */
4
4
  import type { ToolDefinition } from "../../types.js";
5
+ import type { ToolContext } from "../context.js";
5
6
  export declare const writeToolDef: ToolDefinition;
6
- export declare function writeTool(args: Record<string, unknown>): Promise<string>;
7
+ export declare function writeTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
@@ -17,7 +17,7 @@ export const writeToolDef = {
17
17
  required: ["file_path", "content"],
18
18
  },
19
19
  };
20
- export async function writeTool(args) {
20
+ export async function writeTool(args, ctx) {
21
21
  const filePath = args.file_path;
22
22
  const content = args.content;
23
23
  if (!filePath)