@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
@@ -33,14 +33,19 @@ export const DEFAULT_KEYBINDINGS = {
33
33
  "tui.select.confirm": ["enter", "tab"],
34
34
  "tui.select.cancel": ["escape", "ctrl+c"],
35
35
  "app.interrupt": ["escape"],
36
+ "app.rewind": ["escape"],
36
37
  "app.clear": ["ctrl+c"],
37
38
  "app.exit": ["ctrl+d"],
38
39
  "app.message.followUp": ["alt+enter"],
39
40
  "app.message.dequeue": ["alt+up"],
40
- "app.permission.cycle": ["shift+tab"],
41
+ "app.permission.cycle": ["shift+tab", "tab"],
41
42
  "app.tools.expand": ["ctrl+o"],
42
43
  "app.model.select": ["ctrl+l"],
43
44
  "app.thinking.select": ["ctrl+t"],
45
+ /** [W5-A] 底部信息行 full ↔ compact(只影响本会话)。 */
46
+ "app.statusLine.toggle": ["ctrl+g"],
47
+ /** [W5-U] 粘贴剪贴板图片(写进数据目录,输入框插入 `@路径`)。 */
48
+ "app.paste.image": ["ctrl+v"],
44
49
  };
45
50
  export function isActionId(id) {
46
51
  return Object.prototype.hasOwnProperty.call(DEFAULT_KEYBINDINGS, id);
package/docs/acp.md ADDED
@@ -0,0 +1,78 @@
1
+ # ACP(Agent Client Protocol)
2
+
3
+ ama 在 ACP 两侧都能用:
4
+
5
+ - **服务端**:`ama --mode acp` 把 ama 暴露为 ACP Agent,供 Zed、JetBrains、Armadra 的 ACP 节点驱动;
6
+ - **客户端**:ama 经 ACP 驱动外部 Agent(Gemini CLI、OpenCode、Kimi、Copilot 等原生 ACP,或装了适配器的 Claude Code / Codex),见 [agents.md](agents.md)。
7
+
8
+ 协议栈零依赖、手写,只维护一份:`@armadra/agent/acp` 导出类型、分帧、客户端与假 Agent,Armadra 直接复用。设计依据见 [wave5-plan.md](wave5-plan.md) §5(D14)。
9
+
10
+ ## 线路
11
+
12
+ JSON-RPC 2.0 over NDJSON(stdio):只按 `\n` 切行,64 KiB 分片写并等待背压,与 [rpc.md](rpc.md) 的「线路」一致。stdout 只有协议行,诊断写 stderr。由客户端以 `initialize` 起头,没有 `hello`。
13
+
14
+ ## `ama --mode acp`
15
+
16
+ ```sh
17
+ ama --mode acp # 与 -p 互斥;其余参数(--model、--profile、--trust 等)照常
18
+ ```
19
+
20
+ | 方法 | ama 的行为 |
21
+ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
22
+ | `initialize` | `protocolVersion: 1`;`loadSession: true`,`sessionCapabilities: { list, resume, close }`,`promptCapabilities: { image: true, embeddedContext: true }`;不要认证 |
23
+ | `session/new` | 新开会话(启动时那个空会话第一次直接认领);`cwd` 必须是 ama 的启动目录(按 realpath 比较),否则 invalid params |
24
+ | `session/load` | 切到该会话并以 `session/update` 回放历史(用户消息、回复、思考、工具调用) |
25
+ | `session/resume` | 切到该会话,不回放 |
26
+ | `session/list` | 启动目录下的会话(标题取会话名或首条提示) |
27
+ | `session/close` | 中断运行并释放活动会话 |
28
+ | `session/prompt` | 文本与图片照收;`resource_link` 以 `@uri` 文本给出,嵌入资源取文本。回合结束:中断 → `cancelled`,输出截断 → `max_tokens`,出错 → JSON-RPC 错误 |
29
+ | `session/cancel`(通知) | 中断当前回合 |
30
+ | `session/set_mode` | 模式 id 就是 ama 的权限模式(`plan`、`allowlist`、`default`、`auto-edit`、`auto`、`full-auto`) |
31
+
32
+ 一次只有一个活动会话;对非活动会话发 `session/prompt` 时(空闲)先切过去,运行中切换报 invalid request。
33
+
34
+ ### 事件映射
35
+
36
+ | ama | `session/update` |
37
+ | ------------------- | ---------------------------------------------------------------------------------- |
38
+ | 文本增量 / 思考增量 | `agent_message_chunk` / `agent_thought_chunk` |
39
+ | 模型发出工具调用 | `tool_call`(`pending`,带 `rawInput`、`kind`、`locations`) |
40
+ | 工具开始 / 结束 | `tool_call_update`(`in_progress` → `completed` / `failed`,结果只带前 4 KB 文本) |
41
+ | `todo` 更新 | `plan` |
42
+ | 每轮结束 | `usage_update`(上下文已用、窗口、会话累计美元) |
43
+ | 权限模式变化 | `current_mode_update` |
44
+
45
+ codemode 内层调用不单列。`session/prompt` 的结果带本回合 token 用量(`inputTokens`、`outputTokens`、`cachedReadTokens`、`cachedWriteTokens`、`totalTokens`)。
46
+
47
+ ### 审批
48
+
49
+ ama 需要询问的调用经 `session/request_permission` 交给客户端,三个选项:`allow_once`(允许)、`allow_always`(本会话允许)、`reject_once`(拒绝)。`toolCall.toolCallId` 关联到先前 `tool_call` 的 id。客户端回 `cancelled`、连接断开或回合被中断时,按无人作答处理(拒绝)。auto 模式下 ama 自己的分类器照常工作——这只影响 ama 自己的工具;ama 驱动的外部 Agent 发来的请求只交给人(见 [agents.md](agents.md))。
50
+
51
+ 不声明、也不使用客户端的 `fs` / `terminal` 能力:ama 自己读写、自己跑命令,按自己的权限管线。
52
+
53
+ ### 退出
54
+
55
+ stdin 关闭后等已开始的运行结束再退出(0);SIGINT / SIGTERM 中断后退出 130 / 143。宿主看到的模式是 `rpc`(`HostApi.mode`)。SDK 直接 `bootstrap(--mode acp)` 时得到 `mode: "rpc"` 的 Runtime,再交给 `runAcpMode`。
56
+
57
+ ## 作为客户端
58
+
59
+ 模型经 `task(agent="acp:<程序>")` 使用 ACP Agent(ama 自己是 `task(agent="acp:ama")`,见 [agents.md](agents.md)「在 task 里使用」)。
60
+
61
+ `AcpClient`(`@armadra/agent/acp`):`initialize`、`newSession`、`resumeSession`(优先,不回放)、`loadSession`、`listSessions`、`closeSession`、`prompt`、`setMode`、`cancel`。
62
+
63
+ - 声明的客户端能力为空:Agent 发来的 `fs/*`、`terminal/*` 请求回 method not found。
64
+ - `session/request_permission` 交给 `onPermission`;没有处理器时回首个 `reject_once`(无人值守)。
65
+ - `cancel(sessionId)` 发 `session/cancel`,并让该会话挂起的权限请求回 `cancelled`(规范要求)。
66
+ - 只接受 Agent 自己给出的 `optionId`。
67
+
68
+ `AcpDriver` 在客户端之上实现驱动契约(`AgentDriver`):续接优先 `session/resume`,其次 `session/load`(回放的历史丢弃),都不支持就新开并提示;按 ama 模式 `session/set_mode`,只读模式找不到对应模式 id 时拒绝启动。
69
+
70
+ ## 测试替身
71
+
72
+ `runFakeAcpAgent(input, output)` 是进程内的假 ACP Agent,`fakeAcpAgentPath()` 是它的可执行入口(`node <path> [--minimal]`)。行为由提示里的标记决定:`[permission]`(请求权限,四个选项)、`[slow]`(等到 cancel)、`[plan]`、`[think]`、`[refuse]`,其余回 `echo: <文本>`。`--minimal` 不声明 resume / load / list / close,也不给模式,用来测降级路径。
73
+
74
+ 黄金记录在 `test/fixtures/acp/`:`driver-{allow,reject,cancel}.jsonl`(ama 驱动假 Agent 的三条路径)与 `mode-prompt.jsonl`(`ama --mode acp` 一轮往返)。`UPDATE_GOLDEN=1` 重写。
75
+
76
+ ## 兼容性
77
+
78
+ 按 ACP v1(含 2026 年稳定的 `session/list`、`session/resume`、`session/close`、`usage_update`)。v2 计划取消 `session/load`,ama 作客户端时已优先 `resume`。
package/docs/agents.md ADDED
@@ -0,0 +1,250 @@
1
+ # Agent:子 Agent 与外部 Agent
2
+
3
+ 模型只认识两个工具:`task`(委派)与 `task_ctl`(管理后台任务)。`task(agent=…)` 的 `agent` 既可以是 ama 自己的子 Agent
4
+ 类型,也可以是外部 CLI Agent(外部部分见下文「外部 Agent」节)。设计依据:[wave5-plan.md](wave5-plan.md) §7、D13、D22–D24。
5
+
6
+ ## 子 Agent
7
+
8
+ ### 何时可用
9
+
10
+ `task` 与 `task_ctl` 同进退:`default` 预设下只在 codemode 脚本里可调用,`--tools …,task` 或 `tools.default: ["+task"]`
11
+ 时直接暴露;嵌入宿主时宿主可以禁用。子 Agent 运行在同一进程的新会话里(全新上下文,看不到父对话,`prompt` 要写全),
12
+ 有自己的 JSONL(与父会话同目录,头的 `parentSession` 指回父文件)。深度最多 1:子 Agent 里调用 `task` / `task_ctl` 会被拒绝。
13
+
14
+ ### 内置类型
15
+
16
+ | 类型 | 工具 | 权限 | 角色说明(追加在子会话系统提示末尾) |
17
+ | ----------------- | ---------- | ------------------------------------- | ------------------------------------------ |
18
+ | `general`(缺省) | 父的活动集 | 与父相同 | 直接完成、不再委派,结束时给精简报告 |
19
+ | `explore` | 父的活动集 | plan 模式:写类工具与非只读 bash 被拒 | 只定位不评审,返回路径与行号,说明搜索范围 |
20
+ | `plan` | 父的活动集 | plan 模式 | 输出分步计划、关键文件与取舍,不修改文件 |
21
+
22
+ 只读靠权限层:只读类型的子会话用一条 plan 模式的权限管线(规则与父相同),需要确认的调用一律直接拒绝,**不弹审批**。
23
+ 工具表与父会话逐字节相同(`task` / `task_ctl` 也在表里,运行时拒绝),子会话的首个请求能复用父会话已缓存的 tools + system
24
+ 前缀;角色说明是系统提示最后一个节(`role`),父会话的全部节都是它的前缀。只有类型声明了 `tools` / `disallowed-tools`
25
+ (或调用时传了 `tools`)时工具表才不同,此时首个请求不命中父的缓存。
26
+
27
+ ### 定义文件
28
+
29
+ 一个 `*.md` 是一个类型,frontmatter 与 Skill 同一套写法(字段名 kebab-case),正文是角色说明:
30
+
31
+ ```markdown
32
+ ---
33
+ name: reviewer # ^[a-z0-9-]{1,64}$,缺省取文件名
34
+ description: 只读审查改动,按文件与行号报告问题。 # 必填,≤ 1024 字符,出现在 task 工具描述里
35
+ tools: read, grep, glob, bash # 白名单;与 disallowed-tools 二选一
36
+ permission-mode: plan # plan | inherit(缺省);只能比父更严
37
+ model: fast # inherit(缺省)| fast | strong(models.aliases)| provider/model
38
+ thinking: low
39
+ max-turns: 20 # 缺省 30
40
+ isolation: none # none(缺省)| worktree
41
+ background: false
42
+ runner: ama # ama(缺省)| claude | codex | acp:<程序>
43
+ ---
44
+
45
+ 引用改动时写 file:line,先列严重问题。
46
+ ```
47
+
48
+ 发现顺序(同名先发现者胜,并给出提示;内置类型可被同名定义覆盖):
49
+
50
+ 1. `--agent-dir <目录>`(可重复),之后是 profile 的 `agentDirs`;
51
+ 2. config 的 `agents.dirs`;
52
+ 3. `~/.config/ama/agents/*.md`(用户级);
53
+ 4. `<项目>/.ama/agents/*.md`(项目级,**需要信任**;未信任时跳过并在启动时提示)。
54
+
55
+ 不合格的文件不加载并给出提示(名字非法、缺 description、`tools` 与 `disallowed-tools` 同时给出、取值不认识等)。
56
+ 不支持的字段(`hooks`、`mcpServers`、`memory`、`color`、`initialPrompt`、`skills`)忽略;子会话本来就继承父的 Skill 索引。
57
+
58
+ 模型选择:调用参数 `model` > 定义的 `model`(非 inherit)> config `agents.<类型>.model` > `subagents.defaultModel` > 父当前模型。
59
+ `fast` / `strong` 经 `models.aliases` 映射,没配置时用父模型并提示。
60
+
61
+ ### `task` 参数
62
+
63
+ | 参数 | 说明 |
64
+ | ------------------------------------------------ | -------------------------------------------------------------------------- |
65
+ | `prompt` | 必填,完整的任务说明 |
66
+ | `agent` | 类型名,缺省 `general`;也可以是外部 Agent(见「外部 Agent」节) |
67
+ | `description` | 显示用的短标签 |
68
+ | `background` | `true`:立即返回 `taskId`,完成后父会话收到通知;缺省取类型的 `background` |
69
+ | `taskId` | 续聊:向已有任务的子会话追加一条消息(忽略 `agent` / `tools` / `model`) |
70
+ | `isolation` | `worktree`:在独立 git worktree 里运行 |
71
+ | `budgetUsd` | 外部 Agent 的美元预算 |
72
+ | `tools` / `model` / `thinkingLevel` / `maxTurns` | 保留的高级参数(描述里不展开) |
73
+
74
+ 同一条回复里的多个 `task` **并行**执行,由会话的任务池限流(`subagents.maxConcurrent`,缺省 4);排队超过
75
+ `subagents.maxPending`(缺省 16)直接报错,提示模型不要重试。并行且会写文件的任务请用 `isolation: "worktree"`。
76
+ 与 `edit` 等串行工具出现在同一批时,按工具执行规则整批串行。
77
+
78
+ 结果是子 Agent 的最终报告,前面带 `[task tN]`。超过 50 KB 时保留开头 70% 与结尾 30%,中间注明省略了多少字节,
79
+ 全文写到会话目录的 `outputs/<会话 id>-<taskId>.md`(内存会话写到系统临时目录)。轮数用尽且最后一步停在工具结果上时,
80
+ ama 以「不允许调用工具」再跑一轮要最终报告,结果前加 `[Turn limit reached; …]`,状态 `max_turns`。
81
+
82
+ ### 后台任务与 `task_ctl`
83
+
84
+ `background: true` 立即返回 `taskId` 与输出文件路径。任务完成后,ama 在父会话空闲时投递一条 user 消息(`origin: "task"`)
85
+ 并开始新回合;父正忙则等这一轮结束再投递,不打断。多条通知按完成顺序到达:
86
+
87
+ ```text
88
+ <task-notification taskId="t3" agent="explore" status="completed" turns="7" tokens="12.3k" outputFile="…">
89
+ …最终报告(≤ 50 KB)…
90
+ </task-notification>
91
+ ```
92
+
93
+ 系统提示的规则里写明这类消息是后台任务的报告、不是用户发言。被 `task_ctl stop` 停止或随会话关闭的任务不发通知。
94
+ 后台任务的审批照常交给父会话的界面 / RPC 客户端(`-p` 下需要确认的调用视同拒绝);后台任务的全文总会写到输出文件。
95
+
96
+ `task_ctl` 的动作:
97
+
98
+ | `action` | 说明 |
99
+ | -------- | ---------------------------------------------------------------------------------- |
100
+ | `list` | 列出本会话的任务:编号、类型、状态、轮数、token、耗时、是否后台、描述 |
101
+ | `wait` | 等任务结束(`timeoutMs` 缺省 30 000,最多 600 000);超时说明仍在运行 |
102
+ | `stop` | 停止任务,返回终态 |
103
+ | `output` | 运行中返回已有输出,结束后返回最终文本(同样有 50 KB 上限) |
104
+ | `send` | 向任务追加一条消息并放到后台运行(等价于 `task{taskId, prompt, background:true}`) |
105
+
106
+ ### 续聊、保留与 resume
107
+
108
+ 每个任务有会话内唯一的 `taskId`(`t1`、`t2` …)。子会话结束后不立即释放,最多保留 16 个(最久未用的先释放内存;
109
+ JSONL 一直在)。`task{taskId}` / `task_ctl send` 续聊时,保留中的直接追加消息,已释放的按会话文件重新打开再追加——
110
+ 同一个任务始终写同一个 JSONL。父会话在任务开始、每次续聊与结束时写一条 `custom{ama.task}`
111
+ ([session-format.md](session-format.md));`--resume` 时据此重建任务列表,当时还在运行的标 `interrupted`,仍可续聊。
112
+ 内存会话(`--no-session`)的任务被释放后不能续聊。
113
+
114
+ ### worktree 隔离
115
+
116
+ `isolation: "worktree"` 时,ama 在父 cwd 所在仓库里执行
117
+ `git worktree add -b ama/task-<名字> <仓库>/.ama/worktrees/<名字>`(名字 = 会话 id 前 8 位 + `taskId`),子会话的 cwd 是
118
+ worktree 里与父 cwd 对应的目录。结束时没有改动(工作区干净且没有新提交)就删掉 worktree 与分支;有改动则保留,结果末尾给出
119
+ 分支名、路径与 `git diff --stat`(含未跟踪文件),由你决定是否合并。`.ama/worktrees/` 下自动写一个 `.gitignore`(`*`),
120
+ 父仓库的 `git status` 与 grep / glob 都看不到这些目录。不在 git 仓库里时直接报错,不会退回共享目录。
121
+ worktree 里的编辑不记进父会话的检查点。注意:worktree 不共享依赖(`node_modules` 等),不保证能直接构建或运行测试。
122
+
123
+ ### 事件与统计
124
+
125
+ RPC / SDK 事件 `subagent_start` / `subagent_update` / `subagent_end` 见 [rpc.md](rpc.md)「子 Agent 事件」。
126
+ `getStats().tasks` 给出任务总数、运行中数量与按状态的计数;子会话的缓存命中与重计费仍汇总在 `cache.subagents`。
127
+ RPC `get_tasks` / `get_agents` 返回任务快照与可用类型(来源、定义文件路径)。交互界面的 `/tasks`、`/agents` 与 task 工具行的折叠显示见 [tui.md](tui.md)「子 Agent」。
128
+
129
+ ### 配置
130
+
131
+ | 键 | 说明 |
132
+ | --------------------------------- | ------------------------------------------- |
133
+ | `subagents.maxConcurrent` | 同时运行的子 Agent,缺省 4 |
134
+ | `subagents.maxPending` | 排队上限,缺省 16 |
135
+ | `subagents.defaultModel` | 子 Agent 缺省模型,不设继承父会话 |
136
+ | `agents.dirs` | 追加的定义目录 |
137
+ | `agents.<类型>.model` | 某个类型的模型(如让 `explore` 用便宜模型) |
138
+ | `models.aliases.fast` / `.strong` | 定义文件里 `model: fast / strong` 的映射 |
139
+
140
+ ### 限制
141
+
142
+ - 子 Agent 不能再委派(深度 1);协调多个 Agent 的场景交给宿主(如 Armadra 画布)。
143
+ - 只读类型的 bash 只放行 plan 模式认可的只读命令,识别不了的一律拒绝,宁可少用。
144
+ - 不读取 `.claude/agents`;不支持 fork 模式(继承父对话的子 Agent)。
145
+
146
+ ## 外部 Agent
147
+
148
+ ama 能以各 CLI 自己的账户、模型与权限策略驱动外部编码 Agent,结果作为 `task` 的工具结果回到协调者(按资料处理,不是指令)。
149
+
150
+ ### 支持的 Agent 与驱动
151
+
152
+ 每个 Agent 有一条候选链,按优先级取第一个已安装、且支持当前模式的:原生 ACP > 已装的 ACP 适配器 > 原生结构化协议 > 一次性打印模式。
153
+
154
+ | `agent` | 候选(优先级从高到低) | 已验证版本 |
155
+ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------- |
156
+ | `claude` | `claude-agent-acp`(ACP 适配器)→ `claude -p` stream-json(原生)→ `claude -p --output-format json`(一次性,只读) | stream-json:2.1.x |
157
+ | `codex` | `codex-acp`(ACP 适配器)→ `codex app-server`(原生)→ `codex exec --json`(一次性,只读) | app-server:0.160.x |
158
+ | `gemini` | `gemini --acp` → `gemini -p --output-format stream-json`(一次性,只读) | 未验证 |
159
+ | `qwen` | `qwen --acp`(0.23.x 有不发权限请求的问题,只在 plan 下用) | 未验证 |
160
+ | `kimi` / `opencode` / `goose` / `copilot` | 各自的 ACP 子命令 | 未验证 |
161
+ | `ama` | `ama --mode acp` | 随 ama |
162
+ | `acp:<program>` | 任意 ACP Agent:表里有同名程序就用它的参数,否则不带参数启动 | — |
163
+
164
+ 版本越过已验证区间时仍会启动,但会提示协议可能有变化(Claude 的 stream-json 控制协议不是公开接口,Codex app-server 标为实验)。`/agents` 与 RPC `get_agents` 列出探测结果(只查 PATH 与 `--version`,不联网、不计费;结果缓存在 `<数据目录>/drivers.json`)。
165
+
166
+ ### 在 `task` 里使用
167
+
168
+ - **名字**:`task(agent="claude")`、`"codex"`、`"acp:<程序>"`(如 `acp:ama`、`acp:gemini`),以及上表的其它 id(`gemini`、`qwen` …;
169
+ 裸 `ama` 不是外部 Agent,ama 自己经 ACP 写 `acp:ama`);定义文件里 `runner: claude | codex | acp:<程序>` 的类型同样走这里。
170
+ 启动时 PATH 上找得到的 `claude` / `codex` 写进 task 工具描述的类型清单(只查 PATH,不起进程);其余名字按需解析、不进描述
171
+ (描述在会话内字节不变,缓存前缀不受影响)。
172
+ - **首次确认**:每个会话第一次以某个外部 Agent 运行时问一次「将以你在该 CLI 的现有登录运行,模式 Y」(`execute` 类):
173
+ allow 规则 `task` 或 `task(<id>)`(如 `task(claude)`、`task(acp:*)`)与 `full-auto` 直接放行;deny 规则 `task(<id>)` 拒绝;
174
+ `allowlist` 与无人值守(`-p`)没有 allow 规则时拒绝;其余交给人(不经 auto 分类器)。同一 Agent 本会话只问一次。
175
+ 宿主注入的 runner 不问(审批由宿主管)。Manual 模式下 `task(agent="claude")` 本来要问两次(task 调用本身一次、首次运行一次),
176
+ 交互界面合并为一次:task 调用的审批框写明「以你在该 CLI 的登录运行(含本会话首次运行确认)」,允许后紧接着的首次运行
177
+ 确认自动通过;中间夹了别的审批、被拒、超过 60 秒或不是这次调用建立的任务时照常弹出([tui.md](tui.md)「子 Agent」)。
178
+ - **前台 / 后台 / 续聊**:与 ama 子会话相同——结果是外部 Agent 的最终文本加工具摘要与修改的文件(≤ 50 KB);
179
+ `background: true` 完成后收到 `<task-notification>`;`task{taskId}` / `task_ctl send` 在同一外部会话里续聊(进程还在就直接
180
+ 追加一轮;空闲关闭或被停止过的,以外部会话 id `resume` 重开);`task_ctl stop` 发协议级中断,挂起的审批回「已取消」。
181
+ - **模型**:`agents.<id>.model` 或 `task` 的 `model` 参数原样交给外部 CLI;`subagents.defaultModel`(ama 的模型)不传。
182
+ - `/agents` 与 RPC `get_agents` 列出类型目录与外部 Agent(`installed` / `version`,会话建立时异步探测并缓存);`/tasks` 查看任务输出、
183
+ 停止任务。界面见 [tui.md](tui.md)「子 Agent」。
184
+ - 外部 Agent 自己报告的提示(预算用尽、超时、模式降级、拒答提问等)在交互界面的消息区显示为一行 `[claude · t3] …`,
185
+ 其它入口只写进诊断日志(`[task tN] …`,没有对应事件)。
186
+
187
+ ### 权限:只交给人
188
+
189
+ - 外部 Agent 先按它自己的策略判断;它决定要问人的请求才到 ama,到了以后**只走审批通道**(宿主 → 界面 → 无人值守拒绝)。ama 的 auto 分类器与模型都不参与,模型没有回答审批的工具。
190
+ - 对话框标出来源(`[claude · 会话 abc12345]`,三种来源标注见 [permissions.md](permissions.md)「审批对话框的来源标注」);RPC 的 `permission_request` 带 `context.origin`(Agent、会话、工具标题与种类、路径、选项)与 `context.taskId`(来源任务)。
191
+ - 选项:「允许」→ 允许一次;「本会话允许」→ 交给外部 Agent 自己记住(Codex `acceptForSession`;Claude 只回传它给出的会话范围建议,会写配置文件的建议不替你接受);「拒绝」→ 拒绝一次。会改外部 CLI 持久配置的选项(Codex execpolicy 修订、永久拒绝)不提供。
192
+ - 无人值守(`-p`、RPC 未声明 approvals):一律拒绝;Claude 以 `--permission-prompts none` 启动,Codex 用 `approval_policy = never`。
193
+ - 中断、`task_ctl stop`、超时:挂起的请求回「已取消」。
194
+ - 外部 Agent 向你**提问**(Claude `AskUserQuestion`、Codex `requestUserInput`、MCP elicitation)时 ama 不代答:拒绝并请它把问题写进最终回复,界面给出提示。
195
+
196
+ ### 模式:不比 ama 宽
197
+
198
+ 外部 Agent 的模式不得比 ama 当前模式宽;用户级 `agents.<id>.maxMode` 可以显式放宽。父会话在 `plan` 或 `allowlist` 时外部 Agent 只能只读(`allowlist` 也按 `plan`:外部 Agent 的放行规则来自它自己的配置,与 ama 不等价)。
199
+
200
+ | ama 模式 | Claude Code `--permission-mode` | Codex `approval_policy` / `sandbox` | ACP `session/set_mode` |
201
+ | ----------- | ------------------------------------ | ---------------------------------------------------------- | -------------------------------------------------------- |
202
+ | `plan` | `plan` | `never` / `read-only` | `plan`(没有只读模式的 Agent 拒绝启动) |
203
+ | `allowlist` | `plan` | `never` / `read-only` | `plan` |
204
+ | `default` | `manual`(旧版本 `default`) | `on-request` / `read-only` | 同名模式,没有则用它的缺省模式(需要授权的操作仍交给你) |
205
+ | `auto-edit` | `acceptEdits` | `untrusted` / `workspace-write` | 同上 |
206
+ | `auto` | `auto` | `on-request` / `workspace-write` | 同上 |
207
+ | `full-auto` | `auto`(从不给 `bypassPermissions`) | `never` / `workspace-write`(从不给 `danger-full-access`) | 同上 |
208
+
209
+ 一次性打印模式不能审批,只在只读任务下用。
210
+
211
+ ### 环境与账户
212
+
213
+ 外部 Agent 用你在该 CLI 里的现有登录。为了不把订阅计费切成 API 计费,ama 起子进程时**缺省剥离**:全部内置供应商的 API key 变量、`*_BASE_URL`、`AMA_*`、`CODEX_API_KEY`、`ANTHROPIC_AUTH_TOKEN`,以及 `ARMADRA_*`(`ARMADRA_ASKPASS_*` 除外,见「嵌入宿主」);其余(PATH、HOME、LANG、代理、SSH、各 CLI 自己的配置目录与令牌)保留。确实要传的用 `agents.<id>.env.passthrough` 列出(`config.json`,只认用户级):
214
+
215
+ ```json
216
+ {
217
+ "agents": {
218
+ "maxConcurrent": 3,
219
+ "sessionBudgetUsd": 5,
220
+ "claude": { "maxConcurrent": 2, "model": "sonnet", "env": { "passthrough": ["HTTPS_PROXY"] } },
221
+ "codex": { "maxMode": "auto-edit" }
222
+ }
223
+ }
224
+ ```
225
+
226
+ `--bare`(只认 API key)永不使用。
227
+
228
+ ### 信任、并发、预算、记账
229
+
230
+ - **信任**:只在 ama 已信任的目录里起外部 Agent(`claude -p` 会跳过目录信任对话框并执行项目 hooks 与配置);未信任时 `task` 报错并提示 `ama trust`。
231
+ - **并发**:外部 Agent 总共 `agents.maxConcurrent`(缺省 3),每个 Agent 另有上限(`agents.<id>.maxConcurrent`,claude 缺省 2);超出排队,排队可被中断。与 ama 子会话的并发分开计。
232
+ - **预算**:`task` 的 `budgetUsd`(Claude 透传 `--max-budget-usd`,其余按用量累计、超限中断);`agents.sessionBudgetUsd` 是本会话外部 Agent 的美元总额,用尽后不再启动。Codex 订阅 token、Copilot premium request 按各自单位记,不换算美元;Claude 的 `total_cost_usd` 是它自己的估算。
233
+ - **记账**:每回合写 `custom{ama.agent-usage}`,会话建立写 `custom{ama.agent-session}`(外部 CLI 自己的会话 id,用于续聊);`/session` 与 `get_session_stats` 的 `external` 段按 Agent 汇总。ama 会话只存最终文本、工具摘要、用量与引用,外部 Agent 的原始事件只在内存里显示,不落盘。
234
+ - **看门狗**:单回合缺省 30 分钟;中断后 15 秒内没有回合结束就关 stdin 再结束进程树;空闲 10 分钟关进程,能续接的下次续聊时以 resume 重开。外部 Agent 进程登记在 `<数据目录>/drivers/pids.json`,ama 异常退出留下的孤儿在下次使用时清理(核对命令行,pid 被复用的不杀)。
235
+
236
+ ### 嵌入宿主
237
+
238
+ 有宿主(`--host` 或 profile 的 `host`,如嵌入 Armadra)时 ama **不自己启动外部 CLI**:内置外部 Agent 一律不可用,不写进 task 描述,`task(agent="claude")` 以「由宿主提供」失败;只有宿主经 `HostApi.runners.provide(runner)` 注入的 runner 可用,它以同一个 `task(agent=<id>)` 入口出现,同名时替换内置的。`create()` 时已注入的 runner 写进 task 描述(`- <id>: <description>`),之后注入的也能用但不进描述。runner 的 `start` 收到 `prompt`、`cwd`、`mode`(父会话当前模式)、`taskId`、`signal`、`onEvent`;不经首次确认。
239
+
240
+ **在 Armadra 画布终端里直接运行 ama(没有 `--host`)**:此时 ama 按独立模式工作,自己启动的外部 Agent 是这个终端节点里的子进程,不会出现在画布上,也不经连线授权;需要让多个 Agent 在画布上协同,就在画布上连线 Agent 节点,或以宿主模式嵌入 ama。终端带着该节点的身份变量(`ARMADRA_NODE_ID`、`ARMADRA_SESSION_ID`、Hook 端点、`ARMADRA_CANVAS_CONTROL` 等),ama 起子进程时一律剥离(askpass 除外),否则 Armadra 装在 Claude / Codex 上的 Hook 会把子 Agent 的事件记到这个节点名下。
241
+
242
+ ### 本地验证真实 CLI
243
+
244
+ CI 不跑真实 CLI。本机已登录 `claude` / `codex` 时:
245
+
246
+ ```sh
247
+ AMA_E2E_AGENTS=1 pnpm vitest run src/drivers/agents.e2e.test.ts src/agents/external-task.e2e.test.ts
248
+ ```
249
+
250
+ 驱动层每家两轮「只回 OK」加一次触发审批的写文件(临时目录),会使用你的订阅额度;Claude 跑前后比对 `~/.claude` 下 settings 文件的指纹。`task` 层每家一次写文件(首次确认与写文件审批由测试代替人允许)加一轮 `taskId` 续聊;父会话用 fake 供应商。驱动的单元测试用 `test/fixtures/drivers/` 下的手写录制回放,`task` 层的零费用端到端是 ama 驱动 ama(`src/agents/external-task.test.ts`),都不发起计费请求。
package/docs/codemode.md CHANGED
@@ -14,17 +14,19 @@
14
14
 
15
15
  `codemode.mode` 不写时**跟随预设**:
16
16
 
17
- | 预设 | Node ≥ 25(沙箱隔离网络) | Node 22 / 24 |
18
- | ------------------------- | ------------------------- | ---------------------------------------------------------------------- |
19
- | `default` | `on` | `off`,启动时提示一次(每个配置目录一次,记在数据目录 `notices.json`) |
20
- | `codemode-only` | `only` | `only`(`execute` 类,见下) |
21
- | `minimal` / `coordinator` | `off` | `off` |
17
+ | 预设 | 网络隔离(Node ≥ 25,或 Node 22 / 24 + 操作系统沙箱) | Node 22 / 24 且没有操作系统沙箱 |
18
+ | ------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------- |
19
+ | `default` | `on` | `off`,启动时提示一次(每个配置目录一次,记在数据目录 `notices.json`) |
20
+ | `codemode-only` | `only` | `only`(`execute` 类,见下) |
21
+ | `minimal` / `coordinator` | `off` | `off` |
22
22
 
23
- 缺省配置里不写 `codemode.mode`(`ama init` 生成的 `config.json` 也不写),所以这张映射以后调整时老用户同样生效。`ama config show` / `ama doctor` 显示生效模式与原因(跟随哪个预设、Node 是否隔离网络)。
23
+ 操作系统沙箱指 macOS 的 `sandbox-exec`、Linux 的 bubblewrap(退而 `unshare -r -n`),见下文沙箱与 [sandbox.md](sandbox.md);Windows 没有,Node 22 / 24 上行为同右列。
24
+
25
+ 缺省配置里不写 `codemode.mode`(`ama init` 生成的 `config.json` 也不写),所以这张映射以后调整时老用户同样生效。`ama config show` / `ama doctor` 显示生效模式与原因(跟随哪个预设、网络由 Node 还是操作系统沙箱隔离);`ama doctor` 另列操作系统沙箱能力。
24
26
 
25
27
  `coordinator` 预设即使显式 `on`,脚本里能调用的工具也只限它的活动集(read 与宿主工具):`tools.bash`、`tools.write` 在脚本里同样不存在,协调者「不写文件、不跑 bash」的约定不能经 codemode 绕过。
26
28
 
27
- `codemode` 本身的权限类随沙箱能力:网络隔离(Node ≥ 25,见下文沙箱)时是 `read` 类,`default` 权限模式下免审批——脚本只能经 `tools.*` 做事,每次内层调用仍逐个经过权限管线;网络未隔离(Node 22 / 24)时是 `execute` 类,`default` 模式下每次都要审批,`-p` 等无人值守场景直接拒绝,此时常用做法是在配置里放行它:
29
+ `codemode` 本身的权限类随沙箱能力:网络隔离(Node ≥ 25,或有操作系统沙箱,见下文沙箱)时是 `read` 类,`default` 权限模式下免审批——脚本只能经 `tools.*` 做事,每次内层调用仍逐个经过权限管线;网络未隔离(Node 22 / 24 且没有操作系统沙箱)时是 `execute` 类,`default` 模式下每次都要审批,`-p` 等无人值守场景直接拒绝,此时常用做法是在配置里放行它:
28
30
 
29
31
  ```json
30
32
  { "version": 1, "tools": { "preset": "codemode-only" }, "permission": { "allow": ["codemode"] } }
@@ -96,7 +98,8 @@
96
98
  - 空环境启动,拿不到密钥、会话文件与环境变量(Windows 上 libuv 会从父进程补入 PATH、SYSTEMROOT、USERPROFILE 等系统变量,不含密钥);不授予文件写、子进程、worker、addon、inspector 权限;Node 22.0–22.12 用 `--experimental-permission`;嵌入 Electron 时设 `ELECTRON_RUN_AS_NODE=1`。
97
99
  - 子进程里用 `node:vm` 建只含 ECMAScript 内建对象的上下文(`codeGeneration: { strings: false, wasm: false }`,沙箱对象空原型);全局函数都在上下文内定义,只经一个宿主函数交换 JSON 字符串;子进程主 realm 也禁止字符串生成代码,经构造器链逃逸拿不到 `Function("return process")`。
98
100
  - `tools.*` 经 stdin / stdout 的 JSON 行协议回调父进程执行。
99
- - 网络:Node ≥ 25 的权限模型同时拒绝网络(strict);Node 22 / 24 不管网络,脚本若逃出 `vm` 就能联网——此时工具描述标注 `network not isolated`,`codemode.requireStrict: true` 时直接不注册 `codemode` 并给出 warning(codemode-only 预设随之回退到 default)。
101
+ - 操作系统沙箱([sandbox.md](sandbox.md)):探测到可用的 macOS `sandbox-exec` / Linux `bwrap`(退而 `unshare -r -n`)时,上面整条命令行经它启动,内核拒绝网络(含 DNS)与一切写入。探测是启动时跑一次最小探针(嵌套在别的沙箱里、容器里没有用户命名空间都会失败),结果进程内缓存;`sandbox.enabled: "off"`(只认用户级 / profile)或 `AMA_SANDBOX=off` 关闭。
102
+ - 网络:Node ≥ 25 的权限模型同时拒绝网络(strict),操作系统沙箱叠加作纵深防御;Node 22 / 24 的权限模型不管网络,有操作系统沙箱时由它拒绝(strict,子进程必须经它启动,包装不了直接报错);两者都没有时脚本若逃出 `vm` 就能联网——此时工具描述标注 `network not isolated`、状态栏标 `net!`,`codemode.requireStrict: true` 时直接不注册 `codemode` 并给出 warning(codemode-only 预设随之回退到 default)。
100
103
 
101
104
  | 实测(`--permission` + 只读入口) | Node 22.19 | Node 24.21 | Node 26.10 |
102
105
  | --------------------------------- | ---------- | ---------- | ---------- |
@@ -104,6 +107,7 @@
104
107
  | 写文件 | 拒绝 | 拒绝 | 拒绝 |
105
108
  | 起子进程 / worker | 拒绝 | 拒绝 | 拒绝 |
106
109
  | 联网(fetch / TCP) | **允许** | **允许** | 拒绝 |
110
+ | 联网,经 macOS `sandbox-exec` | 拒绝 | 拒绝 | 拒绝 |
107
111
 
108
112
  沙箱防的是脚本**绕过权限管线**,不是对抗性的代码执行环境;脚本能造成的副作用都来自它调用的工具,而工具调用照常受 Hook、权限与审批约束。
109
113
 
package/docs/hooks.md CHANGED
@@ -38,17 +38,19 @@
38
38
 
39
39
  ## 事件
40
40
 
41
- | 事件 | 时机 | stdout JSON 可改变什么 | 退出码 2 |
42
- | ------------------ | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
43
- | `SessionStart` | 会话创建 / 恢复后、首次提示前(`source`) | `additionalContext` → 系统提示的 `hooks` 节;`decision: "block"` → 启动失败 | 启动失败,退出码 6(换会话时忽略) |
44
- | `UserPromptSubmit` | 用户提示展开后、入转录前 | `decision: "block"` + `reason` 阻止本次提示;`updatedPrompt` 替换提示;`additionalContext` 作为 custom 消息随提示进上下文 | 阻止,reason 显示给用户 |
45
- | `PreToolUse` | schema 校验之后、权限管线之前 | `decision: "allow" \| "deny" \| "ask"`、`reason`、`updatedInput` 替换工具输入 | deny,stderr 作为 reason 进工具结果 |
46
- | `PostToolUse` | 工具执行后、结果入转录前 | `additionalContext` 追加到工具结果末尾;`decision: "block"` 把结果改为错误 | 结果标为错误,stderr 追加进结果 |
47
- | `Stop` | 运行将要结束(`agent_before_settle`,没有排队的 followUp) | `decision: "block"` + `reason` → 以 reason 作为新的 user 消息**再跑一轮**(每次运行最多 3 次) | 同左 |
48
- | `SubagentStop` | `task` 子会话将要结束 | 同 Stop,作用于子会话 | 同左 |
49
- | `PreCompact` | 档二摘要压缩前 | `customInstructions` 追加到摘要提示;`decision: "block"` 取消本次压缩 | 取消压缩 |
50
- | `Notification` | 需要用户注意:审批等待、运行结束、错误、重试 | 无(纯通知) | 忽略 |
51
- | `SessionEnd` | 退出或换会话前(`reason: exit \| new \| switch`) | 无 | 忽略 |
41
+ | 事件 | 时机 | stdout JSON 可改变什么 | 退出码 2 |
42
+ | ------------------ | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
43
+ | `SessionStart` | 会话创建 / 恢复后、首次提示前(`source`) | `additionalContext` → 系统提示的 `hooks` 节;`decision: "block"` → 启动失败 | 启动失败,退出码 6(换会话时忽略) |
44
+ | `UserPromptSubmit` | 用户提示展开后、入转录前 | `decision: "block"` + `reason` 阻止本次提示;`updatedPrompt` 替换提示;`additionalContext` 作为 custom 消息随提示进上下文 | 阻止,reason 显示给用户 |
45
+ | `PreToolUse` | schema 校验之后、权限管线之前 | `decision: "allow" \| "deny" \| "ask"`、`reason`、`updatedInput` 替换工具输入 | deny,stderr 作为 reason 进工具结果 |
46
+ | `PostToolUse` | 工具执行后、结果入转录前 | `additionalContext` 追加到工具结果末尾;`decision: "block"` 把结果改为错误 | 结果标为错误,stderr 追加进结果 |
47
+ | `Stop` | 运行将要结束(`agent_before_settle`,没有排队的 followUp) | `decision: "block"` + `reason` → 以 reason 作为新的 user 消息**再跑一轮**(每次运行最多 3 次) | 同左 |
48
+ | `SubagentStop` | `task` 子会话将要结束 | 同 Stop,作用于子会话 | 同左 |
49
+ | `PreCompact` | 档二摘要压缩前 | `customInstructions` 追加到摘要提示;`decision: "block"` 取消本次压缩 | 取消压缩 |
50
+ | `Notification` | 需要用户注意:审批等待、运行结束、错误、重试 | 无(纯通知) | 忽略 |
51
+ | `SessionEnd` | 退出或换会话前(`reason: exit \| new \| switch`) | 无 | 忽略 |
52
+ | `PostRewind` | 回滚完成后(`/rewind`、RPC `rewind`、SDK `session.rewind()`;预览不触发) | 无(纯通知,不可阻止) | 忽略 |
53
+ | `PostCompact` | 档二摘要压缩写入之后(自动与手动;失败或取消不触发) | `additionalContext` 作为 custom 消息(`ama.hook_context`)追加在上下文末尾;不可阻止 | 忽略 |
52
54
 
53
55
  每个事件只接受上表的决策;`deny` 与 `block` 在两类事件间互换(`UserPromptSubmit` 返回 `deny` 视为 `block`,`PreToolUse` 返回 `block` 视为 `deny`),其它不接受的决策忽略并记 warning。
54
56
 
@@ -71,16 +73,18 @@ stdin 是一个 JSON 对象,写完即关闭。所有事件共有:
71
73
 
72
74
  事件特有:
73
75
 
74
- | 事件 | 字段 |
75
- | ----------------------- | ----------------------------------------------------------------------------------------------------- |
76
- | `SessionStart` | `source: startup \| resume \| new \| fork` |
77
- | `SessionEnd` | `reason: exit \| new \| switch` |
78
- | `UserPromptSubmit` | `prompt` |
79
- | `PreToolUse` | `toolCallId`、`toolName`、`toolInput`、`viaCodemode?`、`parentToolCallId?` |
80
- | `PostToolUse` | 同上 + `toolResult: { content, isError }`(content 为文本) |
81
- | `Stop` / `SubagentStop` | `lastAssistantText`、`stopHookActive`(本次运行已被 Stop Hook 续跑过;处理器应避免再 block 造成循环) |
82
- | `PreCompact` | `tokensBefore`、`trigger: auto \| manual` |
83
- | `Notification` | `notification: { kind: approval \| settled \| error \| retry, message }` |
76
+ | 事件 | 字段 |
77
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------- |
78
+ | `SessionStart` | `source: startup \| resume \| new \| fork` |
79
+ | `SessionEnd` | `reason: exit \| new \| switch` |
80
+ | `UserPromptSubmit` | `prompt` |
81
+ | `PreToolUse` | `toolCallId`、`toolName`、`toolInput`、`viaCodemode?`、`parentToolCallId?` |
82
+ | `PostToolUse` | 同上 + `toolResult: { content, isError }`(content 为文本) |
83
+ | `Stop` / `SubagentStop` | `lastAssistantText`、`stopHookActive`(本次运行已被 Stop Hook 续跑过;处理器应避免再 block 造成循环) |
84
+ | `PreCompact` | `tokensBefore`、`trigger: auto \| manual` |
85
+ | `PostCompact` | `tokensBefore`、`tokensAfter`(压缩后估算,含摘要与回注块)、`trigger: auto \| manual` |
86
+ | `Notification` | `notification: { kind: approval \| settled \| error \| retry, message }` |
87
+ | `PostRewind` | `entryId`(回滚到的用户消息)、`mode: both \| conversation \| code`、`files`(被恢复或删除的文件,仅对话时为空) |
84
88
 
85
89
  **codemode**:脚本里经 `tools.*` 发起的每次调用都单独经过 PreToolUse / PostToolUse,matcher 按**真实工具名**匹配(`bash`,不是 `codemode`),输入多两个字段:`viaCodemode: true` 与 `parentToolCallId`(外层 `codemode` 调用的 id)。`codemode` 调用本身也作为一次工具调用经过两个事件。模型直接发起的调用不带这两个字段。
86
90
 
@@ -103,7 +107,7 @@ interface HookOutput {
103
107
  reason?: string;
104
108
  updatedInput?: unknown; // PreToolUse
105
109
  updatedPrompt?: string; // UserPromptSubmit
106
- additionalContext?: string; // SessionStart / UserPromptSubmit / PostToolUse
110
+ additionalContext?: string; // SessionStart / UserPromptSubmit / PostToolUse / PostCompact
107
111
  customInstructions?: string; // PreCompact
108
112
  continue?: false; // 任何事件:结束当前运行
109
113
  suppressOutput?: true;