@armadra/agent 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (527) hide show
  1. package/CHANGELOG.md +257 -0
  2. package/README.md +263 -95
  3. package/THIRD_PARTY_NOTICES.md +34 -0
  4. package/dist/acp.d.ts +18 -0
  5. package/dist/acp.js +19 -0
  6. package/dist/agent/limits.d.ts +38 -0
  7. package/dist/agent/limits.js +127 -0
  8. package/dist/agent/loop-guard.d.ts +38 -0
  9. package/dist/agent/loop-guard.js +95 -0
  10. package/dist/agent/loop.d.ts +4 -0
  11. package/dist/agent/loop.js +7 -0
  12. package/dist/agent/prompt-rules.d.ts +12 -0
  13. package/dist/agent/prompt-rules.js +18 -0
  14. package/dist/agent/reminders.d.ts +59 -0
  15. package/dist/agent/reminders.js +327 -0
  16. package/dist/agent/retry.d.ts +1 -1
  17. package/dist/agent/retry.js +2 -1
  18. package/dist/agent/session-cache.d.ts +5 -0
  19. package/dist/agent/session-cache.js +18 -2
  20. package/dist/agent/session-classifier.d.ts +18 -0
  21. package/dist/agent/session-classifier.js +105 -0
  22. package/dist/agent/session-compaction.d.ts +35 -6
  23. package/dist/agent/session-compaction.js +157 -31
  24. package/dist/agent/session-core.d.ts +40 -1
  25. package/dist/agent/session-extensions.d.ts +61 -0
  26. package/dist/agent/session-extensions.js +129 -0
  27. package/dist/agent/session-images.d.ts +23 -0
  28. package/dist/agent/session-images.js +97 -0
  29. package/dist/agent/session-plan.d.ts +21 -0
  30. package/dist/agent/session-plan.js +524 -0
  31. package/dist/agent/session-rewind.d.ts +81 -0
  32. package/dist/agent/session-rewind.js +354 -0
  33. package/dist/agent/session-run.d.ts +28 -1
  34. package/dist/agent/session-run.js +157 -6
  35. package/dist/agent/session-settings.d.ts +49 -0
  36. package/dist/agent/session-settings.js +95 -0
  37. package/dist/agent/session-subagent.d.ts +36 -24
  38. package/dist/agent/session-subagent.js +259 -129
  39. package/dist/agent/session-sync.d.ts +10 -3
  40. package/dist/agent/session-sync.js +37 -8
  41. package/dist/agent/session-telemetry.d.ts +39 -0
  42. package/dist/agent/session-telemetry.js +231 -0
  43. package/dist/agent/session-tools.js +63 -3
  44. package/dist/agent/session.d.ts +33 -29
  45. package/dist/agent/session.js +91 -126
  46. package/dist/agent/subagent-registry.d.ts +91 -0
  47. package/dist/agent/subagent-registry.js +494 -0
  48. package/dist/agent/system-prompt.d.ts +6 -3
  49. package/dist/agent/system-prompt.js +7 -2
  50. package/dist/agent/tool-runner.d.ts +8 -1
  51. package/dist/agent/tool-runner.js +72 -6
  52. package/dist/agent/types-w5.d.ts +192 -0
  53. package/dist/agent/types-w5.js +10 -0
  54. package/dist/agent/types.d.ts +55 -4
  55. package/dist/agent/types.js +2 -0
  56. package/dist/agent/worktree.d.ts +36 -0
  57. package/dist/agent/worktree.js +86 -0
  58. package/dist/agents/builtin.d.ts +14 -0
  59. package/dist/agents/builtin.js +39 -0
  60. package/dist/agents/catalog.d.ts +43 -0
  61. package/dist/agents/catalog.js +82 -0
  62. package/dist/agents/discover.d.ts +35 -0
  63. package/dist/agents/discover.js +83 -0
  64. package/dist/agents/external.d.ts +82 -0
  65. package/dist/agents/external.js +326 -0
  66. package/dist/agents/parse.d.ts +18 -0
  67. package/dist/agents/parse.js +116 -0
  68. package/dist/agents/result.d.ts +32 -0
  69. package/dist/agents/result.js +67 -0
  70. package/dist/agents/task-control.d.ts +17 -0
  71. package/dist/agents/task-control.js +17 -0
  72. package/dist/agents/task-record.d.ts +78 -0
  73. package/dist/agents/task-record.js +141 -0
  74. package/dist/agents/types.d.ts +46 -0
  75. package/dist/agents/types.js +8 -0
  76. package/dist/ai/apis/anthropic-compat.d.ts +36 -0
  77. package/dist/ai/apis/anthropic-compat.js +92 -0
  78. package/dist/ai/apis/anthropic-messages.js +3 -2
  79. package/dist/ai/apis/anthropic-request.d.ts +7 -6
  80. package/dist/ai/apis/anthropic-request.js +10 -28
  81. package/dist/ai/apis/cache-params.d.ts +11 -2
  82. package/dist/ai/apis/cache-params.js +25 -6
  83. package/dist/ai/apis/google-generative-ai.js +3 -2
  84. package/dist/ai/apis/openai-compat.d.ts +4 -1
  85. package/dist/ai/apis/openai-compat.js +8 -1
  86. package/dist/ai/apis/openai-completions.js +3 -2
  87. package/dist/ai/apis/openai-responses.js +3 -2
  88. package/dist/ai/http.d.ts +28 -6
  89. package/dist/ai/http.js +41 -8
  90. package/dist/ai/image-limits.d.ts +45 -0
  91. package/dist/ai/image-limits.js +68 -0
  92. package/dist/ai/providers/builtin.d.ts +18 -6
  93. package/dist/ai/providers/builtin.js +135 -6
  94. package/dist/ai/providers/catalog-data.js +17 -13
  95. package/dist/ai/providers/catalog.d.ts +60 -7
  96. package/dist/ai/providers/catalog.js +197 -38
  97. package/dist/ai/providers/channels.d.ts +33 -3
  98. package/dist/ai/providers/channels.js +108 -7
  99. package/dist/ai/providers/enrich.d.ts +6 -3
  100. package/dist/ai/providers/enrich.js +19 -4
  101. package/dist/ai/providers/models-dev-cache.d.ts +28 -24
  102. package/dist/ai/providers/models-dev-cache.js +92 -78
  103. package/dist/ai/providers/models-dev-data.d.ts +7 -0
  104. package/dist/ai/providers/models-dev-data.js +32 -0
  105. package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
  106. package/dist/ai/providers/models-dev-snapshot.js +137 -0
  107. package/dist/ai/providers/models-dev.d.ts +51 -10
  108. package/dist/ai/providers/models-dev.js +132 -39
  109. package/dist/ai/providers/registry.d.ts +28 -11
  110. package/dist/ai/providers/registry.js +112 -65
  111. package/dist/ai/providers/suggest.d.ts +18 -0
  112. package/dist/ai/providers/suggest.js +72 -0
  113. package/dist/ai/sse.d.ts +6 -2
  114. package/dist/ai/sse.js +22 -2
  115. package/dist/ai/types.d.ts +37 -4
  116. package/dist/ai/types.js +5 -0
  117. package/dist/bundle/ama.cjs +41979 -21147
  118. package/dist/checkpoints/backend.d.ts +61 -0
  119. package/dist/checkpoints/backend.js +135 -0
  120. package/dist/checkpoints/blobs.d.ts +60 -0
  121. package/dist/checkpoints/blobs.js +203 -0
  122. package/dist/checkpoints/gc.d.ts +47 -0
  123. package/dist/checkpoints/gc.js +144 -0
  124. package/dist/checkpoints/git-head.d.ts +15 -0
  125. package/dist/checkpoints/git-head.js +89 -0
  126. package/dist/checkpoints/index.d.ts +17 -0
  127. package/dist/checkpoints/index.js +17 -0
  128. package/dist/checkpoints/replay.d.ts +48 -0
  129. package/dist/checkpoints/replay.js +154 -0
  130. package/dist/checkpoints/restore.d.ts +86 -0
  131. package/dist/checkpoints/restore.js +263 -0
  132. package/dist/checkpoints/settings.d.ts +14 -0
  133. package/dist/checkpoints/settings.js +23 -0
  134. package/dist/checkpoints/shadow-git.d.ts +108 -0
  135. package/dist/checkpoints/shadow-git.js +491 -0
  136. package/dist/checkpoints/shadow-restore.d.ts +25 -0
  137. package/dist/checkpoints/shadow-restore.js +128 -0
  138. package/dist/checkpoints/tracker.d.ts +64 -0
  139. package/dist/checkpoints/tracker.js +192 -0
  140. package/dist/checkpoints/types.d.ts +99 -0
  141. package/dist/checkpoints/types.js +12 -0
  142. package/dist/cli/args.d.ts +26 -7
  143. package/dist/cli/args.js +75 -82
  144. package/dist/cli/bootstrap.js +40 -4
  145. package/dist/cli/codemode-notice.d.ts +21 -0
  146. package/dist/cli/codemode-notice.js +56 -0
  147. package/dist/cli/compose-agents.d.ts +27 -0
  148. package/dist/cli/compose-agents.js +111 -0
  149. package/dist/cli/compose-extensions.d.ts +29 -0
  150. package/dist/cli/compose-extensions.js +44 -0
  151. package/dist/cli/compose-session.d.ts +8 -0
  152. package/dist/cli/compose-session.js +76 -2
  153. package/dist/cli/compose-store.d.ts +1 -1
  154. package/dist/cli/compose-store.js +3 -1
  155. package/dist/cli/compose.d.ts +17 -4
  156. package/dist/cli/compose.js +60 -14
  157. package/dist/cli/default-model.d.ts +38 -1
  158. package/dist/cli/default-model.js +96 -9
  159. package/dist/cli/deps.d.ts +42 -0
  160. package/dist/cli/exit-codes.d.ts +12 -0
  161. package/dist/cli/exit-codes.js +15 -0
  162. package/dist/cli/fake-visibility.d.ts +13 -0
  163. package/dist/cli/fake-visibility.js +26 -0
  164. package/dist/cli/from-prompt.d.ts +18 -0
  165. package/dist/cli/from-prompt.js +49 -0
  166. package/dist/cli/help-text.d.ts +4 -0
  167. package/dist/cli/help-text.js +102 -0
  168. package/dist/cli/main.d.ts +9 -2
  169. package/dist/cli/main.js +77 -3
  170. package/dist/cli/proxy.d.ts +51 -0
  171. package/dist/cli/proxy.js +135 -0
  172. package/dist/cli/startup-screen.d.ts +29 -0
  173. package/dist/cli/startup-screen.js +51 -2
  174. package/dist/cli/startup-steps.d.ts +1 -1
  175. package/dist/cli/startup-steps.js +21 -13
  176. package/dist/cli/subcommands/config.d.ts +22 -3
  177. package/dist/cli/subcommands/config.js +119 -21
  178. package/dist/cli/subcommands/context.js +4 -1
  179. package/dist/cli/subcommands/doctor.js +33 -1
  180. package/dist/cli/subcommands/init.js +2 -1
  181. package/dist/cli/subcommands/models-discover.d.ts +15 -9
  182. package/dist/cli/subcommands/models-discover.js +58 -52
  183. package/dist/cli/subcommands/models.d.ts +2 -0
  184. package/dist/cli/subcommands/models.js +33 -14
  185. package/dist/cli/subcommands/probe-runner.d.ts +96 -0
  186. package/dist/cli/subcommands/probe-runner.js +264 -0
  187. package/dist/cli/subcommands/providers-probe.d.ts +34 -0
  188. package/dist/cli/subcommands/providers-probe.js +87 -0
  189. package/dist/cli/subcommands/providers.d.ts +3 -2
  190. package/dist/cli/subcommands/providers.js +53 -51
  191. package/dist/cli/subcommands/sessions-export.d.ts +10 -0
  192. package/dist/cli/subcommands/sessions-export.js +59 -0
  193. package/dist/cli/subcommands/sessions-search.d.ts +13 -0
  194. package/dist/cli/subcommands/sessions-search.js +103 -0
  195. package/dist/cli/subcommands/sessions.d.ts +6 -3
  196. package/dist/cli/subcommands/sessions.js +58 -3
  197. package/dist/cli/subcommands/stats.d.ts +17 -0
  198. package/dist/cli/subcommands/stats.js +198 -0
  199. package/dist/cli/system-prompt-arg.d.ts +11 -0
  200. package/dist/cli/system-prompt-arg.js +34 -0
  201. package/dist/codemode/capability.d.ts +24 -7
  202. package/dist/codemode/capability.js +38 -10
  203. package/dist/codemode/host-side.d.ts +14 -0
  204. package/dist/codemode/host-side.js +24 -1
  205. package/dist/codemode/modes.d.ts +4 -11
  206. package/dist/codemode/modes.js +5 -27
  207. package/dist/codemode/tool.d.ts +18 -14
  208. package/dist/codemode/tool.js +76 -31
  209. package/dist/compaction/breaker.d.ts +25 -9
  210. package/dist/compaction/breaker.js +47 -17
  211. package/dist/compaction/estimate.d.ts +11 -3
  212. package/dist/compaction/estimate.js +64 -22
  213. package/dist/compaction/image-budget.d.ts +45 -0
  214. package/dist/compaction/image-budget.js +115 -0
  215. package/dist/compaction/post-compact.d.ts +38 -0
  216. package/dist/compaction/post-compact.js +152 -0
  217. package/dist/compaction/protect.d.ts +27 -0
  218. package/dist/compaction/protect.js +56 -0
  219. package/dist/compaction/prune-tier.d.ts +58 -12
  220. package/dist/compaction/prune-tier.js +120 -54
  221. package/dist/compaction/summarize-tier.d.ts +23 -4
  222. package/dist/compaction/summarize-tier.js +100 -29
  223. package/dist/config/checker.d.ts +28 -0
  224. package/dist/config/checker.js +97 -0
  225. package/dist/config/init.d.ts +6 -2
  226. package/dist/config/init.js +12 -5
  227. package/dist/config/json-schema.d.ts +1 -0
  228. package/dist/config/json-schema.js +98 -4
  229. package/dist/config/key-docs.d.ts +22 -0
  230. package/dist/config/key-docs.js +174 -0
  231. package/dist/config/merge.d.ts +12 -9
  232. package/dist/config/merge.js +102 -13
  233. package/dist/config/profile.d.ts +2 -0
  234. package/dist/config/profile.js +2 -0
  235. package/dist/config/schema-w5.d.ts +18 -0
  236. package/dist/config/schema-w5.js +109 -0
  237. package/dist/config/schema.d.ts +5 -9
  238. package/dist/config/schema.js +91 -118
  239. package/dist/config/types-w5.d.ts +118 -0
  240. package/dist/config/types-w5.js +20 -0
  241. package/dist/config/types.d.ts +84 -7
  242. package/dist/config/types.js +29 -1
  243. package/dist/drivers/acp/client.d.ts +57 -0
  244. package/dist/drivers/acp/client.js +160 -0
  245. package/dist/drivers/acp/driver.d.ts +31 -0
  246. package/dist/drivers/acp/driver.js +274 -0
  247. package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
  248. package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
  249. package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
  250. package/dist/drivers/acp/testing/fake-agent.js +211 -0
  251. package/dist/drivers/acp/types.d.ts +285 -0
  252. package/dist/drivers/acp/types.js +36 -0
  253. package/dist/drivers/agents.d.ts +58 -0
  254. package/dist/drivers/agents.js +142 -0
  255. package/dist/drivers/base.d.ts +35 -0
  256. package/dist/drivers/base.js +59 -0
  257. package/dist/drivers/catalog.d.ts +46 -0
  258. package/dist/drivers/catalog.js +167 -0
  259. package/dist/drivers/env.d.ts +20 -0
  260. package/dist/drivers/env.js +46 -0
  261. package/dist/drivers/host-runners.d.ts +18 -0
  262. package/dist/drivers/host-runners.js +45 -0
  263. package/dist/drivers/jsonrpc.d.ts +58 -0
  264. package/dist/drivers/jsonrpc.js +180 -0
  265. package/dist/drivers/native/claude-normalize.d.ts +46 -0
  266. package/dist/drivers/native/claude-normalize.js +106 -0
  267. package/dist/drivers/native/claude-stream.d.ts +29 -0
  268. package/dist/drivers/native/claude-stream.js +456 -0
  269. package/dist/drivers/native/codex-app-server.d.ts +26 -0
  270. package/dist/drivers/native/codex-app-server.js +407 -0
  271. package/dist/drivers/native/codex-normalize.d.ts +38 -0
  272. package/dist/drivers/native/codex-normalize.js +124 -0
  273. package/dist/drivers/native/oneshot.d.ts +28 -0
  274. package/dist/drivers/native/oneshot.js +312 -0
  275. package/dist/drivers/permissions.d.ts +40 -0
  276. package/dist/drivers/permissions.js +92 -0
  277. package/dist/drivers/pids.d.ts +32 -0
  278. package/dist/drivers/pids.js +93 -0
  279. package/dist/drivers/pool.d.ts +28 -0
  280. package/dist/drivers/pool.js +96 -0
  281. package/dist/drivers/probe.d.ts +47 -0
  282. package/dist/drivers/probe.js +172 -0
  283. package/dist/drivers/process.d.ts +48 -0
  284. package/dist/drivers/process.js +100 -0
  285. package/dist/drivers/runner.d.ts +61 -0
  286. package/dist/drivers/runner.js +388 -0
  287. package/dist/drivers/store.d.ts +49 -0
  288. package/dist/drivers/store.js +91 -0
  289. package/dist/drivers/turn.d.ts +41 -0
  290. package/dist/drivers/turn.js +99 -0
  291. package/dist/drivers/types.d.ts +122 -0
  292. package/dist/drivers/types.js +11 -0
  293. package/dist/git/info.d.ts +75 -0
  294. package/dist/git/info.js +191 -0
  295. package/dist/hooks/protocol.js +6 -1
  296. package/dist/hooks/types.d.ts +10 -1
  297. package/dist/hooks/types.js +2 -0
  298. package/dist/host/api-impl.d.ts +7 -0
  299. package/dist/host/api-impl.js +15 -0
  300. package/dist/host/types.d.ts +24 -2
  301. package/dist/host/types.js +4 -0
  302. package/dist/index.d.ts +3 -0
  303. package/dist/index.js +1 -0
  304. package/dist/modes/acp/acp-events.d.ts +46 -0
  305. package/dist/modes/acp/acp-events.js +233 -0
  306. package/dist/modes/acp/acp-mode.d.ts +17 -0
  307. package/dist/modes/acp/acp-mode.js +47 -0
  308. package/dist/modes/acp/acp-server.d.ts +79 -0
  309. package/dist/modes/acp/acp-server.js +315 -0
  310. package/dist/modes/commands-core.d.ts +7 -1
  311. package/dist/modes/commands-core.js +61 -5
  312. package/dist/modes/image-input.d.ts +12 -4
  313. package/dist/modes/image-input.js +22 -5
  314. package/dist/modes/interactive/agent-panels.d.ts +14 -0
  315. package/dist/modes/interactive/agent-panels.js +103 -0
  316. package/dist/modes/interactive/agent-ui.d.ts +73 -0
  317. package/dist/modes/interactive/agent-ui.js +234 -0
  318. package/dist/modes/interactive/approval-dialog.d.ts +40 -7
  319. package/dist/modes/interactive/approval-dialog.js +192 -35
  320. package/dist/modes/interactive/approval-merge.d.ts +41 -0
  321. package/dist/modes/interactive/approval-merge.js +89 -0
  322. package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
  323. package/dist/modes/interactive/clipboard-paste.js +28 -0
  324. package/dist/modes/interactive/commands.d.ts +20 -3
  325. package/dist/modes/interactive/commands.js +75 -16
  326. package/dist/modes/interactive/double-esc.d.ts +20 -0
  327. package/dist/modes/interactive/double-esc.js +34 -0
  328. package/dist/modes/interactive/event-notices.d.ts +32 -0
  329. package/dist/modes/interactive/event-notices.js +79 -0
  330. package/dist/modes/interactive/external-editor.d.ts +16 -0
  331. package/dist/modes/interactive/external-editor.js +39 -0
  332. package/dist/modes/interactive/interactive-mode.d.ts +16 -2
  333. package/dist/modes/interactive/interactive-mode.js +184 -202
  334. package/dist/modes/interactive/key-dispatch.d.ts +18 -2
  335. package/dist/modes/interactive/key-dispatch.js +53 -6
  336. package/dist/modes/interactive/line/line-mode.d.ts +3 -1
  337. package/dist/modes/interactive/line/line-mode.js +28 -9
  338. package/dist/modes/interactive/line/line-render.d.ts +6 -1
  339. package/dist/modes/interactive/line/line-render.js +66 -8
  340. package/dist/modes/interactive/message-view.d.ts +49 -10
  341. package/dist/modes/interactive/message-view.js +262 -46
  342. package/dist/modes/interactive/panels.d.ts +35 -0
  343. package/dist/modes/interactive/panels.js +157 -0
  344. package/dist/modes/interactive/pickers.d.ts +23 -2
  345. package/dist/modes/interactive/pickers.js +48 -15
  346. package/dist/modes/interactive/plan-command.d.ts +40 -0
  347. package/dist/modes/interactive/plan-command.js +129 -0
  348. package/dist/modes/interactive/plan-dialog.d.ts +98 -0
  349. package/dist/modes/interactive/plan-dialog.js +290 -0
  350. package/dist/modes/interactive/plan-flow.d.ts +34 -0
  351. package/dist/modes/interactive/plan-flow.js +98 -0
  352. package/dist/modes/interactive/rewind-command.d.ts +31 -0
  353. package/dist/modes/interactive/rewind-command.js +106 -0
  354. package/dist/modes/interactive/rewind-flow.d.ts +37 -0
  355. package/dist/modes/interactive/rewind-flow.js +151 -0
  356. package/dist/modes/interactive/rewind-list.d.ts +36 -0
  357. package/dist/modes/interactive/rewind-list.js +123 -0
  358. package/dist/modes/interactive/rewind-panel.d.ts +77 -0
  359. package/dist/modes/interactive/rewind-panel.js +309 -0
  360. package/dist/modes/interactive/rewind-text.d.ts +40 -0
  361. package/dist/modes/interactive/rewind-text.js +139 -0
  362. package/dist/modes/interactive/run-indicator.d.ts +51 -0
  363. package/dist/modes/interactive/run-indicator.js +189 -0
  364. package/dist/modes/interactive/session-events.d.ts +24 -0
  365. package/dist/modes/interactive/session-events.js +96 -0
  366. package/dist/modes/interactive/startup-header.d.ts +40 -0
  367. package/dist/modes/interactive/startup-header.js +169 -0
  368. package/dist/modes/interactive/status-area.d.ts +73 -0
  369. package/dist/modes/interactive/status-area.js +190 -0
  370. package/dist/modes/interactive/status-bar.d.ts +107 -16
  371. package/dist/modes/interactive/status-bar.js +306 -81
  372. package/dist/modes/interactive/status-line.d.ts +33 -0
  373. package/dist/modes/interactive/status-line.js +113 -0
  374. package/dist/modes/interactive/subagent-view.d.ts +56 -0
  375. package/dist/modes/interactive/subagent-view.js +154 -0
  376. package/dist/modes/interactive/tasks-report.d.ts +27 -0
  377. package/dist/modes/interactive/tasks-report.js +114 -0
  378. package/dist/modes/interactive/tool-summary.d.ts +46 -0
  379. package/dist/modes/interactive/tool-summary.js +218 -0
  380. package/dist/modes/interactive/tool-view.d.ts +58 -15
  381. package/dist/modes/interactive/tool-view.js +233 -145
  382. package/dist/modes/print/print-mode.d.ts +40 -4
  383. package/dist/modes/print/print-mode.js +161 -8
  384. package/dist/modes/rpc/commands.d.ts +9 -0
  385. package/dist/modes/rpc/commands.js +49 -0
  386. package/dist/modes/rpc/rpc-mode.js +7 -1
  387. package/dist/modes/session-report.d.ts +11 -0
  388. package/dist/modes/session-report.js +48 -1
  389. package/dist/permissions/auto-safe.d.ts +65 -0
  390. package/dist/permissions/auto-safe.js +547 -0
  391. package/dist/permissions/classifier.d.ts +68 -0
  392. package/dist/permissions/classifier.js +186 -0
  393. package/dist/permissions/dangerous.d.ts +5 -0
  394. package/dist/permissions/dangerous.js +1 -1
  395. package/dist/permissions/modes.d.ts +30 -0
  396. package/dist/permissions/modes.js +78 -0
  397. package/dist/permissions/pipeline.d.ts +72 -6
  398. package/dist/permissions/pipeline.js +306 -11
  399. package/dist/permissions/protected.d.ts +19 -0
  400. package/dist/permissions/protected.js +74 -0
  401. package/dist/permissions/readonly-bash.d.ts +30 -0
  402. package/dist/permissions/readonly-bash.js +118 -0
  403. package/dist/permissions/rules.js +3 -0
  404. package/dist/permissions/types.d.ts +92 -3
  405. package/dist/permissions/types.js +3 -0
  406. package/dist/plan/compose.d.ts +9 -0
  407. package/dist/plan/compose.js +19 -0
  408. package/dist/plan/controller.d.ts +71 -0
  409. package/dist/plan/controller.js +27 -0
  410. package/dist/plan/done-markers.d.ts +17 -0
  411. package/dist/plan/done-markers.js +51 -0
  412. package/dist/plan/extract.d.ts +29 -0
  413. package/dist/plan/extract.js +160 -0
  414. package/dist/plan/prompts.d.ts +36 -0
  415. package/dist/plan/prompts.js +89 -0
  416. package/dist/plan/store.d.ts +37 -0
  417. package/dist/plan/store.js +90 -0
  418. package/dist/rpc.d.ts +58 -2
  419. package/dist/rpc.js +7 -0
  420. package/dist/sandbox/bash.d.ts +74 -0
  421. package/dist/sandbox/bash.js +126 -0
  422. package/dist/sandbox/detect.d.ts +48 -0
  423. package/dist/sandbox/detect.js +149 -0
  424. package/dist/sandbox/index.d.ts +5 -0
  425. package/dist/sandbox/index.js +5 -0
  426. package/dist/sandbox/profile.d.ts +33 -0
  427. package/dist/sandbox/profile.js +76 -0
  428. package/dist/sandbox/wrap.d.ts +29 -0
  429. package/dist/sandbox/wrap.js +117 -0
  430. package/dist/sdk.d.ts +42 -5
  431. package/dist/sdk.js +34 -4
  432. package/dist/session/export.d.ts +32 -0
  433. package/dist/session/export.js +187 -0
  434. package/dist/session/redact.d.ts +15 -0
  435. package/dist/session/redact.js +55 -0
  436. package/dist/session/reuse.d.ts +33 -0
  437. package/dist/session/reuse.js +86 -0
  438. package/dist/session/scan.d.ts +34 -0
  439. package/dist/session/scan.js +140 -0
  440. package/dist/session/search.d.ts +52 -0
  441. package/dist/session/search.js +211 -0
  442. package/dist/session/stats-aggregate.d.ts +63 -0
  443. package/dist/session/stats-aggregate.js +163 -0
  444. package/dist/session/stats-index.d.ts +26 -0
  445. package/dist/session/stats-index.js +91 -0
  446. package/dist/session/stats-scan.d.ts +54 -0
  447. package/dist/session/stats-scan.js +236 -0
  448. package/dist/session/types.d.ts +3 -1
  449. package/dist/session/types.js +1 -0
  450. package/dist/skills/builtin.d.ts +31 -0
  451. package/dist/skills/builtin.js +109 -0
  452. package/dist/skills/discover.d.ts +2 -1
  453. package/dist/skills/index-prompt.js +5 -8
  454. package/dist/tools/background-jobs.d.ts +71 -0
  455. package/dist/tools/background-jobs.js +198 -0
  456. package/dist/tools/bash.d.ts +53 -1
  457. package/dist/tools/bash.js +158 -7
  458. package/dist/tools/clipboard-image.d.ts +44 -0
  459. package/dist/tools/clipboard-image.js +148 -0
  460. package/dist/tools/edit.d.ts +2 -0
  461. package/dist/tools/edit.js +18 -3
  462. package/dist/tools/image-file.d.ts +38 -3
  463. package/dist/tools/image-file.js +81 -10
  464. package/dist/tools/image-resize.d.ts +58 -0
  465. package/dist/tools/image-resize.js +97 -0
  466. package/dist/tools/presets.d.ts +40 -8
  467. package/dist/tools/presets.js +65 -19
  468. package/dist/tools/read.d.ts +5 -2
  469. package/dist/tools/read.js +13 -10
  470. package/dist/tools/registry.d.ts +7 -1
  471. package/dist/tools/registry.js +27 -4
  472. package/dist/tools/task-ctl.d.ts +22 -0
  473. package/dist/tools/task-ctl.js +116 -0
  474. package/dist/tools/task.d.ts +22 -10
  475. package/dist/tools/task.js +66 -26
  476. package/dist/tools/todo.d.ts +22 -2
  477. package/dist/tools/todo.js +58 -14
  478. package/dist/tools/truncate.d.ts +15 -0
  479. package/dist/tools/truncate.js +25 -0
  480. package/dist/tools/types.d.ts +113 -0
  481. package/dist/tools/types.js +5 -0
  482. package/dist/tools/write.js +3 -0
  483. package/dist/tui/component.d.ts +8 -2
  484. package/dist/tui/component.js +3 -1
  485. package/dist/tui/components/box.d.ts +6 -1
  486. package/dist/tui/components/box.js +16 -6
  487. package/dist/tui/components/card.d.ts +23 -0
  488. package/dist/tui/components/card.js +37 -0
  489. package/dist/tui/components/editor-history.d.ts +6 -0
  490. package/dist/tui/components/editor-history.js +45 -0
  491. package/dist/tui/components/editor-paste.d.ts +1 -1
  492. package/dist/tui/components/editor-paste.js +4 -4
  493. package/dist/tui/components/editor.d.ts +11 -5
  494. package/dist/tui/components/editor.js +52 -58
  495. package/dist/tui/components/key-value.d.ts +3 -0
  496. package/dist/tui/components/key-value.js +16 -6
  497. package/dist/tui/components/loader.d.ts +37 -7
  498. package/dist/tui/components/loader.js +84 -21
  499. package/dist/tui/components/markdown.d.ts +5 -1
  500. package/dist/tui/components/markdown.js +45 -21
  501. package/dist/tui/components/meter.d.ts +3 -3
  502. package/dist/tui/components/meter.js +13 -11
  503. package/dist/tui/components/select-list.d.ts +23 -1
  504. package/dist/tui/components/select-list.js +76 -13
  505. package/dist/tui/glyphs.d.ts +72 -0
  506. package/dist/tui/glyphs.js +118 -0
  507. package/dist/tui/keybindings.d.ts +5 -0
  508. package/dist/tui/keybindings.js +5 -0
  509. package/dist/tui/theme.d.ts +30 -6
  510. package/dist/tui/theme.js +103 -17
  511. package/dist/tui.d.ts +4 -2
  512. package/dist/tui.js +3 -1
  513. package/docs/acp.md +78 -0
  514. package/docs/agents.md +250 -0
  515. package/docs/codemode.md +28 -10
  516. package/docs/hooks.md +36 -32
  517. package/docs/permissions.md +212 -0
  518. package/docs/plan.md +107 -0
  519. package/docs/providers.md +261 -62
  520. package/docs/rewind-plan.md +181 -0
  521. package/docs/rpc.md +127 -40
  522. package/docs/sandbox.md +215 -0
  523. package/docs/session-format.md +43 -22
  524. package/docs/sessions.md +174 -0
  525. package/docs/tui-design.md +751 -0
  526. package/docs/tui.md +260 -64
  527. package/package.json +15 -2
