@armadra/agent 0.5.0 → 0.6.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 (471) hide show
  1. package/CHANGELOG.md +177 -294
  2. package/CHANGELOG.zh-CN.md +442 -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/enrich.js +2 -7
  47. package/dist/ai/providers/models-dev-cache.js +15 -19
  48. package/dist/ai/providers/models-dev-snapshot.js +8 -7
  49. package/dist/ai/providers/models-dev.js +5 -15
  50. package/dist/ai/providers/suggest.js +2 -16
  51. package/dist/ai/types.d.ts +27 -1
  52. package/dist/auth/chatgpt/backend-client.d.ts +26 -0
  53. package/dist/auth/chatgpt/backend-client.js +74 -0
  54. package/dist/auth/chatgpt/claims.d.ts +17 -0
  55. package/dist/auth/chatgpt/claims.js +46 -0
  56. package/dist/auth/chatgpt/cli.d.ts +33 -0
  57. package/dist/auth/chatgpt/cli.js +252 -0
  58. package/dist/auth/chatgpt/doctor.d.ts +17 -0
  59. package/dist/auth/chatgpt/doctor.js +36 -0
  60. package/dist/auth/chatgpt/host-id.d.ts +7 -0
  61. package/dist/auth/chatgpt/host-id.js +26 -0
  62. package/dist/auth/chatgpt/login.d.ts +30 -0
  63. package/dist/auth/chatgpt/login.js +130 -0
  64. package/dist/auth/chatgpt/presets.d.ts +66 -0
  65. package/dist/auth/chatgpt/presets.js +120 -0
  66. package/dist/auth/chatgpt/quota-text.d.ts +13 -0
  67. package/dist/auth/chatgpt/quota-text.js +36 -0
  68. package/dist/auth/oauth/browser.d.ts +12 -0
  69. package/dist/auth/oauth/browser.js +27 -0
  70. package/dist/auth/oauth/callback-server.d.ts +47 -0
  71. package/dist/auth/oauth/callback-server.js +147 -0
  72. package/dist/auth/oauth/flows.d.ts +62 -0
  73. package/dist/auth/oauth/flows.js +113 -0
  74. package/dist/auth/oauth/jwt.d.ts +24 -0
  75. package/dist/auth/oauth/jwt.js +81 -0
  76. package/dist/auth/oauth/live.d.ts +21 -0
  77. package/dist/auth/oauth/live.js +25 -0
  78. package/dist/auth/oauth/oidc.d.ts +26 -0
  79. package/dist/auth/oauth/oidc.js +72 -0
  80. package/dist/auth/oauth/pkce.d.ts +15 -0
  81. package/dist/auth/oauth/pkce.js +20 -0
  82. package/dist/auth/oauth/refresh.d.ts +35 -0
  83. package/dist/auth/oauth/refresh.js +129 -0
  84. package/dist/auth/oauth/token-client.d.ts +33 -0
  85. package/dist/auth/oauth/token-client.js +121 -0
  86. package/dist/auth/oauth/token-store.d.ts +23 -0
  87. package/dist/auth/oauth/token-store.js +125 -0
  88. package/dist/auth/testing/fake-oauth.d.ts +73 -0
  89. package/dist/auth/testing/fake-oauth.js +271 -0
  90. package/dist/auth/testing/refresh-child.d.ts +5 -0
  91. package/dist/auth/testing/refresh-child.js +16 -0
  92. package/dist/bundle/ama.cjs +28307 -13241
  93. package/dist/checkpoints/backend.js +6 -5
  94. package/dist/checkpoints/restore.js +3 -2
  95. package/dist/checkpoints/settings.js +2 -1
  96. package/dist/checkpoints/shadow-git.js +7 -6
  97. package/dist/checkpoints/shadow-restore.js +3 -2
  98. package/dist/checkpoints/tracker.js +4 -3
  99. package/dist/cli/args.d.ts +9 -2
  100. package/dist/cli/args.js +74 -27
  101. package/dist/cli/bootstrap.js +53 -31
  102. package/dist/cli/choice-prompt.d.ts +58 -0
  103. package/dist/cli/choice-prompt.js +142 -0
  104. package/dist/cli/codemode-notice.js +2 -2
  105. package/dist/cli/compose-agents.js +2 -1
  106. package/dist/cli/compose-extensions.js +2 -0
  107. package/dist/cli/compose-memory.d.ts +53 -0
  108. package/dist/cli/compose-memory.js +127 -0
  109. package/dist/cli/compose-providers.d.ts +5 -0
  110. package/dist/cli/compose-providers.js +32 -2
  111. package/dist/cli/compose-session.d.ts +5 -0
  112. package/dist/cli/compose-session.js +27 -13
  113. package/dist/cli/compose-store.d.ts +2 -0
  114. package/dist/cli/compose-store.js +9 -5
  115. package/dist/cli/compose.d.ts +2 -0
  116. package/dist/cli/compose.js +13 -5
  117. package/dist/cli/default-model.d.ts +0 -2
  118. package/dist/cli/default-model.js +5 -8
  119. package/dist/cli/deps.d.ts +5 -1
  120. package/dist/cli/exit-codes.d.ts +1 -1
  121. package/dist/cli/exit-codes.js +7 -16
  122. package/dist/cli/from-prompt.js +3 -2
  123. package/dist/cli/help-text.d.ts +2 -1
  124. package/dist/cli/help-text.js +5 -99
  125. package/dist/cli/main.d.ts +5 -0
  126. package/dist/cli/main.js +21 -2
  127. package/dist/cli/proxy.js +14 -9
  128. package/dist/cli/runtime.d.ts +5 -0
  129. package/dist/cli/startup-screen.js +20 -27
  130. package/dist/cli/startup-steps.js +6 -8
  131. package/dist/cli/subcommands/auth.d.ts +6 -3
  132. package/dist/cli/subcommands/auth.js +52 -22
  133. package/dist/cli/subcommands/config-set.d.ts +21 -0
  134. package/dist/cli/subcommands/config-set.js +137 -0
  135. package/dist/cli/subcommands/config.d.ts +2 -1
  136. package/dist/cli/subcommands/config.js +51 -37
  137. package/dist/cli/subcommands/doctor.d.ts +2 -1
  138. package/dist/cli/subcommands/doctor.js +97 -58
  139. package/dist/cli/subcommands/init.d.ts +1 -1
  140. package/dist/cli/subcommands/init.js +8 -7
  141. package/dist/cli/subcommands/memory.d.ts +18 -0
  142. package/dist/cli/subcommands/memory.js +189 -0
  143. package/dist/cli/subcommands/model-meta.js +11 -9
  144. package/dist/cli/subcommands/models-cache-probe.d.ts +1 -1
  145. package/dist/cli/subcommands/models-cache-probe.js +26 -32
  146. package/dist/cli/subcommands/models-discover.d.ts +3 -0
  147. package/dist/cli/subcommands/models-discover.js +44 -21
  148. package/dist/cli/subcommands/models.d.ts +1 -1
  149. package/dist/cli/subcommands/models.js +29 -22
  150. package/dist/cli/subcommands/probe-runner.js +8 -7
  151. package/dist/cli/subcommands/providers-list.js +32 -21
  152. package/dist/cli/subcommands/providers-plan.js +24 -25
  153. package/dist/cli/subcommands/providers-probe.js +5 -6
  154. package/dist/cli/subcommands/providers.d.ts +2 -2
  155. package/dist/cli/subcommands/providers.js +48 -59
  156. package/dist/cli/subcommands/sessions-export.d.ts +1 -1
  157. package/dist/cli/subcommands/sessions-export.js +10 -9
  158. package/dist/cli/subcommands/sessions-search.d.ts +1 -1
  159. package/dist/cli/subcommands/sessions-search.js +11 -10
  160. package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
  161. package/dist/cli/subcommands/sessions-trace.js +156 -0
  162. package/dist/cli/subcommands/sessions.d.ts +4 -3
  163. package/dist/cli/subcommands/sessions.js +40 -37
  164. package/dist/cli/subcommands/stats.d.ts +1 -1
  165. package/dist/cli/subcommands/stats.js +49 -30
  166. package/dist/cli/system-prompt-arg.js +3 -2
  167. package/dist/codemode/capability.js +3 -2
  168. package/dist/compaction/post-compact.d.ts +1 -0
  169. package/dist/compaction/post-compact.js +15 -1
  170. package/dist/compaction/prune-tier.d.ts +1 -1
  171. package/dist/compaction/prune-tier.js +3 -3
  172. package/dist/compaction/serialize.js +2 -1
  173. package/dist/config/auth-file.d.ts +12 -2
  174. package/dist/config/auth-file.js +32 -10
  175. package/dist/config/checker.js +12 -11
  176. package/dist/config/context-files.js +3 -2
  177. package/dist/config/edit.d.ts +106 -0
  178. package/dist/config/edit.js +350 -0
  179. package/dist/config/init.d.ts +4 -3
  180. package/dist/config/init.js +10 -18
  181. package/dist/config/json-schema.d.ts +2 -1
  182. package/dist/config/json-schema.js +101 -68
  183. package/dist/config/key-docs.d.ts +18 -7
  184. package/dist/config/key-docs.js +43 -128
  185. package/dist/config/load.js +7 -6
  186. package/dist/config/merge.d.ts +4 -1
  187. package/dist/config/merge.js +42 -22
  188. package/dist/config/paths.js +6 -5
  189. package/dist/config/profile.d.ts +5 -1
  190. package/dist/config/profile.js +7 -2
  191. package/dist/config/schema-w5.js +3 -2
  192. package/dist/config/schema-w6.d.ts +19 -0
  193. package/dist/config/schema-w6.js +115 -0
  194. package/dist/config/schema.js +34 -20
  195. package/dist/config/settings-registry.d.ts +78 -0
  196. package/dist/config/settings-registry.js +184 -0
  197. package/dist/config/types-w6.d.ts +109 -0
  198. package/dist/config/types-w6.js +19 -0
  199. package/dist/config/types.d.ts +11 -8
  200. package/dist/config/types.js +1 -0
  201. package/dist/drivers/acp/client.js +1 -1
  202. package/dist/drivers/acp/driver.js +13 -8
  203. package/dist/drivers/agents.js +4 -3
  204. package/dist/drivers/base.js +3 -2
  205. package/dist/drivers/host-runners.js +2 -1
  206. package/dist/drivers/native/claude-stream.js +12 -11
  207. package/dist/drivers/native/codex-app-server.js +17 -12
  208. package/dist/drivers/native/oneshot.js +8 -7
  209. package/dist/drivers/pool.js +1 -1
  210. package/dist/drivers/runner.d.ts +3 -1
  211. package/dist/drivers/runner.js +68 -20
  212. package/dist/drivers/turn.js +1 -1
  213. package/dist/hooks/config.js +3 -2
  214. package/dist/hooks/protocol.js +18 -12
  215. package/dist/host/api-impl.js +11 -10
  216. package/dist/host/loader.js +9 -8
  217. package/dist/host/types.d.ts +3 -0
  218. package/dist/i18n/catalog.d.ts +2169 -0
  219. package/dist/i18n/catalog.js +72 -0
  220. package/dist/i18n/format.d.ts +21 -0
  221. package/dist/i18n/format.js +58 -0
  222. package/dist/i18n/index.d.ts +58 -0
  223. package/dist/i18n/index.js +72 -0
  224. package/dist/i18n/messages/agents.d.ts +84 -0
  225. package/dist/i18n/messages/agents.js +85 -0
  226. package/dist/i18n/messages/approval.d.ts +99 -0
  227. package/dist/i18n/messages/approval.js +100 -0
  228. package/dist/i18n/messages/auth.d.ts +187 -0
  229. package/dist/i18n/messages/auth.js +189 -0
  230. package/dist/i18n/messages/cli-args.d.ts +46 -0
  231. package/dist/i18n/messages/cli-args.js +46 -0
  232. package/dist/i18n/messages/cli-help.d.ts +12 -0
  233. package/dist/i18n/messages/cli-help.js +244 -0
  234. package/dist/i18n/messages/cli.d.ts +336 -0
  235. package/dist/i18n/messages/cli.js +311 -0
  236. package/dist/i18n/messages/config-keys.d.ts +289 -0
  237. package/dist/i18n/messages/config-keys.js +292 -0
  238. package/dist/i18n/messages/config.d.ts +502 -0
  239. package/dist/i18n/messages/config.js +239 -0
  240. package/dist/i18n/messages/drivers.d.ts +123 -0
  241. package/dist/i18n/messages/drivers.js +124 -0
  242. package/dist/i18n/messages/errors.d.ts +83 -0
  243. package/dist/i18n/messages/errors.js +171 -0
  244. package/dist/i18n/messages/interactive-line.d.ts +61 -0
  245. package/dist/i18n/messages/interactive-line.js +69 -0
  246. package/dist/i18n/messages/interactive-startup.d.ts +103 -0
  247. package/dist/i18n/messages/interactive-startup.js +104 -0
  248. package/dist/i18n/messages/interactive-view.d.ts +140 -0
  249. package/dist/i18n/messages/interactive-view.js +141 -0
  250. package/dist/i18n/messages/interactive.d.ts +493 -0
  251. package/dist/i18n/messages/interactive.js +248 -0
  252. package/dist/i18n/messages/memory.d.ts +123 -0
  253. package/dist/i18n/messages/memory.js +128 -0
  254. package/dist/i18n/messages/panels.d.ts +190 -0
  255. package/dist/i18n/messages/panels.js +189 -0
  256. package/dist/i18n/messages/permissions.d.ts +126 -0
  257. package/dist/i18n/messages/permissions.js +151 -0
  258. package/dist/i18n/messages/plan.d.ts +123 -0
  259. package/dist/i18n/messages/plan.js +124 -0
  260. package/dist/i18n/messages/print.d.ts +86 -0
  261. package/dist/i18n/messages/print.js +91 -0
  262. package/dist/i18n/messages/report.d.ts +391 -0
  263. package/dist/i18n/messages/report.js +490 -0
  264. package/dist/i18n/messages/rewind.d.ts +198 -0
  265. package/dist/i18n/messages/rewind.js +217 -0
  266. package/dist/i18n/messages/session.d.ts +230 -0
  267. package/dist/i18n/messages/session.js +258 -0
  268. package/dist/i18n/messages/settings.d.ts +348 -0
  269. package/dist/i18n/messages/settings.js +336 -0
  270. package/dist/i18n/messages/subcommands-config.d.ts +111 -0
  271. package/dist/i18n/messages/subcommands-config.js +127 -0
  272. package/dist/i18n/messages/subcommands.d.ts +548 -0
  273. package/dist/i18n/messages/subcommands.js +474 -0
  274. package/dist/i18n/messages/trace.d.ts +243 -0
  275. package/dist/i18n/messages/trace.js +238 -0
  276. package/dist/i18n/types.d.ts +15 -0
  277. package/dist/i18n/types.js +7 -0
  278. package/dist/index.d.ts +6 -0
  279. package/dist/index.js +2 -0
  280. package/dist/memory/edit.d.ts +24 -0
  281. package/dist/memory/edit.js +63 -0
  282. package/dist/memory/frontmatter.d.ts +37 -0
  283. package/dist/memory/frontmatter.js +79 -0
  284. package/dist/memory/index.d.ts +28 -0
  285. package/dist/memory/index.js +126 -0
  286. package/dist/memory/lock.d.ts +17 -0
  287. package/dist/memory/lock.js +62 -0
  288. package/dist/memory/paths.d.ts +57 -0
  289. package/dist/memory/paths.js +175 -0
  290. package/dist/memory/report.d.ts +36 -0
  291. package/dist/memory/report.js +86 -0
  292. package/dist/memory/runtime.d.ts +42 -0
  293. package/dist/memory/runtime.js +36 -0
  294. package/dist/memory/secrets.d.ts +8 -0
  295. package/dist/memory/secrets.js +27 -0
  296. package/dist/memory/section.d.ts +28 -0
  297. package/dist/memory/section.js +59 -0
  298. package/dist/memory/store.d.ts +70 -0
  299. package/dist/memory/store.js +284 -0
  300. package/dist/memory/tool.d.ts +31 -0
  301. package/dist/memory/tool.js +94 -0
  302. package/dist/modes/acp/acp-events.js +2 -1
  303. package/dist/modes/acp/acp-server.js +13 -12
  304. package/dist/modes/commands-core.d.ts +17 -0
  305. package/dist/modes/commands-core.js +101 -61
  306. package/dist/modes/image-input.js +20 -6
  307. package/dist/modes/interactive/agent-bar.d.ts +95 -0
  308. package/dist/modes/interactive/agent-bar.js +248 -0
  309. package/dist/modes/interactive/agent-panels.js +27 -26
  310. package/dist/modes/interactive/agent-transcript.d.ts +47 -0
  311. package/dist/modes/interactive/agent-transcript.js +191 -0
  312. package/dist/modes/interactive/agent-ui.d.ts +36 -1
  313. package/dist/modes/interactive/agent-ui.js +180 -14
  314. package/dist/modes/interactive/agent-view.d.ts +72 -0
  315. package/dist/modes/interactive/agent-view.js +281 -0
  316. package/dist/modes/interactive/approval-dialog.js +46 -34
  317. package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
  318. package/dist/modes/interactive/clipboard-paste.js +9 -4
  319. package/dist/modes/interactive/commands.d.ts +22 -1
  320. package/dist/modes/interactive/commands.js +93 -38
  321. package/dist/modes/interactive/completion.js +2 -1
  322. package/dist/modes/interactive/config-panel.d.ts +70 -0
  323. package/dist/modes/interactive/config-panel.js +319 -0
  324. package/dist/modes/interactive/config-ui.d.ts +96 -0
  325. package/dist/modes/interactive/config-ui.js +397 -0
  326. package/dist/modes/interactive/confirm-dialog.d.ts +49 -0
  327. package/dist/modes/interactive/confirm-dialog.js +120 -0
  328. package/dist/modes/interactive/event-notices.js +11 -9
  329. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  330. package/dist/modes/interactive/interactive-mode.js +25 -22
  331. package/dist/modes/interactive/key-dispatch.d.ts +18 -0
  332. package/dist/modes/interactive/key-dispatch.js +39 -13
  333. package/dist/modes/interactive/line/line-editor.js +2 -1
  334. package/dist/modes/interactive/line/line-mode.d.ts +2 -0
  335. package/dist/modes/interactive/line/line-mode.js +24 -4
  336. package/dist/modes/interactive/line/line-render.js +25 -24
  337. package/dist/modes/interactive/memory-panel.d.ts +64 -0
  338. package/dist/modes/interactive/memory-panel.js +221 -0
  339. package/dist/modes/interactive/message-view.d.ts +4 -2
  340. package/dist/modes/interactive/message-view.js +42 -33
  341. package/dist/modes/interactive/panels.js +39 -31
  342. package/dist/modes/interactive/pickers.d.ts +2 -1
  343. package/dist/modes/interactive/pickers.js +10 -6
  344. package/dist/modes/interactive/plan-command.d.ts +1 -1
  345. package/dist/modes/interactive/plan-command.js +24 -27
  346. package/dist/modes/interactive/plan-dialog.js +18 -17
  347. package/dist/modes/interactive/plan-flow.js +6 -5
  348. package/dist/modes/interactive/rewind-command.d.ts +1 -1
  349. package/dist/modes/interactive/rewind-command.js +18 -16
  350. package/dist/modes/interactive/rewind-flow.d.ts +0 -1
  351. package/dist/modes/interactive/rewind-flow.js +13 -14
  352. package/dist/modes/interactive/rewind-list.js +7 -6
  353. package/dist/modes/interactive/rewind-panel.js +40 -40
  354. package/dist/modes/interactive/rewind-text.d.ts +5 -3
  355. package/dist/modes/interactive/rewind-text.js +48 -38
  356. package/dist/modes/interactive/run-indicator.js +15 -12
  357. package/dist/modes/interactive/session-events.js +3 -2
  358. package/dist/modes/interactive/startup-header.js +22 -23
  359. package/dist/modes/interactive/startup-ui.js +41 -29
  360. package/dist/modes/interactive/status-area.d.ts +2 -0
  361. package/dist/modes/interactive/status-area.js +8 -2
  362. package/dist/modes/interactive/status-bar.js +4 -3
  363. package/dist/modes/interactive/subagent-view.js +9 -7
  364. package/dist/modes/interactive/tasks-report.d.ts +6 -0
  365. package/dist/modes/interactive/tasks-report.js +28 -31
  366. package/dist/modes/interactive/terminal-setup.d.ts +9 -0
  367. package/dist/modes/interactive/terminal-setup.js +23 -0
  368. package/dist/modes/interactive/tool-summary.js +19 -17
  369. package/dist/modes/interactive/tool-view.js +7 -4
  370. package/dist/modes/interactive/trace-view.d.ts +89 -0
  371. package/dist/modes/interactive/trace-view.js +332 -0
  372. package/dist/modes/print/print-mode.js +14 -15
  373. package/dist/modes/rpc/commands.js +7 -3
  374. package/dist/modes/rpc/rpc-mode.js +9 -3
  375. package/dist/modes/session-report.d.ts +2 -0
  376. package/dist/modes/session-report.js +101 -105
  377. package/dist/modes/startup-ui-text.js +11 -6
  378. package/dist/permissions/bypass.d.ts +30 -0
  379. package/dist/permissions/bypass.js +45 -0
  380. package/dist/permissions/memory-class.d.ts +23 -0
  381. package/dist/permissions/memory-class.js +54 -0
  382. package/dist/permissions/modes.d.ts +3 -3
  383. package/dist/permissions/modes.js +21 -16
  384. package/dist/permissions/pipeline.d.ts +1 -1
  385. package/dist/permissions/pipeline.js +9 -2
  386. package/dist/permissions/preview.js +49 -42
  387. package/dist/permissions/rules.js +5 -2
  388. package/dist/permissions/types.d.ts +4 -0
  389. package/dist/plan/store.js +2 -1
  390. package/dist/rpc.d.ts +39 -1
  391. package/dist/rpc.js +3 -0
  392. package/dist/sandbox/bash.js +11 -8
  393. package/dist/sandbox/detect.js +14 -11
  394. package/dist/sdk.d.ts +17 -1
  395. package/dist/sdk.js +29 -7
  396. package/dist/session/export.js +31 -30
  397. package/dist/session/manager.d.ts +1 -1
  398. package/dist/session/manager.js +5 -3
  399. package/dist/session/reuse.js +5 -4
  400. package/dist/session/scan.js +3 -2
  401. package/dist/session/stats-aggregate.d.ts +3 -1
  402. package/dist/session/stats-aggregate.js +5 -1
  403. package/dist/session/stats-index.js +2 -1
  404. package/dist/session/stats-scan.d.ts +4 -1
  405. package/dist/session/stats-scan.js +6 -2
  406. package/dist/session/store.d.ts +11 -0
  407. package/dist/session/store.js +48 -1
  408. package/dist/session/types.d.ts +2 -0
  409. package/dist/skills/builtin.js +2 -1
  410. package/dist/tools/image-file.d.ts +26 -1
  411. package/dist/tools/image-file.js +55 -13
  412. package/dist/tools/presets.d.ts +14 -1
  413. package/dist/tools/presets.js +3 -3
  414. package/dist/tools/registry.js +1 -1
  415. package/dist/tools/truncate.d.ts +1 -1
  416. package/dist/tools/truncate.js +2 -2
  417. package/dist/tools/types.d.ts +17 -1
  418. package/dist/trace/build-index.d.ts +91 -0
  419. package/dist/trace/build-index.js +127 -0
  420. package/dist/trace/build-nodes.d.ts +24 -0
  421. package/dist/trace/build-nodes.js +279 -0
  422. package/dist/trace/build-util.d.ts +43 -0
  423. package/dist/trace/build-util.js +120 -0
  424. package/dist/trace/build.d.ts +82 -0
  425. package/dist/trace/build.js +382 -0
  426. package/dist/trace/detail.d.ts +35 -0
  427. package/dist/trace/detail.js +205 -0
  428. package/dist/trace/flatten.d.ts +69 -0
  429. package/dist/trace/flatten.js +173 -0
  430. package/dist/trace/format.d.ts +47 -0
  431. package/dist/trace/format.js +329 -0
  432. package/dist/trace/html-template.d.ts +19 -0
  433. package/dist/trace/html-template.js +150 -0
  434. package/dist/trace/html.d.ts +104 -0
  435. package/dist/trace/html.js +292 -0
  436. package/dist/trace/preview.d.ts +29 -0
  437. package/dist/trace/preview.js +59 -0
  438. package/dist/trace/query-session.d.ts +14 -0
  439. package/dist/trace/query-session.js +38 -0
  440. package/dist/trace/query.d.ts +55 -0
  441. package/dist/trace/query.js +188 -0
  442. package/dist/trace/session.d.ts +40 -0
  443. package/dist/trace/session.js +168 -0
  444. package/dist/trace/types.d.ts +243 -0
  445. package/dist/trace/types.js +13 -0
  446. package/dist/tui/components/editor-paste.d.ts +2 -0
  447. package/dist/tui/components/editor-paste.js +6 -3
  448. package/dist/tui/components/editor.js +2 -2
  449. package/dist/tui/components/loader.d.ts +3 -0
  450. package/dist/tui/components/loader.js +14 -0
  451. package/dist/tui/components/settings-list.d.ts +61 -0
  452. package/dist/tui/components/settings-list.js +135 -0
  453. package/dist/tui/keybindings.d.ts +6 -1
  454. package/dist/tui/keybindings.js +18 -6
  455. package/dist/tui.d.ts +1 -0
  456. package/dist/tui.js +2 -0
  457. package/docs/en/host-api.md +167 -0
  458. package/docs/en/permissions.md +214 -0
  459. package/docs/en/providers.md +625 -0
  460. package/docs/en/rpc.md +361 -0
  461. package/docs/en/sessions.md +219 -0
  462. package/docs/en/tui.md +527 -0
  463. package/docs/host-api.md +18 -17
  464. package/docs/memory.md +172 -0
  465. package/docs/permissions.md +3 -2
  466. package/docs/providers.md +67 -1
  467. package/docs/rpc.md +31 -3
  468. package/docs/session-format.md +8 -2
  469. package/docs/sessions.md +29 -1
  470. package/docs/tui.md +189 -21
  471. package/package.json +8 -3
