@armadra/agent 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (527) hide show
  1. package/CHANGELOG.md +257 -0
  2. package/README.md +263 -95
  3. package/THIRD_PARTY_NOTICES.md +34 -0
  4. package/dist/acp.d.ts +18 -0
  5. package/dist/acp.js +19 -0
  6. package/dist/agent/limits.d.ts +38 -0
  7. package/dist/agent/limits.js +127 -0
  8. package/dist/agent/loop-guard.d.ts +38 -0
  9. package/dist/agent/loop-guard.js +95 -0
  10. package/dist/agent/loop.d.ts +4 -0
  11. package/dist/agent/loop.js +7 -0
  12. package/dist/agent/prompt-rules.d.ts +12 -0
  13. package/dist/agent/prompt-rules.js +18 -0
  14. package/dist/agent/reminders.d.ts +59 -0
  15. package/dist/agent/reminders.js +327 -0
  16. package/dist/agent/retry.d.ts +1 -1
  17. package/dist/agent/retry.js +2 -1
  18. package/dist/agent/session-cache.d.ts +5 -0
  19. package/dist/agent/session-cache.js +18 -2
  20. package/dist/agent/session-classifier.d.ts +18 -0
  21. package/dist/agent/session-classifier.js +105 -0
  22. package/dist/agent/session-compaction.d.ts +35 -6
  23. package/dist/agent/session-compaction.js +157 -31
  24. package/dist/agent/session-core.d.ts +40 -1
  25. package/dist/agent/session-extensions.d.ts +61 -0
  26. package/dist/agent/session-extensions.js +129 -0
  27. package/dist/agent/session-images.d.ts +23 -0
  28. package/dist/agent/session-images.js +97 -0
  29. package/dist/agent/session-plan.d.ts +21 -0
  30. package/dist/agent/session-plan.js +524 -0
  31. package/dist/agent/session-rewind.d.ts +81 -0
  32. package/dist/agent/session-rewind.js +354 -0
  33. package/dist/agent/session-run.d.ts +28 -1
  34. package/dist/agent/session-run.js +157 -6
  35. package/dist/agent/session-settings.d.ts +49 -0
  36. package/dist/agent/session-settings.js +95 -0
  37. package/dist/agent/session-subagent.d.ts +36 -24
  38. package/dist/agent/session-subagent.js +259 -129
  39. package/dist/agent/session-sync.d.ts +10 -3
  40. package/dist/agent/session-sync.js +37 -8
  41. package/dist/agent/session-telemetry.d.ts +39 -0
  42. package/dist/agent/session-telemetry.js +231 -0
  43. package/dist/agent/session-tools.js +63 -3
  44. package/dist/agent/session.d.ts +33 -29
  45. package/dist/agent/session.js +91 -126
  46. package/dist/agent/subagent-registry.d.ts +91 -0
  47. package/dist/agent/subagent-registry.js +494 -0
  48. package/dist/agent/system-prompt.d.ts +6 -3
  49. package/dist/agent/system-prompt.js +7 -2
  50. package/dist/agent/tool-runner.d.ts +8 -1
  51. package/dist/agent/tool-runner.js +72 -6
  52. package/dist/agent/types-w5.d.ts +192 -0
  53. package/dist/agent/types-w5.js +10 -0
  54. package/dist/agent/types.d.ts +55 -4
  55. package/dist/agent/types.js +2 -0
  56. package/dist/agent/worktree.d.ts +36 -0
  57. package/dist/agent/worktree.js +86 -0
  58. package/dist/agents/builtin.d.ts +14 -0
  59. package/dist/agents/builtin.js +39 -0
  60. package/dist/agents/catalog.d.ts +43 -0
  61. package/dist/agents/catalog.js +82 -0
  62. package/dist/agents/discover.d.ts +35 -0
  63. package/dist/agents/discover.js +83 -0
  64. package/dist/agents/external.d.ts +82 -0
  65. package/dist/agents/external.js +326 -0
  66. package/dist/agents/parse.d.ts +18 -0
  67. package/dist/agents/parse.js +116 -0
  68. package/dist/agents/result.d.ts +32 -0
  69. package/dist/agents/result.js +67 -0
  70. package/dist/agents/task-control.d.ts +17 -0
  71. package/dist/agents/task-control.js +17 -0
  72. package/dist/agents/task-record.d.ts +78 -0
  73. package/dist/agents/task-record.js +141 -0
  74. package/dist/agents/types.d.ts +46 -0
  75. package/dist/agents/types.js +8 -0
  76. package/dist/ai/apis/anthropic-compat.d.ts +36 -0
  77. package/dist/ai/apis/anthropic-compat.js +92 -0
  78. package/dist/ai/apis/anthropic-messages.js +3 -2
  79. package/dist/ai/apis/anthropic-request.d.ts +7 -6
  80. package/dist/ai/apis/anthropic-request.js +10 -28
  81. package/dist/ai/apis/cache-params.d.ts +11 -2
  82. package/dist/ai/apis/cache-params.js +25 -6
  83. package/dist/ai/apis/google-generative-ai.js +3 -2
  84. package/dist/ai/apis/openai-compat.d.ts +4 -1
  85. package/dist/ai/apis/openai-compat.js +8 -1
  86. package/dist/ai/apis/openai-completions.js +3 -2
  87. package/dist/ai/apis/openai-responses.js +3 -2
  88. package/dist/ai/http.d.ts +28 -6
  89. package/dist/ai/http.js +41 -8
  90. package/dist/ai/image-limits.d.ts +45 -0
  91. package/dist/ai/image-limits.js +68 -0
  92. package/dist/ai/providers/builtin.d.ts +18 -6
  93. package/dist/ai/providers/builtin.js +135 -6
  94. package/dist/ai/providers/catalog-data.js +17 -13
  95. package/dist/ai/providers/catalog.d.ts +60 -7
  96. package/dist/ai/providers/catalog.js +197 -38
  97. package/dist/ai/providers/channels.d.ts +33 -3
  98. package/dist/ai/providers/channels.js +108 -7
  99. package/dist/ai/providers/enrich.d.ts +6 -3
  100. package/dist/ai/providers/enrich.js +19 -4
  101. package/dist/ai/providers/models-dev-cache.d.ts +28 -24
  102. package/dist/ai/providers/models-dev-cache.js +92 -78
  103. package/dist/ai/providers/models-dev-data.d.ts +7 -0
  104. package/dist/ai/providers/models-dev-data.js +32 -0
  105. package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
  106. package/dist/ai/providers/models-dev-snapshot.js +137 -0
  107. package/dist/ai/providers/models-dev.d.ts +51 -10
  108. package/dist/ai/providers/models-dev.js +132 -39
  109. package/dist/ai/providers/registry.d.ts +28 -11
  110. package/dist/ai/providers/registry.js +112 -65
  111. package/dist/ai/providers/suggest.d.ts +18 -0
  112. package/dist/ai/providers/suggest.js +72 -0
  113. package/dist/ai/sse.d.ts +6 -2
  114. package/dist/ai/sse.js +22 -2
  115. package/dist/ai/types.d.ts +37 -4
  116. package/dist/ai/types.js +5 -0
  117. package/dist/bundle/ama.cjs +41979 -21147
  118. package/dist/checkpoints/backend.d.ts +61 -0
  119. package/dist/checkpoints/backend.js +135 -0
  120. package/dist/checkpoints/blobs.d.ts +60 -0
  121. package/dist/checkpoints/blobs.js +203 -0
  122. package/dist/checkpoints/gc.d.ts +47 -0
  123. package/dist/checkpoints/gc.js +144 -0
  124. package/dist/checkpoints/git-head.d.ts +15 -0
  125. package/dist/checkpoints/git-head.js +89 -0
  126. package/dist/checkpoints/index.d.ts +17 -0
  127. package/dist/checkpoints/index.js +17 -0
  128. package/dist/checkpoints/replay.d.ts +48 -0
  129. package/dist/checkpoints/replay.js +154 -0
  130. package/dist/checkpoints/restore.d.ts +86 -0
  131. package/dist/checkpoints/restore.js +263 -0
  132. package/dist/checkpoints/settings.d.ts +14 -0
  133. package/dist/checkpoints/settings.js +23 -0
  134. package/dist/checkpoints/shadow-git.d.ts +108 -0
  135. package/dist/checkpoints/shadow-git.js +491 -0
  136. package/dist/checkpoints/shadow-restore.d.ts +25 -0
  137. package/dist/checkpoints/shadow-restore.js +128 -0
  138. package/dist/checkpoints/tracker.d.ts +64 -0
  139. package/dist/checkpoints/tracker.js +192 -0
  140. package/dist/checkpoints/types.d.ts +99 -0
  141. package/dist/checkpoints/types.js +12 -0
  142. package/dist/cli/args.d.ts +26 -7
  143. package/dist/cli/args.js +75 -82
  144. package/dist/cli/bootstrap.js +40 -4
  145. package/dist/cli/codemode-notice.d.ts +21 -0
  146. package/dist/cli/codemode-notice.js +56 -0
  147. package/dist/cli/compose-agents.d.ts +27 -0
  148. package/dist/cli/compose-agents.js +111 -0
  149. package/dist/cli/compose-extensions.d.ts +29 -0
  150. package/dist/cli/compose-extensions.js +44 -0
  151. package/dist/cli/compose-session.d.ts +8 -0
  152. package/dist/cli/compose-session.js +76 -2
  153. package/dist/cli/compose-store.d.ts +1 -1
  154. package/dist/cli/compose-store.js +3 -1
  155. package/dist/cli/compose.d.ts +17 -4
  156. package/dist/cli/compose.js +60 -14
  157. package/dist/cli/default-model.d.ts +38 -1
  158. package/dist/cli/default-model.js +96 -9
  159. package/dist/cli/deps.d.ts +42 -0
  160. package/dist/cli/exit-codes.d.ts +12 -0
  161. package/dist/cli/exit-codes.js +15 -0
  162. package/dist/cli/fake-visibility.d.ts +13 -0
  163. package/dist/cli/fake-visibility.js +26 -0
  164. package/dist/cli/from-prompt.d.ts +18 -0
  165. package/dist/cli/from-prompt.js +49 -0
  166. package/dist/cli/help-text.d.ts +4 -0
  167. package/dist/cli/help-text.js +102 -0
  168. package/dist/cli/main.d.ts +9 -2
  169. package/dist/cli/main.js +77 -3
  170. package/dist/cli/proxy.d.ts +51 -0
  171. package/dist/cli/proxy.js +135 -0
  172. package/dist/cli/startup-screen.d.ts +29 -0
  173. package/dist/cli/startup-screen.js +51 -2
  174. package/dist/cli/startup-steps.d.ts +1 -1
  175. package/dist/cli/startup-steps.js +21 -13
  176. package/dist/cli/subcommands/config.d.ts +22 -3
  177. package/dist/cli/subcommands/config.js +119 -21
  178. package/dist/cli/subcommands/context.js +4 -1
  179. package/dist/cli/subcommands/doctor.js +33 -1
  180. package/dist/cli/subcommands/init.js +2 -1
  181. package/dist/cli/subcommands/models-discover.d.ts +15 -9
  182. package/dist/cli/subcommands/models-discover.js +58 -52
  183. package/dist/cli/subcommands/models.d.ts +2 -0
  184. package/dist/cli/subcommands/models.js +33 -14
  185. package/dist/cli/subcommands/probe-runner.d.ts +96 -0
  186. package/dist/cli/subcommands/probe-runner.js +264 -0
  187. package/dist/cli/subcommands/providers-probe.d.ts +34 -0
  188. package/dist/cli/subcommands/providers-probe.js +87 -0
  189. package/dist/cli/subcommands/providers.d.ts +3 -2
  190. package/dist/cli/subcommands/providers.js +53 -51
  191. package/dist/cli/subcommands/sessions-export.d.ts +10 -0
  192. package/dist/cli/subcommands/sessions-export.js +59 -0
  193. package/dist/cli/subcommands/sessions-search.d.ts +13 -0
  194. package/dist/cli/subcommands/sessions-search.js +103 -0
  195. package/dist/cli/subcommands/sessions.d.ts +6 -3
  196. package/dist/cli/subcommands/sessions.js +58 -3
  197. package/dist/cli/subcommands/stats.d.ts +17 -0
  198. package/dist/cli/subcommands/stats.js +198 -0
  199. package/dist/cli/system-prompt-arg.d.ts +11 -0
  200. package/dist/cli/system-prompt-arg.js +34 -0
  201. package/dist/codemode/capability.d.ts +24 -7
  202. package/dist/codemode/capability.js +38 -10
  203. package/dist/codemode/host-side.d.ts +14 -0
  204. package/dist/codemode/host-side.js +24 -1
  205. package/dist/codemode/modes.d.ts +4 -11
  206. package/dist/codemode/modes.js +5 -27
  207. package/dist/codemode/tool.d.ts +18 -14
  208. package/dist/codemode/tool.js +76 -31
  209. package/dist/compaction/breaker.d.ts +25 -9
  210. package/dist/compaction/breaker.js +47 -17
  211. package/dist/compaction/estimate.d.ts +11 -3
  212. package/dist/compaction/estimate.js +64 -22
  213. package/dist/compaction/image-budget.d.ts +45 -0
  214. package/dist/compaction/image-budget.js +115 -0
  215. package/dist/compaction/post-compact.d.ts +38 -0
  216. package/dist/compaction/post-compact.js +152 -0
  217. package/dist/compaction/protect.d.ts +27 -0
  218. package/dist/compaction/protect.js +56 -0
  219. package/dist/compaction/prune-tier.d.ts +58 -12
  220. package/dist/compaction/prune-tier.js +120 -54
  221. package/dist/compaction/summarize-tier.d.ts +23 -4
  222. package/dist/compaction/summarize-tier.js +100 -29
  223. package/dist/config/checker.d.ts +28 -0
  224. package/dist/config/checker.js +97 -0
  225. package/dist/config/init.d.ts +6 -2
  226. package/dist/config/init.js +12 -5
  227. package/dist/config/json-schema.d.ts +1 -0
  228. package/dist/config/json-schema.js +98 -4
  229. package/dist/config/key-docs.d.ts +22 -0
  230. package/dist/config/key-docs.js +174 -0
  231. package/dist/config/merge.d.ts +12 -9
  232. package/dist/config/merge.js +102 -13
  233. package/dist/config/profile.d.ts +2 -0
  234. package/dist/config/profile.js +2 -0
  235. package/dist/config/schema-w5.d.ts +18 -0
  236. package/dist/config/schema-w5.js +109 -0
  237. package/dist/config/schema.d.ts +5 -9
  238. package/dist/config/schema.js +91 -118
  239. package/dist/config/types-w5.d.ts +118 -0
  240. package/dist/config/types-w5.js +20 -0
  241. package/dist/config/types.d.ts +84 -7
  242. package/dist/config/types.js +29 -1
  243. package/dist/drivers/acp/client.d.ts +57 -0
  244. package/dist/drivers/acp/client.js +160 -0
  245. package/dist/drivers/acp/driver.d.ts +31 -0
  246. package/dist/drivers/acp/driver.js +274 -0
  247. package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
  248. package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
  249. package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
  250. package/dist/drivers/acp/testing/fake-agent.js +211 -0
  251. package/dist/drivers/acp/types.d.ts +285 -0
  252. package/dist/drivers/acp/types.js +36 -0
  253. package/dist/drivers/agents.d.ts +58 -0
  254. package/dist/drivers/agents.js +142 -0
  255. package/dist/drivers/base.d.ts +35 -0
  256. package/dist/drivers/base.js +59 -0
  257. package/dist/drivers/catalog.d.ts +46 -0
  258. package/dist/drivers/catalog.js +167 -0
  259. package/dist/drivers/env.d.ts +20 -0
  260. package/dist/drivers/env.js +46 -0
  261. package/dist/drivers/host-runners.d.ts +18 -0
  262. package/dist/drivers/host-runners.js +45 -0
  263. package/dist/drivers/jsonrpc.d.ts +58 -0
  264. package/dist/drivers/jsonrpc.js +180 -0
  265. package/dist/drivers/native/claude-normalize.d.ts +46 -0
  266. package/dist/drivers/native/claude-normalize.js +106 -0
  267. package/dist/drivers/native/claude-stream.d.ts +29 -0
  268. package/dist/drivers/native/claude-stream.js +456 -0
  269. package/dist/drivers/native/codex-app-server.d.ts +26 -0
  270. package/dist/drivers/native/codex-app-server.js +407 -0
  271. package/dist/drivers/native/codex-normalize.d.ts +38 -0
  272. package/dist/drivers/native/codex-normalize.js +124 -0
  273. package/dist/drivers/native/oneshot.d.ts +28 -0
  274. package/dist/drivers/native/oneshot.js +312 -0
  275. package/dist/drivers/permissions.d.ts +40 -0
  276. package/dist/drivers/permissions.js +92 -0
  277. package/dist/drivers/pids.d.ts +32 -0
  278. package/dist/drivers/pids.js +93 -0
  279. package/dist/drivers/pool.d.ts +28 -0
  280. package/dist/drivers/pool.js +96 -0
  281. package/dist/drivers/probe.d.ts +47 -0
  282. package/dist/drivers/probe.js +172 -0
  283. package/dist/drivers/process.d.ts +48 -0
  284. package/dist/drivers/process.js +100 -0
  285. package/dist/drivers/runner.d.ts +61 -0
  286. package/dist/drivers/runner.js +388 -0
  287. package/dist/drivers/store.d.ts +49 -0
  288. package/dist/drivers/store.js +91 -0
  289. package/dist/drivers/turn.d.ts +41 -0
  290. package/dist/drivers/turn.js +99 -0
  291. package/dist/drivers/types.d.ts +122 -0
  292. package/dist/drivers/types.js +11 -0
  293. package/dist/git/info.d.ts +75 -0
  294. package/dist/git/info.js +191 -0
  295. package/dist/hooks/protocol.js +6 -1
  296. package/dist/hooks/types.d.ts +10 -1
  297. package/dist/hooks/types.js +2 -0
  298. package/dist/host/api-impl.d.ts +7 -0
  299. package/dist/host/api-impl.js +15 -0
  300. package/dist/host/types.d.ts +24 -2
  301. package/dist/host/types.js +4 -0
  302. package/dist/index.d.ts +3 -0
  303. package/dist/index.js +1 -0
  304. package/dist/modes/acp/acp-events.d.ts +46 -0
  305. package/dist/modes/acp/acp-events.js +233 -0
  306. package/dist/modes/acp/acp-mode.d.ts +17 -0
  307. package/dist/modes/acp/acp-mode.js +47 -0
  308. package/dist/modes/acp/acp-server.d.ts +79 -0
  309. package/dist/modes/acp/acp-server.js +315 -0
  310. package/dist/modes/commands-core.d.ts +7 -1
  311. package/dist/modes/commands-core.js +61 -5
  312. package/dist/modes/image-input.d.ts +12 -4
  313. package/dist/modes/image-input.js +22 -5
  314. package/dist/modes/interactive/agent-panels.d.ts +14 -0
  315. package/dist/modes/interactive/agent-panels.js +103 -0
  316. package/dist/modes/interactive/agent-ui.d.ts +73 -0
  317. package/dist/modes/interactive/agent-ui.js +234 -0
  318. package/dist/modes/interactive/approval-dialog.d.ts +40 -7
  319. package/dist/modes/interactive/approval-dialog.js +192 -35
  320. package/dist/modes/interactive/approval-merge.d.ts +41 -0
  321. package/dist/modes/interactive/approval-merge.js +89 -0
  322. package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
  323. package/dist/modes/interactive/clipboard-paste.js +28 -0
  324. package/dist/modes/interactive/commands.d.ts +20 -3
  325. package/dist/modes/interactive/commands.js +75 -16
  326. package/dist/modes/interactive/double-esc.d.ts +20 -0
  327. package/dist/modes/interactive/double-esc.js +34 -0
  328. package/dist/modes/interactive/event-notices.d.ts +32 -0
  329. package/dist/modes/interactive/event-notices.js +79 -0
  330. package/dist/modes/interactive/external-editor.d.ts +16 -0
  331. package/dist/modes/interactive/external-editor.js +39 -0
  332. package/dist/modes/interactive/interactive-mode.d.ts +16 -2
  333. package/dist/modes/interactive/interactive-mode.js +184 -202
  334. package/dist/modes/interactive/key-dispatch.d.ts +18 -2
  335. package/dist/modes/interactive/key-dispatch.js +53 -6
  336. package/dist/modes/interactive/line/line-mode.d.ts +3 -1
  337. package/dist/modes/interactive/line/line-mode.js +28 -9
  338. package/dist/modes/interactive/line/line-render.d.ts +6 -1
  339. package/dist/modes/interactive/line/line-render.js +66 -8
  340. package/dist/modes/interactive/message-view.d.ts +49 -10
  341. package/dist/modes/interactive/message-view.js +262 -46
  342. package/dist/modes/interactive/panels.d.ts +35 -0
  343. package/dist/modes/interactive/panels.js +157 -0
  344. package/dist/modes/interactive/pickers.d.ts +23 -2
  345. package/dist/modes/interactive/pickers.js +48 -15
  346. package/dist/modes/interactive/plan-command.d.ts +40 -0
  347. package/dist/modes/interactive/plan-command.js +129 -0
  348. package/dist/modes/interactive/plan-dialog.d.ts +98 -0
  349. package/dist/modes/interactive/plan-dialog.js +290 -0
  350. package/dist/modes/interactive/plan-flow.d.ts +34 -0
  351. package/dist/modes/interactive/plan-flow.js +98 -0
  352. package/dist/modes/interactive/rewind-command.d.ts +31 -0
  353. package/dist/modes/interactive/rewind-command.js +106 -0
  354. package/dist/modes/interactive/rewind-flow.d.ts +37 -0
  355. package/dist/modes/interactive/rewind-flow.js +151 -0
  356. package/dist/modes/interactive/rewind-list.d.ts +36 -0
  357. package/dist/modes/interactive/rewind-list.js +123 -0
  358. package/dist/modes/interactive/rewind-panel.d.ts +77 -0
  359. package/dist/modes/interactive/rewind-panel.js +309 -0
  360. package/dist/modes/interactive/rewind-text.d.ts +40 -0
  361. package/dist/modes/interactive/rewind-text.js +139 -0
  362. package/dist/modes/interactive/run-indicator.d.ts +51 -0
  363. package/dist/modes/interactive/run-indicator.js +189 -0
  364. package/dist/modes/interactive/session-events.d.ts +24 -0
  365. package/dist/modes/interactive/session-events.js +96 -0
  366. package/dist/modes/interactive/startup-header.d.ts +40 -0
  367. package/dist/modes/interactive/startup-header.js +169 -0
  368. package/dist/modes/interactive/status-area.d.ts +73 -0
  369. package/dist/modes/interactive/status-area.js +190 -0
  370. package/dist/modes/interactive/status-bar.d.ts +107 -16
  371. package/dist/modes/interactive/status-bar.js +306 -81
  372. package/dist/modes/interactive/status-line.d.ts +33 -0
  373. package/dist/modes/interactive/status-line.js +113 -0
  374. package/dist/modes/interactive/subagent-view.d.ts +56 -0
  375. package/dist/modes/interactive/subagent-view.js +154 -0
  376. package/dist/modes/interactive/tasks-report.d.ts +27 -0
  377. package/dist/modes/interactive/tasks-report.js +114 -0
  378. package/dist/modes/interactive/tool-summary.d.ts +46 -0
  379. package/dist/modes/interactive/tool-summary.js +218 -0
  380. package/dist/modes/interactive/tool-view.d.ts +58 -15
  381. package/dist/modes/interactive/tool-view.js +233 -145
  382. package/dist/modes/print/print-mode.d.ts +40 -4
  383. package/dist/modes/print/print-mode.js +161 -8
  384. package/dist/modes/rpc/commands.d.ts +9 -0
  385. package/dist/modes/rpc/commands.js +49 -0
  386. package/dist/modes/rpc/rpc-mode.js +7 -1
  387. package/dist/modes/session-report.d.ts +11 -0
  388. package/dist/modes/session-report.js +48 -1
  389. package/dist/permissions/auto-safe.d.ts +65 -0
  390. package/dist/permissions/auto-safe.js +547 -0
  391. package/dist/permissions/classifier.d.ts +68 -0
  392. package/dist/permissions/classifier.js +186 -0
  393. package/dist/permissions/dangerous.d.ts +5 -0
  394. package/dist/permissions/dangerous.js +1 -1
  395. package/dist/permissions/modes.d.ts +30 -0
  396. package/dist/permissions/modes.js +78 -0
  397. package/dist/permissions/pipeline.d.ts +72 -6
  398. package/dist/permissions/pipeline.js +306 -11
  399. package/dist/permissions/protected.d.ts +19 -0
  400. package/dist/permissions/protected.js +74 -0
  401. package/dist/permissions/readonly-bash.d.ts +30 -0
  402. package/dist/permissions/readonly-bash.js +118 -0
  403. package/dist/permissions/rules.js +3 -0
  404. package/dist/permissions/types.d.ts +92 -3
  405. package/dist/permissions/types.js +3 -0
  406. package/dist/plan/compose.d.ts +9 -0
  407. package/dist/plan/compose.js +19 -0
  408. package/dist/plan/controller.d.ts +71 -0
  409. package/dist/plan/controller.js +27 -0
  410. package/dist/plan/done-markers.d.ts +17 -0
  411. package/dist/plan/done-markers.js +51 -0
  412. package/dist/plan/extract.d.ts +29 -0
  413. package/dist/plan/extract.js +160 -0
  414. package/dist/plan/prompts.d.ts +36 -0
  415. package/dist/plan/prompts.js +89 -0
  416. package/dist/plan/store.d.ts +37 -0
  417. package/dist/plan/store.js +90 -0
  418. package/dist/rpc.d.ts +58 -2
  419. package/dist/rpc.js +7 -0
  420. package/dist/sandbox/bash.d.ts +74 -0
  421. package/dist/sandbox/bash.js +126 -0
  422. package/dist/sandbox/detect.d.ts +48 -0
  423. package/dist/sandbox/detect.js +149 -0
  424. package/dist/sandbox/index.d.ts +5 -0
  425. package/dist/sandbox/index.js +5 -0
  426. package/dist/sandbox/profile.d.ts +33 -0
  427. package/dist/sandbox/profile.js +76 -0
  428. package/dist/sandbox/wrap.d.ts +29 -0
  429. package/dist/sandbox/wrap.js +117 -0
  430. package/dist/sdk.d.ts +42 -5
  431. package/dist/sdk.js +34 -4
  432. package/dist/session/export.d.ts +32 -0
  433. package/dist/session/export.js +187 -0
  434. package/dist/session/redact.d.ts +15 -0
  435. package/dist/session/redact.js +55 -0
  436. package/dist/session/reuse.d.ts +33 -0
  437. package/dist/session/reuse.js +86 -0
  438. package/dist/session/scan.d.ts +34 -0
  439. package/dist/session/scan.js +140 -0
  440. package/dist/session/search.d.ts +52 -0
  441. package/dist/session/search.js +211 -0
  442. package/dist/session/stats-aggregate.d.ts +63 -0
  443. package/dist/session/stats-aggregate.js +163 -0
  444. package/dist/session/stats-index.d.ts +26 -0
  445. package/dist/session/stats-index.js +91 -0
  446. package/dist/session/stats-scan.d.ts +54 -0
  447. package/dist/session/stats-scan.js +236 -0
  448. package/dist/session/types.d.ts +3 -1
  449. package/dist/session/types.js +1 -0
  450. package/dist/skills/builtin.d.ts +31 -0
  451. package/dist/skills/builtin.js +109 -0
  452. package/dist/skills/discover.d.ts +2 -1
  453. package/dist/skills/index-prompt.js +5 -8
  454. package/dist/tools/background-jobs.d.ts +71 -0
  455. package/dist/tools/background-jobs.js +198 -0
  456. package/dist/tools/bash.d.ts +53 -1
  457. package/dist/tools/bash.js +158 -7
  458. package/dist/tools/clipboard-image.d.ts +44 -0
  459. package/dist/tools/clipboard-image.js +148 -0
  460. package/dist/tools/edit.d.ts +2 -0
  461. package/dist/tools/edit.js +18 -3
  462. package/dist/tools/image-file.d.ts +38 -3
  463. package/dist/tools/image-file.js +81 -10
  464. package/dist/tools/image-resize.d.ts +58 -0
  465. package/dist/tools/image-resize.js +97 -0
  466. package/dist/tools/presets.d.ts +40 -8
  467. package/dist/tools/presets.js +65 -19
  468. package/dist/tools/read.d.ts +5 -2
  469. package/dist/tools/read.js +13 -10
  470. package/dist/tools/registry.d.ts +7 -1
  471. package/dist/tools/registry.js +27 -4
  472. package/dist/tools/task-ctl.d.ts +22 -0
  473. package/dist/tools/task-ctl.js +116 -0
  474. package/dist/tools/task.d.ts +22 -10
  475. package/dist/tools/task.js +66 -26
  476. package/dist/tools/todo.d.ts +22 -2
  477. package/dist/tools/todo.js +58 -14
  478. package/dist/tools/truncate.d.ts +15 -0
  479. package/dist/tools/truncate.js +25 -0
  480. package/dist/tools/types.d.ts +113 -0
  481. package/dist/tools/types.js +5 -0
  482. package/dist/tools/write.js +3 -0
  483. package/dist/tui/component.d.ts +8 -2
  484. package/dist/tui/component.js +3 -1
  485. package/dist/tui/components/box.d.ts +6 -1
  486. package/dist/tui/components/box.js +16 -6
  487. package/dist/tui/components/card.d.ts +23 -0
  488. package/dist/tui/components/card.js +37 -0
  489. package/dist/tui/components/editor-history.d.ts +6 -0
  490. package/dist/tui/components/editor-history.js +45 -0
  491. package/dist/tui/components/editor-paste.d.ts +1 -1
  492. package/dist/tui/components/editor-paste.js +4 -4
  493. package/dist/tui/components/editor.d.ts +11 -5
  494. package/dist/tui/components/editor.js +52 -58
  495. package/dist/tui/components/key-value.d.ts +3 -0
  496. package/dist/tui/components/key-value.js +16 -6
  497. package/dist/tui/components/loader.d.ts +37 -7
  498. package/dist/tui/components/loader.js +84 -21
  499. package/dist/tui/components/markdown.d.ts +5 -1
  500. package/dist/tui/components/markdown.js +45 -21
  501. package/dist/tui/components/meter.d.ts +3 -3
  502. package/dist/tui/components/meter.js +13 -11
  503. package/dist/tui/components/select-list.d.ts +23 -1
  504. package/dist/tui/components/select-list.js +76 -13
  505. package/dist/tui/glyphs.d.ts +72 -0
  506. package/dist/tui/glyphs.js +118 -0
  507. package/dist/tui/keybindings.d.ts +5 -0
  508. package/dist/tui/keybindings.js +5 -0
  509. package/dist/tui/theme.d.ts +30 -6
  510. package/dist/tui/theme.js +103 -17
  511. package/dist/tui.d.ts +4 -2
  512. package/dist/tui.js +3 -1
  513. package/docs/acp.md +78 -0
  514. package/docs/agents.md +250 -0
  515. package/docs/codemode.md +28 -10
  516. package/docs/hooks.md +36 -32
  517. package/docs/permissions.md +212 -0
  518. package/docs/plan.md +107 -0
  519. package/docs/providers.md +261 -62
  520. package/docs/rewind-plan.md +181 -0
  521. package/docs/rpc.md +127 -40
  522. package/docs/sandbox.md +215 -0
  523. package/docs/session-format.md +43 -22
  524. package/docs/sessions.md +174 -0
  525. package/docs/tui-design.md +751 -0
  526. package/docs/tui.md +260 -64
  527. package/package.json +15 -2