@@ -3,15 +3,46 @@
3
3
  *
4
4
  * 编辑器之前的输入监听:Ctrl+C 清空输入 / 再按退出、Esc 中断(clearQueue 回填编辑器后 abort)、
5
5
  * Ctrl+D 空输入退出、Alt+Enter followUp、Alt+↑ 取回最后一条排队消息、Shift+Tab 循环权限模式、
6
- * Ctrl+O 展开工具输出、Ctrl+L 模型、Ctrl+T 思考级别。键位由 `keybindings.json` 覆盖。
6
+ * Ctrl+O 展开工具输出与思考块、Ctrl+L 模型、Ctrl+T 思考级别、Ctrl+G 底部信息行 full ↔ compact(W5-A)、
7
+ * Ctrl+V 粘贴剪贴板图片(`app.paste.image`,W5-U)。
8
+ * 键位由 `keybindings.json` 覆盖。
9
+ *
10
+ * [RW-C] 空闲时双击 Esc(`app.rewind`,double-esc.ts):输入框为空打开回滚列表,有字则清空并存进
11
+ * 输入历史;运行中 Esc 仍为中断,中断后交给 `onInterrupted`(中断即撤回)。
7
12
  */
8
13
  import { ExitCode } from "../../cli/exit-codes.js";
9
- import { PERMISSION_MODES_STRICT_FIRST } from "../../permissions/types.js";
14
+ import { nextCycleMode, permissionModeLabel } from "../../permissions/modes.js";
15
+ import { DOUBLE_ESC_HINT_MS, DoubleEscape } from "./double-esc.js";
16
+ import { statusLineText } from "./status-area.js";
10
17
  const DOUBLE_CTRL_C_MS = 1500;
