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

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 (396) hide show
  1. package/README.md +13 -10
  2. package/dist/agent/agent-definition-registry.d.ts +3 -0
  3. package/dist/agent/agent-definition-registry.js +3 -1
  4. package/dist/agent/agent-definition.d.ts +15 -0
  5. package/dist/agent/agent-definition.js +27 -3
  6. package/dist/arena/context/context-tools.js +47 -4
  7. package/dist/arena/ledger.js +9 -1
  8. package/dist/arena/strategies/utils.d.ts +1 -4
  9. package/dist/arena/strategies/utils.js +7 -84
  10. package/dist/automation/cron-expr.d.ts +10 -0
  11. package/dist/automation/cron-expr.js +23 -5
  12. package/dist/automation/runner.d.ts +21 -4
  13. package/dist/automation/runner.js +48 -12
  14. package/dist/automation/scheduler.d.ts +38 -0
  15. package/dist/automation/scheduler.js +89 -12
  16. package/dist/automation/store.js +5 -2
  17. package/dist/capability-control/disabled-lists.d.ts +25 -0
  18. package/dist/capability-control/disabled-lists.js +57 -0
  19. package/dist/capability-control/overlay.d.ts +15 -0
  20. package/dist/capability-control/overlay.js +27 -0
  21. package/dist/cc-orchestrator/agent-adapter.d.ts +50 -0
  22. package/dist/cc-orchestrator/agent-adapter.js +133 -0
  23. package/dist/cc-orchestrator/cc-capability.d.ts +19 -0
  24. package/dist/cc-orchestrator/cc-capability.js +53 -0
  25. package/dist/cc-orchestrator/codex-session-discovery.d.ts +24 -0
  26. package/dist/cc-orchestrator/codex-session-discovery.js +191 -0
  27. package/dist/cc-orchestrator/codex-session-history.d.ts +25 -0
  28. package/dist/cc-orchestrator/codex-session-history.js +187 -0
  29. package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
  30. package/dist/cc-orchestrator/external-agent-changes.js +214 -0
  31. package/dist/cc-orchestrator/external-agent-driver.d.ts +18 -0
  32. package/dist/cc-orchestrator/external-agent-driver.js +69 -0
  33. package/dist/cc-orchestrator/index.d.ts +8 -0
  34. package/dist/cc-orchestrator/index.js +8 -0
  35. package/dist/cc-orchestrator/relevance-judge.d.ts +15 -0
  36. package/dist/cc-orchestrator/relevance-judge.js +29 -0
  37. package/dist/cc-orchestrator/session-discovery.d.ts +46 -0
  38. package/dist/cc-orchestrator/session-discovery.js +125 -0
  39. package/dist/cc-orchestrator/session-history.d.ts +19 -0
  40. package/dist/cc-orchestrator/session-history.js +67 -0
  41. package/dist/cli/agent-server-stdio.d.ts +15 -1
  42. package/dist/cli/agent-server-stdio.js +115 -17
  43. package/dist/cli/agent-server-tcp.js +40 -26
  44. package/dist/context/compaction.d.ts +86 -0
  45. package/dist/context/compaction.js +279 -0
  46. package/dist/context/manager.d.ts +18 -0
  47. package/dist/context/manager.js +181 -48
  48. package/dist/context/token-counter.js +13 -0
  49. package/dist/cost-tracker.js +5 -61
  50. package/dist/credentials/cipher.d.ts +49 -0
  51. package/dist/credentials/cipher.js +45 -0
  52. package/dist/credentials/cookie-jar.d.ts +24 -0
  53. package/dist/credentials/cookie-jar.js +40 -0
  54. package/dist/credentials/index.d.ts +7 -0
  55. package/dist/credentials/index.js +5 -0
  56. package/dist/credentials/inject-credential-tool.d.ts +20 -0
  57. package/dist/credentials/inject-credential-tool.js +130 -0
  58. package/dist/credentials/store.d.ts +72 -0
  59. package/dist/credentials/store.js +184 -0
  60. package/dist/credentials/types.d.ts +56 -0
  61. package/dist/credentials/use-credential-tool.d.ts +29 -0
  62. package/dist/credentials/use-credential-tool.js +205 -0
  63. package/dist/credentials/use-gate.d.ts +56 -0
  64. package/dist/credentials/use-gate.js +52 -0
  65. package/dist/data/model-metadata.d.ts +77 -0
  66. package/dist/data/model-metadata.js +56 -0
  67. package/dist/data/model-metadata.json +216 -0
  68. package/dist/data/openrouter-models.d.ts +18 -7
  69. package/dist/data/openrouter-models.js +35 -8
  70. package/dist/engine/aux-key.d.ts +10 -0
  71. package/dist/engine/aux-key.js +11 -0
  72. package/dist/engine/dynamic-tool-defs.d.ts +19 -0
  73. package/dist/engine/dynamic-tool-defs.js +36 -0
  74. package/dist/engine/engine.d.ts +280 -141
  75. package/dist/engine/engine.js +1193 -245
  76. package/dist/engine/friendly-error.d.ts +18 -0
  77. package/dist/engine/friendly-error.js +63 -0
  78. package/dist/engine/goal.d.ts +145 -0
  79. package/dist/engine/goal.js +144 -0
  80. package/dist/engine/image-policy.d.ts +13 -0
  81. package/dist/engine/image-policy.js +24 -0
  82. package/dist/engine/model-connections-pool.d.ts +17 -0
  83. package/dist/engine/model-connections-pool.js +67 -0
  84. package/dist/engine/model-facade.d.ts +10 -0
  85. package/dist/engine/model-facade.js +15 -0
  86. package/dist/engine/patch-orphaned-tools.js +3 -0
  87. package/dist/engine/query.js +2 -0
  88. package/dist/engine/resolve-llm-config.d.ts +16 -0
  89. package/dist/engine/resolve-llm-config.js +44 -0
  90. package/dist/engine/runtime.d.ts +2 -0
  91. package/dist/engine/runtime.js +27 -1
  92. package/dist/engine/sandbox-cache-key.d.ts +10 -0
  93. package/dist/engine/sandbox-cache-key.js +9 -0
  94. package/dist/engine/sandbox-config.d.ts +31 -0
  95. package/dist/engine/sandbox-config.js +38 -0
  96. package/dist/engine/session-usage.d.ts +31 -0
  97. package/dist/engine/session-usage.js +81 -0
  98. package/dist/engine/steer-queue.d.ts +33 -0
  99. package/dist/engine/steer-queue.js +26 -0
  100. package/dist/engine/streaming-tool-queue.d.ts +12 -0
  101. package/dist/engine/streaming-tool-queue.js +50 -10
  102. package/dist/engine/turn-loop.d.ts +94 -4
  103. package/dist/engine/turn-loop.js +432 -54
  104. package/dist/engine/types.d.ts +175 -0
  105. package/dist/engine/types.js +13 -0
  106. package/dist/external-agents/config.d.ts +2 -0
  107. package/dist/external-agents/config.js +15 -0
  108. package/dist/external-agents/types.d.ts +31 -0
  109. package/dist/external-agents/types.js +1 -0
  110. package/dist/git/utils.d.ts +12 -0
  111. package/dist/git/utils.js +38 -6
  112. package/dist/git/worktree.d.ts +48 -0
  113. package/dist/git/worktree.js +86 -10
  114. package/dist/hooks/goal-stop-hook.d.ts +28 -0
  115. package/dist/hooks/goal-stop-hook.js +186 -9
  116. package/dist/hooks/registry.d.ts +8 -0
  117. package/dist/hooks/registry.js +19 -0
  118. package/dist/hooks/shell-runner.js +10 -21
  119. package/dist/index.d.ts +51 -7
  120. package/dist/index.js +62 -5
  121. package/dist/llm/capabilities/param-specs.d.ts +14 -0
  122. package/dist/llm/capabilities/param-specs.js +62 -0
  123. package/dist/llm/capabilities/rules.js +5 -1
  124. package/dist/llm/capabilities/types.d.ts +10 -0
  125. package/dist/llm/client-base.d.ts +28 -1
  126. package/dist/llm/client-base.js +119 -13
  127. package/dist/llm/model-cache.js +4 -2
  128. package/dist/llm/model-pool.d.ts +21 -0
  129. package/dist/llm/model-pool.js +21 -1
  130. package/dist/llm/provider-auth.d.ts +41 -0
  131. package/dist/llm/provider-auth.js +76 -0
  132. package/dist/llm/provider-catalog.d.ts +4 -0
  133. package/dist/llm/providers/anthropic.js +64 -14
  134. package/dist/llm/providers/openai.d.ts +36 -0
  135. package/dist/llm/providers/openai.js +257 -51
  136. package/dist/llm/reasoning-setting.d.ts +3 -3
  137. package/dist/llm/reasoning-setting.js +9 -1
  138. package/dist/llm/stream-watchdog.js +5 -1
  139. package/dist/llm/token-counter.js +9 -2
  140. package/dist/llm/types.d.ts +4 -0
  141. package/dist/logging/sanitize-messages.js +22 -0
  142. package/dist/lsp/manager.d.ts +1 -1
  143. package/dist/lsp/manager.js +40 -10
  144. package/dist/model-catalog/builtin.d.ts +12 -0
  145. package/dist/model-catalog/builtin.js +412 -0
  146. package/dist/model-catalog/gen-connections.d.ts +20 -0
  147. package/dist/model-catalog/gen-connections.js +28 -0
  148. package/dist/model-catalog/index.d.ts +41 -0
  149. package/dist/model-catalog/index.js +90 -0
  150. package/dist/model-catalog/params.d.ts +20 -0
  151. package/dist/model-catalog/params.js +45 -0
  152. package/dist/model-catalog/resolve.d.ts +48 -0
  153. package/dist/model-catalog/resolve.js +33 -0
  154. package/dist/model-catalog/save-entry.d.ts +32 -0
  155. package/dist/model-catalog/save-entry.js +104 -0
  156. package/dist/model-catalog/types.d.ts +561 -0
  157. package/dist/model-catalog/types.js +93 -0
  158. package/dist/model-catalog/upsert.d.ts +9 -0
  159. package/dist/model-catalog/upsert.js +8 -0
  160. package/dist/onboarding.d.ts +12 -82
  161. package/dist/onboarding.js +61 -326
  162. package/dist/plugins/gitOps.d.ts +19 -0
  163. package/dist/plugins/gitOps.js +73 -4
  164. package/dist/plugins/installer/checkUpdate.d.ts +16 -0
  165. package/dist/plugins/installer/checkUpdate.js +32 -0
  166. package/dist/plugins/installer/codex/convertCommands.d.ts +19 -0
  167. package/dist/plugins/installer/codex/convertCommands.js +46 -0
  168. package/dist/plugins/installer/codex/convertMcp.d.ts +5 -2
  169. package/dist/plugins/installer/codex/convertMcp.js +45 -5
  170. package/dist/plugins/installer/install.js +25 -1
  171. package/dist/plugins/installer/installFromArchive.d.ts +43 -0
  172. package/dist/plugins/installer/installFromArchive.js +134 -0
  173. package/dist/plugins/installer/installFromSource.js +8 -2
  174. package/dist/plugins/installer/loadPluginAgents.js +6 -2
  175. package/dist/plugins/installer/loadPluginMcp.d.ts +9 -2
  176. package/dist/plugins/installer/loadPluginMcp.js +35 -2
  177. package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
  178. package/dist/plugins/installer/pruneDisabled.js +73 -0
  179. package/dist/plugins/installer/types.d.ts +5 -2
  180. package/dist/plugins/installer/types.js +1 -0
  181. package/dist/plugins/installer/uninstall.js +4 -0
  182. package/dist/plugins/installer/unzip.d.ts +14 -0
  183. package/dist/plugins/installer/unzip.js +82 -0
  184. package/dist/plugins/installer/update.d.ts +14 -0
  185. package/dist/plugins/installer/update.js +53 -21
  186. package/dist/plugins/loadPluginHooks.d.ts +47 -1
  187. package/dist/plugins/loadPluginHooks.js +73 -1
  188. package/dist/plugins/marketplaceManager.d.ts +7 -0
  189. package/dist/plugins/marketplaceManager.js +20 -0
  190. package/dist/plugins/pluginCommandHook.js +4 -18
  191. package/dist/plugins/pluginContent.d.ts +30 -0
  192. package/dist/plugins/pluginContent.js +83 -0
  193. package/dist/plugins/pluginInstaller.d.ts +13 -0
  194. package/dist/plugins/pluginInstaller.js +42 -8
  195. package/dist/plugins/schemas.js +1 -0
  196. package/dist/plugins/types.d.ts +6 -0
  197. package/dist/preset/index.d.ts +11 -1
  198. package/dist/preset/index.js +115 -6
  199. package/dist/product/types.d.ts +1 -1
  200. package/dist/prompt/composer.d.ts +32 -0
  201. package/dist/prompt/composer.js +75 -21
  202. package/dist/prompt/instruction-scanner.js +5 -3
  203. package/dist/prompt/section-loader.js +1 -0
  204. package/dist/prompt/sections/base.md +2 -0
  205. package/dist/prompt/sections/browser.md +10 -0
  206. package/dist/prompt/sections/coding.md +4 -0
  207. package/dist/protocol/chat-session-manager.d.ts +9 -2
  208. package/dist/protocol/chat-session-manager.js +38 -0
  209. package/dist/protocol/chat-session.d.ts +69 -1
  210. package/dist/protocol/chat-session.js +102 -4
  211. package/dist/protocol/client.d.ts +31 -0
  212. package/dist/protocol/client.js +44 -0
  213. package/dist/protocol/server.d.ts +120 -7
  214. package/dist/protocol/server.js +753 -51
  215. package/dist/protocol/transport.js +3 -2
  216. package/dist/protocol/types.d.ts +60 -0
  217. package/dist/protocol/types.js +16 -0
  218. package/dist/quota/credentials.d.ts +3 -0
  219. package/dist/quota/credentials.js +80 -0
  220. package/dist/quota/index.d.ts +36 -0
  221. package/dist/quota/index.js +155 -0
  222. package/dist/quota/types.d.ts +48 -0
  223. package/dist/quota/types.js +13 -0
  224. package/dist/review/review-prompt.d.ts +28 -0
  225. package/dist/review/review-prompt.js +81 -0
  226. package/dist/run/FileRunStore.js +8 -3
  227. package/dist/run/RunApprovalBackend.js +25 -5
  228. package/dist/run/RunManager.d.ts +12 -0
  229. package/dist/run/RunManager.js +35 -0
  230. package/dist/run/factory.d.ts +1 -1
  231. package/dist/runtime/background-shell.d.ts +139 -0
  232. package/dist/runtime/background-shell.js +509 -0
  233. package/dist/runtime/output-clean.d.ts +24 -0
  234. package/dist/runtime/output-clean.js +41 -0
  235. package/dist/runtime/ring-file.d.ts +64 -0
  236. package/dist/runtime/ring-file.js +174 -0
  237. package/dist/runtime/safe-spawn.js +98 -39
  238. package/dist/runtime/spawn-common.d.ts +159 -0
  239. package/dist/runtime/spawn-common.js +404 -0
  240. package/dist/runtime/truncate-output.d.ts +22 -0
  241. package/dist/runtime/truncate-output.js +49 -0
  242. package/dist/runtime/utf8-cut.d.ts +11 -0
  243. package/dist/runtime/utf8-cut.js +23 -0
  244. package/dist/services/auto-dream.d.ts +4 -0
  245. package/dist/services/auto-dream.js +26 -26
  246. package/dist/services/diagnostics.d.ts +1 -2
  247. package/dist/services/diagnostics.js +12 -7
  248. package/dist/services/extract-memories.d.ts +14 -1
  249. package/dist/services/extract-memories.js +45 -6
  250. package/dist/services/memory-orchestrator.d.ts +21 -0
  251. package/dist/services/memory-orchestrator.js +125 -50
  252. package/dist/services/session-memory.js +24 -12
  253. package/dist/session/file-history.d.ts +124 -1
  254. package/dist/session/file-history.js +222 -6
  255. package/dist/session/memory.d.ts +116 -2
  256. package/dist/session/memory.js +250 -28
  257. package/dist/session/session-manager.d.ts +40 -0
  258. package/dist/session/session-manager.js +119 -3
  259. package/dist/session/simple-diff.d.ts +23 -0
  260. package/dist/session/simple-diff.js +84 -0
  261. package/dist/session/transcript.d.ts +29 -1
  262. package/dist/session/transcript.js +56 -2
  263. package/dist/session/undo-target.d.ts +67 -0
  264. package/dist/session/undo-target.js +144 -0
  265. package/dist/settings/disk-defaults.d.ts +9 -2
  266. package/dist/settings/disk-defaults.js +11 -2
  267. package/dist/settings/feature-flags.d.ts +64 -0
  268. package/dist/settings/feature-flags.js +61 -0
  269. package/dist/settings/manager.d.ts +68 -1
  270. package/dist/settings/manager.js +266 -29
  271. package/dist/settings/migrate-config.d.ts +45 -0
  272. package/dist/settings/migrate-config.js +125 -0
  273. package/dist/settings/schema-export.d.ts +25 -0
  274. package/dist/settings/schema-export.js +38 -0
  275. package/dist/settings/schema.d.ts +1186 -771
  276. package/dist/settings/schema.js +268 -97
  277. package/dist/skills/scanner.d.ts +9 -0
  278. package/dist/skills/scanner.js +30 -2
  279. package/dist/stt/resolve-transcribe.d.ts +31 -0
  280. package/dist/stt/resolve-transcribe.js +108 -0
  281. package/dist/stt/transcribe.d.ts +51 -0
  282. package/dist/stt/transcribe.js +65 -0
  283. package/dist/tool-system/browser-bridge.d.ts +226 -0
  284. package/dist/tool-system/browser-bridge.js +163 -0
  285. package/dist/tool-system/builtin/agent-heartbeat.d.ts +49 -0
  286. package/dist/tool-system/builtin/agent-heartbeat.js +89 -0
  287. package/dist/tool-system/builtin/agent-notifications.d.ts +12 -3
  288. package/dist/tool-system/builtin/agent-notifications.js +9 -3
  289. package/dist/tool-system/builtin/agent-output-file.d.ts +38 -0
  290. package/dist/tool-system/builtin/agent-output-file.js +72 -0
  291. package/dist/tool-system/builtin/agent-registry.d.ts +12 -0
  292. package/dist/tool-system/builtin/agent-registry.js +8 -0
  293. package/dist/tool-system/builtin/agent.d.ts +21 -1
  294. package/dist/tool-system/builtin/agent.js +489 -42
  295. package/dist/tool-system/builtin/apply-patch/applier.js +66 -8
  296. package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +10 -0
  297. package/dist/tool-system/builtin/apply-patch/backup-targets.js +30 -0
  298. package/dist/tool-system/builtin/apply-patch/index.js +0 -15
  299. package/dist/tool-system/builtin/background-jobs.d.ts +76 -0
  300. package/dist/tool-system/builtin/background-jobs.js +124 -0
  301. package/dist/tool-system/builtin/background-shell-tools.d.ts +20 -0
  302. package/dist/tool-system/builtin/background-shell-tools.js +108 -0
  303. package/dist/tool-system/builtin/background-work.d.ts +67 -0
  304. package/dist/tool-system/builtin/background-work.js +86 -0
  305. package/dist/tool-system/builtin/bash-output-style.d.ts +32 -0
  306. package/dist/tool-system/builtin/bash-output-style.js +40 -0
  307. package/dist/tool-system/builtin/bash.d.ts +5 -2
  308. package/dist/tool-system/builtin/bash.js +101 -64
  309. package/dist/tool-system/builtin/browser-tools.d.ts +33 -0
  310. package/dist/tool-system/builtin/browser-tools.js +312 -0
  311. package/dist/tool-system/builtin/cancel-goal.d.ts +31 -0
  312. package/dist/tool-system/builtin/cancel-goal.js +64 -0
  313. package/dist/tool-system/builtin/check-quota.d.ts +15 -0
  314. package/dist/tool-system/builtin/check-quota.js +34 -0
  315. package/dist/tool-system/builtin/config.js +7 -0
  316. package/dist/tool-system/builtin/cron.d.ts +7 -0
  317. package/dist/tool-system/builtin/cron.js +64 -4
  318. package/dist/tool-system/builtin/drive-claude-code.d.ts +30 -0
  319. package/dist/tool-system/builtin/drive-claude-code.js +157 -0
  320. package/dist/tool-system/builtin/edit-model-catalog.d.ts +3 -0
  321. package/dist/tool-system/builtin/edit-model-catalog.js +104 -0
  322. package/dist/tool-system/builtin/edit.js +20 -16
  323. package/dist/tool-system/builtin/eol.d.ts +29 -0
  324. package/dist/tool-system/builtin/eol.js +37 -0
  325. package/dist/tool-system/builtin/file-cache.d.ts +6 -0
  326. package/dist/tool-system/builtin/file-cache.js +8 -0
  327. package/dist/tool-system/builtin/generate-image.d.ts +35 -0
  328. package/dist/tool-system/builtin/generate-image.js +278 -50
  329. package/dist/tool-system/builtin/generate-video.d.ts +55 -0
  330. package/dist/tool-system/builtin/generate-video.js +364 -0
  331. package/dist/tool-system/builtin/glob.js +0 -7
  332. package/dist/tool-system/builtin/grep.d.ts +9 -0
  333. package/dist/tool-system/builtin/grep.js +106 -11
  334. package/dist/tool-system/builtin/image-providers.d.ts +86 -0
  335. package/dist/tool-system/builtin/image-providers.js +190 -0
  336. package/dist/tool-system/builtin/image-uploader.d.ts +33 -0
  337. package/dist/tool-system/builtin/image-uploader.js +74 -0
  338. package/dist/tool-system/builtin/index.d.ts +10 -2
  339. package/dist/tool-system/builtin/index.js +251 -27
  340. package/dist/tool-system/builtin/mcp-tools.js +23 -3
  341. package/dist/tool-system/builtin/memory.js +45 -7
  342. package/dist/tool-system/builtin/notebook-edit.js +0 -7
  343. package/dist/tool-system/builtin/powershell.js +8 -2
  344. package/dist/tool-system/builtin/read.js +10 -10
  345. package/dist/tool-system/builtin/repl.js +4 -1
  346. package/dist/tool-system/builtin/skill.js +9 -0
  347. package/dist/tool-system/builtin/sleep.js +8 -2
  348. package/dist/tool-system/builtin/tool-search.js +25 -7
  349. package/dist/tool-system/builtin/video-providers.d.ts +154 -0
  350. package/dist/tool-system/builtin/video-providers.js +235 -0
  351. package/dist/tool-system/builtin/web-fetch.js +12 -2
  352. package/dist/tool-system/builtin/web-search.js +21 -7
  353. package/dist/tool-system/builtin/worktree.d.ts +2 -1
  354. package/dist/tool-system/builtin/worktree.js +31 -4
  355. package/dist/tool-system/builtin/write.js +0 -6
  356. package/dist/tool-system/context.d.ts +164 -6
  357. package/dist/tool-system/executor.d.ts +3 -1
  358. package/dist/tool-system/executor.js +197 -90
  359. package/dist/tool-system/investigation-guard.js +1 -1
  360. package/dist/tool-system/mcp-manager.d.ts +42 -4
  361. package/dist/tool-system/mcp-manager.js +203 -20
  362. package/dist/tool-system/mcp-stdio-diagnostics.d.ts +9 -0
  363. package/dist/tool-system/mcp-stdio-diagnostics.js +93 -0
  364. package/dist/tool-system/path-policy.d.ts +5 -0
  365. package/dist/tool-system/path-policy.js +307 -8
  366. package/dist/tool-system/permission.d.ts +39 -2
  367. package/dist/tool-system/permission.js +283 -70
  368. package/dist/tool-system/plan-mode-allowlist.d.ts +13 -2
  369. package/dist/tool-system/plan-mode-allowlist.js +24 -2
  370. package/dist/tool-system/registry.d.ts +1 -0
  371. package/dist/tool-system/registry.js +16 -2
  372. package/dist/tool-system/sandbox/index.d.ts +8 -0
  373. package/dist/tool-system/sandbox/index.js +7 -2
  374. package/dist/tool-system/sandbox/off.js +7 -1
  375. package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
  376. package/dist/tool-system/validate-tool-metadata.js +63 -0
  377. package/dist/types.d.ts +252 -7
  378. package/dist/updater.js +20 -9
  379. package/dist/utils/envUtils.d.ts +0 -9
  380. package/dist/utils/envUtils.js +3 -28
  381. package/dist/utils/exec.d.ts +48 -0
  382. package/dist/utils/exec.js +154 -0
  383. package/dist/utils/json.d.ts +12 -0
  384. package/dist/utils/json.js +92 -0
  385. package/dist/utils/theme.d.ts +1 -1
  386. package/dist/utils/theme.js +1 -1
  387. package/dist/utils/toolDisplay.js +0 -1
  388. package/package.json +13 -7
  389. package/dist/agent/coordinator.d.ts +0 -49
  390. package/dist/agent/coordinator.js +0 -77
  391. package/dist/settings/manager.test.js +0 -73
  392. package/dist/tool-system/builtin/remote-trigger.d.ts +0 -6
  393. package/dist/tool-system/builtin/remote-trigger.js +0 -54
  394. package/dist/tool-system/builtin/send-message.d.ts +0 -6
  395. package/dist/tool-system/builtin/send-message.js +0 -47
  396. /package/dist/{settings/manager.test.d.ts → credentials/types.js} +0 -0
