@armadra/agent 0.5.1 → 0.6.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 (486) hide show
  1. package/CHANGELOG.md +203 -304
  2. package/CHANGELOG.zh-CN.md +462 -0
  3. package/README.md +408 -364
  4. package/README.zh-CN.md +705 -0
  5. package/dist/agent/session-plan.js +2 -2
  6. package/dist/agent/session-state.d.ts +3 -0
  7. package/dist/agent/session-state.js +20 -0
  8. package/dist/agent/session-subagent.d.ts +15 -1
  9. package/dist/agent/session-subagent.js +26 -3
  10. package/dist/agent/session-telemetry.d.ts +16 -2
  11. package/dist/agent/session-telemetry.js +29 -7
  12. package/dist/agent/session-tools.js +5 -2
  13. package/dist/agent/session-trace-writer.d.ts +27 -0
  14. package/dist/agent/session-trace-writer.js +253 -0
  15. package/dist/agent/session.d.ts +2 -0
  16. package/dist/agent/session.js +12 -0
  17. package/dist/agent/subagent-direct.d.ts +20 -0
  18. package/dist/agent/subagent-direct.js +76 -0
  19. package/dist/agent/subagent-registry.d.ts +8 -1
  20. package/dist/agent/subagent-registry.js +28 -1
  21. package/dist/agent/system-prompt.d.ts +3 -1
  22. package/dist/agent/system-prompt.js +3 -0
  23. package/dist/agent/tool-runner.d.ts +2 -1
  24. package/dist/agent/tool-runner.js +5 -4
  25. package/dist/agent/types-w6.d.ts +39 -0
  26. package/dist/agent/types-w6.js +4 -0
  27. package/dist/agent/types.d.ts +5 -2
  28. package/dist/agents/external.js +1 -1
  29. package/dist/agents/task-record.d.ts +74 -1
  30. package/dist/agents/task-record.js +100 -0
  31. package/dist/ai/apis/cache-params.js +2 -1
  32. package/dist/ai/apis/chatgpt-backend.d.ts +52 -0
  33. package/dist/ai/apis/chatgpt-backend.js +224 -0
  34. package/dist/ai/apis/chatgpt-rate-limits.d.ts +26 -0
  35. package/dist/ai/apis/chatgpt-rate-limits.js +91 -0
  36. package/dist/ai/apis/openai-responses-request.d.ts +2 -1
  37. package/dist/ai/apis/openai-responses-request.js +8 -2
  38. package/dist/ai/apis/openai-responses.d.ts +2 -0
  39. package/dist/ai/apis/openai-responses.js +51 -16
  40. package/dist/ai/overflow.d.ts +1 -1
  41. package/dist/ai/overflow.js +10 -7
  42. package/dist/ai/providers/auth.d.ts +15 -2
  43. package/dist/ai/providers/auth.js +69 -2
  44. package/dist/ai/providers/builtin.js +27 -0
  45. package/dist/ai/providers/catalog-data.js +1 -0
  46. package/dist/ai/providers/discovered-cache.d.ts +48 -0
  47. package/dist/ai/providers/discovered-cache.js +102 -0
  48. package/dist/ai/providers/enrich.js +2 -7
  49. package/dist/ai/providers/model-visibility.d.ts +33 -0
  50. package/dist/ai/providers/model-visibility.js +70 -0
  51. package/dist/ai/providers/models-dev-cache.js +15 -19
  52. package/dist/ai/providers/models-dev-snapshot.js +8 -7
  53. package/dist/ai/providers/models-dev.js +5 -15
  54. package/dist/ai/providers/registry.d.ts +2 -0
  55. package/dist/ai/providers/registry.js +6 -1
  56. package/dist/ai/providers/suggest.js +2 -16
  57. package/dist/ai/types.d.ts +27 -1
  58. package/dist/auth/chatgpt/backend-client.d.ts +26 -0
  59. package/dist/auth/chatgpt/backend-client.js +74 -0
  60. package/dist/auth/chatgpt/claims.d.ts +17 -0
  61. package/dist/auth/chatgpt/claims.js +46 -0
  62. package/dist/auth/chatgpt/cli.d.ts +35 -0
  63. package/dist/auth/chatgpt/cli.js +279 -0
  64. package/dist/auth/chatgpt/doctor.d.ts +17 -0
  65. package/dist/auth/chatgpt/doctor.js +36 -0
  66. package/dist/auth/chatgpt/host-id.d.ts +7 -0
  67. package/dist/auth/chatgpt/host-id.js +26 -0
  68. package/dist/auth/chatgpt/login.d.ts +30 -0
  69. package/dist/auth/chatgpt/login.js +130 -0
  70. package/dist/auth/chatgpt/presets.d.ts +66 -0
  71. package/dist/auth/chatgpt/presets.js +120 -0
  72. package/dist/auth/chatgpt/quota-text.d.ts +13 -0
  73. package/dist/auth/chatgpt/quota-text.js +36 -0
  74. package/dist/auth/oauth/browser.d.ts +12 -0
  75. package/dist/auth/oauth/browser.js +27 -0
  76. package/dist/auth/oauth/callback-server.d.ts +47 -0
  77. package/dist/auth/oauth/callback-server.js +147 -0
  78. package/dist/auth/oauth/flows.d.ts +62 -0
  79. package/dist/auth/oauth/flows.js +113 -0
  80. package/dist/auth/oauth/jwt.d.ts +24 -0
  81. package/dist/auth/oauth/jwt.js +81 -0
  82. package/dist/auth/oauth/live.d.ts +21 -0
  83. package/dist/auth/oauth/live.js +25 -0
  84. package/dist/auth/oauth/oidc.d.ts +26 -0
  85. package/dist/auth/oauth/oidc.js +72 -0
  86. package/dist/auth/oauth/pkce.d.ts +15 -0
  87. package/dist/auth/oauth/pkce.js +20 -0
  88. package/dist/auth/oauth/refresh.d.ts +35 -0
  89. package/dist/auth/oauth/refresh.js +129 -0
  90. package/dist/auth/oauth/token-client.d.ts +33 -0
  91. package/dist/auth/oauth/token-client.js +121 -0
  92. package/dist/auth/oauth/token-store.d.ts +23 -0
  93. package/dist/auth/oauth/token-store.js +125 -0
  94. package/dist/auth/testing/fake-oauth.d.ts +73 -0
  95. package/dist/auth/testing/fake-oauth.js +271 -0
  96. package/dist/auth/testing/refresh-child.d.ts +5 -0
  97. package/dist/auth/testing/refresh-child.js +16 -0
  98. package/dist/bundle/ama.cjs +26532 -11045
  99. package/dist/checkpoints/backend.js +6 -5
  100. package/dist/checkpoints/restore.js +3 -2
  101. package/dist/checkpoints/settings.js +2 -1
  102. package/dist/checkpoints/shadow-git.js +7 -6
  103. package/dist/checkpoints/shadow-restore.js +3 -2
  104. package/dist/checkpoints/tracker.js +4 -3
  105. package/dist/cli/args.d.ts +9 -2
  106. package/dist/cli/args.js +74 -27
  107. package/dist/cli/bootstrap.js +53 -31
  108. package/dist/cli/choice-prompt.js +8 -6
  109. package/dist/cli/codemode-notice.js +2 -2
  110. package/dist/cli/compose-agents.js +2 -1
  111. package/dist/cli/compose-extensions.js +2 -0
  112. package/dist/cli/compose-memory.d.ts +53 -0
  113. package/dist/cli/compose-memory.js +127 -0
  114. package/dist/cli/compose-providers.d.ts +6 -0
  115. package/dist/cli/compose-providers.js +38 -2
  116. package/dist/cli/compose-session.d.ts +5 -0
  117. package/dist/cli/compose-session.js +27 -13
  118. package/dist/cli/compose-store.d.ts +2 -0
  119. package/dist/cli/compose-store.js +9 -5
  120. package/dist/cli/compose.d.ts +2 -0
  121. package/dist/cli/compose.js +13 -5
  122. package/dist/cli/default-model.d.ts +0 -2
  123. package/dist/cli/default-model.js +5 -8
  124. package/dist/cli/deps.d.ts +5 -1
  125. package/dist/cli/exit-codes.d.ts +1 -1
  126. package/dist/cli/exit-codes.js +7 -16
  127. package/dist/cli/from-prompt.js +3 -2
  128. package/dist/cli/help-text.d.ts +2 -1
  129. package/dist/cli/help-text.js +5 -99
  130. package/dist/cli/main.d.ts +5 -0
  131. package/dist/cli/main.js +21 -2
  132. package/dist/cli/proxy.js +14 -9
  133. package/dist/cli/runtime.d.ts +5 -0
  134. package/dist/cli/startup-screen.js +20 -27
  135. package/dist/cli/startup-steps.js +6 -8
  136. package/dist/cli/subcommands/auth.d.ts +6 -3
  137. package/dist/cli/subcommands/auth.js +52 -22
  138. package/dist/cli/subcommands/config-set.d.ts +21 -0
  139. package/dist/cli/subcommands/config-set.js +145 -0
  140. package/dist/cli/subcommands/config.d.ts +2 -1
  141. package/dist/cli/subcommands/config.js +51 -37
  142. package/dist/cli/subcommands/doctor.d.ts +2 -1
  143. package/dist/cli/subcommands/doctor.js +97 -58
  144. package/dist/cli/subcommands/init.d.ts +1 -1
  145. package/dist/cli/subcommands/init.js +8 -7
  146. package/dist/cli/subcommands/memory.d.ts +18 -0
  147. package/dist/cli/subcommands/memory.js +189 -0
  148. package/dist/cli/subcommands/model-meta.js +11 -9
  149. package/dist/cli/subcommands/models-cache-probe.js +23 -20
  150. package/dist/cli/subcommands/models-discover.d.ts +4 -0
  151. package/dist/cli/subcommands/models-discover.js +60 -21
  152. package/dist/cli/subcommands/models-enable.d.ts +13 -0
  153. package/dist/cli/subcommands/models-enable.js +145 -0
  154. package/dist/cli/subcommands/models.d.ts +3 -1
  155. package/dist/cli/subcommands/models.js +39 -24
  156. package/dist/cli/subcommands/probe-runner.js +8 -7
  157. package/dist/cli/subcommands/providers-list.js +32 -21
  158. package/dist/cli/subcommands/providers-plan.js +24 -25
  159. package/dist/cli/subcommands/providers-probe.js +5 -6
  160. package/dist/cli/subcommands/providers.d.ts +1 -1
  161. package/dist/cli/subcommands/providers.js +45 -50
  162. package/dist/cli/subcommands/sessions-export.d.ts +1 -1
  163. package/dist/cli/subcommands/sessions-export.js +10 -9
  164. package/dist/cli/subcommands/sessions-search.d.ts +1 -1
  165. package/dist/cli/subcommands/sessions-search.js +11 -10
  166. package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
  167. package/dist/cli/subcommands/sessions-trace.js +156 -0
  168. package/dist/cli/subcommands/sessions.d.ts +4 -3
  169. package/dist/cli/subcommands/sessions.js +40 -37
  170. package/dist/cli/subcommands/stats.d.ts +1 -1
  171. package/dist/cli/subcommands/stats.js +49 -30
  172. package/dist/cli/system-prompt-arg.js +3 -2
  173. package/dist/codemode/capability.js +3 -2
  174. package/dist/compaction/post-compact.d.ts +1 -0
  175. package/dist/compaction/post-compact.js +15 -1
  176. package/dist/compaction/prune-tier.d.ts +1 -1
  177. package/dist/compaction/prune-tier.js +3 -3
  178. package/dist/compaction/serialize.js +2 -1
  179. package/dist/config/auth-file.d.ts +12 -2
  180. package/dist/config/auth-file.js +32 -10
  181. package/dist/config/checker.js +12 -11
  182. package/dist/config/context-files.js +3 -2
  183. package/dist/config/edit.d.ts +106 -0
  184. package/dist/config/edit.js +350 -0
  185. package/dist/config/init.d.ts +4 -3
  186. package/dist/config/init.js +10 -18
  187. package/dist/config/json-schema.d.ts +2 -1
  188. package/dist/config/json-schema.js +102 -69
  189. package/dist/config/key-docs.d.ts +18 -7
  190. package/dist/config/key-docs.js +43 -128
  191. package/dist/config/load.js +7 -6
  192. package/dist/config/merge.d.ts +4 -1
  193. package/dist/config/merge.js +42 -22
  194. package/dist/config/paths.js +6 -5
  195. package/dist/config/profile.d.ts +5 -1
  196. package/dist/config/profile.js +7 -2
  197. package/dist/config/schema-w5.js +12 -4
  198. package/dist/config/schema-w6.d.ts +19 -0
  199. package/dist/config/schema-w6.js +115 -0
  200. package/dist/config/schema.js +34 -20
  201. package/dist/config/settings-registry.d.ts +81 -0
  202. package/dist/config/settings-registry.js +185 -0
  203. package/dist/config/types-w5.d.ts +7 -0
  204. package/dist/config/types-w5.js +2 -0
  205. package/dist/config/types-w6.d.ts +109 -0
  206. package/dist/config/types-w6.js +19 -0
  207. package/dist/config/types.d.ts +11 -8
  208. package/dist/config/types.js +1 -0
  209. package/dist/drivers/acp/client.js +1 -1
  210. package/dist/drivers/acp/driver.js +13 -8
  211. package/dist/drivers/agents.js +4 -3
  212. package/dist/drivers/base.js +3 -2
  213. package/dist/drivers/host-runners.js +2 -1
  214. package/dist/drivers/native/claude-stream.js +12 -11
  215. package/dist/drivers/native/codex-app-server.js +17 -12
  216. package/dist/drivers/native/oneshot.js +8 -7
  217. package/dist/drivers/pool.js +1 -1
  218. package/dist/drivers/runner.d.ts +3 -1
  219. package/dist/drivers/runner.js +68 -20
  220. package/dist/drivers/turn.js +1 -1
  221. package/dist/hooks/config.js +3 -2
  222. package/dist/hooks/protocol.js +18 -12
  223. package/dist/host/api-impl.js +11 -10
  224. package/dist/host/loader.js +9 -8
  225. package/dist/host/types.d.ts +3 -0
  226. package/dist/i18n/catalog.d.ts +2209 -0
  227. package/dist/i18n/catalog.js +72 -0
  228. package/dist/i18n/format.d.ts +21 -0
  229. package/dist/i18n/format.js +58 -0
  230. package/dist/i18n/index.d.ts +58 -0
  231. package/dist/i18n/index.js +72 -0
  232. package/dist/i18n/messages/agents.d.ts +84 -0
  233. package/dist/i18n/messages/agents.js +85 -0
  234. package/dist/i18n/messages/approval.d.ts +99 -0
  235. package/dist/i18n/messages/approval.js +100 -0
  236. package/dist/i18n/messages/auth.d.ts +189 -0
  237. package/dist/i18n/messages/auth.js +201 -0
  238. package/dist/i18n/messages/cli-args.d.ts +46 -0
  239. package/dist/i18n/messages/cli-args.js +46 -0
  240. package/dist/i18n/messages/cli-help.d.ts +12 -0
  241. package/dist/i18n/messages/cli-help.js +248 -0
  242. package/dist/i18n/messages/cli.d.ts +336 -0
  243. package/dist/i18n/messages/cli.js +311 -0
  244. package/dist/i18n/messages/config-keys.d.ts +293 -0
  245. package/dist/i18n/messages/config-keys.js +296 -0
  246. package/dist/i18n/messages/config.d.ts +508 -0
  247. package/dist/i18n/messages/config.js +241 -0
  248. package/dist/i18n/messages/drivers.d.ts +123 -0
  249. package/dist/i18n/messages/drivers.js +124 -0
  250. package/dist/i18n/messages/errors.d.ts +83 -0
  251. package/dist/i18n/messages/errors.js +171 -0
  252. package/dist/i18n/messages/interactive-line.d.ts +61 -0
  253. package/dist/i18n/messages/interactive-line.js +69 -0
  254. package/dist/i18n/messages/interactive-startup.d.ts +99 -0
  255. package/dist/i18n/messages/interactive-startup.js +100 -0
  256. package/dist/i18n/messages/interactive-view.d.ts +140 -0
  257. package/dist/i18n/messages/interactive-view.js +141 -0
  258. package/dist/i18n/messages/interactive.d.ts +489 -0
  259. package/dist/i18n/messages/interactive.js +248 -0
  260. package/dist/i18n/messages/memory.d.ts +123 -0
  261. package/dist/i18n/messages/memory.js +128 -0
  262. package/dist/i18n/messages/panels.d.ts +233 -0
  263. package/dist/i18n/messages/panels.js +232 -0
  264. package/dist/i18n/messages/permissions.d.ts +126 -0
  265. package/dist/i18n/messages/permissions.js +151 -0
  266. package/dist/i18n/messages/plan.d.ts +123 -0
  267. package/dist/i18n/messages/plan.js +124 -0
  268. package/dist/i18n/messages/print.d.ts +86 -0
  269. package/dist/i18n/messages/print.js +91 -0
  270. package/dist/i18n/messages/report.d.ts +391 -0
  271. package/dist/i18n/messages/report.js +490 -0
  272. package/dist/i18n/messages/rewind.d.ts +198 -0
  273. package/dist/i18n/messages/rewind.js +217 -0
  274. package/dist/i18n/messages/session.d.ts +230 -0
  275. package/dist/i18n/messages/session.js +258 -0
  276. package/dist/i18n/messages/settings.d.ts +355 -0
  277. package/dist/i18n/messages/settings.js +343 -0
  278. package/dist/i18n/messages/subcommands-config.d.ts +113 -0
  279. package/dist/i18n/messages/subcommands-config.js +129 -0
  280. package/dist/i18n/messages/subcommands-models.d.ts +34 -0
  281. package/dist/i18n/messages/subcommands-models.js +34 -0
  282. package/dist/i18n/messages/subcommands.d.ts +576 -0
  283. package/dist/i18n/messages/subcommands.js +477 -0
  284. package/dist/i18n/messages/trace.d.ts +243 -0
  285. package/dist/i18n/messages/trace.js +238 -0
  286. package/dist/i18n/types.d.ts +15 -0
  287. package/dist/i18n/types.js +7 -0
  288. package/dist/index.d.ts +6 -0
  289. package/dist/index.js +2 -0
  290. package/dist/memory/edit.d.ts +24 -0
  291. package/dist/memory/edit.js +63 -0
  292. package/dist/memory/frontmatter.d.ts +37 -0
  293. package/dist/memory/frontmatter.js +79 -0
  294. package/dist/memory/index.d.ts +28 -0
  295. package/dist/memory/index.js +126 -0
  296. package/dist/memory/lock.d.ts +17 -0
  297. package/dist/memory/lock.js +62 -0
  298. package/dist/memory/paths.d.ts +57 -0
  299. package/dist/memory/paths.js +175 -0
  300. package/dist/memory/report.d.ts +36 -0
  301. package/dist/memory/report.js +86 -0
  302. package/dist/memory/runtime.d.ts +42 -0
  303. package/dist/memory/runtime.js +36 -0
  304. package/dist/memory/secrets.d.ts +8 -0
  305. package/dist/memory/secrets.js +27 -0
  306. package/dist/memory/section.d.ts +28 -0
  307. package/dist/memory/section.js +59 -0
  308. package/dist/memory/store.d.ts +70 -0
  309. package/dist/memory/store.js +284 -0
  310. package/dist/memory/tool.d.ts +31 -0
  311. package/dist/memory/tool.js +94 -0
  312. package/dist/modes/acp/acp-events.js +2 -1
  313. package/dist/modes/acp/acp-server.js +13 -12
  314. package/dist/modes/commands-core.d.ts +11 -0
  315. package/dist/modes/commands-core.js +93 -62
  316. package/dist/modes/image-input.js +20 -6
  317. package/dist/modes/interactive/agent-bar.d.ts +95 -0
  318. package/dist/modes/interactive/agent-bar.js +248 -0
  319. package/dist/modes/interactive/agent-panels.js +27 -26
  320. package/dist/modes/interactive/agent-transcript.d.ts +47 -0
  321. package/dist/modes/interactive/agent-transcript.js +191 -0
  322. package/dist/modes/interactive/agent-ui.d.ts +36 -1
  323. package/dist/modes/interactive/agent-ui.js +180 -14
  324. package/dist/modes/interactive/agent-view.d.ts +72 -0
  325. package/dist/modes/interactive/agent-view.js +281 -0
  326. package/dist/modes/interactive/approval-dialog.js +46 -34
  327. package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
  328. package/dist/modes/interactive/clipboard-paste.js +9 -4
  329. package/dist/modes/interactive/commands.d.ts +22 -1
  330. package/dist/modes/interactive/commands.js +100 -49
  331. package/dist/modes/interactive/completion.js +2 -1
  332. package/dist/modes/interactive/config-panel.d.ts +70 -0
  333. package/dist/modes/interactive/config-panel.js +319 -0
  334. package/dist/modes/interactive/config-ui.d.ts +96 -0
  335. package/dist/modes/interactive/config-ui.js +397 -0
  336. package/dist/modes/interactive/confirm-dialog.js +6 -7
  337. package/dist/modes/interactive/event-notices.js +11 -9
  338. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  339. package/dist/modes/interactive/interactive-mode.js +21 -22
  340. package/dist/modes/interactive/key-dispatch.d.ts +12 -0
  341. package/dist/modes/interactive/key-dispatch.js +24 -9
  342. package/dist/modes/interactive/line/line-editor.js +2 -1
  343. package/dist/modes/interactive/line/line-mode.js +18 -7
  344. package/dist/modes/interactive/line/line-render.js +25 -24
  345. package/dist/modes/interactive/memory-panel.d.ts +64 -0
  346. package/dist/modes/interactive/memory-panel.js +221 -0
  347. package/dist/modes/interactive/message-view.d.ts +4 -2
  348. package/dist/modes/interactive/message-view.js +42 -33
  349. package/dist/modes/interactive/model-items.d.ts +45 -0
  350. package/dist/modes/interactive/model-items.js +134 -0
  351. package/dist/modes/interactive/model-picker.d.ts +57 -0
  352. package/dist/modes/interactive/model-picker.js +191 -0
  353. package/dist/modes/interactive/panels.js +39 -31
  354. package/dist/modes/interactive/pickers.d.ts +2 -1
  355. package/dist/modes/interactive/pickers.js +10 -6
  356. package/dist/modes/interactive/plan-command.d.ts +1 -1
  357. package/dist/modes/interactive/plan-command.js +24 -27
  358. package/dist/modes/interactive/plan-dialog.js +18 -17
  359. package/dist/modes/interactive/plan-flow.js +6 -5
  360. package/dist/modes/interactive/rewind-command.d.ts +1 -1
  361. package/dist/modes/interactive/rewind-command.js +18 -16
  362. package/dist/modes/interactive/rewind-flow.d.ts +0 -1
  363. package/dist/modes/interactive/rewind-flow.js +13 -14
  364. package/dist/modes/interactive/rewind-list.js +7 -6
  365. package/dist/modes/interactive/rewind-panel.js +40 -40
  366. package/dist/modes/interactive/rewind-text.d.ts +5 -3
  367. package/dist/modes/interactive/rewind-text.js +48 -38
  368. package/dist/modes/interactive/run-indicator.js +15 -12
  369. package/dist/modes/interactive/session-events.js +3 -2
  370. package/dist/modes/interactive/startup-header.js +22 -23
  371. package/dist/modes/interactive/startup-ui.d.ts +3 -9
  372. package/dist/modes/interactive/startup-ui.js +44 -88
  373. package/dist/modes/interactive/status-area.d.ts +2 -0
  374. package/dist/modes/interactive/status-area.js +8 -2
  375. package/dist/modes/interactive/status-bar.js +4 -3
  376. package/dist/modes/interactive/subagent-view.js +9 -7
  377. package/dist/modes/interactive/tasks-report.d.ts +6 -0
  378. package/dist/modes/interactive/tasks-report.js +28 -31
  379. package/dist/modes/interactive/terminal-setup.d.ts +9 -0
  380. package/dist/modes/interactive/terminal-setup.js +23 -0
  381. package/dist/modes/interactive/tool-summary.js +19 -17
  382. package/dist/modes/interactive/tool-view.js +7 -4
  383. package/dist/modes/interactive/trace-view.d.ts +89 -0
  384. package/dist/modes/interactive/trace-view.js +332 -0
  385. package/dist/modes/print/print-mode.js +14 -15
  386. package/dist/modes/rpc/commands.js +7 -3
  387. package/dist/modes/rpc/rpc-mode.js +9 -3
  388. package/dist/modes/session-report.d.ts +2 -0
  389. package/dist/modes/session-report.js +101 -105
  390. package/dist/modes/startup-ui-text.js +11 -6
  391. package/dist/permissions/bypass.d.ts +8 -10
  392. package/dist/permissions/bypass.js +19 -10
  393. package/dist/permissions/memory-class.d.ts +23 -0
  394. package/dist/permissions/memory-class.js +54 -0
  395. package/dist/permissions/modes.d.ts +3 -3
  396. package/dist/permissions/modes.js +21 -16
  397. package/dist/permissions/pipeline.d.ts +1 -1
  398. package/dist/permissions/pipeline.js +9 -2
  399. package/dist/permissions/preview.js +49 -42
  400. package/dist/permissions/rules.js +5 -2
  401. package/dist/permissions/types.d.ts +4 -0
  402. package/dist/plan/store.js +2 -1
  403. package/dist/rpc.d.ts +39 -1
  404. package/dist/rpc.js +3 -0
  405. package/dist/sandbox/bash.js +11 -8
  406. package/dist/sandbox/detect.js +14 -11
  407. package/dist/sdk.d.ts +17 -1
  408. package/dist/sdk.js +29 -7
  409. package/dist/session/export.js +31 -30
  410. package/dist/session/manager.d.ts +1 -1
  411. package/dist/session/manager.js +5 -3
  412. package/dist/session/reuse.js +5 -4
  413. package/dist/session/scan.js +3 -2
  414. package/dist/session/stats-aggregate.d.ts +3 -1
  415. package/dist/session/stats-aggregate.js +5 -1
  416. package/dist/session/stats-index.js +2 -1
  417. package/dist/session/stats-scan.d.ts +4 -1
  418. package/dist/session/stats-scan.js +6 -2
  419. package/dist/session/store.d.ts +11 -0
  420. package/dist/session/store.js +48 -1
  421. package/dist/session/types.d.ts +2 -0
  422. package/dist/skills/builtin.js +2 -1
  423. package/dist/tools/image-file.d.ts +26 -1
  424. package/dist/tools/image-file.js +55 -13
  425. package/dist/tools/presets.d.ts +14 -1
  426. package/dist/tools/presets.js +3 -3
  427. package/dist/tools/registry.js +1 -1
  428. package/dist/tools/truncate.d.ts +1 -1
  429. package/dist/tools/truncate.js +2 -2
  430. package/dist/tools/types.d.ts +17 -1
  431. package/dist/trace/build-index.d.ts +91 -0
  432. package/dist/trace/build-index.js +127 -0
  433. package/dist/trace/build-nodes.d.ts +24 -0
  434. package/dist/trace/build-nodes.js +279 -0
  435. package/dist/trace/build-util.d.ts +43 -0
  436. package/dist/trace/build-util.js +120 -0
  437. package/dist/trace/build.d.ts +82 -0
  438. package/dist/trace/build.js +382 -0
  439. package/dist/trace/detail.d.ts +35 -0
  440. package/dist/trace/detail.js +205 -0
  441. package/dist/trace/flatten.d.ts +69 -0
  442. package/dist/trace/flatten.js +173 -0
  443. package/dist/trace/format.d.ts +47 -0
  444. package/dist/trace/format.js +329 -0
  445. package/dist/trace/html-template.d.ts +19 -0
  446. package/dist/trace/html-template.js +150 -0
  447. package/dist/trace/html.d.ts +104 -0
  448. package/dist/trace/html.js +292 -0
  449. package/dist/trace/preview.d.ts +29 -0
  450. package/dist/trace/preview.js +59 -0
  451. package/dist/trace/query-session.d.ts +14 -0
  452. package/dist/trace/query-session.js +38 -0
  453. package/dist/trace/query.d.ts +55 -0
  454. package/dist/trace/query.js +188 -0
  455. package/dist/trace/session.d.ts +40 -0
  456. package/dist/trace/session.js +168 -0
  457. package/dist/trace/types.d.ts +243 -0
  458. package/dist/trace/types.js +13 -0
  459. package/dist/tui/components/editor-paste.d.ts +2 -0
  460. package/dist/tui/components/editor-paste.js +6 -3
  461. package/dist/tui/components/editor.js +2 -2
  462. package/dist/tui/components/loader.d.ts +3 -0
  463. package/dist/tui/components/loader.js +14 -0
  464. package/dist/tui/components/select-list.d.ts +2 -0
  465. package/dist/tui/components/select-list.js +7 -0
  466. package/dist/tui/components/settings-list.d.ts +61 -0
  467. package/dist/tui/components/settings-list.js +135 -0
  468. package/dist/tui/keybindings.d.ts +5 -0
  469. package/dist/tui/keybindings.js +17 -5
  470. package/dist/tui.d.ts +1 -0
  471. package/dist/tui.js +2 -0
  472. package/docs/en/host-api.md +167 -0
  473. package/docs/en/permissions.md +214 -0
  474. package/docs/en/providers.md +627 -0
  475. package/docs/en/rpc.md +361 -0
  476. package/docs/en/sessions.md +219 -0
  477. package/docs/en/tui.md +534 -0
  478. package/docs/host-api.md +18 -17
  479. package/docs/memory.md +172 -0
  480. package/docs/permissions.md +2 -2
  481. package/docs/providers.md +73 -1
  482. package/docs/rpc.md +31 -3
  483. package/docs/session-format.md +8 -2
  484. package/docs/sessions.md +29 -1
  485. package/docs/tui.md +140 -4
  486. package/package.json +8 -3