11
18
  /** 返回输入监听器:已处理返回 true,交给编辑器返回 false。 */
12
19
  export function createKeyDispatch(deps) {
13
20
  const { keys, editor, tools, status } = deps;
14
21
  let ctrlCArmedAt = Number.NEGATIVE_INFINITY;
22
+ const esc = new DoubleEscape(deps.doubleEscMs);
23
+ const doubleEscape = () => {
24
+ switch (esc.press(deps.now(), editor.isEmpty())) {
25
+ case "arm-rewind":
26
+ deps.showHint("再按 Esc 回滚", DOUBLE_ESC_HINT_MS);
27
+ return;
28
+ case "arm-clear":
29
+ deps.showHint("再按 Esc 清空", DOUBLE_ESC_HINT_MS);
30
+ return;
31
+ case "rewind":
32
+ deps.showHint("");
33
+ deps.runCommand("/rewind");
34
+ return;
35
+ case "clear": {
36
+ // 记进输入历史再清空:↑ 可取回
37
+ const text = editor.getExpandedText();
38
+ if (text.trim() !== "")
39
+ editor.addToHistory(text);
40
+ editor.clear();
41
+ deps.showHint("已清空输入 · ↑ 取回");
42
+ return;
43
+ }
44
+ }
45
+ };
15
46
  const interrupt = () => {
16
47
  const session = deps.session();
17
48
  const queued = session.clearQueue();
@@ -39,17 +70,17 @@ export function createKeyDispatch(deps) {
39
70
  };
40
71
  const cyclePermission = () => {
41
72
  const session = deps.session();
42
- const modes = PERMISSION_MODES_STRICT_FIRST;
43
- const index = modes.indexOf(session.state.permissionMode);
44
- const next = modes[(index + 1) % modes.length];
73
+ const next = nextCycleMode(session.state.permissionMode);
45
74
  session.setPermissionMode(next);
46
75
  status.refresh();
47
- deps.showHint(`权限模式:${next}`);
76
+ deps.showHint(`权限模式:${permissionModeLabel(next)}`);
48
77
  };
49
78
  return (data) => {
50
79
  if (deps.inactive())
51
80
  return false;
52
81
  const is = (action) => keys.matches(data, action);
82
+ if (!is("app.rewind"))
83
+ esc.reset();
53
84
  if (is("app.clear")) {
54
85
  if (!editor.isEmpty()) {
55
86
  editor.clear();
@@ -67,8 +98,14 @@ export function createKeyDispatch(deps) {
67
98
  }
68
99
  ctrlCArmedAt = Number.NEGATIVE_INFINITY;
69
100
  if (is("app.interrupt") && !editor.isCompletionOpen && deps.busy()) {
101
+ esc.reset();
70
102
  interrupt();
71
103
  deps.showHint("已中断");
104
+ deps.onInterrupted?.(editor.isEmpty());
105
+ return true;
106
+ }
107
+ if (is("app.rewind") && !editor.isCompletionOpen && !deps.busy()) {
108
+ doubleEscape();
72
109
  return true;
73
110
  }
74
111
  if (is("app.exit") && editor.isEmpty()) {
@@ -91,6 +128,7 @@ export function createKeyDispatch(deps) {
91
128
  }
92
129
  if (is("app.tools.expand")) {
93
130
  const expanded = tools.toggleExpanded();
131
+ deps.onExpandToggle?.(expanded);
94
132
  deps.showHint(expanded ? "工具输出:展开" : "工具输出:折叠");
95
133
  return true;
96
134
  }
@@ -102,6 +140,15 @@ export function createKeyDispatch(deps) {
102
140
  deps.runCommand("/thinking");
103
141
  return true;
104
142
  }
143
+ if (is("app.paste.image") && deps.onPasteImage !== undefined) {
144
+ deps.onPasteImage();
145
+ return true;
146
+ }
147
+ if (is("app.statusLine.toggle") && deps.onStatusLineToggle !== undefined) {
148
+ const mode = deps.onStatusLineToggle();
149
+ deps.showHint(statusLineText(mode));
150
+ return true;
151
+ }
105
152
  return false;
106
153
  };
107
154
  }
@@ -5,7 +5,9 @@
5
5
  * = steer;Ctrl+C 运行中中断、空闲时连按两次退出(130);空行 Ctrl+D 退出;审批 y / a / N 单键问答。
6
6
  * 问句之前逐行打印执行前预览(`request.preview`,W3-B9a-2)。
7
7
  * - 否则(管道):逐行读 stdin,每行依次执行(等上一条运行结束);没有审批 UI,ask → deny。
8
- * - 斜杠命令走 commands-core(与 B7 同一语义),`pick` 退化为列出候选。
8
+ * 模型错误在运行结束时只打印一次(重试中只显示 ↻);有运行最终失败时退出码 1。
9
+ * - 斜杠命令走 commands-core(与 B7 同一语义),`pick` 退化为列出候选;`/rewind` 列编号、
10
+ * `/rewind <n> …` 执行,回到的单行原消息放回编辑行。
9
11
  */
10
12
  import type { ModeContext } from "../../../cli/deps.js";
11
13
  import type { Runtime } from "../../../cli/runtime.js";
@@ -5,9 +5,12 @@
5
5
  * = steer;Ctrl+C 运行中中断、空闲时连按两次退出(130);空行 Ctrl+D 退出;审批 y / a / N 单键问答。
6
6
  * 问句之前逐行打印执行前预览(`request.preview`,W3-B9a-2)。
7
7
  * - 否则(管道):逐行读 stdin,每行依次执行(等上一条运行结束);没有审批 UI,ask → deny。
8
- * - 斜杠命令走 commands-core(与 B7 同一语义),`pick` 退化为列出候选。
8
+ * 模型错误在运行结束时只打印一次(重试中只显示 ↻);有运行最终失败时退出码 1。
9
+ * - 斜杠命令走 commands-core(与 B7 同一语义),`pick` 退化为列出候选;`/rewind` 列编号、
10
+ * `/rewind <n> …` 执行,回到的单行原消息放回编辑行。
9
11
  */
10
12
  import { promptImages, sessionModel } from "../../image-input.js";
13
+ import { taskRegistryView } from "../../../agent/subagent-registry.js";
11
14
  import { currentSession, switchSession } from "../../../cli/compose-session.js";
12
15
  import { ExitCode } from "../../../cli/exit-codes.js";
13
16
  import { previewDisplayLines } from "../../../permissions/preview.js";
@@ -63,22 +66,37 @@ export async function runLineMode(runtime, context, options = {}) {
63
66
  await prompt(session, result.text);
64
67
  else if (result.kind === "pick")
65
68
  out(`${await pickHint(result.what, runtime, session)}\n`);
66
- else if (result.message !== undefined)
67
- out(`${result.message}\n`);
69
+ else {
70
+ if (result.message !== undefined)
71
+ out(`${result.message}\n`);
72
+ // /rewind 回到某条消息之前:单行原消息放回编辑行(多行只在输出里给出)
73
+ const draft = result.draft?.text;
74
+ if (editor !== undefined && draft !== undefined && !draft.includes("\n")) {
75
+ editor.buffer = draft;
76
+ editor.cursor = draft.length;
77
+ }
78
+ // /plan approve 开了新回合:跑完再收下一行(与直接发提示一致)
79
+ if (result.wait === true) {
80
+ await session.waitForIdle();
81
+ printer.endLine();
82
+ }
83
+ }
68
84
  }
69
85
  catch (error) {
70
86
  printer.endLine();
87
+ printer.failures++;
71
88
  err(`ama: ${errorText(error)}\n`);
72
89
  }
73
90
  return undefined;
74
91
  };
75
92
  const prompt = async (target, text) => {
76
- const images = await promptImages(text, [], target.state.cwd, sessionModel(runtime.providers, target));
93
+ const resize = runtime.config.images?.resize;
94
+ const images = await promptImages(text, [], target.state.cwd, sessionModel(runtime.providers, target), resize !== undefined ? { resize } : {});
77
95
  await target.prompt(text, images.length > 0 ? { images } : {});
78
96
  printer.endLine();
79
97
  };
80
98
  if (!raw)
81
- return runPiped(stdin, context, handle, () => session, () => unsubscribe());
99
+ return runPiped(stdin, context, handle, () => session, () => unsubscribe(), () => printer.failures > 0);
82
100
  // ---- raw 终端 ----
83
101
  const tty = stdin;
84
102
  editor = new LineEditor({ prompt: "› ", write: (t) => io.stdout(t) });
@@ -93,7 +111,8 @@ export async function runLineMode(runtime, context, options = {}) {
93
111
  return resolve(undefined);
94
112
  signal.addEventListener("abort", () => resolve(undefined), { once: true });
95
113
  const preview = previewDisplayLines(request.preview).map((l) => ` ${l}\n`);
96
- void ed.ask(`\n${preview.join("")}${approvalQuestion(request)}`, "n").then((answer) => {
114
+ const question = approvalQuestion(request, (taskId) => taskRegistryView(session.state.sessionId)?.get(taskId)?.agent);
115
+ void ed.ask(`\n${preview.join("")}${question}`, "n").then((answer) => {
97
116
  resolve(answer === "y" ? "allow" : answer === "a" ? "allow_session" : "deny");
98
117
  if (!busy)
99
118
  ed.render();
@@ -182,8 +201,8 @@ export async function runLineMode(runtime, context, options = {}) {
182
201
  ed.render();
183
202
  });
184
203
  }
185
- /** 管道:逐行依次执行;stdin 结束后等最后一条跑完退出 0。 */
186
- function runPiped(stdin, context, handle, session, unsubscribe) {
204
+ /** 管道:逐行依次执行;stdin 结束后等最后一条跑完退出——有失败的运行时 1,否则 0。 */
205
+ function runPiped(stdin, context, handle, session, unsubscribe, failed) {
187
206
  return new Promise((resolve) => {
188
207
  let chain = Promise.resolve(undefined);
189
208
  let finished = false;
@@ -205,7 +224,7 @@ function runPiped(stdin, context, handle, session, unsubscribe) {
205
224
  });
206
225
  };
207
226
  const reader = createLineReader(stdin, enqueue, () => {
208
- void chain.then(() => finish(ExitCode.Ok));
227
+ void chain.then(() => finish(failed() ? ExitCode.RuntimeError : ExitCode.Ok));
209
228
  });
210
229
  const offSignals = onTerminationSignals((code) => {
211
230
  void session()
@@ -6,9 +6,10 @@ import type { AgentSession, SessionEvent } from "../../../agent/types.js";
6
6
  import type { Runtime } from "../../../cli/runtime.js";
7
7
  import type { ApprovalRequest } from "../../../permissions/types.js";
8
8
  import type { CommandResult } from "../../commands-core.js";
9
+ import { type TaskAgentLookup } from "../approval-dialog.js";
9
10
  /** 工具参数的一行摘要(第一个常见字段,折叠换行、截到 80 字符)。 */
10
11
  export declare function argsSummary(args: unknown): string;
11
- export declare function approvalQuestion(request: ApprovalRequest): string;
12
+ export declare function approvalQuestion(request: ApprovalRequest, taskAgent?: TaskAgentLookup): string;
12
13
  /** [W3-C2] 缓存提示的开关(line 模式由 runLineMode 传入)。 */
13
14
  export interface EventPrinterOptions {
14
15
  /** `cache.missNotices`(每次现取,切换会话后跟随新会话);缺省 true。 */
@@ -23,6 +24,10 @@ export declare class EventPrinter {
23
24
  private readonly err;
24
25
  private readonly options;
25
26
  private midLine;
27
+ /** 本次运行的模型错误:等 agent_settled 再打(重试中的失败尝试只显示 ↻ 那一行)。 */
28
+ private pendingError;
29
+ /** 最终失败的运行次数(管道模式据此返回退出码 1)。 */
30
+ failures: number;
26
31
  constructor(out: (text: string) => void, err: (text: string) => void, options?: EventPrinterOptions);
27
32
  private line;
28
33
  /** 收尾:保证光标在行首。 */
@@ -4,8 +4,11 @@
4
4
  */
5
5
  import { THINKING_LEVELS } from "../../../ai/thinking.js";
6
6
  import { listSessions } from "../../../cli/compose-store.js";
7
- import { PERMISSION_MODES_STRICT_FIRST } from "../../../permissions/types.js";
7
+ import { AUTO_LAYER_TEXT, permissionModeLines } from "../../../permissions/modes.js";
8
8
  import { cacheEventNotice, warmSentNotice } from "../../session-report.js";
9
+ import { isFirstRunRequest, sourceLabel } from "../approval-dialog.js";
10
+ import { LIMIT_WARNING, backgroundJobText, limitReachedText, modelFallbackText, } from "../event-notices.js";
11
+ import { taskStatusText } from "../tasks-report.js";
9
12
  const SUMMARY_KEYS = ["command", "path", "pattern", "file_path", "url", "description", "name"];
10
13
  /** 工具参数的一行摘要(第一个常见字段,折叠换行、截到 80 字符)。 */
11
14
  export function argsSummary(args) {
@@ -21,14 +24,27 @@ export function argsSummary(args) {
21
24
  }
22
25
  return "";
23
26
  }
24
- export function approvalQuestion(request) {
25
- const task = (request.context?.depth ?? 0) > 0 ? "[task] " : "";
27
+ export function approvalQuestion(request, taskAgent) {
28
+ const label = sourceLabel(request, taskAgent);
29
+ const task = label === undefined ? "" : `${label} `;
30
+ const origin = request.context?.origin;
31
+ if (origin !== undefined) {
32
+ const where = origin.toolCall.locations?.[0];
33
+ return `${task}允许 ${origin.toolCall.title}${where !== undefined ? ` ${where}` : ""}?[y 允许 / a 本会话都允许 / N 拒绝] `;
34
+ }
35
+ if (isFirstRunRequest(request)) {
36
+ const input = request.input;
37
+ return `${task}${String(input["note"])} 允许?[y 允许 / N 拒绝] `;
38
+ }
26
39
  const summary = argsSummary(request.input);
40
+ const auto = request.autoDecision;
27
41
  const why = request.reason === "dangerous"
28
42
  ? "(危险命令)"
29
43
  : request.hookReason !== undefined
30
44
  ? `(${request.hookReason})`
31
- : "";
45
+ : auto !== undefined
46
+ ? `(Auto ${AUTO_LAYER_TEXT[auto.layer]}:${auto.reason})`
47
+ : "";
32
48
  return `${task}允许 ${request.toolName}${summary !== "" ? ` ${summary}` : ""}${why}?[y 允许 / a 本会话都允许 / N 拒绝] `;
33
49
  }
34
50
  /** `AMA_LOG=info|debug`。 */
@@ -40,6 +56,10 @@ export class EventPrinter {
40
56
  err;
41
57
  options;
42
58
  midLine = false;
59
+ /** 本次运行的模型错误:等 agent_settled 再打(重试中的失败尝试只显示 ↻ 那一行)。 */
60
+ pendingError;
61
+ /** 最终失败的运行次数(管道模式据此返回退出码 1)。 */
62
+ failures = 0;
43
63
  constructor(out, err, options = {}) {
44
64
  this.out = out;
45
65
  this.err = err;
@@ -72,9 +92,13 @@ export class EventPrinter {
72
92
  if (event.message.role === "assistant") {
73
93
  this.endLine();
74
94
  if (event.message.stopReason === "error")
75
- this.line(`ama: 错误:${event.message.errorMessage ?? "模型调用失败"}`, true);
95
+ this.pendingError = event.message.errorMessage ?? "模型调用失败";
76
96
  }
77
97
  return;
98
+ case "agent_end":
99
+ if (event.willRetry)
100
+ this.pendingError = undefined;
101
+ return;
78
102
  case "tool_execution_start": {
79
103
  const summary = argsSummary(event.args);
80
104
  this.line(`● ${event.toolName}${summary !== "" ? ` ${summary}` : ""}`);
@@ -112,11 +136,42 @@ export class EventPrinter {
112
136
  this.line(`ama: ${text}`, true);
113
137
  return;
114
138
  }
115
- case "agent_settled":
139
+ case "agent_settled": {
116
140
  this.endLine();
117
- if (event.warning !== undefined)
141
+ const error = this.pendingError;
142
+ this.pendingError = undefined;
143
+ if (error !== undefined) {
144
+ this.failures++;
145
+ this.line(`ama: 错误:${error}`, true);
146
+ }
147
+ // 失败时 warning 就是同一条错误文本,不再重复打印;预算到限已由 limit_reached 说明
148
+ if (event.warning !== undefined &&
149
+ event.warning !== error &&
150
+ event.warning !== LIMIT_WARNING)
118
151
  this.line(`ama: ${event.warning}`, true);
119
152
  return;
153
+ }
154
+ // [W5-U] 第五波事件
155
+ case "plan_proposed": {
156
+ const file = event.filePath !== undefined ? `(${event.filePath})` : "";
157
+ this.line(`◇ 计划 v${event.version} 待审批${file}:/plan approve [模式|fresh] 批准 · /plan reject 放弃 · 直接输入修改意见`);
158
+ return;
159
+ }
160
+ case "subagent_start":
161
+ this.line(` ↳ ${event.taskId} ${event.agent}${event.background ? "(后台)" : ""} 开始`);
162
+ return;
163
+ case "subagent_end":
164
+ this.line(` ↳ ${event.taskId} ${taskStatusText(event.status)}`);
165
+ return;
166
+ case "limit_reached":
167
+ this.line(`ama: ${limitReachedText(event)}`, true);
168
+ return;
169
+ case "model_fallback":
170
+ this.line(`ama: ${modelFallbackText(event)}`, true);
171
+ return;
172
+ case "background_job":
173
+ this.line(`ama: ${backgroundJobText(event)}`, true);
174
+ return;
120
175
  default:
121
176
  return;
122
177
  }
@@ -164,7 +219,10 @@ export async function pickHint(what, runtime, session) {
164
219
  ].join("\n");
165
220
  }
166
221
  case "permission":
167
- return `权限模式(/permission <模式>):${PERMISSION_MODES_STRICT_FIRST.join(" | ")};当前 ${session.state.permissionMode}`;
222
+ return [
223
+ "Mode(/permission <模式>):",
224
+ ...permissionModeLines(session.state.permissionMode, runtime.config.permission?.mode ?? "default").map((line) => ` ${line}`),
225
+ ].join("\n");
168
226
  case "thinking":
169
227
  return `思考级别(/thinking <级别>):${THINKING_LEVELS.join(" | ")};当前 ${session.state.thinkingLevel}`;
170
228
  }
@@ -1,18 +1,21 @@
1
1
  /**
2
2
  * 消息区(设计 §12.5)。[B7]
3
3
  *
4
- * 一个纵向 `Container`,块与块之间空一行:
5
- * - 用户消息 `› 文本`;steer / followUp / 宿主注入按 `UserMessage.origin` 标 `↳ steer` / `↳ host` …;
4
+ * 一个纵向 `Container`,块与块之间空一行(终端界面视觉设计 v1 §1 原则 2:相邻工具调用之间不空行,
5
+ * `ui.compact` 时全部不空行):
6
+ * - 用户消息 `› 文本`(续行缩进 2 列);插话 / 之后 / 宿主注入按 `UserMessage.origin` 标
7
+ * `↳ 插话` / `↳ 之后` / `↳ 宿主`(整行 muted,其它 origin 原样显示);
6
8
  * - 助手消息按内容块渲染:文本走 `Markdown`(`ui.markdown: false` 时纯文本),流式时只改末块
7
- * (Markdown 自己按块缓存);思考块按 `ui.showThinking`:`collapsed`(缺省)一行 `思考 · N token`、
8
- * `full` 显示全文、`hidden` 不显示;
9
- * - 压缩摘要卡、重试提示、Hook 阻止提示、宿主 / 系统通知;
9
+ * (Markdown 自己按块缓存);思考块按 `ui.showThinking`:`collapsed`(缺省)一行 `✻ 思考 · N token`
10
+ * (流式中 `✻ 思考中…`),Ctrl+O 展开为标题 + 缩进 2 列的正文(最多 60 行);`full` 总是展开且不限行;
11
+ * `hidden` 不显示;
12
+ * - 压缩摘要卡(左竖条 Card)、重试提示、Hook 阻止提示、宿主 / 系统通知;字形取 `theme.glyphs`;
10
13
  * - `replay()` 把已有消息(恢复会话、切换会话、/tree 之后)重新画出来,工具调用交给调用方构造。
11
14
  *
12
15
  * 滚动交给终端回滚:消息区只追加,切换会话时整体清空重画。
13
16
  */
14
17
  import type { AssistantMessage, ContentBlock, ToolCallBlock, UserMessage } from "../../ai/types.js";
15
- import type { CompactionResult, ToolResultMessage } from "../../agent/types.js";
18
+ import type { CompactionResult, SessionStats, ToolResultMessage } from "../../agent/types.js";
16
19
  import type { AgentMessage } from "../../session/types.js";
17
20
  import { Container, type Component, type Theme } from "../../tui.js";
18
21
  export type ThinkingDisplay = "full" | "collapsed" | "hidden";
@@ -22,8 +25,29 @@ export interface MessageViewOptions {
22
25
  showThinking?: ThinkingDisplay;
23
26
  /** false:助手文本不做 Markdown 渲染。 */
24
27
  markdown?: boolean;
28
+ /** `ui.compact`:块间不空行。 */
29
+ compact?: boolean;
25
30
  }
26
- /** 粗估 token(4 字符 ≈ 1 token),只用于思考块的流式计数。 */
31
+ /**
32
+ * 退出摘要(§3.14):`─ 会话 <id> · 时长 · N 回合 · ↑in ↓out · cache x% · $y(重计费 $z)` 与
33
+ * ` 恢复:ama --resume <id>`。整体 dim,会话 id 与恢复命令正文色;0 回合只到「回合」;会话没落盘不给恢复行。
34
+ */
35
+ export declare function exitSummaryLines(stats: Pick<SessionStats, "sessionId" | "sessionFile" | "userMessages" | "tokens" | "cost" | "cache" | "cacheHitRate">, elapsedMs: number, theme: Theme): string[];
36
+ /** 思考块展开时的正文行数上限(`full` 不限)。 */
37
+ export declare const THINKING_EXPANDED_LINES = 60;
38
+ /** origin → 中文标签(未知 origin 原样显示)。 */
39
+ export declare const ORIGIN_LABELS: Readonly<Record<string, string>>;
40
+ /** 首行带前缀、续行按 `indent` 缩进的文本(用户消息、排队消息)。 */
41
+ export declare class PrefixedText implements Component {
42
+ private readonly prefix;
43
+ private readonly body;
44
+ private readonly indent;
45
+ private cache;
46
+ constructor(prefix: string, body: string, indent?: number);
47
+ render(width: number): string[];
48
+ invalidate(): void;
49
+ }
50
+ export declare function displayText(text: string): string;
27
51
  export declare function estimateTokens(text: string): number;
28
52
  export declare function contentText(content: string | readonly ContentBlock[]): string;
29
53
  /** 一条助手消息:按内容块(思考 / 文本)同步子组件;工具调用块由 tool-view 单独显示。 */
@@ -32,7 +56,10 @@ export declare class AssistantView extends Container {
32
56
  private readonly parts;
33
57
  private readonly status;
34
58
  private streaming;
59
+ private thinkingExpanded;
35
60
  constructor(options: MessageViewOptions);
61
+ /** Ctrl+O:展开 / 折叠本消息的思考块(`collapsed` 模式下)。 */
62
+ setThinkingExpanded(expanded: boolean): void;
36
63
  update(message: AssistantMessage): void;
37
64
  /** 收尾:错误 / 中断 / 长度截断提示,思考计数换成用量里的值。 */
38
65
  finish(message: AssistantMessage): void;
@@ -47,25 +74,37 @@ export declare class MessageView extends Container {
47
74
  private readonly options;
48
75
  private current;
49
76
  private readonly blocks;
77
+ /** 工具调用块(相邻的不空行)。 */
78
+ private readonly toolBlocks;
79
+ private readonly assistants;
80
+ private thinkingExpanded;
50
81
  constructor(options: MessageViewOptions);
51
82
  private get theme();
52
- /** 追加一块(与上一块之间空一行)。 */
83
+ /** 追加一块(与上一块之间空一行;`compact` 不空行)。 */
53
84
  add(component: Component): void;
85
+ /** 追加工具调用块:紧跟在另一个工具调用后面时不空行。 */
86
+ addTool(component: Component): void;
87
+ private push;
54
88
  /** 去掉一块(空的助手消息等)。 */
55
89
  remove(component: Component): void;
56
90
  reset(): void;
57
91
  get blockCount(): number;
58
- /** 启动画面:首行加粗,其余变暗。 */
92
+ /** Ctrl+O:所有助手消息的思考块一起展开 / 折叠(之后的新消息沿用)。 */
93
+ setThinkingExpanded(expanded: boolean): void;
94
+ /** 纯文本启动画面(line 模式风格):首行加粗,其余变暗。交互模式用 StartupHeader。 */
59
95
  addHeader(lines: readonly string[]): void;
60
96
  addUser(message: Pick<UserMessage, "content" | "origin">): void;
97
+ private newAssistant;
61
98
  startAssistant(message: AssistantMessage): AssistantView;
62
99
  updateAssistant(message: AssistantMessage): void;
63
100
  endAssistant(message: AssistantMessage): void;
64
101
  addNotice(level: NoticeLevel, message: string): void;
65
102
  addHookBlocked(reason: string): void;
66
103
  addRetry(attempt: number, maxAttempts: number, delayMs: number, error: string): void;
104
+ /** 退出前追加的会话摘要(留在终端回滚里)。 */
105
+ addExitSummary(lines: readonly string[]): void;
67
106
  addRetryFailed(error: string | undefined): void;
68
- /** 压缩 / 分支摘要卡:token 变化(有则显示)+ 摘要前 3 行。 */
107
+ /** 压缩 / 分支摘要卡(左竖条):标题 + token 变化(有则显示)+ 摘要前 3 行。 */
69
108
  addSummaryCard(summary: string, options?: {
70
109
  title?: string;
71
110
  tokensBefore?: number;