@armadra/agent 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (432) hide show
  1. package/CHANGELOG.md +184 -1
  2. package/README.md +202 -83
  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/session-cache.d.ts +5 -0
  17. package/dist/agent/session-cache.js +17 -1
  18. package/dist/agent/session-classifier.d.ts +1 -1
  19. package/dist/agent/session-classifier.js +3 -1
  20. package/dist/agent/session-compaction.d.ts +35 -6
  21. package/dist/agent/session-compaction.js +157 -31
  22. package/dist/agent/session-core.d.ts +27 -1
  23. package/dist/agent/session-extensions.d.ts +61 -0
  24. package/dist/agent/session-extensions.js +129 -0
  25. package/dist/agent/session-images.d.ts +23 -0
  26. package/dist/agent/session-images.js +97 -0
  27. package/dist/agent/session-plan.d.ts +21 -0
  28. package/dist/agent/session-plan.js +524 -0
  29. package/dist/agent/session-rewind.d.ts +81 -0
  30. package/dist/agent/session-rewind.js +354 -0
  31. package/dist/agent/session-run.d.ts +28 -1
  32. package/dist/agent/session-run.js +157 -6
  33. package/dist/agent/session-settings.d.ts +49 -0
  34. package/dist/agent/session-settings.js +95 -0
  35. package/dist/agent/session-subagent.d.ts +36 -24
  36. package/dist/agent/session-subagent.js +259 -129
  37. package/dist/agent/session-sync.d.ts +10 -3
  38. package/dist/agent/session-sync.js +37 -8
  39. package/dist/agent/session-telemetry.d.ts +39 -0
  40. package/dist/agent/session-telemetry.js +231 -0
  41. package/dist/agent/session-tools.js +40 -1
  42. package/dist/agent/session.d.ts +30 -29
  43. package/dist/agent/session.js +79 -123
  44. package/dist/agent/subagent-registry.d.ts +91 -0
  45. package/dist/agent/subagent-registry.js +494 -0
  46. package/dist/agent/system-prompt.d.ts +6 -3
  47. package/dist/agent/system-prompt.js +7 -2
  48. package/dist/agent/tool-runner.d.ts +8 -1
  49. package/dist/agent/tool-runner.js +57 -4
  50. package/dist/agent/types-w5.d.ts +192 -0
  51. package/dist/agent/types-w5.js +10 -0
  52. package/dist/agent/types.d.ts +47 -4
  53. package/dist/agent/types.js +2 -0
  54. package/dist/agent/worktree.d.ts +36 -0
  55. package/dist/agent/worktree.js +86 -0
  56. package/dist/agents/builtin.d.ts +14 -0
  57. package/dist/agents/builtin.js +39 -0
  58. package/dist/agents/catalog.d.ts +43 -0
  59. package/dist/agents/catalog.js +82 -0
  60. package/dist/agents/discover.d.ts +35 -0
  61. package/dist/agents/discover.js +83 -0
  62. package/dist/agents/external.d.ts +82 -0
  63. package/dist/agents/external.js +326 -0
  64. package/dist/agents/parse.d.ts +18 -0
  65. package/dist/agents/parse.js +116 -0
  66. package/dist/agents/result.d.ts +32 -0
  67. package/dist/agents/result.js +67 -0
  68. package/dist/agents/task-control.d.ts +17 -0
  69. package/dist/agents/task-control.js +17 -0
  70. package/dist/agents/task-record.d.ts +78 -0
  71. package/dist/agents/task-record.js +141 -0
  72. package/dist/agents/types.d.ts +46 -0
  73. package/dist/agents/types.js +8 -0
  74. package/dist/ai/apis/anthropic-compat.d.ts +36 -0
  75. package/dist/ai/apis/anthropic-compat.js +92 -0
  76. package/dist/ai/apis/anthropic-request.d.ts +7 -6
  77. package/dist/ai/apis/anthropic-request.js +10 -28
  78. package/dist/ai/apis/cache-params.d.ts +11 -2
  79. package/dist/ai/apis/cache-params.js +25 -6
  80. package/dist/ai/apis/openai-compat.d.ts +4 -1
  81. package/dist/ai/apis/openai-compat.js +8 -1
  82. package/dist/ai/image-limits.d.ts +45 -0
  83. package/dist/ai/image-limits.js +68 -0
  84. package/dist/ai/providers/builtin.d.ts +18 -6
  85. package/dist/ai/providers/builtin.js +135 -6
  86. package/dist/ai/providers/catalog-data.js +17 -13
  87. package/dist/ai/providers/catalog.d.ts +60 -7
  88. package/dist/ai/providers/catalog.js +197 -38
  89. package/dist/ai/providers/channels.d.ts +33 -3
  90. package/dist/ai/providers/channels.js +108 -7
  91. package/dist/ai/providers/enrich.d.ts +6 -3
  92. package/dist/ai/providers/enrich.js +19 -4
  93. package/dist/ai/providers/models-dev-cache.d.ts +28 -24
  94. package/dist/ai/providers/models-dev-cache.js +92 -78
  95. package/dist/ai/providers/models-dev-data.d.ts +7 -0
  96. package/dist/ai/providers/models-dev-data.js +32 -0
  97. package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
  98. package/dist/ai/providers/models-dev-snapshot.js +137 -0
  99. package/dist/ai/providers/models-dev.d.ts +51 -10
  100. package/dist/ai/providers/models-dev.js +132 -39
  101. package/dist/ai/providers/registry.d.ts +20 -10
  102. package/dist/ai/providers/registry.js +82 -43
  103. package/dist/ai/types.d.ts +28 -2
  104. package/dist/ai/types.js +5 -0
  105. package/dist/bundle/ama.cjs +37605 -21619
  106. package/dist/checkpoints/backend.d.ts +61 -0
  107. package/dist/checkpoints/backend.js +135 -0
  108. package/dist/checkpoints/blobs.d.ts +60 -0
  109. package/dist/checkpoints/blobs.js +203 -0
  110. package/dist/checkpoints/gc.d.ts +47 -0
  111. package/dist/checkpoints/gc.js +144 -0
  112. package/dist/checkpoints/git-head.d.ts +15 -0
  113. package/dist/checkpoints/git-head.js +89 -0
  114. package/dist/checkpoints/index.d.ts +17 -0
  115. package/dist/checkpoints/index.js +17 -0
  116. package/dist/checkpoints/replay.d.ts +48 -0
  117. package/dist/checkpoints/replay.js +154 -0
  118. package/dist/checkpoints/restore.d.ts +86 -0
  119. package/dist/checkpoints/restore.js +263 -0
  120. package/dist/checkpoints/settings.d.ts +14 -0
  121. package/dist/checkpoints/settings.js +23 -0
  122. package/dist/checkpoints/shadow-git.d.ts +108 -0
  123. package/dist/checkpoints/shadow-git.js +491 -0
  124. package/dist/checkpoints/shadow-restore.d.ts +25 -0
  125. package/dist/checkpoints/shadow-restore.js +128 -0
  126. package/dist/checkpoints/tracker.d.ts +64 -0
  127. package/dist/checkpoints/tracker.js +192 -0
  128. package/dist/checkpoints/types.d.ts +99 -0
  129. package/dist/checkpoints/types.js +12 -0
  130. package/dist/cli/args.d.ts +8 -4
  131. package/dist/cli/args.js +17 -97
  132. package/dist/cli/bootstrap.js +13 -1
  133. package/dist/cli/choice-prompt.d.ts +58 -0
  134. package/dist/cli/choice-prompt.js +140 -0
  135. package/dist/cli/codemode-notice.d.ts +3 -2
  136. package/dist/cli/codemode-notice.js +3 -2
  137. package/dist/cli/compose-agents.d.ts +27 -0
  138. package/dist/cli/compose-agents.js +111 -0
  139. package/dist/cli/compose-extensions.d.ts +29 -0
  140. package/dist/cli/compose-extensions.js +44 -0
  141. package/dist/cli/compose-session.d.ts +3 -0
  142. package/dist/cli/compose-session.js +47 -4
  143. package/dist/cli/compose.d.ts +3 -0
  144. package/dist/cli/compose.js +33 -6
  145. package/dist/cli/deps.d.ts +6 -0
  146. package/dist/cli/exit-codes.d.ts +10 -0
  147. package/dist/cli/exit-codes.js +12 -0
  148. package/dist/cli/help-text.d.ts +4 -0
  149. package/dist/cli/help-text.js +102 -0
  150. package/dist/cli/startup-screen.js +5 -3
  151. package/dist/cli/startup-steps.js +7 -1
  152. package/dist/cli/subcommands/config.d.ts +4 -1
  153. package/dist/cli/subcommands/config.js +17 -6
  154. package/dist/cli/subcommands/doctor.js +21 -0
  155. package/dist/cli/subcommands/models-cache-probe.d.ts +1 -1
  156. package/dist/cli/subcommands/models-cache-probe.js +3 -12
  157. package/dist/cli/subcommands/models-discover.js +5 -6
  158. package/dist/cli/subcommands/models.d.ts +2 -0
  159. package/dist/cli/subcommands/models.js +33 -14
  160. package/dist/cli/subcommands/providers.d.ts +1 -1
  161. package/dist/cli/subcommands/providers.js +8 -15
  162. package/dist/cli/subcommands/sessions.d.ts +3 -1
  163. package/dist/cli/subcommands/sessions.js +36 -2
  164. package/dist/codemode/capability.d.ts +24 -7
  165. package/dist/codemode/capability.js +38 -10
  166. package/dist/codemode/host-side.d.ts +14 -0
  167. package/dist/codemode/host-side.js +24 -1
  168. package/dist/codemode/tool.d.ts +1 -1
  169. package/dist/codemode/tool.js +6 -4
  170. package/dist/compaction/breaker.d.ts +25 -9
  171. package/dist/compaction/breaker.js +47 -17
  172. package/dist/compaction/estimate.d.ts +11 -3
  173. package/dist/compaction/estimate.js +64 -22
  174. package/dist/compaction/image-budget.d.ts +45 -0
  175. package/dist/compaction/image-budget.js +115 -0
  176. package/dist/compaction/post-compact.d.ts +38 -0
  177. package/dist/compaction/post-compact.js +152 -0
  178. package/dist/compaction/protect.d.ts +27 -0
  179. package/dist/compaction/protect.js +56 -0
  180. package/dist/compaction/prune-tier.d.ts +58 -12
  181. package/dist/compaction/prune-tier.js +120 -54
  182. package/dist/compaction/summarize-tier.d.ts +23 -4
  183. package/dist/compaction/summarize-tier.js +100 -29
  184. package/dist/config/checker.d.ts +28 -0
  185. package/dist/config/checker.js +97 -0
  186. package/dist/config/json-schema.js +63 -2
  187. package/dist/config/key-docs.js +72 -3
  188. package/dist/config/merge.d.ts +5 -3
  189. package/dist/config/merge.js +81 -7
  190. package/dist/config/profile.d.ts +2 -0
  191. package/dist/config/profile.js +2 -0
  192. package/dist/config/schema-w5.d.ts +18 -0
  193. package/dist/config/schema-w5.js +109 -0
  194. package/dist/config/schema.d.ts +5 -9
  195. package/dist/config/schema.js +68 -114
  196. package/dist/config/types-w5.d.ts +118 -0
  197. package/dist/config/types-w5.js +20 -0
  198. package/dist/config/types.d.ts +50 -1
  199. package/dist/config/types.js +12 -0
  200. package/dist/drivers/acp/client.d.ts +57 -0
  201. package/dist/drivers/acp/client.js +160 -0
  202. package/dist/drivers/acp/driver.d.ts +31 -0
  203. package/dist/drivers/acp/driver.js +274 -0
  204. package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
  205. package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
  206. package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
  207. package/dist/drivers/acp/testing/fake-agent.js +211 -0
  208. package/dist/drivers/acp/types.d.ts +285 -0
  209. package/dist/drivers/acp/types.js +36 -0
  210. package/dist/drivers/agents.d.ts +58 -0
  211. package/dist/drivers/agents.js +142 -0
  212. package/dist/drivers/base.d.ts +35 -0
  213. package/dist/drivers/base.js +59 -0
  214. package/dist/drivers/catalog.d.ts +46 -0
  215. package/dist/drivers/catalog.js +167 -0
  216. package/dist/drivers/env.d.ts +20 -0
  217. package/dist/drivers/env.js +46 -0
  218. package/dist/drivers/host-runners.d.ts +18 -0
  219. package/dist/drivers/host-runners.js +45 -0
  220. package/dist/drivers/jsonrpc.d.ts +58 -0
  221. package/dist/drivers/jsonrpc.js +180 -0
  222. package/dist/drivers/native/claude-normalize.d.ts +46 -0
  223. package/dist/drivers/native/claude-normalize.js +106 -0
  224. package/dist/drivers/native/claude-stream.d.ts +29 -0
  225. package/dist/drivers/native/claude-stream.js +456 -0
  226. package/dist/drivers/native/codex-app-server.d.ts +26 -0
  227. package/dist/drivers/native/codex-app-server.js +407 -0
  228. package/dist/drivers/native/codex-normalize.d.ts +38 -0
  229. package/dist/drivers/native/codex-normalize.js +124 -0
  230. package/dist/drivers/native/oneshot.d.ts +28 -0
  231. package/dist/drivers/native/oneshot.js +312 -0
  232. package/dist/drivers/permissions.d.ts +40 -0
  233. package/dist/drivers/permissions.js +92 -0
  234. package/dist/drivers/pids.d.ts +32 -0
  235. package/dist/drivers/pids.js +93 -0
  236. package/dist/drivers/pool.d.ts +28 -0
  237. package/dist/drivers/pool.js +96 -0
  238. package/dist/drivers/probe.d.ts +47 -0
  239. package/dist/drivers/probe.js +172 -0
  240. package/dist/drivers/process.d.ts +48 -0
  241. package/dist/drivers/process.js +100 -0
  242. package/dist/drivers/runner.d.ts +61 -0
  243. package/dist/drivers/runner.js +388 -0
  244. package/dist/drivers/store.d.ts +49 -0
  245. package/dist/drivers/store.js +91 -0
  246. package/dist/drivers/turn.d.ts +41 -0
  247. package/dist/drivers/turn.js +99 -0
  248. package/dist/drivers/types.d.ts +122 -0
  249. package/dist/drivers/types.js +11 -0
  250. package/dist/git/info.d.ts +75 -0
  251. package/dist/git/info.js +191 -0
  252. package/dist/hooks/protocol.js +6 -1
  253. package/dist/hooks/types.d.ts +10 -1
  254. package/dist/hooks/types.js +2 -0
  255. package/dist/host/api-impl.d.ts +7 -0
  256. package/dist/host/api-impl.js +15 -0
  257. package/dist/host/types.d.ts +24 -2
  258. package/dist/host/types.js +4 -0
  259. package/dist/index.d.ts +3 -0
  260. package/dist/index.js +1 -0
  261. package/dist/modes/acp/acp-events.d.ts +46 -0
  262. package/dist/modes/acp/acp-events.js +233 -0
  263. package/dist/modes/acp/acp-mode.d.ts +17 -0
  264. package/dist/modes/acp/acp-mode.js +47 -0
  265. package/dist/modes/acp/acp-server.d.ts +79 -0
  266. package/dist/modes/acp/acp-server.js +315 -0
  267. package/dist/modes/commands-core.d.ts +13 -1
  268. package/dist/modes/commands-core.js +64 -0
  269. package/dist/modes/image-input.d.ts +12 -4
  270. package/dist/modes/image-input.js +22 -5
  271. package/dist/modes/interactive/agent-panels.d.ts +14 -0
  272. package/dist/modes/interactive/agent-panels.js +103 -0
  273. package/dist/modes/interactive/agent-ui.d.ts +73 -0
  274. package/dist/modes/interactive/agent-ui.js +234 -0
  275. package/dist/modes/interactive/approval-dialog.d.ts +21 -4
  276. package/dist/modes/interactive/approval-dialog.js +98 -20
  277. package/dist/modes/interactive/approval-merge.d.ts +41 -0
  278. package/dist/modes/interactive/approval-merge.js +89 -0
  279. package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
  280. package/dist/modes/interactive/clipboard-paste.js +28 -0
  281. package/dist/modes/interactive/commands.d.ts +12 -1
  282. package/dist/modes/interactive/commands.js +31 -1
  283. package/dist/modes/interactive/confirm-dialog.d.ts +49 -0
  284. package/dist/modes/interactive/confirm-dialog.js +121 -0
  285. package/dist/modes/interactive/double-esc.d.ts +20 -0
  286. package/dist/modes/interactive/double-esc.js +34 -0
  287. package/dist/modes/interactive/event-notices.d.ts +32 -0
  288. package/dist/modes/interactive/event-notices.js +79 -0
  289. package/dist/modes/interactive/external-editor.d.ts +16 -0
  290. package/dist/modes/interactive/external-editor.js +39 -0
  291. package/dist/modes/interactive/interactive-mode.d.ts +14 -1
  292. package/dist/modes/interactive/interactive-mode.js +140 -136
  293. package/dist/modes/interactive/key-dispatch.d.ts +22 -2
  294. package/dist/modes/interactive/key-dispatch.js +66 -7
  295. package/dist/modes/interactive/line/line-mode.d.ts +4 -1
  296. package/dist/modes/interactive/line/line-mode.js +31 -5
  297. package/dist/modes/interactive/line/line-render.d.ts +2 -1
  298. package/dist/modes/interactive/line/line-render.js +40 -4
  299. package/dist/modes/interactive/message-view.d.ts +1 -1
  300. package/dist/modes/interactive/message-view.js +24 -2
  301. package/dist/modes/interactive/panels.d.ts +18 -1
  302. package/dist/modes/interactive/panels.js +19 -5
  303. package/dist/modes/interactive/plan-command.d.ts +40 -0
  304. package/dist/modes/interactive/plan-command.js +129 -0
  305. package/dist/modes/interactive/plan-dialog.d.ts +98 -0
  306. package/dist/modes/interactive/plan-dialog.js +290 -0
  307. package/dist/modes/interactive/plan-flow.d.ts +34 -0
  308. package/dist/modes/interactive/plan-flow.js +98 -0
  309. package/dist/modes/interactive/rewind-command.d.ts +31 -0
  310. package/dist/modes/interactive/rewind-command.js +106 -0
  311. package/dist/modes/interactive/rewind-flow.d.ts +37 -0
  312. package/dist/modes/interactive/rewind-flow.js +151 -0
  313. package/dist/modes/interactive/rewind-list.d.ts +36 -0
  314. package/dist/modes/interactive/rewind-list.js +123 -0
  315. package/dist/modes/interactive/rewind-panel.d.ts +77 -0
  316. package/dist/modes/interactive/rewind-panel.js +309 -0
  317. package/dist/modes/interactive/rewind-text.d.ts +40 -0
  318. package/dist/modes/interactive/rewind-text.js +139 -0
  319. package/dist/modes/interactive/session-events.d.ts +24 -0
  320. package/dist/modes/interactive/session-events.js +96 -0
  321. package/dist/modes/interactive/startup-ui.js +5 -1
  322. package/dist/modes/interactive/status-area.d.ts +73 -0
  323. package/dist/modes/interactive/status-area.js +190 -0
  324. package/dist/modes/interactive/status-bar.d.ts +99 -11
  325. package/dist/modes/interactive/status-bar.js +273 -90
  326. package/dist/modes/interactive/status-line.d.ts +33 -0
  327. package/dist/modes/interactive/status-line.js +113 -0
  328. package/dist/modes/interactive/subagent-view.d.ts +56 -0
  329. package/dist/modes/interactive/subagent-view.js +154 -0
  330. package/dist/modes/interactive/tasks-report.d.ts +27 -0
  331. package/dist/modes/interactive/tasks-report.js +114 -0
  332. package/dist/modes/interactive/tool-view.d.ts +12 -2
  333. package/dist/modes/interactive/tool-view.js +34 -4
  334. package/dist/modes/print/print-mode.d.ts +13 -4
  335. package/dist/modes/print/print-mode.js +56 -12
  336. package/dist/modes/rpc/commands.d.ts +9 -0
  337. package/dist/modes/rpc/commands.js +44 -0
  338. package/dist/modes/rpc/rpc-mode.js +7 -1
  339. package/dist/modes/session-report.d.ts +11 -0
  340. package/dist/modes/session-report.js +48 -1
  341. package/dist/permissions/auto-safe.d.ts +5 -0
  342. package/dist/permissions/auto-safe.js +18 -0
  343. package/dist/permissions/bypass.d.ts +32 -0
  344. package/dist/permissions/bypass.js +36 -0
  345. package/dist/permissions/classifier.d.ts +4 -0
  346. package/dist/permissions/classifier.js +2 -0
  347. package/dist/permissions/modes.js +1 -1
  348. package/dist/permissions/pipeline.d.ts +43 -4
  349. package/dist/permissions/pipeline.js +114 -9
  350. package/dist/permissions/readonly-bash.d.ts +30 -0
  351. package/dist/permissions/readonly-bash.js +118 -0
  352. package/dist/permissions/types.d.ts +42 -0
  353. package/dist/plan/compose.d.ts +9 -0
  354. package/dist/plan/compose.js +19 -0
  355. package/dist/plan/controller.d.ts +71 -0
  356. package/dist/plan/controller.js +27 -0
  357. package/dist/plan/done-markers.d.ts +17 -0
  358. package/dist/plan/done-markers.js +51 -0
  359. package/dist/plan/extract.d.ts +29 -0
  360. package/dist/plan/extract.js +160 -0
  361. package/dist/plan/prompts.d.ts +36 -0
  362. package/dist/plan/prompts.js +89 -0
  363. package/dist/plan/store.d.ts +37 -0
  364. package/dist/plan/store.js +90 -0
  365. package/dist/rpc.d.ts +58 -2
  366. package/dist/rpc.js +7 -0
  367. package/dist/sandbox/bash.d.ts +74 -0
  368. package/dist/sandbox/bash.js +126 -0
  369. package/dist/sandbox/detect.d.ts +48 -0
  370. package/dist/sandbox/detect.js +149 -0
  371. package/dist/sandbox/index.d.ts +5 -0
  372. package/dist/sandbox/index.js +5 -0
  373. package/dist/sandbox/profile.d.ts +33 -0
  374. package/dist/sandbox/profile.js +76 -0
  375. package/dist/sandbox/wrap.d.ts +29 -0
  376. package/dist/sandbox/wrap.js +117 -0
  377. package/dist/sdk.d.ts +33 -2
  378. package/dist/sdk.js +24 -2
  379. package/dist/session/types.d.ts +3 -1
  380. package/dist/session/types.js +1 -0
  381. package/dist/skills/builtin.d.ts +31 -0
  382. package/dist/skills/builtin.js +109 -0
  383. package/dist/skills/discover.d.ts +2 -1
  384. package/dist/skills/index-prompt.js +5 -8
  385. package/dist/tools/background-jobs.d.ts +71 -0
  386. package/dist/tools/background-jobs.js +198 -0
  387. package/dist/tools/bash.d.ts +53 -1
  388. package/dist/tools/bash.js +158 -7
  389. package/dist/tools/clipboard-image.d.ts +44 -0
  390. package/dist/tools/clipboard-image.js +148 -0
  391. package/dist/tools/edit.d.ts +2 -0
  392. package/dist/tools/edit.js +18 -3
  393. package/dist/tools/image-file.d.ts +38 -3
  394. package/dist/tools/image-file.js +81 -10
  395. package/dist/tools/image-resize.d.ts +58 -0
  396. package/dist/tools/image-resize.js +97 -0
  397. package/dist/tools/presets.d.ts +7 -2
  398. package/dist/tools/presets.js +11 -4
  399. package/dist/tools/read.d.ts +5 -2
  400. package/dist/tools/read.js +13 -10
  401. package/dist/tools/registry.d.ts +7 -1
  402. package/dist/tools/registry.js +27 -4
  403. package/dist/tools/task-ctl.d.ts +22 -0
  404. package/dist/tools/task-ctl.js +116 -0
  405. package/dist/tools/task.d.ts +22 -10
  406. package/dist/tools/task.js +66 -26
  407. package/dist/tools/todo.d.ts +22 -2
  408. package/dist/tools/todo.js +58 -14
  409. package/dist/tools/truncate.d.ts +15 -0
  410. package/dist/tools/truncate.js +25 -0
  411. package/dist/tools/types.d.ts +113 -0
  412. package/dist/tools/types.js +5 -0
  413. package/dist/tools/write.js +3 -0
  414. package/dist/tui/glyphs.d.ts +4 -0
  415. package/dist/tui/glyphs.js +4 -0
  416. package/dist/tui/keybindings.d.ts +6 -1
  417. package/dist/tui/keybindings.js +6 -1
  418. package/docs/acp.md +78 -0
  419. package/docs/agents.md +250 -0
  420. package/docs/codemode.md +12 -8
  421. package/docs/hooks.md +26 -22
  422. package/docs/permissions.md +78 -13
  423. package/docs/plan.md +107 -0
  424. package/docs/providers.md +228 -52
  425. package/docs/rewind-plan.md +181 -0
  426. package/docs/rpc.md +92 -5
  427. package/docs/sandbox.md +215 -0
  428. package/docs/session-format.md +41 -21
  429. package/docs/sessions.md +41 -1
  430. package/docs/tui-design.md +751 -0
  431. package/docs/tui.md +179 -21
  432. package/package.json +13 -2