@@ -5,34 +5,74 @@
5
5
  * | ------------- | ----------------------------------------- |
6
6
  * | `default` | read、edit、write、bash、grep、glob |
7
7
  * | `minimal` | read、edit、write、bash |
8
- * | `codemode` | 只有 codemode(其余工具在脚本里调用) |
8
+ * | `codemode-only` | 只有 codemode(其余工具在脚本里调用) |
9
9
  * | `coordinator` | read + 宿主注册的工具 |
10
10
  *
11
11
  * - 预设只管**内置**工具;宿主 / SDK 注册的工具(`canvas_*` 等)总在活动集里,除非用户
12
12
  * `--tools a,b,c` 整组替换(之后只用列出的名字)。
13
13
  * - `tools.default`:`+name` / `-name` 在预设上增减;不带前缀的名字整组替换预设的内置工具,
14
14
  * 之后再应用带前缀的项。未注册的名字记 warning 并忽略。
15
- * - codemode 开关跟随预设:`codemode` 预设 → `only`,其余 → `off`;`codemode.mode` 显式配置覆盖。
16
- * - codemode 工具由 B10 经组装根的 `toolFactories` 注册(`codemode.mode` 为 off 时不注册);不可用
17
- * (例如 `codemode.requireStrict` 而运行时 Node 不隔离网络)时 codemode 预设**回退到 default 并
18
- * warning**(不报错:零配置用户不应因此起不来),`on` 同样忽略。
15
+ * - (D20)`todo` 不在 `default` 里:W5-C0 曾把它加进来,以 `bench-presets` 复测为门(费用增幅 ≤ 5% 且
16
+ * 成功率不降);W5-Z 用多步长任务复测(docs/benchmarks/presets-todo-2026-10-03.md)成功数下降 1、估价
17
+ * +4.6%、保守计价 +11.3%,按门撤回。计划批准后的进度改用 `[DONE:n]` 文本标记(plan/done-markers.ts);
18
+ * 要 todo 就 `tools.default: ["+todo"]`。
19
+ * - (W5-C0)`task_ctl` 与 `task` 同进退:`+task` 一起暴露、`-task` 一起去掉(`pairCompanions`)。
20
+ * - `codemode` 是 `codemode-only` 的旧名(0.3.0),配置合并与命令行解析时折成规范名。
21
+ * - codemode 开关跟随预设(`presetCodemodeMode`):`default` → `on`(只在沙箱 strict,即 Node ≥ 25 隔离
22
+ * 网络时;Node 22 / 24 → `off`),`codemode-only` → `only`,`minimal` / `coordinator` → `off`。
23
+ * `codemode.mode` 显式配置覆盖(缺省配置不写这个键,以后调整映射能惠及老用户)。
24
+ * - `coordinator` 预设即使显式 `on`,脚本里能调用的工具也只限活动集(read + 宿主工具),见
25
+ * `codemodeCallableFilter`:协调者「不写文件、不跑 bash」的约定不能经 codemode 绕过。
26
+ * - codemode 工具由 B10 经组装根的 `toolFactories` 注册(生效模式为 off 时不注册);不可用
27
+ * (例如 `codemode.requireStrict` 而运行时 Node 不隔离网络)时 codemode-only 预设**回退到 default 并
28
+ * warning**(不报错:零配置用户不应因此起不来),显式 `on` 同样忽略;跟随预设得到的 `on` 静默回退。
19
29
  * - `only` 模式活动集独占:宿主 / SDK 工具也不直接暴露,只能在脚本里调用(`exclusive`)。