@@ -10,9 +10,10 @@
10
10
  // Algorithm uses code adapted from codex-rs/apply-patch/src/lib.rs (Apache-2.0)
11
11
  // for the chunk-replacement phase (compute_replacements, apply_replacements).
12
12
  import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
13
- import { existsSync } from "node:fs";
14
- import { dirname, isAbsolute, resolve } from "node:path";
13
+ import { existsSync, realpathSync } from "node:fs";
14
+ import { dirname, isAbsolute, resolve, sep } from "node:path";
15
15
  import { seekSequence } from "./seek-sequence.js";
16
+ import { detectEol, toLf, applyEol } from "../eol.js";
16
17
  /**
17
18
  * Plan and commit the patch atomically.
18
19
  *
@@ -76,8 +77,15 @@ async function planHunks(hunks, cwd) {
76
77
  if (!stats) {
77
78
  throw new Error(`Failed to update file: ${sourcePath} does not exist`);
78
79
  }
79
- const originalText = await readFile(sourcePath, "utf-8");
80
- const newText = applyChunksToText(originalText, hunk.chunks, sourcePath);
80
+ const originalRaw = await readFile(sourcePath, "utf-8");
81
+ // CRLF handling: patch context lines are LF (the model emits LF). Match in
82
+ // LF space, then write back in the file's original EOL so a CRLF file isn't
83
+ // silently converted to LF (which would diff the whole file). originalText
84
+ // (LF) is what we compare; originalRaw is preserved for rollback so a
85
+ // restore writes back the exact bytes. See eol.ts.
86
+ const eol = detectEol(originalRaw);
87
+ const originalText = toLf(originalRaw);
88
+ const newText = applyEol(applyChunksToText(originalText, hunk.chunks, sourcePath), eol);
81
89
  if (hunk.movePath !== undefined) {
82
90
  const destPath = resolveAgainst(hunk.movePath, cwd);
83
91
  if (destPath === sourcePath) {
@@ -85,7 +93,7 @@ async function planHunks(hunks, cwd) {
85
93
  schedule(sourcePath, {
86
94
  path: sourcePath,
87
95
  newContent: newText,
88
- originalContent: originalText,
96
+ originalContent: originalRaw,
89
97
  });
90
98
  }
91
99
  else {
@@ -93,7 +101,7 @@ async function planHunks(hunks, cwd) {
93
101
  schedule(sourcePath, {
94
102
  path: sourcePath,
95
103
  newContent: null,
96
- originalContent: originalText,
104
+ originalContent: originalRaw,
97
105
  });
98
106
  schedule(destPath, {
99
107
  path: destPath,
@@ -107,7 +115,7 @@ async function planHunks(hunks, cwd) {
107
115
  schedule(sourcePath, {
108
116
  path: sourcePath,
109
117
  newContent: newText,
110
- originalContent: originalText,
118
+ originalContent: originalRaw,
111
119
  });
112
120
  set.modified.push(original);
113
121
  }
@@ -229,8 +237,58 @@ async function writeChange(change) {
229
237
  await writeFile(change.path, change.newContent, "utf-8");
230
238
  }
231
239
  // ─── helpers ──────────────────────────────────────────────────────
240
+ /**
241
+ * Resolve a patch-relative (or absolute) path against cwd, then HARD-ENFORCE
242
+ * that the result stays inside cwd.
243
+ *
244
+ * This is the applier's own containment guard, independent of the executor-level
245
+ * pathPolicy. apply-patch is reachable with the path gate bypassed (e.g.
246
+ * bypassPermissions, or a direct call), so the last line of defense lives here.
247
+ *
248
+ * Containment is checked against the REAL paths: we realpath cwd and walk the
249
+ * target up to its nearest existing ancestor and realpath that. This defeats a
250
+ * symlink planted inside cwd that points outside — a plain string `resolve()`
251
+ * would look contained while the write follows the link out.
252
+ */
232
253
  function resolveAgainst(p, cwd) {
233
- return isAbsolute(p) ? p : resolve(cwd, p);
254
+ const resolved = isAbsolute(p) ? p : resolve(cwd, p);
255
+ const realCwd = nearestRealPath(cwd);
256
+ const realTarget = nearestRealPath(resolved);
257
+ if (!isInside(realTarget, realCwd)) {
258
+ throw new Error(`Refusing to apply patch outside the working directory: "${p}" resolves to "${realTarget}", which escapes "${realCwd}".`);
259
+ }
260
+ return resolved;
261
+ }
262
+ /**
263
+ * Realpath the nearest existing ancestor of `abs`, then re-attach the
264
+ * not-yet-existing trailing segments. Mirrors path-policy.safeRealpath so
265
+ * symlinked ancestors are resolved even when the leaf doesn't exist yet.
266
+ */
267
+ function nearestRealPath(abs) {
268
+ let candidate = abs;
269
+ const segments = [];
270
+ for (let i = 0; i < 64; i++) {
271
+ try {
272
+ const real = realpathSync(candidate);
273
+ if (segments.length === 0)
274
+ return real;
275
+ return resolve(real, ...segments.reverse());
276
+ }
277
+ catch {
278
+ const parent = dirname(candidate);
279
+ if (parent === candidate)
280
+ return abs;
281
+ segments.push(candidate.slice(parent.length + (parent.endsWith(sep) ? 0 : 1)));
282
+ candidate = parent;
283
+ }
284
+ }
285
+ return abs;
286
+ }
287
+ function isInside(child, parent) {
288
+ if (child === parent)
289
+ return true;
290
+ const p = parent.endsWith(sep) ? parent : parent + sep;
291
+ return child.startsWith(p);
234
292
  }