@@ -7,19 +7,25 @@
7
7
  * `tool_execution_end` 按完成顺序发;toolResult 消息按原序发 `message_start/end`(入转录)。
8
8
  * `terminate` 要整批都为真才提前结束。`stopReason: "length"` 且有工具调用 → 整批判失败不执行。
9
9
  * abort:未开始的调用直接给 `aborted by user` 错误结果;执行中的工具收到 signal,超过宽限期仍未结束
10
- * 则不再等待、记 `aborted by user`。结果超 `maxToolResultChars` 截断并把全文写到 `outputDir`。
10
+ * 则不再等待、记 `aborted by user`。结果超 `maxToolResultChars` 截断并把全文写到 `outputDir`:
11
+ * [W5-H2] 保留头 70% + 尾 30%,中间 `[… N 字符已省略,全文 <path>]`(tools/truncate.ts)。
11
12
  *
12
13
  * 嵌套调用(`ToolContext.tools.executeTool`,codemode 脚本里的 `tools.*`)走 `runSingleToolCall`:
13
14
  * 同一套校验与门禁,按**全部未禁用工具**查找(codemode only 模式下活动集只有 codemode),
14
15
  * 发带 `parentToolCallId` 的 `tool_execution_start / update / end`(不入转录),门禁与 PostToolUse