20
30
  */
21
- import { ToolRegistry } from "./registry.js";
31
+ import { sandboxCapabilityFor } from "../codemode/capability.js";
32
+ import { canonicalPreset, } from "../config/types.js";
33
+ import { ToolRegistry, pairCompanions } from "./registry.js";
22
34
  export const CODEMODE_TOOL = "codemode";
23
- /** 各预设下模型直接看到的内置工具(codemode 预设见 `resolvePreset`)。 */
35
+ /** 各预设下模型直接看到的内置工具(codemode-only 预设见 `resolvePreset`)。 */
24
36
  export const PRESET_TOOLS = Object.freeze({
37
+ // D20:todo 不在 default(W5-Z 复测未过门,见文件头)
25
38
  default: ["bash", "edit", "glob", "grep", "read", "write"],
26
39
  minimal: ["bash", "edit", "read", "write"],
27
- codemode: [CODEMODE_TOOL],
40
+ "codemode-only": [CODEMODE_TOOL],
28
41
  coordinator: ["read"],
29
42
  });
30
- /** 生效的 codemode 模式:显式配置优先,否则跟随预设。 */
31
- export function effectiveCodemodeMode(config) {
43
+ /**
44
+ * 预设对应的 codemode 模式(没有显式 `codemode.mode` 时)。`default` 只在沙箱 strict(Node ≥ 25,
45
+ * 权限模型同时隔离网络)时开 `on`:Node 22 / 24 下 codemode 属 execute 类,每次都要审批,`-p` 下
46
+ * 直接被拒,所以缺省关闭(启动时提示一次,见 cli/codemode-notice.ts)。
47
+ */
48
+ export function presetCodemodeMode(preset, strict) {
49
+ switch (preset) {
50
+ case "codemode-only":
51
+ return "only";
52
+ case "default":
53
+ return strict ? "on" : "off";
54
+ default:
55
+ return "off";
56
+ }
57
+ }
58
+ /** 生效的 codemode 模式及其来源;`strict` 缺省按运行时探测(测试与组装根可注入)。 */
59
+ export function resolveCodemodeMode(config, strict = sandboxCapabilityFor(config).strict) {
60
+ const preset = canonicalPreset(config.tools?.preset) ?? "default";
32
61
  const explicit = config.codemode?.mode;
33
62
  if (explicit !== undefined)
34
- return explicit;
35
- return config.tools?.preset === "codemode" ? "only" : "off";
63
+ return { mode: explicit, source: "config", preset, strict };
64
+ return { mode: presetCodemodeMode(preset, strict), source: "preset", preset, strict };
65
+ }
66
+ /** 生效的 codemode 模式:显式配置优先,否则跟随预设。 */
67
+ export function effectiveCodemodeMode(config, strict) {
68
+ return resolveCodemodeMode(config, strict).mode;
69
+ }
70
+ /**
71
+ * codemode 脚本里可调用工具的范围:`coordinator` 预设只能调活动集里的工具(`"active"`),其它预设
72
+ * 不限(`undefined`;`on` 模式下脚本还能调没直接暴露的 ls / task / todo 等)。
73
+ */
74
+ export function codemodeCallableFilter(config) {
75
+ return canonicalPreset(config.tools?.preset) === "coordinator" ? "active" : undefined;
36
76
  }
37
77
  /**
38
78
  * `tools.default` 微调:不带前缀的名字整组替换 `base`,再依次应用 `+name` / `-name`。
@@ -55,13 +95,18 @@ export function applyToolAdjustments(base, adjustments) {
55
95
  }
56
96
  export function resolvePreset(input) {
57
97
  const warnings = [];
58
- let preset = input.config.tools?.preset ?? "default";
59
- let codemode = effectiveCodemodeMode(input.config);
98
+ const resolved = resolveCodemodeMode(input.config, input.strict);
99
+ let preset = resolved.preset;
100
+ let codemode = resolved.mode;
101
+ // 跟随预设得到的 on(default 预设)在 codemode 不可用时静默回退:零配置不该因此出 warning。
102
+ if (codemode === "on" && resolved.source === "preset" && !input.available(CODEMODE_TOOL)) {
103
+ codemode = "off";
104
+ }
60
105
  if (codemode !== "off" && !input.available(CODEMODE_TOOL)) {
61
- warnings.push(preset === "codemode"
62
- ? "工具预设 codemode 需要 codemode 工具(不可用),已回退到 default"
106
+ warnings.push(preset === "codemode-only"
107
+ ? "工具预设 codemode-only 需要 codemode 工具(不可用),已回退到 default"
63
108
  : `codemode.mode ${codemode} 需要 codemode 工具(不可用),已忽略`);
64
- if (preset === "codemode")
109
+ if (preset === "codemode-only")
65
110
  preset = "default";
66
111
  codemode = "off";
67
112
  }
@@ -69,12 +114,13 @@ export function resolvePreset(input) {
69
114
  if (codemode === "only")
70
115
  base = [CODEMODE_TOOL];
71
116
  else {
72
- base = [...PRESET_TOOLS[preset === "codemode" ? "default" : preset]];
117
+ base = [...PRESET_TOOLS[preset === "codemode-only" ? "default" : preset]];
73
118
  if (codemode === "on")
74
119
  base.push(CODEMODE_TOOL);
75
120
  }
76
121
  const names = [];
77
- for (const name of applyToolAdjustments(base, input.config.tools?.default)) {
122
+ const adjusted = applyToolAdjustments(base, input.config.tools?.default);
123
+ for (const name of pairCompanions(adjusted, input.available)) {
78
124
  if (input.available(name))
79
125
  names.push(name);
80
126
  else
@@ -3,10 +3,11 @@
3
3
  *
4
4
  * 文本按 `cat -n` 形状返回(行号右对齐 6 位 + Tab);头截断 2000 行 / 50 KB 先到者,末尾提示
5
5
  * `offset` 续读;NUL 嗅探判二进制并拒绝;png / jpg / gif / webp 作为 ImageBlock 返回(MIME 按文件头,
6
- * 与 `--image` / `@图片` 共用 image-file.ts;模型不支持图片或超过 5 MB 时只给路径与尺寸);成功后
7
- * `ctx.markRead(abs)`。
6
+ * 与 `--image` / `@图片` 共用 image-file.ts;模型不支持图片、超过当前端点的单图上限(base64 后,
7
+ * [W5-I] 按端点分档)或任一边 > 8000 px 时只给路径与尺寸);成功后 `ctx.markRead(abs)`。
8
8
  */
9
9
  import type { ToolContext, ToolDefinition, ToolResult } from "./types.js";
10
+ import { type ImageFitOptions } from "./image-file.js";
10
11
  export { imageSize, type ImageSize } from "./image-file.js";
11
12
  export interface ReadInput {
12
13
  path: string;
@@ -16,6 +17,8 @@ export interface ReadInput {
16
17
  export interface ReadToolOptions {
17
18
  /** 当前模型是否接受图片输入;缺省 true。 */
18
19
  supportsImages?(ctx: ToolContext): boolean;
20
+ /** [W5-I] 当前模型的单图上限与缩放设置;缺省 5 MB(base64 后)。 */
21
+ imageOptions?(ctx: ToolContext): ImageFitOptions;
19
22
  }
20
23
  export declare function isBinary(buf: Buffer): boolean;
21
24
  /** `cat -n` 形状。 */
@@ -3,14 +3,14 @@
3
3
  *
4
4
  * 文本按 `cat -n` 形状返回(行号右对齐 6 位 + Tab);头截断 2000 行 / 50 KB 先到者,末尾提示
5
5
  * `offset` 续读;NUL 嗅探判二进制并拒绝;png / jpg / gif / webp 作为 ImageBlock 返回(MIME 按文件头,
6
- * 与 `--image` / `@图片` 共用 image-file.ts;模型不支持图片或超过 5 MB 时只给路径与尺寸);成功后
7
- * `ctx.markRead(abs)`。
6
+ * 与 `--image` / `@图片` 共用 image-file.ts;模型不支持图片、超过当前端点的单图上限(base64 后,
7
+ * [W5-I] 按端点分档)或任一边 > 8000 px 时只给路径与尺寸);成功后 `ctx.markRead(abs)`。
8
8
  */
9
9
  import { readFile, stat } from "node:fs/promises";
10
10
  import { displayPath, resolvePath } from "./paths.js";
11
11
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead } from "./truncate.js";
12
12
  import { normalizeToLF, splitBom } from "./edit-fuzzy.js";
13
- import { MAX_IMAGE_BYTES, imageMimeFromPath, imageSize, sniffImageMime } from "./image-file.js";
13
+ import { MAX_IMAGE_FILE_BYTES, fitImage, imageMimeFromPath, imageSize, sniffImageMime, } from "./image-file.js";
14
14
  export { imageSize } from "./image-file.js";
15
15
  const SNIFF_BYTES = 8000;
16
16
  export function isBinary(buf) {
@@ -38,15 +38,18 @@ async function readImage(abs, shown, ctx, options) {
38
38
  if (options.supportsImages && !options.supportsImages(ctx)) {
39
39
  return { content: `${caption}\n[The current model does not accept image input.]`, details };
40
40
  }
41
- if (buf.length > MAX_IMAGE_BYTES) {
42
- return {
43
- content: `${caption}\n[Image exceeds the ${formatSize(MAX_IMAGE_BYTES)} attachment limit; not attached.]`,
44
- details,
45
- };
41
+ if (buf.length > MAX_IMAGE_FILE_BYTES) {
42
+ return { content: `${caption}\n[Image file is too large to attach.]`, details };
46
43
  }
44
+ const fit = await fitImage(buf, mimeType, options.imageOptions?.(ctx) ?? {}, abs);
45
+ if (!fit.ok)
46
+ return { content: `${caption}\n[${fit.note}]`, details };
47
+ const note = fit.resized !== undefined && fit.size !== undefined
48
+ ? `\n[Resized to ${fit.size.width}x${fit.size.height} to fit the attachment limit.]`
49
+ : "";
47
50
  const blocks = [
48
- { type: "text", text: caption },
49
- { type: "image", data: buf.toString("base64"), mimeType },
51
+ { type: "text", text: caption + note },
52
+ { type: "image", data: fit.buf.toString("base64"), mimeType: fit.mimeType },
50
53
  ];
51
54
  return { content: blocks, details };
52
55
  }
@@ -6,6 +6,8 @@
6
6
  * - `disable(name)` 后不再出现在 `list()` / `active()`,也不能被 `setActive` 选中;未注册的名字也
7
7
  * 记下(宿主可能先 disable 再由内置注册,例如 `disable("task")`);
8
8
  * - 活动集缺省 = 全部已注册且未禁用;`setActive(names)` 之后只用这些(未知名 → tool_not_found);
9
+ * - (W5-C0)伴随工具 `TOOL_COMPANIONS`:`task_ctl` 与 `task` 同进退——`disable("task")` 一并禁用,
10
+ * `setActive` 选了 `task` 时一并选上(预设里的配对在 presets.ts);
9
11
  * - `builtinTools()` 给出全部内置工具;Skill 正文由模型用 read 读取(设计 §5.6 删除了 skill 工具),
10
12
  * `/skill:` 命令展开在 skills/expand.ts。
11
13
  */
@@ -13,6 +15,10 @@ import type { ToolDefinition, ToolExecutionMode, ToolRegistryApi, ToolSource } f
13
15
  import { type ReadToolOptions } from "./read.js";
14
16
  import { type BashToolOptions } from "./bash.js";
15
17
  import { type TaskToolOptions } from "./task.js";
18
+ /** [W5-C0] 主工具 → 随它出现 / 消失的伴随工具。 */
19
+ export declare const TOOL_COMPANIONS: Readonly<Record<string, readonly string[]>>;
20
+ /** 按 `TOOL_COMPANIONS` 配对:有主工具就带上(已注册的)伴随工具,没有就去掉。 */
21
+ export declare function pairCompanions(names: Iterable<string>, available: (name: string) => boolean): string[];
16
22
  export declare const TOOL_NAME_RE: RegExp;
17
23
  /** 未声明时:read → parallel;write / execute → sequential。 */
18
24
  export declare function executionModeOf(tool: Pick<ToolDefinition, "permission" | "executionMode">): ToolExecutionMode;
@@ -35,7 +41,7 @@ export interface BuiltinToolOptions {
35
41
  bash?: BashToolOptions;
36
42
  task?: TaskToolOptions;
37
43
  }
38
- /** 全部内置工具(read / write / edit / bash / grep / glob / ls / todo / task)。 */
44
+ /** 全部内置工具(read / write / edit / bash / grep / glob / ls / todo / task / task_ctl)。 */
39
45
  export declare function builtinTools(options?: BuiltinToolOptions): ToolDefinition[];
40
46
  /** 新建注册表并登记全部内置工具;`disabled` 来自 config.tools.disabled。 */
41
47
  export declare function createToolRegistry(options?: BuiltinToolOptions & {
@@ -6,6 +6,8 @@
6
6
  * - `disable(name)` 后不再出现在 `list()` / `active()`,也不能被 `setActive` 选中;未注册的名字也
7
7
  * 记下(宿主可能先 disable 再由内置注册,例如 `disable("task")`);
8
8
  * - 活动集缺省 = 全部已注册且未禁用;`setActive(names)` 之后只用这些(未知名 → tool_not_found);
9
+ * - (W5-C0)伴随工具 `TOOL_COMPANIONS`:`task_ctl` 与 `task` 同进退——`disable("task")` 一并禁用,
10
+ * `setActive` 选了 `task` 时一并选上(预设里的配对在 presets.ts);
9
11
  * - `builtinTools()` 给出全部内置工具;Skill 正文由模型用 read 读取(设计 §5.6 删除了 skill 工具),
10
12
  * `/skill:` 命令展开在 skills/expand.ts。
11
13
  */
@@ -20,6 +22,24 @@ import { createGlobTool } from "./glob.js";
20
22
  import { createLsTool } from "./ls.js";
21
23
  import { createTodoTool } from "./todo.js";
22
24
  import { createTaskTool } from "./task.js";
25
+ import { TASK_CTL_TOOL, createTaskCtlTool } from "./task-ctl.js";
26
+ /** [W5-C0] 主工具 → 随它出现 / 消失的伴随工具。 */
27
+ export const TOOL_COMPANIONS = Object.freeze({
28
+ task: [TASK_CTL_TOOL],
29
+ });
30
+ /** 按 `TOOL_COMPANIONS` 配对:有主工具就带上(已注册的)伴随工具,没有就去掉。 */
31
+ export function pairCompanions(names, available) {
32
+ const set = new Set(names);
33
+ for (const [main, companions] of Object.entries(TOOL_COMPANIONS)) {
34
+ for (const companion of companions) {
35
+ if (set.has(main) && available(companion))
36
+ set.add(companion);
37
+ else
38
+ set.delete(companion);
39
+ }
40
+ }
41
+ return [...set];
42
+ }
23
43
  export const TOOL_NAME_RE = /^[a-z][a-z0-9_]{1,63}$/;
24
44
  /** 未声明时:read → parallel;write / execute → sequential。 */
25
45
  export function executionModeOf(tool) {
@@ -52,8 +72,10 @@ export class ToolRegistry {
52
72
  this.entries.set(tool.name, { tool, source });
53
73
  }
54
74
  disable(name) {
55
- this.disabled.add(name);
56
- this.activeNames?.delete(name);
75
+ for (const target of [name, ...(TOOL_COMPANIONS[name] ?? [])]) {
76
+ this.disabled.add(target);
77
+ this.activeNames?.delete(target);
78
+ }
57
79
  }
58
80
  isDisabled(name) {
59
81
  return this.disabled.has(name);
@@ -77,10 +99,10 @@ export class ToolRegistry {
77
99
  throw new AmaError("tool_not_found", `Unknown or disabled tool "${name}"`);
78
100
  }
79
101
  }
80
- this.activeNames = new Set(names);
102
+ this.activeNames = new Set(pairCompanions(names, (n) => this.entries.has(n) && !this.disabled.has(n)));
81
103
  }
82
104
  }
83
- /** 全部内置工具(read / write / edit / bash / grep / glob / ls / todo / task)。 */
105
+ /** 全部内置工具(read / write / edit / bash / grep / glob / ls / todo / task / task_ctl)。 */
84
106
  export function builtinTools(options = {}) {
85
107
  const tools = [
86
108
  createReadTool(options.read),
@@ -92,6 +114,7 @@ export function builtinTools(options = {}) {
92
114
  createLsTool(),
93
115
  createTodoTool(),
94
116
  createTaskTool(options.task),
117
+ createTaskCtlTool(),
95
118
  ];
96
119
  return tools;
97
120
  }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `task_ctl` 工具:查看 / 等待 / 停止后台子 Agent 任务,读输出,向任务追加消息
3
+ * (docs/wave5-plan.md §7.3,D13)。[W5-C0 桩 → W5-G]
4
+ *
5
+ * - 与 `task` 同进退(预设、`--tools`、`disable("task")`,见 registry.ts 的 `TOOL_COMPANIONS`);
6
+ * - 控制面按会话 id 取(agents/task-control.ts,注册表登记);子会话里(depth ≥ 1)不可用——工具表
7
+ * 与父一致,运行时拒绝;
8
+ * - `wait` / `output` 是轮询类调用(`annotations.pollable`,重复调用检测豁免);
9
+ * - `send` = 续聊放后台:等价于 `task{taskId, prompt, background:true}`,完成后同样收到通知。
10
+ */
11
+ import type { ToolDefinition } from "./types.js";
12
+ export declare const TASK_CTL_TOOL = "task_ctl";
13
+ export declare const DEFAULT_WAIT_MS = 30000;
14
+ export declare const MAX_WAIT_MS = 600000;
15
+ export interface TaskCtlInput {
16
+ action: "list" | "wait" | "stop" | "output" | "send";
17
+ taskId?: string;
18
+ timeoutMs?: number;
19
+ /** send:追加给任务的消息。 */
20
+ prompt?: string;
21
+ }
22
+ export declare function createTaskCtlTool(): ToolDefinition<TaskCtlInput>;
@@ -0,0 +1,116 @@
1
+ /**
2
+ * `task_ctl` 工具:查看 / 等待 / 停止后台子 Agent 任务,读输出,向任务追加消息
3
+ * (docs/wave5-plan.md §7.3,D13)。[W5-C0 桩 → W5-G]
4
+ *
5
+ * - 与 `task` 同进退(预设、`--tools`、`disable("task")`,见 registry.ts 的 `TOOL_COMPANIONS`);
6
+ * - 控制面按会话 id 取(agents/task-control.ts,注册表登记);子会话里(depth ≥ 1)不可用——工具表
7
+ * 与父一致,运行时拒绝;
8
+ * - `wait` / `output` 是轮询类调用(`annotations.pollable`,重复调用检测豁免);
9
+ * - `send` = 续聊放后台:等价于 `task{taskId, prompt, background:true}`,完成后同样收到通知。
10
+ */
11
+ import { capTaskText, formatTokens } from "../agents/result.js";
12
+ import { taskControl } from "../agents/task-control.js";
13
+ export const TASK_CTL_TOOL = "task_ctl";
14
+ export const DEFAULT_WAIT_MS = 30_000;
15
+ export const MAX_WAIT_MS = 600_000;
16
+ function fail(message) {
17
+ return { content: message, isError: true };
18
+ }
19
+ function line(task, now) {
20
+ const parts = [task.taskId, task.agent, task.status];
21
+ if (task.turns !== undefined)
22
+ parts.push(`${task.turns} turns`);
23
+ if (task.usage !== undefined)
24
+ parts.push(`${formatTokens(task.usage.totalTokens)} tokens`);
25
+ parts.push(`${Math.round(((task.endedAt ?? now) - task.startedAt) / 1000)}s`);
26
+ if (task.background)
27
+ parts.push("background");
28
+ const text = parts.join(" · ");
29
+ return task.description === "" ? text : `${text} — ${task.description}`;
30
+ }
31
+ async function send(input, ctx) {
32
+ if (input.prompt === undefined || input.prompt.trim() === "")
33
+ return fail("send needs a non-empty prompt");
34
+ if (ctx.spawnSubagent === undefined)
35
+ return fail("Sub-agents are not available here.");
36
+ const result = await ctx.spawnSubagent({
37
+ prompt: input.prompt,
38
+ taskId: input.taskId,
39
+ background: true,
40
+ parentToolCallId: ctx.toolCallId,
41
+ signal: ctx.signal,
42
+ });
43
+ return { content: result.text, isError: result.isError };
44
+ }
45
+ export function createTaskCtlTool() {
46
+ return {
47
+ name: TASK_CTL_TOOL,
48
+ label: "TaskCtl",
49
+ description: "Manage sub-agent tasks started by task: list them, wait for one, stop it, read its " +
50
+ "output, or send it a follow-up message (runs in background).",
51
+ parameters: {
52
+ type: "object",
53
+ properties: {
54
+ action: { type: "string", enum: ["list", "wait", "stop", "output", "send"] },
55
+ taskId: { type: "string", description: "Required except for list" },
56
+ timeoutMs: { type: "number", description: `wait only (default ${DEFAULT_WAIT_MS})` },
57
+ prompt: { type: "string", description: "send only" },
58
+ },
59
+ required: ["action"],
60
+ additionalProperties: false,
61
+ },
62
+ permission: "read",
63
+ executionMode: "parallel",
64
+ annotations: { pollable: true },
65
+ async execute(input, ctx) {
66
+ if (ctx.depth >= 1)
67
+ return fail("task_ctl is not available inside a sub-agent.");
68
+ const control = taskControl(ctx.sessionId);
69
+ if (input.action === "list") {
70
+ const tasks = control?.list() ?? ctx.tasks?.list() ?? [];
71
+ if (tasks.length === 0)
72
+ return { content: "No sub-agent tasks." };
73
+ const now = Date.now();
74
+ return { content: tasks.map((task) => line(task, now)).join("\n") };
75
+ }
76
+ const taskId = input.taskId;
77
+ if (taskId === undefined || taskId === "")
78
+ return fail(`${input.action} needs taskId`);
79
+ const info = control?.get(taskId);
80
+ if (control === undefined || info === undefined)
81
+ return fail(`Unknown task ${taskId}.`);
82
+ switch (input.action) {
83
+ case "send":
84
+ return send(input, ctx);
85
+ case "output": {
86
+ const text = control.output(taskId) ?? "";
87
+ const head = info.status === "running" ? `Task ${taskId} is running; output so far:` : "";
88
+ const body = capTaskText(text, info.outputFile).text || "(no output yet)";
89
+ return { content: head === "" ? body : `${head}\n${body}` };
90
+ }
91
+ case "stop": {
92
+ const result = await control.stop(taskId);
93
+ return {
94
+ content: `Task ${taskId} ${result?.status ?? control.get(taskId)?.status ?? "stopped"}.`,
95
+ };
96
+ }
97
+ case "wait": {
98
+ const timeout = Math.min(Math.max(input.timeoutMs ?? DEFAULT_WAIT_MS, 0), MAX_WAIT_MS);
99
+ const result = await control.wait(taskId, timeout);
100
+ if (result === undefined) {
101
+ const turns = control.get(taskId)?.turns ?? 0;
102
+ return {
103
+ content: `Task ${taskId} is still running (${turns} turns so far). Wait again or stop it.`,
104
+ };
105
+ }
106
+ return {
107
+ content: `[task ${taskId} ${result.status ?? "completed"}]\n${result.text}`,
108
+ isError: result.isError,
109
+ };
110
+ }
111
+ default:
112
+ return fail(`unknown action ${String(input.action)}`);
113
+ }
114
+ },
115
+ };
116
+ }
@@ -1,29 +1,41 @@
1
1
  /**
2
- * `task` 工具:同进程子 Agent(设计 §5.2、D14)。[B3]
2
+ * `task` 工具:子 Agent 的统一入口(设计 §5.2、D14;第五波 docs/wave5-plan.md §7.3,D13、D23)。
3
+ * [B3 → W5-G]
3
4
  *
4
- * 子会话由 `ctx.spawnSubagent`(B2 的 AgentSession 提供)创建:独立 JSONL、继承权限模式与 broker、
5
- * 审批串到父。本工具负责:
6
- * - 深度 ≤ 1:`ctx.depth ≥ 1` 或无 `spawnSubagent` → 错误(子 Agent 里没有 task);
7
- * - 并发 ≤ 4:由会话的 `SubagentPool`(agent/session-subagent.ts,`subagents.maxConcurrent`)排队,
8
- * 本工具不再自带一层信号量;排队中父 abort → 子会话抛 aborted,这里返回 aborted;
9
- * - 工具子集:`tools` 里去掉 `task`(缺省交给 spawnSubagent = 父活动集去掉 task);
10
- * - 父 abort 级联:把 `ctx.signal` 传给子;
11
- * - 结果 = 子的最后助手文本 + `details{ sessionFile, usage, stopReason }`。
5
+ * - `agent`:子 Agent 类型(内置 general / explore / plan、`.ama/agents/*.md`)或外部 Agent;缺省
6
+ * general。描述里列出可用类型(catalog 由 compose-agents.ts 经 `bindTaskAgents` 绑定;没绑定时
7
+ * 只列内置类型)。
8
+ * - `background`:立即返回 taskId,完成后父会话收到 `<task-notification>`;`taskId`:向已有子会话
9
+ * 追加消息(续聊,忽略 agent / tools / model);`isolation: "worktree"`:在独立 git worktree 里跑。
10
+ * - **parallel**:同一回复里的多个 task 真并行(会话注册表的池限流,缺省 4);与 sequential 工具
11
+ * (edit 等)同批时仍按 tool-runner 的规则整批串行。
12
+ * - 深度 ≤ 1:子会话的工具表里保留 task(与父字节一致,缓存前缀可复用),运行时在这里拒绝。
13
+ * - 结果 = 子 Agent 的最终报告(> 50 KB 截头尾、全文落 outputs/,见 agents/result.ts)+ details。
12
14
  */
13
15
  import type { ModelThinkingLevel } from "../ai/types.js";
16
+ import { AgentCatalog } from "../agents/catalog.js";
14
17
  import type { SubagentRequest, ToolContext, ToolDefinition } from "./types.js";
15
18
  export declare const MAX_TASK_DEPTH = 1;
16
19
  export declare const DEFAULT_TASK_MAX_TURNS = 30;
17
20
  export interface TaskInput {
18
21
  prompt: string;
22
+ agent?: string;
19
23
  description?: string;
24
+ background?: boolean;
25
+ taskId?: string;
26
+ isolation?: "none" | "worktree";
27
+ budgetUsd?: number;
20
28
  tools?: string[];
21
29
  model?: string;
22
30
  thinkingLevel?: ModelThinkingLevel;
23
31
  maxTurns?: number;
24
32
  }
25
- /** 预留(并发上限在会话的 SubagentPool,见文件头)。 */
33
+ /** 预留(并发上限在会话的任务注册表,见 agent/subagent-registry.ts)。 */
26
34
  export interface TaskToolOptions {
27
35
  }
36
+ /** 描述里类型清单的标题(清单本身另有 400 token 预算,见 agents/catalog.ts)。 */
37
+ export declare const TASK_AGENTS_HEADING = "\nAgents:\n";
38
+ /** 组装根把会话的类型目录绑到 task 工具上(描述里的类型清单)。 */
39
+ export declare function bindTaskAgents(tool: ToolDefinition | undefined, catalog: AgentCatalog): void;
28
40
  export declare function buildSubagentRequest(input: TaskInput, ctx: ToolContext): SubagentRequest | string;
29
41
  export declare function createTaskTool(_options?: TaskToolOptions): ToolDefinition<TaskInput>;