@@ -19,13 +19,17 @@ import { loadHookConfigs } from "../hooks/config.js";
19
19
  import { HookDispatcher } from "../hooks/dispatcher.js";
20
20
  import { AgentEventBus, createHostApi } from "../host/api-impl.js";
21
21
  import { activateHost, disposeHost } from "../host/loader.js";
22
- import { HELP_TEXT, parseArgs, UsageError } from "./args.js";
22
+ import { helpText, parseArgs, UsageError } from "./args.js";
23
23
  import { applyFromOption } from "./from-prompt.js";
24
24
  import { ExitCode } from "./exit-codes.js";
25
25
  import { applyProfile, applyToolFilters, decideMode, defaultSendUser, instructionSources, resolveModel, sessionRequestOf, sourceOf, step, thinkingOf, toStartupError, } from "./startup-steps.js";
26
26
  import { resolveSystemPromptArg } from "./system-prompt-arg.js";
27
+ import { memoryEnvOverride, resolveMemory } from "./compose-memory.js";
28
+ import { msg, resolveLocale, setLocale } from "../i18n/index.js";
27
29
  /** §11.1 第 3–14 步。 */
28
30
  export async function bootstrap(argsIn, deps, io) {
31
+ // 文案按调用时的语言取(第 9 步可能按 profile / 项目级 ui.language 补定语言)
32
+ const m = () => msg().cli.bootstrap;
29
33
  const warnings = [];
30
34
  const warn = (message) => {
31
35
  warnings.push(message);
@@ -43,13 +47,13 @@ export async function bootstrap(argsIn, deps, io) {
43
47
  const mode = decideMode(args, io);
44
48
  const interactive = mode === "interactive" || mode === "line";
45
49
  // 5. 目录
46
- const paths = await step(ExitCode.Config, "目录", () => {
50
+ const paths = await step(ExitCode.Config, m().steps.dirs, () => {
47
51
  const resolved = resolvePaths({ env: io.env, cwd: io.cwd, sessionDirFlag: args.sessionDir });
48
52
  ensurePaths(resolved);
49
53
  return resolved;
50
54
  });
51
55
  // 6. 用户级 + profile.config
52
- const base = await step(ExitCode.Config, "配置", () => {
56
+ const base = await step(ExitCode.Config, m().steps.config, () => {
53
57
  const user = loadConfigFile("config", userFile(paths, CONFIG_FILE));
54
58
  if (user !== undefined)
55
59
  warnings.push(...user.warnings);
@@ -63,27 +67,27 @@ export async function bootstrap(argsIn, deps, io) {
63
67
  let request = sessionRequestOf(args);
64
68
  if (request === "pick") {
65
69
  if (!interactive || deps.ui?.pickSession === undefined || deps.sessions.list === undefined) {
66
- throw new UsageError("--resume 在非交互模式下需要会话 id");
70
+ throw new UsageError(m().resumeNeedsId);
67
71
  }
68
- const items = await step(ExitCode.Session, "会话列表", () => deps.sessions.list?.({ sessionDir: paths.sessionDir, cwd: paths.cwd }) ?? []);
72
+ const items = await step(ExitCode.Session, m().steps.sessionList, () => deps.sessions.list?.({ sessionDir: paths.sessionDir, cwd: paths.cwd }) ?? []);
69
73
  const id = await deps.ui.pickSession(items);
70
74
  if (id === undefined)
71
- throw new StartupError("session_not_found", "未选择会话", ExitCode.Session);
75
+ throw new StartupError("session_not_found", m().noSessionPicked, ExitCode.Session);
72
76
  request = { kind: "resume", id };
73
77
  }
74
78
  const sessionRequest = request;
75
- const sessionManager = await step(ExitCode.Session, "会话", () => deps.sessions.open(sessionRequest, { sessionDir: paths.sessionDir, cwd: paths.cwd }));
79
+ const sessionManager = await step(ExitCode.Session, m().steps.session, () => deps.sessions.open(sessionRequest, { sessionDir: paths.sessionDir, cwd: paths.cwd }));
76
80
  let sessionCwd = sessionManager.cwd;
77
81
  if (!existsSync(sessionCwd)) {
78
82
  const replacement = interactive ? await deps.ui?.askCwd?.(sessionCwd) : undefined;
79
83
  if (replacement === undefined) {
80
- throw new StartupError("session_corrupt", `会话的工作目录不存在:${sessionCwd}`, ExitCode.Session);
84
+ throw new StartupError("session_corrupt", m().sessionCwdMissing(sessionCwd), ExitCode.Session);
81
85
  }
82
86
  sessionCwd = resolve(replacement);
83
87
  }
84
88
  const runtimePaths = { ...paths, cwd: sessionCwd };
85
89
  // 8. 信任(以会话 cwd 为准)
86
- const trust = await step(ExitCode.Config, "信任", () => decideTrust({
90
+ const trust = await step(ExitCode.Config, m().steps.trust, () => decideTrust({
87
91
  cwd: sessionCwd,
88
92
  configDir: paths.configDir,
89
93
  flag: args.trust,
@@ -92,7 +96,7 @@ export async function bootstrap(argsIn, deps, io) {
92
96
  prompt: deps.ui?.promptTrust,
93
97
  }));
94
98
  // 9. 项目级配置(只能收紧)+ 命令行
95
- const merged = await step(ExitCode.Config, "项目配置", () => {
99
+ const merged = await step(ExitCode.Config, m().steps.projectConfig, () => {
96
100
  const project = loadConfigFile("config", projectFile(sessionCwd, CONFIG_FILE));
97
101
  if (project !== undefined)
98
102
  warnings.push(...project.warnings);
@@ -105,16 +109,21 @@ export async function bootstrap(argsIn, deps, io) {
105
109
  tuiMode: args.tuiMode,
106
110
  toolsPreset: args.toolsPreset,
107
111
  codemode: args.codemode,
112
+ memory: args.memory ?? memoryEnvOverride(io.env),
108
113
  });
109
114
  });
110
115
  warnings.push(...merged.warnings);
111
116
  const config = merged.config;
117
+ // [W6-C0] main.ts 只看了用户级;profile 的 language 与合并后的 ui.language 在这里补定(AMA_LANG / --lang 仍优先)
118
+ const language = profile?.language ?? config.ui?.language;
119
+ if (language === "zh" || language === "en")
120
+ setLocale(resolveLocale(io.env, { language }, args.lang));
112
121
  // 10. 资源发现
113
122
  const context = findContextFiles({ cwd: sessionCwd, configDir: paths.configDir });
114
123
  warnings.push(...context.warnings);
115
124
  const discovered = deps.resources === undefined
116
125
  ? { skills: [], prompts: [], warnings: [] }
117
- : await step(ExitCode.Config, "Skill 发现", () => deps.resources?.discover({
126
+ : await step(ExitCode.Config, m().steps.skillDiscovery, () => deps.resources?.discover({
118
127
  cwd: sessionCwd,
119
128
  configDir: paths.configDir,
120
129
  trusted: trust.trusted,
@@ -139,7 +148,7 @@ export async function bootstrap(argsIn, deps, io) {
139
148
  instructions,
140
149
  };
141
150
  // 11. 供应商与模型
142
- const providers = await step(ExitCode.Config, "供应商", () => deps.providers.create({
151
+ const providers = await step(ExitCode.Config, m().steps.providers, () => deps.providers.create({
143
152
  config,
144
153
  cwd: sessionCwd,
145
154
  authFile: args.authFile !== undefined
@@ -157,18 +166,25 @@ export async function bootstrap(argsIn, deps, io) {
157
166
  }
158
167
  : {}),
159
168
  }));
160
- const { model, provider } = await step(ExitCode.NoModel, "模型", () => resolveModel(args, providers, sessionManager, config.defaultModel, deps, interactive, io.env));
169
+ const { model, provider } = await step(ExitCode.NoModel, m().steps.model, () => resolveModel(args, providers, sessionManager, config.defaultModel, deps, interactive, io.env));
161
170
  const thinkingLevel = thinkingOf(args, sessionManager, config.thinkingLevel);
162
171
  // 12. 工具注册表
163
- const tools = await step(ExitCode.RuntimeError, "工具", () => deps.tools.create({
172
+ const tools = await step(ExitCode.RuntimeError, m().steps.tools, () => deps.tools.create({
164
173
  config,
165
174
  cwd: sessionCwd,
166
175
  mode,
167
176
  paths: { configDir: paths.configDir, dataDir: paths.dataDir },
177
+ memory: resolveMemory({
178
+ config,
179
+ cwd: sessionCwd,
180
+ dataDir: paths.dataDir,
181
+ trusted: trust.trusted,
182
+ embedded: profile,
183
+ }),
168
184
  }));
169
185
  for (const name of config.tools?.disabled ?? []) {
170
186
  if (tools.get(name) === undefined)
171
- warn(`config tools.disabled:未知工具 ${name},已忽略`);
187
+ warn(m().unknownDisabledTool(name));
172
188
  else
173
189
  tools.disable(name);
174
190
  }
@@ -176,7 +192,7 @@ export async function bootstrap(argsIn, deps, io) {
176
192
  let session;
177
193
  const events = new AgentEventBus((level, message, detail) => {
178
194
  if (level === "warn" || level === "error")
179
- warn(`${message}${detail instanceof Error ? `:${detail.message}` : ""}`);
195
+ warn(m().eventWarning(message, detail instanceof Error ? detail.message : undefined));
180
196
  });
181
197
  const binding = createHostApi({
182
198
  mode,
@@ -191,7 +207,7 @@ export async function bootstrap(argsIn, deps, io) {
191
207
  bus: events,
192
208
  sendUser: (text, origin) => {
193
209
  if (session === undefined)
194
- return Promise.reject(new AmaError("busy", "会话尚未就绪"));
210
+ return Promise.reject(new AmaError("busy", m().sessionNotReady));
195
211
  return (deps.sendUser ?? defaultSendUser)(session, text, origin);
196
212
  },
197
213
  stderr: io.stderr,
@@ -200,7 +216,7 @@ export async function bootstrap(argsIn, deps, io) {
200
216
  const hostSpec = args.host;
201
217
  let host;
202
218
  if (hostSpec !== undefined) {
203
- host = await step(ExitCode.HostOrHook, "宿主适配器", () => activateHost({ module: hostSpec, binding, cwd: io.cwd }));
219
+ host = await step(ExitCode.HostOrHook, m().steps.host, () => activateHost({ module: hostSpec, binding, cwd: io.cwd }));
204
220
  }
205
221
  let shutdown;
206
222
  try {
@@ -209,7 +225,7 @@ export async function bootstrap(argsIn, deps, io) {
209
225
  const unattended = mode === "print";
210
226
  const builtinDeny = config.permission?.builtinDeny;
211
227
  const autoSafeCommands = config.permission?.autoSafeCommands;
212
- const permission = await step(ExitCode.Config, "权限", () => deps.permissions.create({
228
+ const permission = await step(ExitCode.Config, m().steps.permission, () => deps.permissions.create({
213
229
  mode: config.permission?.mode ?? "default",
214
230
  rules: merged.ruleSpecs,
215
231
  unattended,
@@ -285,14 +301,14 @@ export async function bootstrap(argsIn, deps, io) {
285
301
  overrides.systemPrompt = systemPrompt;
286
302
  if (Object.keys(overrides).length > 0)
287
303
  assembly.overrides = overrides;
288
- session = await step(ExitCode.RuntimeError, "会话组装", () => deps.session.create(assembly));
304
+ session = await step(ExitCode.RuntimeError, m().steps.assembly, () => deps.session.create(assembly));
289
305
  const active = session;
290
306
  let disposed;
291
307
  shutdown = (reason) => {
292
308
  disposed ??= (async () => {
293
309
  await events.emit("session_shutdown", {});
294
310
  await hooks.run("SessionEnd", { reason }).catch(() => undefined);
295
- await disposeHost(host, (e) => warn(`宿主适配器 dispose 失败:${String(e)}`));
311
+ await disposeHost(host, (e) => warn(m().hostDisposeFailed(String(e))));
296
312
  // 会话被替换过时 dispose 当前那个(旧会话由替换方负责)
297
313
  await (session ?? active).dispose();
298
314
  })();
@@ -306,14 +322,18 @@ export async function bootstrap(argsIn, deps, io) {
306
322
  });
307
323
  const outcome = await hooks.run("SessionStart", { source });
308
324
  if (outcome.decision === "block") {
309
- throw new StartupError("hook_failed", `SessionStart Hook 阻止启动:${outcome.reason ?? "(无原因)"}`, ExitCode.HostOrHook);
325
+ throw new StartupError("hook_failed", m().sessionStartBlocked(outcome.reason), ExitCode.HostOrHook);
310
326
  }
311
327
  sessionStartContext = outcome.additionalContext;
312
328
  const finalShutdown = shutdown;
313
329
  return {
314
330
  mode,
315
331
  paths: runtimePaths,
316
- config,
332
+ // [W6-S] /config 换配置:getter 跟随 assembly.config(/new 组装会话读它)
333
+ get config() {
334
+ return assembly.config;
335
+ },
336
+ replaceConfig: (next) => void (assembly.config = next),
317
337
  trust,
318
338
  resources,
319
339
  providers,
@@ -340,7 +360,7 @@ export async function bootstrap(argsIn, deps, io) {
340
360
  await shutdown("exit").catch(() => undefined);
341
361
  else
342
362
  await disposeHost(host);
343
- throw toStartupError(error, ExitCode.RuntimeError, "启动");
363
+ throw toStartupError(error, ExitCode.RuntimeError, m().steps.startup);
344
364
  }
345
365
  }
346
366
  /** 非交互模式接管 stdout:console.log / info / debug 改写到 stderr;返回还原函数。 */
@@ -362,14 +382,14 @@ export async function runCli(argv, deps, io) {
362
382
  try {
363
383
  const parsed = parseArgs(argv);
364
384
  if (parsed.kind !== "run")
365
- throw new UsageError("子命令应由 main 分派");
385
+ throw new UsageError(msg().cli.bootstrap.subcommandNotDispatched);
366
386
  args = parsed.args;
367
387
  }
368
388
  catch (error) {
369
389
  return reportError(error, io);
370
390
  }
371
391
  if (args.help) {
372
- io.stdout(HELP_TEXT);
392
+ io.stdout(helpText());
373
393
  return ExitCode.Ok;
374
394
  }
375
395
  // [W5-E] --mode acp:装配同 rpc(宿主看到的 mode 也是 rpc),分派到 ACP 服务端
@@ -377,7 +397,7 @@ export async function runCli(argv, deps, io) {
377
397
  if (acp)
378
398
  args = { ...args, mode: "rpc" };
379
399
  if (deps === undefined) {
380
- io.stderr("ama: 运行时尚未装配(集成批次通过 registerRuntimeDeps 注入实现)\n");
400
+ io.stderr(msg().cli.bootstrap.runtimeNotAssembled);
381
401
  return ExitCode.RuntimeError;
382
402
  }
383
403
  let runtime;
@@ -392,7 +412,7 @@ export async function runCli(argv, deps, io) {
392
412
  try {
393
413
  if (runtime.mode !== "interactive")
394
414
  for (const w of runtime.warnings)
395
- io.stderr(`ama: 警告:${w}\n`);
415
+ io.stderr(msg().cli.bootstrap.warning(w));
396
416
  // [W4-D] --from:旧会话的一条用户消息作提示(-p 时连图片,临时文件在 finally 删除)。
397
417
  const from = applyFromOption(args, runtime, io);
398
418
  cleanupFrom = from.cleanup;
@@ -401,7 +421,9 @@ export async function runCli(argv, deps, io) {
401
421
  ? (await import("../modes/acp/acp-mode.js")).runAcpMode
402
422
  : deps.modes[runtime.mode];
403
423
  if (runner === undefined)
404
- throw new AmaError("not_implemented", `模式 ${runtime.mode} 尚未装配`, { exitCode: 1 });
424
+ throw new AmaError("not_implemented", msg().cli.bootstrap.modeNotAssembled(runtime.mode), {
425
+ exitCode: 1,
426
+ });
405
427
  try {
406
428
  return await runner(runtime, context);
407
429
  }
@@ -409,7 +431,7 @@ export async function runCli(argv, deps, io) {
409
431
  const line = deps.modes.line;
410
432
  if (runtime.mode !== "interactive" || !isTerminalInitError(error) || line === undefined)
411
433
  throw error;
412
- io.stderr(`ama: 警告:终端初始化失败,降级为行式界面(${error.message})\n`);
434
+ io.stderr(msg().cli.bootstrap.terminalFallback(error.message));
413
435
  return await line(runtime, context);
414
436
  }
415
437
  }
@@ -424,7 +446,7 @@ export async function runCli(argv, deps, io) {
424
446
  }
425
447
  export function reportError(error, io, fallback = ExitCode.RuntimeError) {
426
448
  if (error instanceof UsageError) {
427
- io.stderr(`ama: ${error.message}\n(ama --help 查看用法)\n`);
449
+ io.stderr(msg().cli.bootstrap.usageError(error.message));
428
450
  return ExitCode.Usage;
429
451
  }
430
452
  const message = error instanceof Error ? error.message : String(error);
@@ -0,0 +1,58 @@
1
+ /**
2
+ * CLI 子命令的方向键选择(零依赖):TTY 下 raw mode 画一个编号选项列表,原地重画。
3
+ *
4
+ * - 按键:↑↓(与 Ctrl+P / Ctrl+N)移动、Enter 确认、数字直选、选项按键提示里的单个字母直选(`y` / `n`),
5
+ * Esc / Ctrl+C / stdin 结束 = 取消;
6
+ * - 结束后把列表收成一行「? 问题 答案」,恢复 raw 状态与光标,暂停 stdin;进程意外退出时也恢复;
7
+ * - 颜色与字形按环境:`NO_COLOR` / 非 TTY 输出无色,`AMA_ASCII` / 区域设置决定 ASCII 字形(字形表见
8
+ * docs/tui-design.md §2.2);
9
+ * - 输入不是可开 raw 的 TTY(管道、CI)时 {@link confirmContinue} 回落为原来的文本 `[y/N]` 问答。
10
+ */
11
+ export interface ChoiceInput {
12
+ isTTY?: boolean;
13
+ isRaw?: boolean;
14
+ setRawMode?(raw: boolean): unknown;
15
+ on(event: "data" | "end", listener: (chunk?: Buffer | string) => void): unknown;
16
+ off(event: "data" | "end", listener: (chunk?: Buffer | string) => void): unknown;
17
+ resume?(): unknown;
18
+ pause?(): unknown;
19
+ }
20
+ export interface ChoiceOption {
21
+ label: string;
22
+ /** 右侧按键提示(空格分隔);其中的单个字母同时是直选键。 */
23
+ keys?: string;
24
+ }
25
+ export interface PromptChoiceOptions {
26
+ question: string;
27
+ options: readonly ChoiceOption[];
28
+ /** 缺省选中的下标。 */
29
+ selected?: number;
30
+ /** 缺省 `process.stdin`。 */
31
+ input?: ChoiceInput;
32
+ /** 缺省写 stderr。 */
33
+ write?(text: string): void;
34
+ env?: NodeJS.ProcessEnv;
35
+ /** 输出是否 TTY(决定颜色);缺省看 stderr。 */
36
+ outputIsTTY?: boolean;
37
+ }
38
+ /** 能否用方向键选择:输入是 TTY 且能开 raw。 */
39
+ export declare function canPromptChoice(input?: ChoiceInput): boolean;
40
+ /** 一块输入切成单个按键(转义序列整体、其余逐字符)。 */
41
+ export declare function splitKeys(data: string): string[];
42
+ /** 方向键选择:返回选中的下标,取消返回 undefined。调用方先用 {@link canPromptChoice} 判断。 */
43
+ export declare function promptChoice(options: PromptChoiceOptions): Promise<number | undefined>;
44
+ export interface ConfirmOptions {
45
+ /** 缺省「继续?」。 */
46
+ question?: string;
47
+ input?: ChoiceInput & NodeJS.ReadableStream;
48
+ write?(text: string): void;
49
+ /** 文本回落时问句写到哪里,缺省 stderr。 */
50
+ output?: NodeJS.WritableStream;
51
+ env?: NodeJS.ProcessEnv;
52
+ outputIsTTY?: boolean;
53
+ }
54
+ /**
55
+ * 计费 / 写入前的确认:TTY 下方向键选择「继续 / 取消」(缺省取消,`y` / `n` 直选);
56
+ * 否则回落为文本 `继续?[y/N]`(只有 y / yes 算同意)。
57
+ */
58
+ export declare function confirmContinue(options?: ConfirmOptions): Promise<boolean>;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * CLI 子命令的方向键选择(零依赖):TTY 下 raw mode 画一个编号选项列表,原地重画。
3
+ *
4
+ * - 按键:↑↓(与 Ctrl+P / Ctrl+N)移动、Enter 确认、数字直选、选项按键提示里的单个字母直选(`y` / `n`),
5
+ * Esc / Ctrl+C / stdin 结束 = 取消;
6
+ * - 结束后把列表收成一行「? 问题 答案」,恢复 raw 状态与光标,暂停 stdin;进程意外退出时也恢复;
7
+ * - 颜色与字形按环境:`NO_COLOR` / 非 TTY 输出无色,`AMA_ASCII` / 区域设置决定 ASCII 字形(字形表见
8
+ * docs/tui-design.md §2.2);
9
+ * - 输入不是可开 raw 的 TTY(管道、CI)时 {@link confirmContinue} 回落为原来的文本 `[y/N]` 问答。
10
+ */
11
+ import { createInterface } from "node:readline/promises";
12
+ import { createTheme, defaultKeybindings, detectCapabilities, padToWidth, resolveAscii, visibleWidth, } from "../tui.js";
13
+ import { msg } from "../i18n/index.js";
14
+ const HIDE_CURSOR = "\x1b[?25l";
15
+ const SHOW_CURSOR = "\x1b[?25h";
16
+ /** 能否用方向键选择:输入是 TTY 且能开 raw。 */
17
+ export function canPromptChoice(input = process.stdin) {
18
+ return input.isTTY === true && typeof input.setRawMode === "function";
19
+ }
20
+ /** 一块输入切成单个按键(转义序列整体、其余逐字符)。 */
21
+ export function splitKeys(data) {
22
+ return data.match(/\x1b\[[0-9;?]*[ -/]*[@-~]|\x1bO[A-Za-z]|\x1b(?![[O])|[\s\S]/gu) ?? [];
23
+ }
24
+ /** 方向键选择:返回选中的下标,取消返回 undefined。调用方先用 {@link canPromptChoice} 判断。 */
25
+ export function promptChoice(options) {
26
+ const input = options.input ?? process.stdin;
27
+ const write = options.write ?? ((text) => void process.stderr.write(text));
28
+ const env = options.env ?? process.env;
29
+ const theme = createTheme("dark", {
30
+ caps: detectCapabilities(env, options.outputIsTTY ?? process.stderr.isTTY === true),
31
+ ascii: resolveAscii(undefined, env),
32
+ });
33
+ const g = theme.glyphs;
34
+ const items = options.options;
35
+ const n = items.length;
36
+ let selected = Math.max(0, Math.min(n - 1, options.selected ?? 0));
37
+ let drawn = 0;
38
+ const keyWidth = Math.max(0, ...items.map((o) => (o.keys ?? "").length));
39
+ const labelWidth = Math.max(...items.map((o) => visibleWidth(o.label)));
40
+ const question = `${theme.fg("accent", "?")} ${theme.bold(options.question)}`;
41
+ const frame = () => [
42
+ question,
43
+ ...items.map((item, i) => {
44
+ const on = i === selected;
45
+ const left = `${on ? g.prompt : " "} ${i + 1}. ${padToWidth(item.label, labelWidth)}`;
46
+ const keys = item.keys === undefined ? "" : ` ${theme.fg("dim", item.keys.padEnd(keyWidth))}`;
47
+ return (on ? theme.fg("accent", theme.bold(left)) : left) + keys;
48
+ }),
49
+ theme.fg("dim", msg().cli.choicePrompt.hint(`${g.arrowUp}${g.arrowDown}`, n)),
50
+ ];
51
+ const draw = (lines) => {
52
+ const up = drawn > 0 ? `\x1b[${drawn}A` : "";
53
+ write(`${up}\r\x1b[J${lines.join("\n")}\n`);
54
+ drawn = lines.length;
55
+ };
56
+ return new Promise((resolve) => {
57
+ const wasRaw = input.isRaw === true;
58
+ let done = false;
59
+ const restore = () => {
60
+ input.setRawMode?.(wasRaw);
61
+ write(SHOW_CURSOR);
62
+ };
63
+ const finish = (index) => {
64
+ if (done)
65
+ return;
66
+ done = true;
67
+ input.off("data", onData);
68
+ input.off("end", onEnd);
69
+ process.off("exit", restore);
70
+ const answer = index === undefined ? msg().cli.choicePrompt.cancelled : items[index].label;
71
+ draw([`${question} ${theme.fg("dim", answer)}`]);
72
+ restore();
73
+ input.pause?.();
74
+ resolve(index);
75
+ };
76
+ const onKey = (key) => {
77
+ const letter = /^[a-z]$/i.test(key) ? key.toLowerCase() : "";
78
+ const byLetter = letter === "" ? -1 : items.findIndex((o) => (o.keys ?? "").split(/\s+/).includes(letter));
79
+ if (byLetter !== -1)
80
+ return finish(byLetter);
81
+ if (defaultKeybindings.matches(key, "tui.select.cancel"))
82
+ return finish(undefined);
83
+ if (/^[1-9]$/.test(key) && Number(key) <= n)
84
+ return finish(Number(key) - 1);
85
+ if (key === "\r" || key === "\n")
86
+ return finish(selected);
87
+ if (defaultKeybindings.matches(key, "tui.select.up"))
88
+ selected = (selected + n - 1) % n;
89
+ else if (defaultKeybindings.matches(key, "tui.select.down"))
90
+ selected = (selected + 1) % n;
91
+ else
92
+ return;
93
+ draw(frame());
94
+ };
95
+ const onData = (chunk) => {
96
+ for (const key of splitKeys(String(chunk ?? ""))) {
97
+ if (done)
98
+ return;
99
+ onKey(key);
100
+ }
101
+ };
102
+ const onEnd = () => finish(undefined);
103
+ process.once("exit", restore);
104
+ input.setRawMode?.(true);
105
+ write(HIDE_CURSOR);
106
+ draw(frame());
107
+ input.on("data", onData);
108
+ input.on("end", onEnd);
109
+ input.resume?.();
110
+ });
111
+ }
112
+ /**
113
+ * 计费 / 写入前的确认:TTY 下方向键选择「继续 / 取消」(缺省取消,`y` / `n` 直选);
114
+ * 否则回落为文本 `继续?[y/N]`(只有 y / yes 算同意)。
115
+ */
116
+ export async function confirmContinue(options = {}) {
117
+ const m = msg().cli.choicePrompt;
118
+ const question = options.question ?? m.continueQuestion;
119
+ const input = options.input ?? process.stdin;
120
+ if (canPromptChoice(input)) {
121
+ const index = await promptChoice({
122
+ question,
123
+ options: [
124
+ { label: m.continue, keys: "y" },
125
+ { label: m.cancel, keys: "n Esc" },
126
+ ],
127
+ selected: 1,
128
+ input,
129
+ ...(options.write !== undefined ? { write: options.write } : {}),
130
+ ...(options.env !== undefined ? { env: options.env } : {}),
131
+ ...(options.outputIsTTY !== undefined ? { outputIsTTY: options.outputIsTTY } : {}),
132
+ });
133
+ return index === 0;
134
+ }
135
+ const rl = createInterface({ input, output: options.output ?? process.stderr });
136
+ try {
137
+ return /^y(es)?$/i.test((await rl.question(m.textQuestion(question))).trim());
138
+ }
139
+ finally {
140
+ rl.close();
141
+ }
142
+ }
@@ -11,6 +11,7 @@
11
11
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
12
12
  import { join } from "node:path";
13
13
  import { resolveCodemodeMode } from "../tools/presets.js";
14
+ import { msg } from "../i18n/index.js";
14
15
  export const NOTICES_FILE = "notices.json";
15
16
  const KEY = "codemodeNonStrictDefault";
16
17
  function readNotices(path) {
@@ -30,8 +31,7 @@ function readNotices(path) {
30
31
  return { version: 1 };
31
32
  }
32
33
  export function codemodeNoticeText(capability) {
33
- return (`Node ${capability.nodeMajor} < 25 且没有可用的操作系统沙箱:codemode 沙箱的网络未隔离,codemode 缺省关闭;` +
34
- "用 `--codemode on` 或 config 的 codemode.mode 开启(每个配置目录只提示一次)");
34
+ return msg().cli.codemodeNotice(capability.nodeMajor);
35
35
  }
36
36
  /** 需要提示时返回文案并记下(之后同一配置目录不再提示);不需要时 undefined。 */
37
37
  export function takeCodemodeNotice(input) {
@@ -18,6 +18,7 @@ import { agentSources, discoverAgents } from "../agents/discover.js";
18
18
  import { NO_AGENT_PROBE_ENV, SessionExternalAgents, registerExternalAgents, } from "../agents/external.js";
19
19
  import { hostRunnersOf } from "../host/api-impl.js";
20
20
  import { bindTaskAgents } from "../tools/task.js";
21
+ import { msg } from "../i18n/index.js";
21
22
  /** 同一装配材料只提示一次(`/new` 等会重新装配会话)。 */
22
23
  const warned = new WeakSet();
23
24
  export function loadAgentCatalog(deps) {
@@ -33,7 +34,7 @@ export function loadAgentCatalog(deps) {
33
34
  for (const warning of found.warnings)
34
35
  assembly.warn(warning);
35
36
  for (const dir of found.skippedUntrusted)
36
- assembly.warn(`项目未信任,跳过子 Agent 定义目录 ${dir}(--trust 后生效)`);
37
+ assembly.warn(msg().cli.composeAgents.untrustedAgentDir(dir));
37
38
  }
38
39
  return new AgentCatalog(found.agents);
39
40
  }
@@ -19,6 +19,7 @@
19
19
  * 配置从 `deps.assembly.config` 读(键与校验已在 config/schema-w5.ts,C0 统一加好)。
20
20
  */
21
21
  import { telemetryFactory } from "../agent/session-telemetry.js";
22
+ import { traceWriterFactory } from "../agent/session-trace-writer.js";
22
23
  import { createImageBudgetExtension } from "../agent/session-images.js";
23
24
  import { createLimitsExtension } from "../agent/limits.js";
24
25
  import { createRemindersExtension, remindersSettings } from "../agent/reminders.js";
@@ -37,6 +38,7 @@ export function composeExtensions(deps) {
37
38
  ({ core }) => createImageBudgetExtension(core),
38
39
  // [W5-A] createTelemetryExtension(...)
39
40
  telemetryFactory(deps.assembly.config.ui),
41
+ traceWriterFactory(), // [W6-C0] ama.trace(主会话与子会话都写)
40
42
  // [W5-E] 外部 Agent 记账 → SessionStats.external(只主会话)
41
43
  ({ core }) => core.depth > 0 ? undefined : createExternalStatsExtension(() => core.manager.branch()),
42
44
  createSubagentsFactory(deps), // [W5-G] 子 Agent 任务注册表
@@ -0,0 +1,53 @@
1
+ /**
2
+ * 记忆的组装(docs/wave6-plan.md §3、D8、D9、D11、D12)。[W6-M]
3
+ *
4
+ * - 开关:独立终端看合并后的 `memory.enabled`(用户级 / profile.config;项目级只能设 false;`--memory` /
5
+ * `--no-memory`;`AMA_MEMORY=0|1` 经 bootstrap 并入命令行覆盖,命令行优先)。缺省关闭:不建运行期、不读盘、
6
+ * 不注册工具、不渲染节。
7
+ * - 嵌入宿主(有 profile;SDK `createAgentSession`):只看 `profile.memory = { enabled, dir }`,作用域只有
8
+ * `workspace`(= dir),不读用户级;合并配置里显式 `memory.enabled: false`(项目级、`--no-memory`、
9
+ * `AMA_MEMORY=0`)仍可关掉。
10
+ * - 项目作用域要求项目已受信任,否则跳过(`/memory` 提示)。
11
+ * - 系统节:会话开始(新会话)渲染一次;resume / fork 沿用会话里已有的 `memory` 节;压缩结束后重渲染
12
+ * (`compaction_end` 时 `updateSystem`,压缩本就是前缀重置点);`/memory reload` 显式重渲染。
13
+ */
14
+ import type { AgentSessionImpl } from "../agent/session.js";
15
+ import type { AgentSession } from "../agent/types.js";
16
+ import type { AmaConfig, ProfileMemoryOptions } from "../config/types.js";
17
+ import { MemoryRuntime } from "../memory/runtime.js";
18
+ import type { SessionManager } from "../session/manager.js";
19
+ /** `AMA_MEMORY=0|1`(也认 true / false / on / off);其它值或未设 → undefined。 */
20
+ export declare function memoryEnvOverride(env: Readonly<Record<string, string | undefined>>): boolean | undefined;
21
+ export interface MemorySetupInput {
22
+ config: Pick<AmaConfig, "memory">;
23
+ cwd: string;
24
+ dataDir: string;
25
+ trusted: boolean;
26
+ /** 嵌入宿主:profile 存在(或 SDK 会话)时给出(`memory` 可缺省 = 禁用)。 */
27
+ embedded?: {
28
+ memory?: ProfileMemoryOptions | undefined;
29
+ } | undefined;
30
+ today?(): string;
31
+ }
32
+ /** 按配置建运行期;关闭时返回 undefined(什么都不做)。 */
33
+ export declare function resolveMemory(input: MemorySetupInput): MemoryRuntime | undefined;
34
+ /** 会话的记忆运行期(未开启 → undefined)。 */
35
+ export declare function memoryOf(session: AgentSession): MemoryRuntime | undefined;
36
+ /**
37
+ * 新会话渲染当前索引;会话里已有 system 状态(resume / fork)时沿用其中的 `memory` 节(可能没有)。
38
+ * 未开启 → undefined。
39
+ */
40
+ export declare function initialMemorySection(runtime: MemoryRuntime | undefined, manager: Pick<SessionManager, "branch">): string | undefined;
41
+ /** 把 `memory` 节并进静态系统输入(未开启时原样返回同一对象,字节不变)。 */
42
+ export declare function withMemorySection<T extends {
43
+ memory?: string;
44
+ }>(system: T, runtime: MemoryRuntime | undefined, manager: Pick<SessionManager, "branch">): T;
45
+ /** 会话建好后:登记运行期,压缩结束后重渲染 `memory` 节。 */
46
+ export declare function attachMemory(session: AgentSessionImpl, runtime: MemoryRuntime | undefined): void;
47
+ /**
48
+ * `/memory reload`:按磁盘重渲染 `memory` 节。返回 undefined = 会话未开启记忆;`changed` = 节有变化
49
+ * (下次请求产生一条 system 补丁,缓存前缀断一次)。
50
+ */
51
+ export declare function reloadMemorySection(session: AgentSession): {
52
+ changed: boolean;
53
+ } | undefined;