15
16
  * 拿到 `parent`(Hook 输入的 `viaCodemode / parentToolCallId`);结果给脚本而不是模型,截断上限放宽到
16
17
  * `NESTED_MAX_RESULT_CHARS`。
18
+ *
19
+ * [W5-H2] 重复调用检测(loop-guard.ts)只看顶层调用:同 run 同名同参第 3、4 次在结果末尾追加提醒,
20
+ * 第 5 次不执行、给错误结果,整批返回 `stop: "repeated_tool_call"`(循环据此结束 run)。
17
21
  */
18
22
  import { mkdirSync, writeFileSync } from "node:fs";
19
23
  import { join } from "node:path";
24
+ import { REPEATED_TOOL_CALL, guardFor, loopReminderText, loopStopText, } from "./loop-guard.js";
20
25
  import { formatSchemaErrors, validateSchema } from "./schema.js";
21
26
  import { CODEMODE_TOOL } from "../tools/presets.js";
22
27
  import { executionModeOf } from "../tools/registry.js";
28
+ import { truncateMiddle } from "../tools/truncate.js";
23
29
  export const ABORTED_TOOL_TEXT = "aborted by user";
24
30
  export const DEFAULT_MAX_TOOL_RESULT_CHARS = 30_000;
25
31
  export const DEFAULT_ABORT_GRACE_MS = 3000;