235
293
  async function safeStat(path) {
236
294
  try {
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Which files an ApplyPatch would modify-in-place or delete — i.e. the files
3
+ * that already exist and therefore have pre-patch content worth snapshotting
4
+ * for /undo. Pure (parse-only, no fs): given the patch text and the cwd to
5
+ * resolve relative paths against, return absolute target paths.
6
+ *
7
+ * "add" hunks are excluded: a newly-created file has no prior content to back
8
+ * up (undo of an add = delete, handled separately if/when /undo grows that).
9
+ */
10
+ export declare function patchBackupTargets(patchText: string, cwd: string): string[];
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Which files an ApplyPatch would modify-in-place or delete — i.e. the files
3
+ * that already exist and therefore have pre-patch content worth snapshotting
4
+ * for /undo. Pure (parse-only, no fs): given the patch text and the cwd to
5
+ * resolve relative paths against, return absolute target paths.
6
+ *
7
+ * "add" hunks are excluded: a newly-created file has no prior content to back
8
+ * up (undo of an add = delete, handled separately if/when /undo grows that).
9
+ */
10
+ import { resolve as resolvePath } from "node:path";
11
+ import { parsePatch } from "./parser.js";
12
+ export function patchBackupTargets(patchText, cwd) {
13
+ let parsed;
14
+ try {
15
+ parsed = parsePatch(patchText, "lenient");
16
+ }
17
+ catch {
18
+ // Unparseable patch → nothing to back up; the tool itself will reject it.
19
+ return [];
20
+ }
21
+ const out = [];
22
+ for (const hunk of parsed.hunks) {
23
+ if (hunk.kind === "update" || hunk.kind === "delete") {
24
+ out.push(resolvePath(cwd, hunk.path));
25
+ }
26
+ }
27
+ // De-dupe while preserving order (a patch shouldn't target one file twice,
28
+ // but be defensive — saveSnapshot is idempotent on identical content anyway).
29
+ return [...new Set(out)];
30
+ }
@@ -17,7 +17,6 @@
17
17
  import { fileCache } from "../file-cache.js";
18
18
  import { applyPatch } from "./applier.js";
19
19
  import { parsePatch } from "./parser.js";
20
- import { enforcePathPolicy } from "../../path-policy.js";
21
20
  import { resolve as resolvePath } from "node:path";
22
21
  export const applyPatchToolDef = {
23
22
  name: "ApplyPatch",
@@ -70,20 +69,6 @@ export async function applyPatchTool(args, ctx) {
70
69
  // A4: resolve relative patch paths against the Engine's cwd, not the
71
70
  // host process cwd. See standard §S5.
72
71
  const cwd = ctx?.cwd ?? process.cwd();
73
- // Path-policy gate every target before any IO. A multi-file patch is
74
- // atomic — if *any* target is blocked the whole patch must reject so we
75
- // don't end up writing some files and refusing others.
76
- for (const hunk of parsed.hunks) {
77
- const targets = [resolvePath(cwd, hunk.path)];
78
- if (hunk.kind === "update" && hunk.movePath) {
79
- targets.push(resolvePath(cwd, hunk.movePath));
80
- }
81
- for (const t of targets) {
82
- const blocked = enforcePathPolicy(t, "write", cwd);
83
- if (blocked)
84
- return blocked;
85
- }
86
- }
87
72
  let result;
88
73
  try {
89
74
  result = await applyPatch(parsed.hunks, { cwd });
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Registry of NON-agent background jobs (GenerateVideo poll loops, DriveAgent
3
+ * external CLI runs). Mirrors the role `asyncAgentRegistry` plays for background
4
+ * sub-agents, but a job is not an agent — it has no transcript, no abort(), and
5
+ * must NOT show up in AgentStatus.
6
+ *
7
+ * The engine's wait-for-background loop parks the turn until a session has no
8
+ * more RUNNING jobs, so the goal-stop-hook doesn't force the model to busy-loop
9
+ * with `sleep` while a video renders (the s-mqe0ox7n-a8d11c26 bug).
10
+ *
11
+ * Finished jobs are RETAINED (status flips to completed/failed, result stored)
12
+ * so the background panel can show them + let the user open the result — they
13
+ * don't vanish the instant they complete (#2/#5). Retention is bounded:
14
+ * - event-driven: a session's jobs are dropped when the session is deleted
15
+ * (dropForSession, wired to session close/delete);
16
+ * - a generous per-session cap on TERMINAL jobs is a pure memory backstop for
17
+ * a session that spawns hundreds of jobs and is never deleted.
18
+ *
19
+ * Process-local singleton, same pattern as asyncAgentRegistry. The video/Drive
20
+ * loops run in the main engine process, so start/finish and the engine's wait
21
+ * loop observe the same instance.
22
+ */
23
+ type Listener = () => void;
24
+ export type BackgroundJobStatus = "running" | "completed" | "failed";
25
+ /** A background job, running or finished. */
26
+ export interface BackgroundJobEntry {
27
+ jobId: string;
28
+ sessionId: string;
29
+ /** Human description (e.g. "Generating video: <prompt>"). Shown to the goal
30
+ * judge (running) and in the background panel (all). */
31
+ description: string;
32
+ status: BackgroundJobStatus;
33
+ startedAt: number;
34
+ /** Set when status flips to a terminal state. */
35
+ finishedAt?: number;
36
+ /** Result summary (video URL, DriveAgent final text) or error message. */
37
+ finalText?: string;
38
+ /** External CLI session id, when the job is a DriveAgent run — lets the host
39
+ * read that CLI's transcript to attribute file changes (#6). */
40
+ ccSessionId?: string;
41
+ /** Files the external agent changed (parsed from its transcript, #6). */
42
+ changedFiles?: string[];
43
+ }
44
+ /** Outcome passed to finish() to record how a job ended. */
45
+ export interface BackgroundJobOutcome {
46
+ status?: "completed" | "failed";
47
+ finalText?: string;
48
+ ccSessionId?: string;
49
+ changedFiles?: string[];
50
+ }
51
+ declare class BackgroundJobRegistry {
52
+ private jobs;
53
+ private listeners;
54
+ /** Register a running job. Invalid sessionId is ignored (cannot be waited on). */
55
+ start(jobId: string, sessionId: string, description?: string): void;
56
+ /** Mark a job terminal (retained, not deleted). Unknown id is a no-op (no
57
+ * notify) so a double-finish or a finish after reset stays quiet. */
58
+ finish(jobId: string, outcome?: BackgroundJobOutcome): void;
59
+ /** True while any RUNNING job spawned by `sessionId` remains. */
60
+ hasRunningForSession(sessionId: string): boolean;
61
+ /** Running jobs spawned by `sessionId`. Feeds the goal judge's task list. */
62
+ listRunningForSession(sessionId: string): BackgroundJobEntry[];
63
+ /** All jobs (running + retained terminal) for `sessionId`. Feeds the panel. */
64
+ listForSession(sessionId: string): BackgroundJobEntry[];
65
+ /** Drop every job of a session — called when the session is deleted/closed. */
66
+ dropForSession(sessionId: string): void;
67
+ subscribe: (cb: Listener) => (() => void);
68
+ /** Test helper: drop all tracked jobs. */
69
+ reset(): void;
70
+ /** Backstop: keep at most MAX_TERMINAL_JOBS_PER_SESSION terminal jobs per
71
+ * session, evicting the oldest (insertion order). Running jobs never evicted. */
72
+ private evictTerminalOverCap;
73
+ private notify;
74
+ }
75
+ export declare const backgroundJobRegistry: BackgroundJobRegistry;
76
+ export {};
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Registry of NON-agent background jobs (GenerateVideo poll loops, DriveAgent
3
+ * external CLI runs). Mirrors the role `asyncAgentRegistry` plays for background
4
+ * sub-agents, but a job is not an agent — it has no transcript, no abort(), and
5
+ * must NOT show up in AgentStatus.
6
+ *
7
+ * The engine's wait-for-background loop parks the turn until a session has no
8
+ * more RUNNING jobs, so the goal-stop-hook doesn't force the model to busy-loop
9
+ * with `sleep` while a video renders (the s-mqe0ox7n-a8d11c26 bug).
10
+ *
11
+ * Finished jobs are RETAINED (status flips to completed/failed, result stored)
12
+ * so the background panel can show them + let the user open the result — they
13
+ * don't vanish the instant they complete (#2/#5). Retention is bounded:
14
+ * - event-driven: a session's jobs are dropped when the session is deleted
15
+ * (dropForSession, wired to session close/delete);
16
+ * - a generous per-session cap on TERMINAL jobs is a pure memory backstop for
17
+ * a session that spawns hundreds of jobs and is never deleted.
18
+ *
19
+ * Process-local singleton, same pattern as asyncAgentRegistry. The video/Drive
20
+ * loops run in the main engine process, so start/finish and the engine's wait
21
+ * loop observe the same instance.
22
+ */
23
+ function isValidSessionId(sid) {
24
+ return typeof sid === "string" && sid.length > 0;
25
+ }
26
+ /** Generous per-session cap on retained terminal jobs — a leak backstop, not a
27
+ * UX limit; a human never spawns this many background jobs in one session. */
28
+ const MAX_TERMINAL_JOBS_PER_SESSION = 50;
29
+ class BackgroundJobRegistry {
30
+ jobs = new Map(); // jobId -> entry (insertion-ordered)
31
+ listeners = new Set();
32
+ /** Register a running job. Invalid sessionId is ignored (cannot be waited on). */
33
+ start(jobId, sessionId, description = "") {
34
+ if (!isValidSessionId(sessionId))
35
+ return;
36
+ this.jobs.set(jobId, {
37
+ jobId,
38
+ sessionId,
39
+ description,
40
+ status: "running",
41
+ startedAt: Date.now(),
42
+ });
43
+ this.notify();
44
+ }
45
+ /** Mark a job terminal (retained, not deleted). Unknown id is a no-op (no
46
+ * notify) so a double-finish or a finish after reset stays quiet. */
47
+ finish(jobId, outcome) {
48
+ const entry = this.jobs.get(jobId);
49
+ if (!entry)
50
+ return;
51
+ entry.status = outcome?.status ?? "completed";
52
+ entry.finishedAt = Date.now();
53
+ if (outcome?.finalText !== undefined)
54
+ entry.finalText = outcome.finalText;
55
+ if (outcome?.ccSessionId !== undefined)
56
+ entry.ccSessionId = outcome.ccSessionId;
57
+ if (outcome?.changedFiles !== undefined)
58
+ entry.changedFiles = outcome.changedFiles;
59
+ this.evictTerminalOverCap(entry.sessionId);
60
+ this.notify();
61
+ }
62
+ /** True while any RUNNING job spawned by `sessionId` remains. */
63
+ hasRunningForSession(sessionId) {
64
+ for (const e of this.jobs.values()) {
65
+ if (e.sessionId === sessionId && e.status === "running")
66
+ return true;
67
+ }
68
+ return false;
69
+ }
70
+ /** Running jobs spawned by `sessionId`. Feeds the goal judge's task list. */
71
+ listRunningForSession(sessionId) {
72
+ return [...this.jobs.values()].filter((e) => e.sessionId === sessionId && e.status === "running");
73
+ }
74
+ /** All jobs (running + retained terminal) for `sessionId`. Feeds the panel. */
75
+ listForSession(sessionId) {
76
+ return [...this.jobs.values()].filter((e) => e.sessionId === sessionId);
77
+ }
78
+ /** Drop every job of a session — called when the session is deleted/closed. */
79
+ dropForSession(sessionId) {
80
+ let removed = false;
81
+ for (const [id, e] of this.jobs) {
82
+ if (e.sessionId === sessionId) {
83
+ this.jobs.delete(id);
84
+ removed = true;
85
+ }
86
+ }
87
+ if (removed)
88
+ this.notify();
89
+ }
90
+ subscribe = (cb) => {
91
+ this.listeners.add(cb);
92
+ return () => {
93
+ this.listeners.delete(cb);
94
+ };
95
+ };
96
+ /** Test helper: drop all tracked jobs. */
97
+ reset() {
98
+ this.jobs.clear();
99
+ }
100
+ /** Backstop: keep at most MAX_TERMINAL_JOBS_PER_SESSION terminal jobs per
101
+ * session, evicting the oldest (insertion order). Running jobs never evicted. */
102
+ evictTerminalOverCap(sessionId) {
103
+ const terminal = [...this.jobs.values()].filter((e) => e.sessionId === sessionId && e.status !== "running");
104
+ const over = terminal.length - MAX_TERMINAL_JOBS_PER_SESSION;
105
+ if (over <= 0)
106
+ return;
107
+ // Map iteration is insertion order → the first `over` terminal entries are
108
+ // the oldest.
109
+ for (let i = 0; i < over; i++) {
110
+ this.jobs.delete(terminal[i].jobId);
111
+ }
112
+ }
113
+ notify() {
114
+ for (const cb of this.listeners) {
115
+ try {
116
+ cb();
117
+ }
118
+ catch {
119
+ // isolate per-listener errors
120
+ }
121
+ }
122
+ }
123
+ }
124
+ export const backgroundJobRegistry = new BackgroundJobRegistry();
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Background-shell tools — BashOutput / KillShell / ListShells.
3
+ *
4
+ * Companions to `Bash(run_in_background=true)` (design §5.2–5.4). They
5
+ * operate on the {@link BackgroundShellManager} (threaded via
6
+ * `ctx.backgroundShells`, falling back to the process-local singleton).
7
+ *
8
+ * All three are session-scoped: a shell started in session A is invisible
9
+ * and unreachable from session B (the manager enforces this; we pass
10
+ * `ctx.sessionId` so cross-session ids report a plain "unknown shell_id"
11
+ * rather than leaking another session's processes).
12
+ */
13
+ import type { ToolContext } from "../context.js";
14
+ import type { ToolDefinition } from "../../types.js";
15
+ export declare const bashOutputToolDef: ToolDefinition;
16
+ export declare function bashOutputTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
17
+ export declare const killShellToolDef: ToolDefinition;
18
+ export declare function killShellTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
19
+ export declare const listShellsToolDef: ToolDefinition;
20
+ export declare function listShellsTool(_args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Background-shell tools — BashOutput / KillShell / ListShells.
3
+ *
4
+ * Companions to `Bash(run_in_background=true)` (design §5.2–5.4). They
5
+ * operate on the {@link BackgroundShellManager} (threaded via
6
+ * `ctx.backgroundShells`, falling back to the process-local singleton).
7
+ *
8
+ * All three are session-scoped: a shell started in session A is invisible
9
+ * and unreachable from session B (the manager enforces this; we pass
10
+ * `ctx.sessionId` so cross-session ids report a plain "unknown shell_id"
11
+ * rather than leaking another session's processes).
12
+ */
13
+ import { backgroundShellManager } from "../../runtime/background-shell.js";
14
+ function managerFor(ctx) {
15
+ return ctx?.backgroundShells ?? backgroundShellManager;
16
+ }
17
+ // ─── BashOutput ──────────────────────────────────────────────────────
18
+ export const bashOutputToolDef = {
19
+ name: "BashOutput",
20
+ description: "Read output from a background shell started via Bash(run_in_background=true). " +
21
+ "Returns new output since your last read (incremental by default). ANSI colors and progress bars are stripped. " +
22
+ "Use this only for an on-demand peek at a STILL-RUNNING process — you do NOT need to poll it to wait for " +
23
+ "completion: when the background command finishes you are automatically woken with the result, so end your " +
24
+ "turn instead of looping Sleep + BashOutput.",
25
+ inputSchema: {
26
+ type: "object",
27
+ properties: {
28
+ shell_id: {
29
+ type: "string",
30
+ description: "The shell_id returned by Bash(run_in_background=true).",
31
+ },
32
+ mode: {
33
+ type: "string",
34
+ enum: ["incremental", "all"],
35
+ description: "incremental (default): output since your last read. all: the full retained buffer.",
36
+ },
37
+ },
38
+ required: ["shell_id"],
39
+ },
40
+ };
41
+ export async function bashOutputTool(args, ctx) {
42
+ const shellId = args.shell_id;
43
+ if (!shellId)
44
+ return "Error: shell_id is required";
45
+ const mode = args.mode === "all" ? "all" : "incremental";
46
+ const res = managerFor(ctx).readOutput(shellId, mode, ctx?.sessionId);
47
+ if (!res.ok)
48
+ return `Error: ${res.error}`;
49
+ const body = res.text.length > 0 ? res.text : "(no new output)";
50
+ return `${res.header}\n${body}`;
51
+ }
52
+ // ─── KillShell ───────────────────────────────────────────────────────
53
+ export const killShellToolDef = {
54
+ name: "KillShell",
55
+ description: "Terminate a background shell (and its whole process group) started via Bash(run_in_background=true).",
56
+ inputSchema: {
57
+ type: "object",
58
+ properties: {
59
+ shell_id: { type: "string", description: "The shell_id to terminate." },
60
+ },
61
+ required: ["shell_id"],
62
+ },
63
+ };
64
+ export async function killShellTool(args, ctx) {
65
+ const shellId = args.shell_id;
66
+ if (!shellId)
67
+ return "Error: shell_id is required";
68
+ const res = await managerFor(ctx).kill(shellId, ctx?.sessionId);
69
+ if (!res.ok)
70
+ return `Error: ${res.error}`;
71
+ if (res.alreadyExited) {
72
+ return `Background shell ${shellId} had already exited (status=${res.status}).`;
73
+ }
74
+ return `Background shell ${shellId} terminated (status=${res.status}).`;
75
+ }
76
+ // ─── ListShells ──────────────────────────────────────────────────────
77
+ export const listShellsToolDef = {
78
+ name: "ListShells",
79
+ description: "List background shells for the current session, with status and detected port.",
80
+ inputSchema: { type: "object", properties: {} },
81
+ };
82
+ function ago(ms) {
83
+ const s = Math.max(0, Math.round((Date.now() - ms) / 1000));
84
+ if (s < 60)
85
+ return `${s}s ago`;
86
+ const m = Math.round(s / 60);
87
+ if (m < 60)
88
+ return `${m}m ago`;
89
+ return `${Math.round(m / 60)}h ago`;
90
+ }
91
+ export async function listShellsTool(_args, ctx) {
92
+ const sessionId = ctx?.sessionId;
93
+ if (!sessionId)
94
+ return "No background shells (no session context).";
95
+ const shells = managerFor(ctx).listForSession(sessionId);
96
+ if (shells.length === 0)
97
+ return "No background shells for this session.";
98
+ const rows = shells.map((s) => {
99
+ const portPart = s.detectedPort !== undefined ? ` port=${s.detectedPort}` : "";
100
+ const exitPart = s.status === "exited"
101
+ ? s.signal
102
+ ? ` signal=${s.signal}`
103
+ : ` exit=${s.exitCode ?? "?"}`
104
+ : "";
105
+ return `${s.shellId} ${s.status}${portPart}${exitPart} ${s.command} (started ${ago(s.startedAt)})`;
106
+ });
107
+ return rows.join("\n");
108
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Unified view over the THREE kinds of async background work — background
3
+ * sub-agents (asyncAgentRegistry), background jobs / video polls
4
+ * (backgroundJobRegistry), and background shells (backgroundShellManager).
5
+ *
6
+ * Used by the goal-stop-hook to show the judge LLM what's still running, so it
7
+ * can tell "the goal is done except for a finite task that will wake me" (a
8
+ * download / video render → allow stop, wait for the wakeup) from "a long-lived
9
+ * service that the goal doesn't depend on" (a dev server → judge the goal
10
+ * normally). Replacing the old mechanical `hasRunningForSession` short-circuit:
11
+ * a boolean can't distinguish a finite download from a never-ending dev server,
12
+ * but the judge — given each task's kind + command — can.
13
+ */
14
+ import { type AsyncAgentStatus } from "./agent-registry.js";
15
+ import { type BackgroundJobStatus } from "./background-jobs.js";
16
+ import { type BgShell } from "../../runtime/background-shell.js";
17
+ export type BackgroundWorkKind = "subagent" | "job" | "shell";
18
+ export interface BackgroundWorkItem {
19
+ kind: BackgroundWorkKind;
20
+ /** Human description for the judge (sub-agent task / video prompt / shell command). */
21
+ description: string;
22
+ /**
23
+ * For kind === "shell": a port the shell is listening on, if detected. A
24
+ * listening port is a strong signal the shell is a long-lived service (dev
25
+ * server) rather than a finite task — fed to the judge so it doesn't mistake
26
+ * `make serve` / an opaquely-named server script for something to "wait on".
27
+ */
28
+ detectedPort?: number;
29
+ }
30
+ /** List every still-running background work item spawned by `sessionId`. */
31
+ export declare function listRunningBackgroundWork(sessionId: string): BackgroundWorkItem[];
32
+ /** One background-work row for the desktop panel, discriminated by `kind`. */
33
+ export type BackgroundWorkEntry = {
34
+ kind: "shell";
35
+ /** Full shell snapshot — the panel already renders this shape (output/kill
36
+ * still go through the dedicated agent/backgroundShells RPC by shellId). */
37
+ shell: BgShell;
38
+ } | {
39
+ kind: "subagent";
40
+ agentId: string;
41
+ name?: string;
42
+ agentType?: string;
43
+ description: string;
44
+ status: AsyncAgentStatus;
45
+ startedAt: number;
46
+ finishedAt?: number;
47
+ } | {
48
+ kind: "job";
49
+ jobId: string;
50
+ description: string;
51
+ status: BackgroundJobStatus;
52
+ startedAt: number;
53
+ finishedAt?: number;
54
+ /** Result summary / error, once finished. */
55
+ finalText?: string;
56
+ /** Files an external agent (DriveAgent) changed, parsed from its transcript. */
57
+ changedFiles?: string[];
58
+ };
59
+ /**
60
+ * Every background-work item spawned by `sessionId`, with per-kind detail, for
61
+ * the desktop panel. Includes finished sub-agents that are still within their
62
+ * fade window (so a just-completed agent doesn't vanish before the user sees
63
+ * it); shells carry their own terminal status and the panel decides how long to
64
+ * keep them. Jobs are only ever present while running (the registry drops them
65
+ * on finish).
66
+ */
67
+ export declare function listBackgroundWorkForUI(sessionId: string): BackgroundWorkEntry[];
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Unified view over the THREE kinds of async background work — background
3
+ * sub-agents (asyncAgentRegistry), background jobs / video polls
4
+ * (backgroundJobRegistry), and background shells (backgroundShellManager).
5
+ *
6
+ * Used by the goal-stop-hook to show the judge LLM what's still running, so it
7
+ * can tell "the goal is done except for a finite task that will wake me" (a
8
+ * download / video render → allow stop, wait for the wakeup) from "a long-lived
9
+ * service that the goal doesn't depend on" (a dev server → judge the goal
10
+ * normally). Replacing the old mechanical `hasRunningForSession` short-circuit:
11
+ * a boolean can't distinguish a finite download from a never-ending dev server,
12
+ * but the judge — given each task's kind + command — can.
13
+ */
14
+ import { asyncAgentRegistry } from "./agent-registry.js";
15
+ import { backgroundJobRegistry } from "./background-jobs.js";
16
+ import { backgroundShellManager } from "../../runtime/background-shell.js";
17
+ /** List every still-running background work item spawned by `sessionId`. */
18
+ export function listRunningBackgroundWork(sessionId) {
19
+ const items = [];
20
+ for (const a of asyncAgentRegistry.listForSession(sessionId)) {
21
+ if (a.status === "running") {
22
+ items.push({
23
+ kind: "subagent",
24
+ description: a.description || a.name || a.agentType || "(background sub-agent)",
25
+ });
26
+ }
27
+ }
28
+ for (const j of backgroundJobRegistry.listRunningForSession(sessionId)) {
29
+ items.push({ kind: "job", description: j.description || "(background job)" });
30
+ }
31
+ for (const s of backgroundShellManager.listForSession(sessionId)) {
32
+ if (s.status === "running" || s.status === "starting") {
33
+ items.push({
34
+ kind: "shell",
35
+ description: s.command,
36
+ ...(s.detectedPort != null ? { detectedPort: s.detectedPort } : {}),
37
+ });
38
+ }
39
+ }
40
+ return items;
41
+ }
42
+ /**
43
+ * Every background-work item spawned by `sessionId`, with per-kind detail, for
44
+ * the desktop panel. Includes finished sub-agents that are still within their
45
+ * fade window (so a just-completed agent doesn't vanish before the user sees
46
+ * it); shells carry their own terminal status and the panel decides how long to
47
+ * keep them. Jobs are only ever present while running (the registry drops them
48
+ * on finish).
49
+ */
50
+ export function listBackgroundWorkForUI(sessionId) {
51
+ const entries = [];
52
+ for (const s of backgroundShellManager.listForSession(sessionId)) {
53
+ entries.push({ kind: "shell", shell: s });
54
+ }
55
+ const now = Date.now();
56
+ for (const a of asyncAgentRegistry.listForSession(sessionId)) {
57
+ // Keep running agents, plus finished ones still inside their fade window so
58
+ // a completion is briefly visible. (finishedFadeAt = finishedAt + 30s.)
59
+ const fresh = a.status === "running" || (a.finishedFadeAt != null && a.finishedFadeAt > now);
60
+ if (!fresh)
61
+ continue;
62
+ entries.push({
63
+ kind: "subagent",
64
+ agentId: a.agentId,
65
+ name: a.name,
66
+ agentType: a.agentType,
67
+ description: a.description,
68
+ status: a.status,
69
+ startedAt: a.startedAt,
70
+ finishedAt: a.finishedAt,
71
+ });
72
+ }
73
+ for (const j of backgroundJobRegistry.listForSession(sessionId)) {
74
+ entries.push({
75
+ kind: "job",
76
+ jobId: j.jobId,
77
+ description: j.description,
78
+ status: j.status,
79
+ startedAt: j.startedAt,
80
+ ...(j.finishedAt != null ? { finishedAt: j.finishedAt } : {}),
81
+ ...(j.finalText != null ? { finalText: j.finalText } : {}),
82
+ ...(j.changedFiles && j.changedFiles.length ? { changedFiles: j.changedFiles } : {}),
83
+ });
84
+ }
85
+ return entries;
86
+ }