package/docs/en/rpc.md ADDED
@@ -0,0 +1,361 @@
1
+ # RPC protocol (stdio JSONL)
2
+
3
+ English · [简体中文](../rpc.md)
4
+
5
+ > Translated from the Chinese [docs/rpc.md](../rpc.md) as of commit `312ddb6`. When the two differ, the Chinese version is
6
+ > authoritative.
7
+
8
+ `ama --mode rpc` reads commands from stdin and writes responses and events to stdout, one JSON value per line. The types are defined in `@armadra/agent/rpc` (`src/rpc.ts`) and implemented in `src/modes/rpc/`. The events printed by `ama -p --output-format stream-json` have the same shapes. The design rationale is in [design.md](../design.md) §13.2 (Chinese).
9
+
10
+ ## Wire
11
+
12
+ - Reading: lines are split on `\n` only (a trailing `\r` is removed, empty lines are skipped), never on U+2028 / U+2029; multi-byte UTF-8 is reassembled across chunks; when stdin ends, a final segment without a newline still counts as a line.
13
+ - Writing: each line is one `JSON.stringify` result, with U+2028 / U+2029 escaped as `\u2028` / `\u2029`, `Error` serialized as `{ name, message }`, bigint as a string, and image base64 never truncated. Large lines are written in 64 KiB pieces honoring backpressure, and lines never interleave.
14
+ - stdout carries protocol lines only; logs and the human-readable copy of host notifications go to stderr.
15
+
16
+ ## Handshake
17
+
18
+ On startup the server first sends `hello`, then the current session's `session_start`:
19
+
20
+ ```json
21
+ {"type":"hello","protocolVersion":1,"agent":"ama","version":"0.1.0","capabilities":["approvals","images","hooks","plans"]}
22
+ {"type":"session_start","sessionId":"…","cwd":"/work","reason":"startup"}
23
+ ```
24
+
25
+ `protocolVersion` is `RPC_PROTOCOL_VERSION` (currently 1). `capabilities` lists what the server supports; a client that wants to handle approvals declares so with `set_client_capabilities` (see "Approvals").
26
+
27
+ ## Commands and responses
28
+
29
+ A command has the shape `{ "id"?: string, "type": <command name>, ...parameters }`. Responses:
30
+
31
+ ```json
32
+ { "id": "1", "type": "response", "command": "prompt", "success": true, "data": { "disposition": "started" } }
33
+ { "id": "2", "type": "response", "command": "set_model", "success": false, "error": "…", "code": "model_not_found" }
34
+ ```
35
+
36
+ - A response carries the request's `id` back (only string ids). Commands are processed concurrently: `prompt` does not block later commands, so responses may arrive in a different order than requests; match them by `id`.
37
+ - On failure `error` is human-readable text and `code` is the `AmaError.code` (when there is one). Unknown commands → `code: "invalid_arguments"`.
38
+ **Hosts must decide by `code` and never parse `error` / `message`**: human-readable text follows the interface language (`AMA_LANG`, `--lang`, `ui.language`; bilingual since wave 6, see [i18n.md](../i18n.md), Chinese). The same holds for the `message` of `notification` events.
39
+ - A line that is not valid JSON or lacks `type` → `{ "type": "response", "command": "parse", "success": false, "error": … }`, without `id`.
40
+ - Commands that need extension methods of the session implementation (marked † below) return `code: "not_implemented"` on sessions that are not `AgentSessionImpl`; sessions created by the CLI and the SDK are all `AgentSessionImpl`.
41
+
42
+ ### Prompts
43
+
44
+ | Command | Parameters | `data` |
45
+ | ------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
46
+ | `prompt` | `message: string`, `images?: ImageBlock[]`, `streamingBehavior?: "steer" \| "followUp"` | `{ disposition: "started" \| "queued" \| "handled" }` |
47
+ | `steer` | `message`, `images?` | Same as above |
48
+ | `follow_up` | `message`, `images?` | Same as above |
49
+ | `abort` | — | `{}` (answered once idle again; the queue is not cleared) |
50
+ | `clear_queue` | — | `{ steering: string[], followUp: string[] }` (the cleared text) |
51
+
52
+ Prompt commands **do not wait for the run to finish**: they are answered as soon as the session starts running (`before_agent_start` / `agent_start`), or the message is queued or handled (for example a slash command, or a hook block); progress arrives as events. Sending `prompt` while running without `streamingBehavior` fails with `code: "busy"`; with `steer` / `followUp` it is queued. Run failures after the response are reported as `{"type":"notification","level":"error","message":…}`.
53
+
54
+ ### State
55
+
56
+ | Command | Parameters | `data` |
57
+ | ------------------------- | ---------- | ----------------------------------------------------------- |
58
+ | `get_state` | — | `SessionState` (below) |
59
+ | `get_messages` | — | `{ messages: AgentMessage[] }` (projected context messages) |
60
+ | `get_last_assistant_text` | — | `{ text: string \| null }` |
61
+ | `get_session_stats` | — | `SessionStats` (see "Session stats") |
62
+
63
+ `SessionState`: `isStreaming`, `isCompacting`, `isRetrying`, `model` (`{ provider, id, channel? }` or absent; `channel` appears only for multi-channel providers), `thinkingLevel`, `permissionMode`, `sessionId`, `sessionFile`, `cwd`, `sessionName`, `messageCount`, `pendingMessageCount`, `steeringMode`, `followUpMode`, `autoCompaction`, `autoRetry`.
64
+
65
+ ### Models
66
+
67
+ | Command | Parameters | `data` |
68
+ | ------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------- |
69
+ | `set_model` | `provider: string`, `modelId: string`, `channel?: string` | `{ model: { provider, id, channel? } }` |
70
+ | `get_available_models` | — | `{ models: RpcModelInfo[] }` |
71
+ | `set_thinking_level` | `level: off \| minimal \| low \| medium \| high \| xhigh` | `{ level }` |
72
+ | `get_available_thinking_levels` | — | `{ levels: string[] }` (levels the current model supports; `["off"]` without a model) |
73
+
74
+ `RpcModelInfo`: `provider`, `id`, `name`, `hasKey`, `keySource` (`cli` / `auth-file` / `config` / `env` / `oauth` / `none`; `oauth` is the wave 6 ChatGPT login), `contextWindow?`, `maxTokens`, `reasoning`, `input` (`"text"` / `"image"`). **Keys never leave the process**: only whether there is one and where it comes from are reported.
75
+
76
+ ### Queue, compaction, retry
77
+
78
+ | Command | Parameters | `data` |
79
+ | ----------------------- | -------------------------------- | ------------------------------------------------------------------------------------------- |
80
+ | `set_steering_mode` † | `mode: "one-at-a-time" \| "all"` | `{ mode }` |
81
+ | `set_follow_up_mode` † | `mode` | `{ mode }` |
82
+ | `compact` | `customInstructions?: string` | `CompactionResult`: `summary`, `firstKeptEntryId`, `tokensBefore`, `tokensAfter?`, `usage?` |
83
+ | `set_auto_compaction` † | `enabled: boolean` | `{ enabled }` |
84
+ | `set_auto_retry` † | `enabled: boolean` | `{ enabled }` |
85
+ | `abort_retry` | — | `{ aborted: boolean }` (interrupts the run while waiting to retry) |
86
+
87
+ ### Sessions
88
+
89
+ | Command | Parameters | `data` |
90
+ | --------------------- | ------------------------ | ----------------------------------------------------------------------------------------------- |
91
+ | `new_session` | `parentSession?: string` | `{ sessionId, sessionFile }` |
92
+ | `switch_session` | `sessionPath: string` | Same as above |
93
+ | `fork` | `entryId: string` | Same as above (copies a new session file up to before that entry) |
94
+ | `get_entries` † | `since?: string` | `{ entries: SessionEntry[], leafId: string \| null }`; `since` is an entry id cursor, exclusive |
95
+ | `get_tree` † | — | `{ tree: SessionTreeNode[] }` (`{ entry, children, label? }`) |
96
+ | `set_session_name` † | `name: string` | `{ name }` |
97
+ | `get_fork_messages` † | — | `{ messages: { entryId, text }[] }` (user messages on the active branch, candidates for `fork`) |
98
+
99
+ ### Rewind
100
+
101
+ Details in [rewind-plan.md](../rewind-plan.md) §3 (Chinese). Rewind points are the user messages on the active path that start new turns (steers and queued messages belong to the current turn and are not listed). Calling while running returns `busy`.
102
+
103
+ | Command | Parameters | `data` |
104
+ | ------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
105
+ | `get_rewind_points` | — | `{ points: { entryId, text, timestamp, hasCheckpoint }[] }`, oldest first; `hasCheckpoint: false` (in-memory sessions, checkpoints off, beyond the retention count) allows conversation only |
106
+ | `rewind` | `entryId`, `mode: both \| conversation \| code`, `dryRun?: boolean`, `onConflict?: "skip" \| "overwrite"` | `RewindResult`: `conversation?: { leafId, draft: { text, images? } }`, `code?: CodeRestoreResult`, `gitHint?: { recordedHead, currentHead }`; `dryRun` only returns a preview and changes nothing |
107
+ | `summarize_from` | `entryId`, `instructions?: string` | `{ leafId, draft, summary? }`: returns to before the message, writes a `branch_summary` for the abandoned branch and puts the original message back |
108
+ | `summarize_up_to` | `entryId`, `instructions?: string` | `CompactionResult`: compacts the context before that message (`firstKeptEntryId` = the message) and stays at the end |
109
+
110
+ `CodeRestoreResult`: `restored` / `deleted` / `conflicts` (left untouched with `skip`, overwritten with `overwrite`) / `skipped: { path, reason }[]` (`symlink` / `hardlink` / `not_regular` / `parent_moved` / `too_large` / `backup_missing`) / `failed: { path, message }[]` / `insertions` / `deletions`; paths inside cwd are relative (`/`-separated). Error codes: restoring code without a checkpoint → `no_checkpoint`; everything failed and nothing was restored → `rewind_failed` (the conversation is left alone); the entry is not a rewind point on the active path → `invalid_arguments`. For conversation-only or code-only rewinds, a `custom_message{customType: "ama.rewind-note"}` is appended to the end of the context before the next prompt, telling the model which files disagree with the conversation.
111
+
112
+ After a session switch the server re-subscribes to events and sends `session_start` for the new session (`reason` `new` / `resume` / `fork`). `new_session` does not use the `parentSession` parameter yet. Entry shapes are in [session-format.md](../session-format.md) (Chinese).
113
+
114
+ ### Approvals
115
+
116
+ | Command | Parameters | `data` |
117
+ | ------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
118
+ | `set_client_capabilities` | `capabilities: ("approvals" \| "images" \| "hooks" \| "plans")[]` | `{ capabilities }` |
119
+ | `permission_response` | `requestId: string`, `decision: "allow" \| "deny" \| "allow_session"` | `{ accepted: boolean }` (false = not currently waiting for this id; kept and applied when that request is asked) |
120
+
121
+ ### Tools, permissions, discovery
122
+
123
+ | Command | Parameters | `data` |
124
+ | --------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
125
+ | `get_tools` | — | `{ tools: { name, description, parameters, permission, active }[] }` (every tool in the registry; `active` means the model sees it now) |
126
+ | `set_active_tools` | `names: string[]` | `{ names }` (active tool names after the change) |
127
+ | `set_permission_mode` | `mode: plan \| allowlist \| default \| auto-edit \| auto \| full-auto` | `{ mode }` (unknown mode → `invalid_arguments`) |
128
+ | `get_commands` | — | `{ commands: { name, description?, source: "builtin" \| "template" \| "skill" }[] }`; Skill names are written `skill:<name>` |
129
+ | `get_skills` | — | `{ skills: { name, description, location, … }[] }` (discovered Skills; `location` is the SKILL.md path) |
130
+
131
+ ### Plans and tasks (wave 5)
132
+
133
+ | Command | Parameters | `data` |
134
+ | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
135
+ | `plan_response` | `planId`, `decision: approve \| approve_fresh \| revise \| reject`, `mode?` (execution mode after approval), `feedback?` (for revise), `editedMarkdown?` | `{ planId, decision }`; a `planId` that is not awaiting approval → `plan_not_found`. See "Plan approval" |
136
+ | `get_plan` | `planId?` | `PlanData \| null`: `{ id, version, status, markdown, steps, sourceEntryId, filePath? }`; the latest by default |
137
+ | `get_todos` | — | `{ items: { id, text, status: pending \| in_progress \| done, planStep? }[] }` |
138
+ | `get_tasks` | — | `{ tasks: TaskInfo[] }` (a read-only view of the sub-agent task registry; empty when not wired) |
139
+ | `get_agents` | — | `{ agents: AgentInfo[] }` (available sub-agent types and external agents; empty when not wired) |
140
+
141
+ ### Traces (wave 6)
142
+
143
+ `get_trace` returns the session trace (the same tree as the TUI `/trace` and `ama sessions trace`, see [tui.md](tui.md)
144
+ "Traces"). There is no new event: after `entry_appended`, fetch again with the previous `cursor.since` to refresh incrementally.
145
+
146
+ | Parameter | Meaning |
147
+ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
148
+ | `branch?` | `leaf` (default, root to the current leaf) \| `all` (every entry in the file) |
149
+ | `turnLimit?` | Number of turns, tail first; default 50, range 1–500 |
150
+ | `before?` | A turn id (= the entry id of the turn's user message); returns the `turnLimit` turns before it (paging backwards) |
151
+ | `since?` | An entry id (as in `get_entries.since`): returns every turn from the one containing that entry to the end (no `turnLimit`); excludes `before` |
152
+ | `taskId?` | That task's sub-trace: an ama subagent returns its child session's trace (cursor and `leafId` refer to the child); an external agent returns no turns and its skeleton in `task.external` |
153
+ | `content?` | `none` (default: structure, times and tokens only) \| `preview` (adds `previews`) |
154
+
155
+ `data`: `{ trace, hasMoreBefore, cursor: { before?, since }, leafId, task?, previews? }`
156
+
157
+ - `trace` is a `Trace` (a type exported by `@armadra/agent`): `turns` is the requested window, while `totals` and `aux`
158
+ (auxiliary requests such as cache warm-up and the permission classifier) always cover the whole branch.
159
+ - `cursor.before` is the id of the window's first turn (present only when there are earlier turns) for the next `before`;
160
+ `cursor.since` is the id of the last entry on the branch for the next `since`.
161
+ - **Merging increments**: replace the tail of the local list starting at the first returned turn id; if the local list does
162
+ not have that id (rewind switched branches), replace everything; an empty list means the branch has no turns. The turn that
163
+ contains `since` is always sent again (it may still be running); when a late entry from a background task changes an earlier
164
+ turn, the response starts from that turn. If `since` is not on the selected branch, every turn is returned from the first.
165
+ - `task`: with `taskId`, the subagent node itself (without `child`).
166
+ - `previews`: `<kind>:<node id>` → `{ input?, output?, args?, result? }` (the turn's prompt, the request's reply text, the
167
+ tool's arguments JSON and result) for this session's nodes inside the window; redacted first (as `sessions export`) and then
168
+ truncated — arguments to 500 characters, the rest to 2000 — with `…` at the cut.
169
+ - The whole `data` is redacted; nodes carry only ids, times, counts and usage, and content appears only in `previews`. Tools
170
+ still running without a result are marked `running`.
171
+ - Errors: `invalid_arguments` (out-of-range parameters, `before` not a turn id on this branch, `before` together with
172
+ `since`) and `task_not_found`.
173
+
174
+ 43 commands in total; their names are the keys of `RpcCommandMap`.
175
+
176
+ ## Events
177
+
178
+ Events are the in-process `SessionEvent` (`src/agent/types.ts`); only `message_update` is replaced by pure deltas on the wire. Grouped by where they appear:
179
+
180
+ | Event | Fields |
181
+ | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
182
+ | `session_start` | `sessionId`, `sessionFile?`, `cwd`, `reason: startup \| resume \| new \| fork` |
183
+ | `session_changed` | `sessionId`, `sessionFile?` |
184
+ | `session_rewound` | `entryId`, `mode`, `restored`, `deleted`, `conflicts`, `skipped` (rewind finished; not sent for `dryRun`; file lists are empty for conversation only) |
185
+ | `before_agent_start` | `prompt` (after the UserPromptSubmit hook and template expansion) |
186
+ | `agent_start` / `turn_start` / `agent_before_settle` | — |
187
+ | `turn_end` | `message` (assistant message), `toolResults` |
188
+ | `agent_end` | `stopReason`, `willRetry` |
189
+ | `agent_settled` | `warning?` (the run has fully ended, retries and followUps included) |
190
+ | `message_start` / `message_end` | `message` (`AgentMessage`) |
191
+ | `message_update` | `assistantMessageEvent`, `usage?` (see below) |
192
+ | `tool_execution_start` | `toolCallId`, `toolName`, `args`, `parentToolCallId?` |
193
+ | `tool_execution_update` | `toolCallId`, `toolName`, `partial` (output text while running), `parentToolCallId?` |
194
+ | `tool_execution_end` | `toolCallId`, `toolName`, `result`, `isError`, `parentToolCallId?`, `autoDecision?` (auto mode: `{ layer: rule \| static \| classifier, decision, reason, cached? }`), `denied?` (`true`: not executed because permissions / a hook / approval denied it; the reason is in `result`) |
195
+ | `queue_update` | `steering: string[]`, `followUp: string[]` |
196
+ | `compaction_start` | `trigger: threshold \| overflow \| manual` |
197
+ | `compaction_end` | `trigger`, `result?`, `aborted`, `willRetry`, `error?` |
198
+ | `auto_retry_start` | `attempt`, `maxAttempts`, `delayMs`, `errorMessage` |
199
+ | `auto_retry_end` | `success`, `attempt`, `finalError?` |
200
+ | `permission_request` | `requestId`, `toolName`, `input`, `reason: mode \| dangerous \| hook`, `hookReason?`, `timeoutMs`, `preview?`, `autoDecision?` (why auto mode asks), `context?` (origin, see "Sub-agent events") |
201
+ | `permission_resolved` | `requestId`, `decision` |
202
+ | `permission_mode_changed` | `mode` |
203
+ | `model_changed` | `model: { provider, id, channel? }` |
204
+ | `thinking_level_changed` | `level` |
205
+ | `entry_appended` | `entry` (the session entry just written) |
206
+ | `hook_executed` | `event`, `command`, `exitCode` (null on timeout or when killed by a signal), `durationMs` |
207
+ | `cache_miss` | `missedTokens`, `missedCost?`, `reason`, `detail?`, `idleMs` |
208
+ | `cache_warm` | `phase: scheduled \| sent \| stopped`, `nextWarmAt?`, `usage?`, `cost?`, `reason?` |
209
+ | `context_pressure` | `percent`, `threshold: 70 \| 90`, `remainingTokens?`, `estimatedTurnsLeft?` |
210
+
211
+ There is also the non-session event `{"type":"notification","level":"info"|"warn"|"error","message":…}`: the host's `ui.notify` and run failures after the response.
212
+
213
+ `parentToolCallId` appears only on inner calls made through `tools.*` inside codemode scripts; its value is the id of the outer `codemode` call, which clients use to fold the display. Inner calls do not enter the transcript.
214
+
215
+ ### Sub-agent events (wave 5)
216
+
217
+ Sub-agents started by `task` / `task_ctl` (ama sub-sessions and external agents share the same events, see [agents.md](../agents.md), Chinese):
218
+
219
+ | Event | Fields |
220
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
221
+ | `subagent_start` | `taskId`, `parentToolCallId`, `agent`, `runner` (`ama` / `claude` / `codex` / `acp:<program>`), `description`, `background`, `model?`, `sessionFile?`, `cwd`; sent again when the same `taskId` is continued |
222
+ | `subagent_update` | `taskId`, `kind: tool \| text \| turn`, `toolName?`, `textDelta?` (merged over ≥ 250 ms), `turn`, `usage?` |
223
+ | `subagent_end` | `taskId`, `status: completed \| failed \| aborted \| max_turns \| interrupted`, `usage?`, `cache?`, `outputFile?`, `worktree?: { branch, changed }` |
224
+
225
+ Approvals of sub-sessions and external agents are sent to this connection as `permission_request` as usual, with an optional `context` marking the origin (since wave 6, approvals of this session's own tool calls also carry `context.toolCallId`, the id of the tool call that triggered the approval, which traces use to compute approval wait time; external agent requests do not carry it): `depth` (1 = from a task sub-agent), `taskId` (the originating task), `origin` (permission requests from external agents: `agent`, `sessionId` (the external CLI's own session id), `toolCall: { title, kind, locations?, inputSummary? }`, `options`). Dialogs use it to show `[task:<agent>]` or `[claude · session abc1]`. For external agent requests `toolName` is `agent:<id>` and the answer applies to this one request only ("allow for this session" is remembered by the external agent itself); the first run of an external agent in a session additionally gets one confirmation with `toolName: "task"`, `input: { agent, mode, note }` (`context.taskId`). `test/fixtures/rpc/external.out.jsonl` is the golden record of the three approvals of `task(agent="acp:ama")` (the task tool, the first run, the child ama's bash), updated by `src/agents/external-rpc.test.ts` with `UPDATE_GOLDEN=1`. After a background task completes, the parent session receives a user message with `origin: "task"` (`<task-notification …>…</task-notification>`) and starts a new turn as usual. Task and type lists are returned by `get_tasks` / `get_agents` (shapes `TaskInfo` / `AgentInfo`; empty without the task tool), with data from the current session's `taskRegistryView(sessionId)` / `sessionAgents(sessionId)` (`src/agent/subagent-registry.ts`). `get_agents` also includes external agents (`installed` / `version` come from PATH and a `--version` probe, cached asynchronously when the session is created and refreshed when external tasks end or host injections change; before the cache is ready there is only the type catalog, see `cachedAgentInfos` in `src/agents/external.ts`). `test/fixtures/rpc/subagent.out.jsonl` is the golden record of a foreground `task(agent="explore")` plus `get_tasks` / `get_agents` (keeping only responses, `tool_execution_*`, `subagent_*` and `agent_settled`), updated by `src/agent/subagent-rpc.test.ts` with `UPDATE_GOLDEN=1`.
226
+
227
+ ### Throughput telemetry (wave 5)
228
+
229
+ The main session has a telemetry extension (`src/agent/session-telemetry.ts`) that only counts chat requests (`purpose: "turn"`; compaction summaries, warming, probes and the classifier are not counted):
230
+
231
+ - Event `{"type":"telemetry_tick"}`: about every 500 ms after the first token while streaming (≤ 2 Hz, driven by deltas; not sent for short replies that finish instantly), and not sent with `ui.animation: false`; it has no payload, the data comes from `get_session_stats`'s `telemetry`.
232
+ - `SessionStats.telemetry`: `{ sessionStartedAt, last?, live?, avgTps? }`. `last` is the latest request (`requestAt`, `firstTokenAt?`, `ttftMs?`, `doneAt?`, `outputTokens?`, `tps?`; a request in progress becomes `last` once its first token arrives, and `doneAt` etc. are filled in when it ends); `live` exists only while streaming (`tps` estimated over the last 2 s window, `outputTokens` estimated from delta characters, `elapsedMs` since the first token); `avgTps` = Σoutput / Σ(end − first token), excluding requests that generated for less than 250 ms (their `tps` stays empty too). All times are millisecond timestamps.
233
+
234
+ ### Budget, fallback and background command events (wave 5 W5-H2)
235
+
236
+ | Event | Fields |
237
+ | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
238
+ | `limit_reached` | `kind: turns \| cost`, `value` (turns / USD of this run), `limit`; once per kind per run when `limits.*` (config; `-p` also has `--max-turns` / `--max-cost`) is reached, followed by `agent_settled{warning:"limit_reached"}` |
239
+ | `model_fallback` | `from`, `to` (`{ provider, id, channel? }`), `reason` (the triggering error text); when a retryable error is overloaded or retries are exhausted, switches to `fallbackModel` for one retry and switches back after the reply (plus two `model_changed`) |
240
+ | `background_job` | `jobId`, `phase: started \| exited \| stopped`, `command`, `pid?`, `outputPath?`, `exitCode?`; background commands started by `bash{background:true}` |
241
+
242
+ When repeated-call detection (the 5th call with the same name and arguments in one run) ends a run, it ends with `agent_settled{warning:"repeated_tool_call"}`.
243
+
244
+ ### `message_update` and rebuilding messages
245
+
246
+ On the wire `message_update` drops the accumulated message and `partial`, keeping only deltas:
247
+
248
+ ```json
249
+ {
250
+ "type": "message_update",
251
+ "assistantMessageEvent": { "type": "text_delta", "contentIndex": 0, "delta": "hello" },
252
+ "usage": { "input": 12, "output": 3, "cacheRead": 0, "cacheWrite": 0, "totalTokens": 15 }
253
+ }
254
+ ```
255
+
256
+ Values of `assistantMessageEvent.type`: `start`, `text_start` / `text_delta` / `text_end`, `thinking_start` / `thinking_delta` / `thinking_end`, `toolcall_start` (with `id`, `name`) / `toolcall_delta` (argument JSON fragments) / `toolcall_end` (with the complete `toolCall`), `done` (`reason: stop | length | toolUse`, with the final `message`), `error` (`reason: aborted | error`, with the final `message`). Rebuilding on the client:
257
+
258
+ 1. `message_start` gives the initial assistant message (`content: []`);
259
+ 2. keep content blocks by `contentIndex`: `*_start` creates a block, `*_delta` appends text (tool arguments are concatenated as a string first), `toolcall_end` replaces the block with the complete `toolCall`;
260
+ 3. `usage` is the latest usage at that moment and simply overwrites;
261
+ 4. replace the whole message with `message_end` (or the `message` of `done` / `error`); the rebuilt result is only for streaming display.
262
+
263
+ ### Session stats
264
+
265
+ The `data` of `get_session_stats` is `SessionStats`:
266
+
267
+ | Field | Description |
268
+ | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- |
269
+ | `sessionId` / `sessionFile` | Session identity |
270
+ | `userMessages` / `assistantMessages` / `toolCalls` / `toolResults` | Counts |
271
+ | `tokens` | `{ input, output, cacheRead, cacheWrite, total }`, including warming requests |
272
+ | `cost` | USD; absent when any message lacks a cost (the interface shows `$?`) |
273
+ | `contextTokens` / `contextWindow` / `contextPercent` | Current context estimate, window and usage (0–100); absent when the model has no window |
274
+ | `cacheHitRate` | The legacy hit rate: cacheRead / (input + cacheRead + cacheWrite), every request in the denominator |
275
+ | `cache` | `SessionCacheStats` (example below), present only when the session-layer cache controller is wired |
276
+
277
+ ```json
278
+ {
279
+ "type": "response",
280
+ "command": "get_session_stats",
281
+ "success": true,
282
+ "data": {
283
+ "tokens": { "input": 1177, "output": 64, "cacheRead": 2176, "cacheWrite": 0, "total": 3417 },
284
+ "cacheHitRate": 0.65,
285
+ "cache": {
286
+ "reporting": "reported",
287
+ "lastHitRate": 0.84,
288
+ "hitRate": 0.65,
289
+ "reBilledTokens": 0,
290
+ "reBilledUsd": 0,
291
+ "misses": { "count": 0, "byReason": {} },
292
+ "warming": { "mode": "streaming", "state": "stopped", "reason": "no_ttl" },
293
+ "contextRemainingTokens": 127077,
294
+ "estimatedTurnsLeft": 2443
295
+ }
296
+ }
297
+ }
298
+ ```
299
+
300
+ | `cache` field | Description |
301
+ | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
302
+ | `reporting` | The three states of the current endpoint (provider, baseUrl host, model): `unknown` / `reported` / `silent`; in memory only, reused across sessions in the same process |
303
+ | `lastHitRate` / `hitRate` | Latest / cumulative session hit rate (0–1); no `lastHitRate` for `unknown` / `silent`, and requests not reporting cache usage stay out of the `hitRate` denominator |
304
+ | `reBilledTokens` / `reBilledUsd` | Total re-billing from misses; no `reBilledUsd` when unpriced models are involved |
305
+ | `misses` | `count` and `byReason` (`prefix_changed` / `model_changed` / `idle` / `subtask` / `evicted`); every miss counts, regardless of the interface notice threshold |
306
+ | `warming` | `mode` (`off` / `streaming` / `idle`), `state` (`inactive` / `scheduled` / `stopped`), `phase?`, `nextWarmAt?`, stop reason `reason?`, `sent?`, `costUsd?`, `expectedSavingsUsd?` |
307
+ | `contextRemainingTokens` / `estimatedTurnsLeft` | Remaining context and the turns left estimated from the growth of the last 5 turns |
308
+ | `subagents` | Summary of task sub-sessions: `count`, `hitRate?`, `reBilledTokens` |
309
+ | `granularity` | Optional: the inferred cache-read chunk granularity of the current endpoint (tokens; the GCD of non-zero cacheRead values, given only with ≥ 2 samples and within 128–8192); the miss noise floor is the largest of it, 1024 and `minTokens` |
310
+
311
+ `tokens` / `cacheHitRate` keep the legacy definitions; new clients use `cache`. Cache event examples:
312
+
313
+ ```json
314
+ {"type":"cache_miss","missedTokens":142000,"missedCost":0.1278,"reason":"evicted","idleMs":3}
315
+ {"type":"cache_warm","phase":"scheduled","nextWarmAt":1790000000000}
316
+ {"type":"cache_warm","phase":"sent","usage":{"input":1,"output":1,"cacheRead":12000,"cacheWrite":0,"totalTokens":12002},"cost":0.0012}
317
+ {"type":"cache_warm","phase":"stopped","reason":"no_cache_hits"}
318
+ {"type":"context_pressure","percent":71,"threshold":70,"remainingTokens":57990,"estimatedTurnsLeft":6}
319
+ ```
320
+
321
+ `cache_miss` gives `detail` only for `prefix_changed` (`system` / `tools`). The values and meanings of `reason` for `cache_warm{stopped}` are in [tui.md](tui.md) "Cache and context". The result object of `ama -p --output-format json` also has a `cache` field of the same shape.
322
+
323
+ ## Approvals
324
+
325
+ 1. When a tool call needs confirmation, the server sends `permission_request`. `preview` (optional) is the pre-execution preview: `{ kind: "bash" | "write" | "edit" | "other", lines: string[], severity: "info" | "warn" | "danger", affected?: { path, exists, bytes?, files? }[] }`; `lines` are already laid out without colors and can be shown as is. The preview is read-only and bounded, and absent when it cannot be computed.
326
+ 2. The client is asked only if it sent `set_client_capabilities{capabilities:["approvals"]}` earlier; otherwise nobody answers the ask → deny. Removing `approvals` from the declaration withdraws the client and makes all pending approvals resolve as unanswered.
327
+ 3. The client replies with `permission_response{requestId, decision}`. `allow_session` remembers the same tool and normalized input prefix within this session, without writing to disk. Answers arriving before their request are kept and used once the request appears.
328
+ 4. Order of answerers: host broker (`HostApi.approvals.setBroker`) → RPC client → deny when nobody answers. Approvals are serial: only one waits at a time.
329
+ 5. Timeout: without an answer within `timeoutMs` (default 600 000, i.e. 10 minutes; the `AMA_APPROVAL_TIMEOUT_MS` environment variable changes it), the server treats it as deny and sends `permission_resolved`. When the run is interrupted it is also deny, even if the client already allowed.
330
+
331
+ ## Plan approval
332
+
333
+ Plan mode and the plan format are described in [plan.md](../plan.md) (Chinese).
334
+
335
+ 1. When a turn ends in plan mode with plain text and the reply contains a `<proposed_plan>` block, the server saves the plan and sends `plan_proposed{ planId, version, markdown, steps, filePath? }` (`steps[]`: `{ id, text, dependsOn?, agent? }`), followed by `agent_settled` as usual.
336
+ 2. The client answers only if it declared `set_client_capabilities{capabilities:["plans"]}`; otherwise the config `plan.unattended` applies: `stop` by default (the plan stays proposed, no mode switch, no execution; the client can still answer later with `plan_response`), and `approve` approves and executes within the same run.
337
+ 3. `plan_response`:
338
+ - `approve`: the plan is marked approved, its steps become todos (the first one in_progress, `todo_updated` sent), `plan_resolved{ planId, decision, mode }` is sent, and the permission mode switches to `mode` (default: the mode before entering plan; `default` when that was plan already). Then a new turn starts automatically: the user message `The plan is approved. Go ahead.` (`origin: "plan"`) + `custom_message{ama.plan_approved}` (the full plan, the file path, and the progress convention: with the todo tool, progress goes through todo; without it the model writes a `[DONE:<step>]` line per finished step, which ama uses to advance the todos and send `todo_updated`).
339
+ - `approve_fresh`: marked approved and the mode switched as above, then a new session is created (`session_start{reason:"new"}` sent), the todos are written in the new session, and a turn starts with the full plan as the first user message.
340
+ - `revise`: stays in plan; a non-empty `feedback` starts a turn as an ordinary user message, and the model rewrites the plan into a new version (the old one is marked superseded).
341
+ - `reject`: the plan is marked rejected and the session stays in plan.
342
+ - `editedMarkdown`: the full text as edited by the client; if it differs from the original, a new version is saved first (`plan_proposed` sent again) and then `decision` is applied.
343
+ 4. `todo_updated{ items }`: sent on every change of the todo list (set / update of the `todo` tool, generation on approval), shaped like `get_todos`.
344
+
345
+ `test/fixtures/rpc/plan.out.jsonl` is the golden file of a complete approval round trip (without `entry_appended` and `message_update`): declare `plans` → `set_permission_mode plan` → prompt → the `ama.plan_mode` note → a reply with a plan block → `plan_proposed` → `agent_settled` → `get_plan` → `plan_response approve` → `todo_updated`, `plan_resolved`, `permission_mode_changed` → the execution turn (`ama.plan_approved`) → `get_todos`. It is updated by `src/modes/rpc/rpc-plan.test.ts` with `UPDATE_GOLDEN=1`.
346
+
347
+ ## Exit
348
+
349
+ - stdin closed: no more commands are accepted and approvals are withdrawn (later asks resolve as unanswered → deny); in-flight commands and started runs finish and their responses are written, then the exit code is 0. So `printf '{"type":"prompt","message":"hi"}\n' | ama --mode rpc` gets a complete reply; to stop early, send `abort` first.
350
+ - SIGINT / SIGTERM: the current run is interrupted and the process exits in order, with exit code 130 / 143.
351
+ - Startup failures use the CLI exit codes ([design.md](../design.md) §11.3, Chinese): config error 3, no model or key 4, session error 5, host / hook startup failure 6, host API version mismatch 78.
352
+
353
+ ## Examples
354
+
355
+ `test/fixtures/rpc/prompt.out.jsonl` is the golden file of a complete round trip (fake provider; `prompt` → `get_last_assistant_text`, with session ids, timestamps and paths normalized): `hello` → `session_start` → `entry_appended` (model, thinking level, the first system message) → `before_agent_start` → `agent_start` → `turn_start` → the `prompt` response → the user message → `message_update` deltas of the assistant message → `turn_end` → `agent_end` → `agent_before_settle` → `agent_settled` → the response to the second command. After protocol changes, update it with `UPDATE_GOLDEN=1` via `src/modes/rpc/rpc-mode.test.ts` and review the diff. `test/fixtures/rpc/rewind.out.jsonl` records rewind round trips (without `entry_appended`; the second turn created `c.txt` with write): `get_rewind_points` → `rewind{mode:"both", dryRun:true}` returns only a preview → `rewind{mode:"both"}` sends `session_rewound` first, then returns `RewindResult` (`c.txt` deleted, the conversation back to before the second message) → `summarize_up_to` on a non-rewind point returns `invalid_arguments` → `get_rewind_points` after the rewind.
356
+
357
+ A minimal session (closing stdin withdraws approvals, so piping only suits prompts that need no approval; to answer approvals, keep stdin open and send `set_client_capabilities` first):
358
+
359
+ ```sh
360
+ printf '%s\n' '{"id":"1","type":"prompt","message":"hi"}' | ama --mode rpc --model anthropic/<model-id>
361
+ ```