@@ -139,10 +145,10 @@ function truncateResult(call, result, options, nested = false) {
139
145
  const images = typeof result.content === "string"
140
146
  ? []
141
147
  : result.content.filter((block) => block.type === "image");
142
- const head = `${text.slice(0, limit)}\n\n[输出过长已截断:共 ${text.length} 字符,${where}]`;
148
+ const { content } = truncateMiddle(text, limit, (omitted) => `[… ${omitted} 字符已省略(输出过长已截断:共 ${text.length} 字符,${where})]`);
143
149
  return {
144
150
  ...result,
145
- content: images.length > 0 ? [{ type: "text", text: head }, ...images] : head,
151
+ content: images.length > 0 ? [{ type: "text", text: content }, ...images] : content,
146
152
  };
147
153
  }
148
154
  async function execute(prepared, options, signal, emit, parent) {
@@ -227,6 +233,9 @@ async function emitResultMessages(finalized, emit) {
227
233
  export async function runToolBatch(assistant, options, signal, emit) {
228
234
  const calls = toolCallsOf(assistant);
229
235
  const preparedList = [];
236
+ const guard = guardFor(signal);
237
+ const verdicts = new Map();
238
+ let stop;
230
239
  for (const call of calls) {
231
240
  await emit({
232
241
  type: "tool_execution_start",
@@ -234,6 +243,15 @@ export async function runToolBatch(assistant, options, signal, emit) {
234
243
  toolName: call.name,
235
244
  args: call.arguments,
236
245
  });
246
+ const verdict = guard.observe(call, options.getTool(call.name));
247
+ verdicts.set(call, verdict);
248
+ if (verdict === "stop") {
249
+ stop = REPEATED_TOOL_CALL;
250
+ const result = errorResult(loopStopText(call.name, guard.count(call)));
251
+ await emitEnd(call, result, emit);
252
+ preparedList.push({ kind: "immediate", call, result });
253
+ continue;
254
+ }
237
255
  const prepared = await prepare(call, assistant, options, signal);
238
256
  if (prepared.kind === "immediate")
239
257
  await emitEnd(call, prepared.result, emit);
@@ -262,9 +280,44 @@ export async function runToolBatch(assistant, options, signal, emit) {
262
280
  }));
263
281
  finalized.push(...results);
264
282
  }
283
+ appendBatchSuffix(finalized, signal, stop);
284
+ for (const item of finalized) {
285
+ if (verdicts.get(item.call) === "remind")
286
+ item.result = withReminder(item.result, loopReminderText(item.call.name, guard.count(item.call)));
287
+ }
265
288
  const messages = await emitResultMessages(finalized, emit);
266
289
  const terminate = finalized.length > 0 && finalized.every(({ result }) => result.terminate === true);
267
- return { messages, terminate };
290
+ return stop === undefined ? { messages, terminate } : { messages, terminate, stop };
291
+ }
292
+ /**
293
+ * [W5-H2] 本 run 的「批次尾部提醒」来源(reminders.ts 在 agent_start 时以 run 的 signal 登记):
294
+ * 每个工具批次结束时取一次,非空就追加在本批**最后一条**结果末尾——run 进行中的提醒(todo 复述、
295
+ * 文件改动、上下文用量、预算、后台命令退出)由此进上下文,只改新结果、不碰前缀。
296
+ */
297
+ const batchSuffixSources = new WeakMap();
298
+ export function setBatchSuffixSource(signal, source) {
299
+ batchSuffixSources.set(signal, source);
300
+ }
301
+ function appendBatchSuffix(finalized, signal, stop) {
302
+ const last = finalized.at(-1);
303
+ if (last === undefined || stop !== undefined || signal.aborted)
304
+ return;
305
+ let suffix;
306
+ try {
307
+ suffix = batchSuffixSources.get(signal)?.();
308
+ }
309
+ catch {
310
+ suffix = undefined;
311
+ }
312
+ if (suffix !== undefined && suffix !== "")
313
+ last.result = withReminder(last.result, suffix);
314
+ }
315
+ /** 在结果末尾追加一段文本(字符串结果拼接,块数组追加 text 块)。 */
316
+ function withReminder(result, text) {
317
+ const content = typeof result.content === "string"
318
+ ? `${result.content}\n\n${text}`
319
+ : [...result.content, { type: "text", text }];
320
+ return { ...result, content };
268
321
  }
269
322
  /** `length` 截断的助手消息:整批判失败,不执行。 */
270
323
  export async function failTruncatedBatch(assistant, emit) {
@@ -0,0 +1,192 @@
1
+ /**
2
+ * 第五波会话契约(docs/wave5-plan.md §1.3、§5.4、§6.3、§6.5、§7.5、§8.3;[W5-C0])。
3
+ *
4
+ * 这里放新增事件的载荷与 `SessionStats` 的扩展形状,由 agent/types.ts 并入 `SessionEvent` /
5
+ * `SessionStats` 并再导出(agent/types.ts 已接近 600 行)。全部是新增事件与可选字段:
6
+ * `RpcEvent` 由 `SessionEvent` 派生,新事件自动上线;`RPC_PROTOCOL_VERSION` 不变。
7
+ * 实现归各批次:遥测 W5-A、子 Agent W5-G(外部 runner W5-E)、计划 / todo W5-F、
8
+ * 预算 / 回退 / 后台命令 W5-H2。
9
+ */
10
+ import type { ModelRef, Usage } from "../ai/types.js";
11
+ import type { PermissionMode } from "../permissions/types.js";
12
+ import type { SubagentStatus } from "../tools/types.js";
13
+ export type { SubagentStatus } from "../tools/types.js";
14
+ /** 一次 `purpose: "turn"` 请求的速率数据。 */
15
+ export interface RequestTelemetry {
16
+ requestAt: number;
17
+ /** 首个 text_delta / thinking_delta / toolcall_start。 */
18
+ firstTokenAt?: number;
19
+ doneAt?: number;
20
+ /** usage.output(含 reasoning);流式期间用增量字符估算。 */
21
+ outputTokens?: number;
22
+ /** outputTokens / (doneAt − firstTokenAt)。 */
23
+ tps?: number;
24
+ ttftMs?: number;
25
+ }
26
+ export interface SessionTelemetry {
27
+ /** 最近一次 turn 请求。 */
28
+ last?: RequestTelemetry;
29
+ /** 流式中(2 s 滑动窗口)。 */
30
+ live?: {
31
+ tps: number;
32
+ outputTokens: number;
33
+ elapsedMs: number;
34
+ };
35
+ /** 会话内全部 turn 请求的 Σoutput / Σ(done − firstToken)。 */
36
+ avgTps?: number;
37
+ /** 本进程打开该会话的时刻(不是会话文件创建时间)。 */
38
+ sessionStartedAt: number;
39
+ }
40
+ /** 外部 Agent 的用量单位(Codex 订阅 token、Copilot premium request 等不换算美元)。 */
41
+ export type ExternalUsageUnit = "usd" | "tokens" | "requests";
42
+ export interface SubagentStartEvent {
43
+ type: "subagent_start";
44
+ taskId: string;
45
+ parentToolCallId: string;
46
+ /** 子 Agent 类型(`general` / `explore` / 定义文件名 / 外部 Agent id)。 */
47
+ agent: string;
48
+ /** `ama` | `claude` | `codex` | `acp:<program>` | 宿主 runner id。 */
49
+ runner: string;
50
+ description: string;
51
+ background: boolean;
52
+ model?: string;
53
+ sessionFile?: string;
54
+ cwd: string;
55
+ }
56
+ export interface SubagentUpdateEvent {
57
+ type: "subagent_update";
58
+ taskId: string;
59
+ kind: "tool" | "text" | "turn";
60
+ toolName?: string;
61
+ /** 文本增量(节流 ≥ 250 ms 合并)。 */
62
+ textDelta?: string;
63
+ turn: number;
64
+ usage?: Usage;
65
+ }
66
+ export interface SubagentEndEvent {
67
+ type: "subagent_end";
68
+ taskId: string;
69
+ status: SubagentStatus;
70
+ /** 外部 runner 可能拿不到 token 用量。 */
71
+ usage?: Usage;
72
+ cache?: {
73
+ hitRate?: number;
74
+ reBilledTokens: number;
75
+ };
76
+ /** 全文结果(> 50 KB 截断时)。 */
77
+ outputFile?: string;
78
+ worktree?: {
79
+ branch: string;
80
+ changed: boolean;
81
+ };
82
+ }
83
+ export interface PlanStep {
84
+ /** `S1`、`S2` …;编号列表时按序号生成。 */
85
+ id: string;
86
+ text: string;
87
+ dependsOn?: string[];
88
+ /** 建议执行者(`[agent: codex]`)。 */
89
+ agent?: string;
90
+ }
91
+ /** `custom{customType:"ama.plan"}` 的 data,也是 RPC `get_plan` 的返回。 */
92
+ export interface PlanData {
93
+ id: string;
94
+ version: number;
95
+ status: "proposed" | "approved" | "rejected" | "superseded";
96
+ markdown: string;
97
+ steps: PlanStep[];
98
+ sourceEntryId: string;
99
+ filePath?: string;
100
+ }
101
+ /** `custom{customType:"ama.plan_state"}` 的 data(resume 回到 plan 模式)。 */
102
+ export interface PlanStateData {
103
+ active: boolean;
104
+ prePlanMode: PermissionMode;
105
+ planId?: string;
106
+ }
107
+ /** 审批四选项 + 拒绝(Esc)。 */
108
+ export type PlanDecisionKind = "approve" | "approve_fresh" | "revise" | "reject";
109
+ export interface PlanProposedEvent {
110
+ type: "plan_proposed";
111
+ planId: string;
112
+ version: number;
113
+ markdown: string;
114
+ steps: PlanStep[];
115
+ filePath?: string;
116
+ }
117
+ export interface PlanResolvedEvent {
118
+ type: "plan_resolved";
119
+ planId: string;
120
+ decision: PlanDecisionKind;
121
+ /** `approve` 时指定的执行模式(缺省回到进入 plan 前的模式)。 */
122
+ mode?: PermissionMode;
123
+ }
124
+ /** todo 条目的线上形状(与 `tools/todo.ts` 的 `TodoItem` 结构兼容;`planStep` 由 W5-F 加)。 */
125
+ export interface TodoItemView {
126
+ id: string;
127
+ text: string;
128
+ status: "pending" | "in_progress" | "done";
129
+ planStep?: string;
130
+ }
131
+ export interface TodoUpdatedEvent {
132
+ type: "todo_updated";
133
+ items: TodoItemView[];
134
+ }
135
+ export type LimitKind = "turns" | "cost";
136
+ /** `--max-turns` / `--max-cost` / `limits.*` 到限;`-p` 下以退出码 7 结束。 */
137
+ export interface LimitReachedEvent {
138
+ type: "limit_reached";
139
+ kind: LimitKind;
140
+ /** 到限时的值(回合数或美元)。 */
141
+ value: number;
142
+ limit: number;
143
+ }
144
+ export interface ModelFallbackEvent {
145
+ type: "model_fallback";
146
+ from: ModelRef;
147
+ to: ModelRef;
148
+ /** 触发原因(`overloaded` / 重试用尽的错误文本)。 */
149
+ reason: string;
150
+ }
151
+ export interface BackgroundJobEvent {
152
+ type: "background_job";
153
+ jobId: string;
154
+ phase: "started" | "exited" | "stopped";
155
+ command: string;
156
+ pid?: number;
157
+ outputPath?: string;
158
+ exitCode?: number | null;
159
+ }
160
+ export type SessionEventW5 =
161
+ /** 流式中 ≤ 2 Hz(`ui.animation: false` 时不发);数据从 `getStats().telemetry` 取。 */
162
+ {
163
+ type: "telemetry_tick";
164
+ } | SubagentStartEvent | SubagentUpdateEvent | SubagentEndEvent | PlanProposedEvent | PlanResolvedEvent | TodoUpdatedEvent | LimitReachedEvent | ModelFallbackEvent | BackgroundJobEvent;
165
+ /** 外部 Agent 记账(`custom{ama.agent-usage}` 汇总,§5.4)。 */
166
+ export interface ExternalAgentStats {
167
+ byAgent: Record<string, {
168
+ runs: number;
169
+ unit: ExternalUsageUnit;
170
+ amount: number;
171
+ tokens?: number;
172
+ }>;
173
+ }
174
+ /** 子 Agent 任务注册表的汇总(`/session` 与 `get_session_stats`)。 */
175
+ export interface SessionTaskStats {
176
+ total: number;
177
+ running: number;
178
+ byStatus: Partial<Record<SubagentStatus, number>>;
179
+ }
180
+ export interface SessionStatsW5 {
181
+ /** [W5-A] 速率与会话时长;遥测扩展未装配时缺省。 */
182
+ telemetry?: SessionTelemetry;
183
+ /** [W5-E] 外部 Agent 用量;没有外部运行时缺省。 */
184
+ external?: ExternalAgentStats;
185
+ /** [W5-G] 子 Agent 任务;没有任务时缺省。 */
186
+ tasks?: SessionTaskStats;
187
+ }
188
+ /** `limits` 选项(`--max-turns` / `--max-cost` / config `limits.*`),W5-H2 实现。 */
189
+ export interface SessionLimits {
190
+ maxTurns?: number;
191
+ maxCostUsd?: number;
192
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 第五波会话契约(docs/wave5-plan.md §1.3、§5.4、§6.3、§6.5、§7.5、§8.3;[W5-C0])。
3
+ *
4
+ * 这里放新增事件的载荷与 `SessionStats` 的扩展形状,由 agent/types.ts 并入 `SessionEvent` /
5
+ * `SessionStats` 并再导出(agent/types.ts 已接近 600 行)。全部是新增事件与可选字段:
6
+ * `RpcEvent` 由 `SessionEvent` 派生,新事件自动上线;`RPC_PROTOCOL_VERSION` 不变。
7
+ * 实现归各批次:遥测 W5-A、子 Agent W5-G(外部 runner W5-E)、计划 / todo W5-F、
8
+ * 预算 / 回退 / 后台命令 W5-H2。
9
+ */
10
+ export {};
@@ -17,13 +17,18 @@
17
17
  * - (W3-C0)缓存可观测性(第三波 §1.10):`SessionEvent` 加 `cache_miss` / `cache_warm` /
18
18
  * `context_pressure`,`SessionStats.cache`(可选,C1b 填);`CacheSettings` 是
19
19
  * `SessionCacheController` 的解析后设置(来自 config `cache` 段与环境变量)。
20
+ * - (W5-C0)第五波事件与统计(遥测、子 Agent、计划 / todo、预算、回退、后台命令)定义在
21
+ * agent/types-w5.ts,这里并入 `SessionEvent` / `SessionStats` 并再导出。
20
22
  */
21
23
  import type { AssistantEvent, AssistantMessage, CacheRetention, ImageBlock, Message, MessageOrigin, Model, ModelRef, ModelThinkingLevel, ToolCallBlock, ToolResultMessage, TranscriptContext, Usage } from "../ai/types.js";
22
24
  import type { CacheMiss, CacheMissReason, CacheReporting, WarmerStatus, WarmingMode } from "../ai/cache/types.js";
23
25
  import type { HookEvent } from "../hooks/types.js";
24
- import type { ActionPreview, ApprovalDecision, ApprovalReason, AutoDecision, PermissionMode } from "../permissions/types.js";
25
- import type { AgentMessage, SessionEntry } from "../session/types.js";
26
+ import type { ActionPreview, ApprovalDecision, ApprovalReason, AutoDecision, PermissionMode, PermissionRequestContext } from "../permissions/types.js";
27
+ import type { AgentMessage, BranchSummaryEntry, SessionEntry } from "../session/types.js";
28
+ import type { RewindMode, RewindPoint, RewindRequest, RewindResult, RewindSkipReason } from "../checkpoints/types.js";
26
29
  import type { ToolDefinition, ToolResult } from "../tools/types.js";
30
+ import type { SessionEventW5, SessionStatsW5 } from "./types-w5.js";
31
+ export type * from "./types-w5.js";
27
32
  export type { AssistantContentBlock, AssistantMessage, ContentBlock, ImageBlock, Message, StopReason, SystemMessage, TextBlock, ThinkingBlock, ToolCallBlock, ToolResultMessage, Usage, UserMessage, } from "../ai/types.js";
28
33
  export type { AgentMessage, BranchSummaryMessage, CompactionSummaryMessage, CustomMessage, } from "../session/types.js";
29
34
  export type ToolCall = ToolCallBlock;
@@ -218,6 +223,11 @@ export type SessionEvent = {
218
223
  preview?: ActionPreview;
219
224
  /** auto 权限模式下为什么询问(同 `ApprovalRequest.autoDecision`)。 */
220
225
  autoDecision?: AutoDecision;
226
+ /**
227
+ * [W5-EG] 发起方:`depth > 0` 来自 task 子 Agent、`taskId` 来源任务、`origin` 外部 Agent 的
228
+ * 权限请求(对话框标 `[claude · 会话 abc1]`)。主会话自己的调用不带。
229
+ */
230
+ context?: PermissionRequestContext;
221
231
  } | {
222
232
  type: "permission_resolved";
223
233
  requestId: string;
@@ -238,6 +248,19 @@ export type SessionEvent = {
238
248
  type: "session_changed";
239
249
  sessionId: string;
240
250
  sessionFile?: string;
251
+ }
252
+ /** [RW-B] 回滚完成(rewind-plan §5):dryRun 不发;仅对话时文件清单为空。 */
253
+ | {
254
+ type: "session_rewound";
255
+ entryId: string;
256
+ mode: RewindMode;
257
+ restored: string[];
258
+ deleted: string[];
259
+ conflicts: string[];
260
+ skipped: {
261
+ path: string;
262
+ reason: RewindSkipReason;
263
+ }[];
241
264
  } | {
242
265
  type: "model_changed";
243
266
  model: ModelRef;
@@ -267,7 +290,9 @@ export type SessionEvent = {
267
290
  remainingTokens?: number;
268
291
  /** 按最近 5 回合均值估算。 */
269
292
  estimatedTurnsLeft?: number;
270
- };
293
+ }
294
+ /** [W5-C0] 第五波事件(agent/types-w5.ts)。 */
295
+ | SessionEventW5;
271
296
  export type SessionEventType = SessionEvent["type"];
272
297
  export type PromptDisposition = "started" | "queued" | "handled";
273
298
  export interface PromptOptions {
@@ -299,7 +324,8 @@ export interface SessionState {
299
324
  autoCompaction: boolean;
300
325
  autoRetry: boolean;
301
326
  }
302
- export interface SessionStats {
327
+ /** [W5-C0] `telemetry? / external? / tasks?` 见 `SessionStatsW5`。 */
328
+ export interface SessionStats extends SessionStatsW5 {
303
329
  sessionId: string;
304
330
  sessionFile: string | undefined;
305
331
  userMessages: number;
@@ -382,5 +408,22 @@ export interface AgentSession {
382
408
  readonly entries: readonly SessionEntry[];
383
409
  getLastAssistantText(): string | null;
384
410
  getStats(): SessionStats;
411
+ /** [RW-B] 活动路径上开启新回合的用户消息,从旧到新(rewind-plan §3.1)。 */
412
+ rewindPoints(): RewindPoint[];
413
+ /** [RW-B] 运行中 → busy;全部失败且无一恢复 → rewind_failed。 */
414
+ rewind(request: RewindRequest): Promise<RewindResult>;
415
+ /** [RW-B] 「从这里摘要」:回到该消息之前并为离开的分支写摘要,返回原消息草稿。 */
416
+ summarizeFrom(entryId: string, instructions?: string): Promise<{
417
+ leafId: string | null;
418
+ draft: RewindDraftText;
419
+ summary?: BranchSummaryEntry;
420
+ }>;
421
+ /** [RW-B] 「摘要到这里」:以该消息为切点压缩之前的上下文,停在末尾。 */
422
+ summarizeUpTo(entryId: string, instructions?: string): Promise<CompactionResult>;
385
423
  dispose(): Promise<void>;
386
424
  }
425
+ /** [RW-B] 回滚回填的原消息。 */
426
+ export type RewindDraftText = {
427
+ text: string;
428
+ images?: ImageBlock[];
429
+ };
@@ -17,5 +17,7 @@
17
17
  * - (W3-C0)缓存可观测性(第三波 §1.10):`SessionEvent` 加 `cache_miss` / `cache_warm` /
18
18
  * `context_pressure`,`SessionStats.cache`(可选,C1b 填);`CacheSettings` 是
19
19
  * `SessionCacheController` 的解析后设置(来自 config `cache` 段与环境变量)。
20
+ * - (W5-C0)第五波事件与统计(遥测、子 Agent、计划 / todo、预算、回退、后台命令)定义在
21
+ * agent/types-w5.ts,这里并入 `SessionEvent` / `SessionStats` 并再导出。
20
22
  */
21
23
  export {};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * 子 Agent 的 git worktree 隔离(docs/wave5-plan.md §7.4,D24)。[W5-G]
3
+ *
4
+ * - `git worktree add -b ama/task-<taskId> <repo>/.ama/worktrees/<taskId> HEAD`;子会话 cwd 指向
5
+ * worktree 里与父 cwd 对应的子目录;
6
+ * - 结束时没有改动(工作区干净且 HEAD 未动)→ `git worktree remove --force` 并删分支;有改动则保留,
7
+ * 结果里给分支名与 `git diff --stat`;
8
+ * - 非 git 目录直接报错,不回落到共享目录;`.ama/worktrees/.gitignore` 写 `*`,父会话的 git 与
9
+ * grep / glob(读嵌套 .gitignore)都看不到这些目录;
10
+ * - worktree 不保证可运行:依赖(node_modules 等)不共享。
11
+ */
12
+ export interface Worktree {
13
+ /** worktree 根目录。 */
14
+ path: string;
15
+ /** 子会话 cwd(worktree 里与父 cwd 对应的目录)。 */
16
+ cwd: string;
17
+ branch: string;
18
+ /** 创建时的提交(判断有无新提交)。 */
19
+ base: string;
20
+ repo: string;
21
+ }
22
+ export interface WorktreeOutcome {
23
+ branch: string;
24
+ changed: boolean;
25
+ /** 有改动时:`git diff --stat <base>` 与未跟踪文件。 */
26
+ diffStat?: string;
27
+ /** 保留时的路径。 */
28
+ path?: string;
29
+ }
30
+ export type GitRunner = (args: readonly string[], cwd: string) => Promise<string>;
31
+ export declare const runGit: GitRunner;
32
+ export declare function worktreeBranch(taskId: string): string;
33
+ /** 在父 cwd 所在仓库里为任务建 worktree;非 git 目录抛错。 */
34
+ export declare function createWorktree(cwd: string, taskId: string, git?: GitRunner): Promise<Worktree>;
35
+ /** 运行结束:无改动删除 worktree 与分支;有改动保留并给 diff 摘要。 */
36
+ export declare function finishWorktree(tree: Worktree, git?: GitRunner): Promise<WorktreeOutcome>;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * 子 Agent 的 git worktree 隔离(docs/wave5-plan.md §7.4,D24)。[W5-G]
3
+ *
4
+ * - `git worktree add -b ama/task-<taskId> <repo>/.ama/worktrees/<taskId> HEAD`;子会话 cwd 指向
5
+ * worktree 里与父 cwd 对应的子目录;
6
+ * - 结束时没有改动(工作区干净且 HEAD 未动)→ `git worktree remove --force` 并删分支;有改动则保留,
7
+ * 结果里给分支名与 `git diff --stat`;
8
+ * - 非 git 目录直接报错,不回落到共享目录;`.ama/worktrees/.gitignore` 写 `*`,父会话的 git 与
9
+ * grep / glob(读嵌套 .gitignore)都看不到这些目录;
10
+ * - worktree 不保证可运行:依赖(node_modules 等)不共享。
11
+ */
12
+ import { execFile } from "node:child_process";
13
+ import { existsSync, mkdirSync, realpathSync, writeFileSync } from "node:fs";
14
+ import { join, relative } from "node:path";
15
+ const TIMEOUT_MS = 30_000;
16
+ export const runGit = (args, cwd) => new Promise((resolve, reject) => {
17
+ execFile("git", [...args], { cwd, timeout: TIMEOUT_MS, maxBuffer: 4 * 1024 * 1024, windowsHide: true }, (error, stdout, stderr) => {
18
+ if (error)
19
+ reject(new Error(String(stderr).trim() || error.message));
20
+ else
21
+ resolve(String(stdout));
22
+ });
23
+ });
24
+ /**
25
+ * 两边都取系统的真实路径再比:git 给的是真实路径(macOS 的 /var → /private/var;Windows 是长文件名、
26
+ * 正斜杠),而 cwd 可能是 8.3 短名(RUNNER~1)或符号链接。
27
+ */
28
+ function realPath(path) {
29
+ try {
30
+ return realpathSync.native(path);
31
+ }
32
+ catch {
33
+ return path;
34
+ }
35
+ }
36
+ export function worktreeBranch(taskId) {
37
+ return `ama/task-${taskId}`;
38
+ }
39
+ /** 在父 cwd 所在仓库里为任务建 worktree;非 git 目录抛错。 */
40
+ export async function createWorktree(cwd, taskId, git = runGit) {
41
+ let repo;
42
+ try {
43
+ repo = realPath((await git(["rev-parse", "--show-toplevel"], cwd)).trim());
44
+ }
45
+ catch {
46
+ throw new Error(`isolation "worktree" needs a git repository; ${cwd} is not inside one`);
47
+ }
48
+ const base = (await git(["rev-parse", "HEAD"], repo)).trim();
49
+ const root = join(repo, ".ama", "worktrees");
50
+ mkdirSync(root, { recursive: true });
51
+ const ignore = join(root, ".gitignore");
52
+ if (!existsSync(ignore))
53
+ writeFileSync(ignore, "*\n");
54
+ const path = join(root, taskId);
55
+ const branch = worktreeBranch(taskId);
56
+ if (!existsSync(path))
57
+ await git(["worktree", "add", "-b", branch, path, base], repo);
58
+ const sub = relative(repo, realPath(cwd));
59
+ const childCwd = sub === "" || sub.startsWith("..") ? path : join(path, sub);
60
+ mkdirSync(childCwd, { recursive: true });
61
+ return { path, cwd: childCwd, branch, base, repo };
62
+ }
63
+ /** 运行结束:无改动删除 worktree 与分支;有改动保留并给 diff 摘要。 */
64
+ export async function finishWorktree(tree, git = runGit) {
65
+ const status = (await git(["status", "--porcelain"], tree.path)).trim();
66
+ const head = (await git(["rev-parse", "HEAD"], tree.path)).trim();
67
+ if (status === "" && head === tree.base) {
68
+ await git(["worktree", "remove", "--force", tree.path], tree.repo);
69
+ await git(["branch", "-D", tree.branch], tree.repo).catch(() => "");
70
+ return { branch: tree.branch, changed: false };
71
+ }
72
+ const stat = (await git(["diff", "--stat", tree.base], tree.path).catch(() => "")).trim();
73
+ const untracked = status
74
+ .split("\n")
75
+ .filter((line) => line.startsWith("??"))
76
+ .map((line) => line.slice(3));
77
+ const parts = [stat];
78
+ if (untracked.length > 0)
79
+ parts.push(`untracked: ${untracked.join(", ")}`);
80
+ return {
81
+ branch: tree.branch,
82
+ changed: true,
83
+ diffStat: parts.filter((part) => part !== "").join("\n"),
84
+ path: tree.path,
85
+ };
86
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 内置子 Agent 类型(docs/wave5-plan.md §7.2,D22–D23)。[W5-G]
3
+ *
4
+ * 三个类型都用父会话的活动工具集(工具表与父字节一致,缓存前缀可复用);只读靠权限层:
5
+ * `explore` / `plan` 的 `permissionMode: "plan"` 让子会话用 plan 模式的管线,写类工具与非只读 bash
6
+ * 被拒绝且不弹审批(session-subagent.ts)。正文是追加到子会话系统提示末尾的角色说明(`role` 节)。
7
+ */
8
+ import type { AgentDefinition } from "./types.js";
9
+ /** 所有 ama 子会话共有的角色说明(类型正文追加在它后面)。 */
10
+ export declare const SUBAGENT_ROLE_PREAMBLE: string;
11
+ export declare const BUILTIN_AGENTS: readonly AgentDefinition[];
12
+ export declare const DEFAULT_AGENT = "general";
13
+ /** 子会话系统提示 `role` 节:通用说明 + 类型正文。 */
14
+ export declare function agentRole(agent: Pick<AgentDefinition, "prompt">): string;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * 内置子 Agent 类型(docs/wave5-plan.md §7.2,D22–D23)。[W5-G]
3
+ *
4
+ * 三个类型都用父会话的活动工具集(工具表与父字节一致,缓存前缀可复用);只读靠权限层:
5
+ * `explore` / `plan` 的 `permissionMode: "plan"` 让子会话用 plan 模式的管线,写类工具与非只读 bash
6
+ * 被拒绝且不弹审批(session-subagent.ts)。正文是追加到子会话系统提示末尾的角色说明(`role` 节)。
7
+ */
8
+ /** 所有 ama 子会话共有的角色说明(类型正文追加在它后面)。 */
9
+ export const SUBAGENT_ROLE_PREAMBLE = "You are a sub-agent: the main agent delegated one task to you. It cannot see your work, only " +
10
+ "your final reply. Complete the task directly; do not delegate further. End with a concise " +
11
+ "report: what you did, key findings, and files changed (if any).";
12
+ function builtin(name, description, prompt, permissionMode) {
13
+ return {
14
+ name,
15
+ description,
16
+ permissionMode,
17
+ model: "inherit",
18
+ maxTurns: 30,
19
+ isolation: "none",
20
+ background: false,
21
+ runner: "ama",
22
+ prompt,
23
+ source: "builtin",
24
+ };
25
+ }
26
+ export const BUILTIN_AGENTS = Object.freeze([
27
+ builtin("general", "General-purpose sub-agent (default): researches and changes code like you do.", "", "inherit"),
28
+ builtin("explore", "Read-only search: locates files, symbols and code paths; returns paths with line numbers.", "Locate, do not review. Return file paths with line numbers and short notes on what is " +
29
+ "where. State the search scope you covered. You cannot modify files; bash runs read-only " +
30
+ "commands only.", "plan"),
31
+ builtin("plan", "Read-only planner: returns a step-by-step plan with key files and trade-offs.", "Produce a step-by-step implementation plan: key files to change, the order of steps, and " +
32
+ "trade-offs or risks. Do not modify files; you are read-only.", "plan"),
33
+ ]);
34
+ export const DEFAULT_AGENT = "general";
35
+ /** 子会话系统提示 `role` 节:通用说明 + 类型正文。 */
36
+ export function agentRole(agent) {
37
+ const own = agent.prompt.trim();
38
+ return own === "" ? SUBAGENT_ROLE_PREAMBLE : `${SUBAGENT_ROLE_PREAMBLE}\n\n${own}`;
39
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 子 Agent 类型目录:内置 ⊕ 发现的定义 ⊕ 外部 runner(docs/wave5-plan.md §7.1–§7.3、§7.6)。[W5-G]
3
+ *
4
+ * - 发现的同名定义覆盖内置类型(不 warning);外部 runner(W5-E 的 ProcessRunner、宿主 runner)以
5
+ * `add()` 登记,名字已存在时保留先登记者。
6
+ * - `describe()`:task 工具描述里的类型清单,总预算约 400 token(1 600 字符),超出只列名字。
7
+ * - `resolveModel()`:调用参数 `model` > 定义 `model`(非 inherit)> config `agents.<name>.model` >
8
+ * `subagents.defaultModel` > 父当前模型(返回 undefined);`fast` / `strong` 经 `models.aliases`。
9
+ */
10
+ import { type AgentsConfig, type ModelsConfig } from "../config/types-w5.js";
11
+ import type { AgentDefinition, AgentInfo } from "./types.js";
12
+ export declare const AGENT_LIST_BUDGET_CHARS = 1600;
13
+ export interface AgentModelConfig {
14
+ agents?: AgentsConfig;
15
+ subagents?: {
16
+ defaultModel?: string;
17
+ };
18
+ models?: ModelsConfig;
19
+ }
20
+ export declare class AgentCatalog {
21
+ private readonly byName;
22
+ private resolver;
23
+ constructor(discovered?: readonly AgentDefinition[]);
24
+ /**
25
+ * 目录里没有的名字按需解析(`acp:<program>`、未在启动时登记的外部 / 宿主 runner,见
26
+ * agents/external.ts)。解析出的类型不进 {@link describe}:task 工具描述在会话内保持字节不变。
27
+ */
28
+ setResolver(resolver: ((name: string) => AgentDefinition | undefined) | undefined): void;
29
+ get(name: string): AgentDefinition | undefined;
30
+ /** 外部 / 宿主类型;同名已存在返回 false。 */
31
+ add(agent: AgentDefinition): boolean;
32
+ list(): AgentDefinition[];
33
+ names(): string[];
34
+ infos(): AgentInfo[];
35
+ /** task 工具描述里的类型清单(`- name: description`;超预算只列名字)。 */
36
+ describe(budget?: number): string;
37
+ }
38
+ export interface ResolvedAgentModel {
39
+ /** `provider/model[@channel]`;undefined = 继承父当前模型。 */
40
+ ref?: string;
41
+ warning?: string;
42
+ }
43
+ export declare function resolveAgentModel(agent: AgentDefinition, requested: string | undefined, config: AgentModelConfig): ResolvedAgentModel;