@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
@@ -10,6 +10,7 @@ import { CHANNEL_NAME_PATTERN } from "../../config/types.js";
10
10
  import { padToWidth, visibleWidth } from "../../tui/ansi.js";
11
11
  import { UsageError } from "../args.js";
12
12
  import { compactTokens } from "./model-meta.js";
13
+ import { msg } from "../../i18n/index.js";
13
14
  export const PROBE_APIS = [
14
15
  "openai-completions",
15
16
  "openai-responses",
@@ -21,14 +22,14 @@ const API_CHOICES = [...PROBE_APIS, "google-generative-ai"];
21
22
  export function parseChannelSpec(spec) {
22
23
  const m = /^([^=]+)=([^@]+)@(.+)$/.exec(spec.trim());
23
24
  if (!m)
24
- throw new UsageError(`--channel 应为 <名字>=<协议>@<地址>:${spec}`);
25
+ throw new UsageError(msg().subcommands.providersPlan.channelSpec(spec));
25
26
  const [, name = "", api = "", baseUrl = ""] = m;
26
27
  if (!CHANNEL_NAME_PATTERN.test(name))
27
- throw new UsageError(`渠道名不合法:${name}`);
28
+ throw new UsageError(msg().subcommands.providersPlan.channelName(name));
28
29
  if (!API_CHOICES.includes(api))
29
- throw new UsageError(`--channel 的协议应为 ${API_CHOICES.join(" | ")}(收到 ${api})`);
30
+ throw new UsageError(msg().subcommands.providersPlan.channelApi(API_CHOICES, api));
30
31
  if (!/^https?:\/\//.test(baseUrl))
31
- throw new UsageError(`--channel 的地址应为 http(s) URL:${baseUrl}`);
32
+ throw new UsageError(msg().subcommands.providersPlan.channelUrl(baseUrl));
32
33
  return { name, api: api, baseUrl: baseUrl.replace(/\/+$/, "") };
33
34
  }
34
35
  /** 从 `--base-url` 推出候选渠道;`api` 给定(非 auto)时只留对应的一个。 */
@@ -43,7 +44,7 @@ export function defaultChannels(baseUrl, api) {
43
44
  if (api === undefined || api === "auto")
44
45
  return all;
45
46
  if (!API_CHOICES.includes(api))
46
- throw new UsageError(`--api 的取值应为 ${[...PROBE_APIS, "auto"].join(" | ")}(收到 ${api})`);
47
+ throw new UsageError(msg().subcommands.common.invalidChoice("--api", [...PROBE_APIS, "auto"], api));
47
48
  const one = all.find((c) => c.api === api);
48
49
  return [one ?? { name: apiShortName(api), api: api, baseUrl: base }];
49
50
  }
@@ -166,32 +167,30 @@ export function mergeProvider(existing, input) {
166
167
  config.models = models;
167
168
  return { config, addedChannels, addedModels };
168
169
  }
169
- const STATUS_TEXT = {
170
- ok: "探测通过",
171
- unprobed: "未探测",
172
- failed: "探测失败,不写入",
173
- "no-tools": "不支持工具调用,不写入",
174
- "no-channel": "候选渠道都不支持,不写入",
175
- existing: "已存在,未改动",
176
- };
170
+ function statusText(status) {
171
+ const t = msg().subcommands.providersPlan.status;
172
+ return status === "no-tools" ? t.noTools : status === "no-channel" ? t.noChannel : t[status];
173
+ }
177
174
  function cost(fields) {
178
175
  return fields.cost !== undefined ? `$${fields.cost.input}/${fields.cost.output}` : "—";
179
176
  }
180
177
  function yesNo(value) {
181
- return value === undefined ? "?" : value ? "是" : "否";
178
+ const t = msg().subcommands.providersPlan;
179
+ return value === undefined ? "?" : value ? t.yes : t.no;
182
180
  }
183
181
  /** 表格:id、渠道、上下文、输出、图像、推理、工具、价格($/M 入/出)、状态、models.dev 匹配。 */
184
182
  export function renderTable(plans) {
183
+ const h = msg().subcommands.providersPlan.head;
185
184
  const head = [
186
- "模型",
187
- "渠道",
188
- "上下文",
189
- "输出",
190
- "图像",
191
- "推理",
192
- "工具",
193
- "价格$/M",
194
- "状态",
185
+ h.model,
186
+ h.channel,
187
+ h.context,
188
+ h.output,
189
+ h.image,
190
+ h.reasoning,
191
+ h.tools,
192
+ h.price,
193
+ h.status,
195
194
  "models.dev",
196
195
  ];
197
196
  const rows = plans.map((p) => [
@@ -199,11 +198,11 @@ export function renderTable(plans) {
199
198
  p.channels.length > 0 ? p.channels.join(",") : "—",
200
199
  compactTokens(p.fields.contextWindow),
201
200
  compactTokens(p.fields.maxTokens),
202
- p.fields.input === undefined ? "?" : p.fields.input.includes("image") ? "是" : "否",
201
+ p.fields.input === undefined ? "?" : yesNo(p.fields.input.includes("image")),
203
202
  yesNo(p.fields.reasoning),
204
203
  yesNo(p.fields.toolCall),
205
204
  cost(p.fields),
206
- STATUS_TEXT[p.status],
205
+ statusText(p.status),
207
206
  matchLabel(p.match),
208
207
  ]);
209
208
  const widths = head.map((h, i) => Math.max(visibleWidth(h), ...rows.map((r) => visibleWidth(r[i] ?? ""))));
@@ -5,6 +5,7 @@
5
5
  import { withCustomDefaults } from "../../ai/providers/catalog.js";
6
6
  import { materializeModel } from "../../ai/providers/registry.js";
7
7
  import { ProbeProgress, ProbeScheduler } from "./probe-runner.js";
8
+ import { msg } from "../../i18n/index.js";
8
9
  /** 渠道的探测用供应商数据(key 由调用方传入)。 */
9
10
  function probeProvider(id, channel) {
10
11
  return {
@@ -33,8 +34,8 @@ export async function probeChannels(input) {
33
34
  concurrency: input.concurrency,
34
35
  timeoutMs: input.timeoutMs,
35
36
  retryDelayMs: input.retryDelayMs,
36
- onThrottle: (n) => progress.line(` 遇到 429 限流,并发降到 ${n},稍后重试一次\n`),
37
- onRecover: (n) => progress.line(` 一段时间没再限流,并发回升到 ${n}\n`),
37
+ onThrottle: (n) => progress.line(msg().subcommands.probe.throttled(n)),
38
+ onRecover: (n) => progress.line(msg().subcommands.probe.recovered(n)),
38
39
  });
39
40
  let printed = 0;
40
41
  /** 按模型顺序输出:前面的模型都探完才输出后面的。 */
@@ -55,15 +56,13 @@ export async function probeChannels(input) {
55
56
  result.ok.push(name);
56
57
  else {
57
58
  result.error = firstLine(outcome.error);
58
- failed.push(`${name}:${result.error}`);
59
+ failed.push({ name, error: result.error });
59
60
  }
60
61
  }
61
62
  if (!complete && result.ok.length === 0)
62
63
  continue;
63
64
  results.set(id, result);
64
- progress.line(` ${id} ${result.ok.length > 0 ? result.ok.join(", ") : "全部失败"}` +
65
- `${failed.length > 0 ? `(失败 ${failed.join(";")})` : ""}` +
66
- `${complete ? "" : "(探测提前停止,部分渠道未探)"}\n`);
65
+ progress.line(msg().subcommands.probe.modelLine(id, result.ok, failed, complete));
67
66
  }
68
67
  };
69
68
  await scheduler.run(tasks.length, async (index) => {
@@ -8,14 +8,14 @@
8
8
  * - list / channels:供应商 → 渠道 → 模型数与 key 来源(从不显示 key)。remove:删配置与 auth.json 条目。
9
9
  *
10
10
  * 计费:`--probe` 每模型每渠道一次最小请求(并发执行,见到首个流事件即判可用并断开,见
11
- * probe-runner.ts);执行前打印预估,TTY 问 y/N,非 TTY 必须 `--yes`。
11
+ * probe-runner.ts);执行前打印预估,TTY 下方向键选「继续 / 取消」(choice-prompt.ts,y / n 直选),非 TTY 必须 `--yes`。
12
12
  */
13
13
  import type { AmaConfig } from "../../config/types.js";
14
14
  import type { CliIo, RuntimeDeps } from "../deps.js";
15
15
  import { type UserLevel } from "./context.js";
16
16
  export declare const DEFAULT_MAX_REQUESTS = 60;
17
17
  export declare const DEFAULT_LIMIT = 30;
18
- export declare const PROVIDERS_USAGE = "\u7528\u6CD5\uFF1Aama providers add <id> --base-url <url> [--channel <\u540D\u5B57>=<\u534F\u8BAE>@<\u5730\u5740> \u2026]\n [--api openai-completions|openai-responses|anthropic-messages|auto]\n [--key-env <VAR>] [--probe] [--limit N] [--probe-models a,b,\u2026]\n [--max-requests N] [--concurrency N] [--probe-timeout ms]\n [--prefer chat,responses,messages] [--include-no-tools] [--yes]\n ama providers list\n ama providers channels <id>\n ama providers remove <id>\n ama providers refresh <id> [--probe] [--limit N] [--probe-models a,b,\u2026] [--max-requests N]\n [--concurrency N] [--probe-timeout ms] [--yes]\n";
18
+ export declare function providersUsage(): string;
19
19
  export interface Ctx {
20
20
  io: CliIo;
21
21
  deps: Pick<RuntimeDeps, "providers">;
@@ -8,10 +8,9 @@
8
8
  * - list / channels:供应商 → 渠道 → 模型数与 key 来源(从不显示 key)。remove:删配置与 auth.json 条目。
9
9
  *
10
10
  * 计费:`--probe` 每模型每渠道一次最小请求(并发执行,见到首个流事件即判可用并断开,见
11
- * probe-runner.ts);执行前打印预估,TTY 问 y/N,非 TTY 必须 `--yes`。
11
+ * probe-runner.ts);执行前打印预估,TTY 下方向键选「继续 / 取消」(choice-prompt.ts,y / n 直选),非 TTY 必须 `--yes`。
12
12
  */
13
13
  import { existsSync } from "node:fs";
14
- import { createInterface } from "node:readline/promises";
15
14
  import { describeModelsDev, loadModelsDevIndex } from "../../ai/providers/models-dev-cache.js";
16
15
  import { modelsDevFields } from "../../ai/providers/models-dev.js";
17
16
  import { PROVIDER_ID_PATTERN, setAuthKey } from "../../config/auth-file.js";
@@ -19,6 +18,7 @@ import { loadConfigFile } from "../../config/load.js";
19
18
  import { CONFIG_FILE_VERSION } from "../../config/types.js";
20
19
  import { writeConfigFile } from "../../config/write.js";
21
20
  import { parseSubArgs, UsageError } from "../args.js";
21
+ import { confirmContinue } from "../choice-prompt.js";
22
22
  import { pickByPrice } from "../default-model.js";
23
23
  import { ExitCode } from "../exit-codes.js";
24
24
  import { extractKey } from "./auth.js";
@@ -28,19 +28,12 @@ import { DISCOVER_TIMEOUT_MS } from "./models-discover.js";
28
28
  import { describeProbePlan, parseProbeTuning } from "./probe-runner.js";
29
29
  import { probeChannels } from "./providers-probe.js";
30
30
  import { DEFAULT_PREFER, capRequests, defaultChannels, hintedChannels, listingTarget, mergeProvider, orderChannels, parseChannelSpec, parseModelList, probeSelection, renderTable, } from "./providers-plan.js";
31
+ import { msg } from "../../i18n/index.js";
31
32
  export const DEFAULT_MAX_REQUESTS = 60;
32
33
  export const DEFAULT_LIMIT = 30;
33
- export const PROVIDERS_USAGE = `用法:ama providers add <id> --base-url <url> [--channel <名字>=<协议>@<地址> …]
34
- [--api openai-completions|openai-responses|anthropic-messages|auto]
35
- [--key-env <VAR>] [--probe] [--limit N] [--probe-models a,b,…]
36
- [--max-requests N] [--concurrency N] [--probe-timeout ms]
37
- [--prefer chat,responses,messages] [--include-no-tools] [--yes]
38
- ama providers list
39
- ama providers channels <id>
40
- ama providers remove <id>
41
- ama providers refresh <id> [--probe] [--limit N] [--probe-models a,b,…] [--max-requests N]
42
- [--concurrency N] [--probe-timeout ms] [--yes]
43
- `;
34
+ export function providersUsage() {
35
+ return msg().subcommands.providers.usage;
36
+ }
44
37
  const VALUE_OPTIONS = [
45
38
  "base-url",
46
39
  "api",
@@ -62,7 +55,7 @@ function intValue(ctx, name, fallback) {
62
55
  return fallback;
63
56
  const n = Number(raw);
64
57
  if (!Number.isInteger(n) || n < 1)
65
- throw new UsageError(`--${name} 需要正整数:${raw}`);
58
+ throw new UsageError(msg().subcommands.providers.positiveInt(name, raw));
66
59
  return n;
67
60
  }
68
61
  function list(raw) {
@@ -76,20 +69,14 @@ export function userConfig(level) {
76
69
  }
77
70
  async function confirm(io, question) {
78
71
  io.stderr(question);
79
- const rl = createInterface({ input: process.stdin, output: process.stderr });
80
- try {
81
- return /^y(es)?$/i.test((await rl.question("继续?[y/N] ")).trim());
82
- }
83
- finally {
84
- rl.close();
85
- }
72
+ return confirmContinue({ env: io.env });
86
73
  }
87
74
  /** --yes / TTY 确认;非 TTY 且没有 --yes 返回 false 并提示(调用方退出 2)。 */
88
75
  async function approved(ctx, what) {
89
76
  if (ctx.flags.has("yes"))
90
77
  return true;
91
78
  if (!ctx.io.stdinIsTTY) {
92
- ctx.io.stderr(`ama: ${what},非交互环境需加 --yes\n`);
79
+ ctx.io.stderr(msg().subcommands.providers.needsYes(what));
93
80
  return "usage";
94
81
  }
95
82
  return confirm(ctx.io, `${what}\n`);
@@ -144,10 +131,8 @@ async function plan(ctx, input) {
144
131
  const max = intValue(ctx, "max-requests", DEFAULT_MAX_REQUESTS);
145
132
  const capped = capRequests(selected, tryChannels, max);
146
133
  const tuning = parseProbeTuning(ctx.values);
147
- io.stdout(`\n探测:${capped.ids.length} 个模型、${capped.requests} 次最小请求(每模型每渠道 1 次,上限 ${max})` +
148
- `${capped.dropped > 0 ? `;另有 ${capped.dropped} 个超出上限未探测` : ""}\n` +
149
- `${describeProbePlan(capped.requests, tuning.concurrency, tuning.timeoutMs)}\n`);
150
- const ok = await approved(ctx, `将发 ${capped.requests} 次计费请求并写入 ${ctx.level.userConfigPath}`);
134
+ io.stdout(msg().subcommands.providers.probePlan(capped.ids.length, capped.requests, max, capped.dropped) + `${describeProbePlan(capped.requests, tuning.concurrency, tuning.timeoutMs)}\n`);
135
+ const ok = await approved(ctx, msg().subcommands.providers.confirmProbe(capped.requests, ctx.level.userConfigPath));
151
136
  if (ok === "usage")
152
137
  return { plans: [], cancelled: ExitCode.Usage };
153
138
  if (!ok)
@@ -203,10 +188,10 @@ async function obtainKey(ctx, id, registry) {
203
188
  const keyEnv = ctx.values.get("key-env");
204
189
  if (keyEnv !== undefined) {
205
190
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(keyEnv))
206
- throw new UsageError(`--key-env 不是合法的变量名:${keyEnv}`);
191
+ throw new UsageError(msg().subcommands.providers.invalidKeyEnv(keyEnv));
207
192
  const value = ctx.io.env[keyEnv]?.trim();
208
193
  if (!value)
209
- ctx.io.stderr(`ama: 警告:环境变量 ${keyEnv} 未设置,列模型与探测将不带 key\n`);
194
+ ctx.io.stderr(msg().subcommands.providers.keyEnvUnset(keyEnv));
210
195
  return { apiKey: value || undefined, configValue: `$${keyEnv}` };
211
196
  }
212
197
  if (registry.get(id) !== undefined) {
@@ -215,22 +200,23 @@ async function obtainKey(ctx, id, registry) {
215
200
  return { apiKey: existing.apiKey };
216
201
  }
217
202
  if (ctx.io.stdinIsTTY)
218
- ctx.io.stderr(`输入 ${id} 的 API key(不回显),回车结束:`);
203
+ ctx.io.stderr(msg().subcommands.providers.keyPrompt(id));
219
204
  const key = extractKey(await ctx.io.readStdin());
220
205
  if (ctx.io.stdinIsTTY)
221
206
  ctx.io.stderr("\n");
222
207
  if (key === "")
223
- throw new UsageError("没有从 stdin 读到 key(或用 --key-env <VAR>)");
208
+ throw new UsageError(msg().subcommands.providers.noKeyOnStdin);
224
209
  return { apiKey: key, store: key };
225
210
  }
226
211
  async function add(ctx, id, refresh) {
227
212
  const { io, level } = ctx;
213
+ const m = msg().subcommands.providers;
228
214
  if (!PROVIDER_ID_PATTERN.test(id) || id.includes("@"))
229
- throw new UsageError(`供应商 id 不合法:${id}`);
215
+ throw new UsageError(m.invalidId(id));
230
216
  const config = userConfig(level);
231
217
  const existing = config.providers?.[id];
232
218
  if (refresh && existing === undefined) {
233
- io.stderr(`ama: ${level.userConfigPath} 里没有供应商 ${id}(先 ama providers add)\n`);
219
+ io.stderr(m.missingInConfig(level.userConfigPath, id));
234
220
  return ExitCode.Usage;
235
221
  }
236
222
  const registry = await buildRegistry(level, io, ctx.deps);
@@ -242,28 +228,28 @@ async function add(ctx, id, refresh) {
242
228
  else {
243
229
  const baseUrl = ctx.values.get("base-url");
244
230
  if (baseUrl === undefined)
245
- throw new UsageError("ama providers add 需要 --base-url <url> 或 --channel");
231
+ throw new UsageError(m.needsBaseUrl);
246
232
  if (!/^https?:\/\//.test(baseUrl))
247
- throw new UsageError(`--base-url 应为 http(s) URL:${baseUrl}`);
233
+ throw new UsageError(m.baseUrlNotHttp(baseUrl));
248
234
  candidates = defaultChannels(baseUrl, ctx.values.get("api"));
249
235
  }
250
236
  const target = listingTarget(candidates);
251
237
  if (target === undefined)
252
- throw new UsageError(`${id} 没有可用的渠道`);
238
+ throw new UsageError(m.noChannel(id));
253
239
  const key = await obtainKey(ctx, id, registry);
254
240
  let listed;
255
241
  try {
256
242
  listed = await fetchModelList(target, key.apiKey);
257
243
  }
258
244
  catch (error) {
259
- io.stderr(`ama: ${id} 模型列表获取失败:${error.message}\n`);
245
+ io.stderr(m.listFailed(id, error.message));
260
246
  return ExitCode.RuntimeError;
261
247
  }
262
- io.stdout(`${id}:发现 ${listed.length} 个模型(${target.url})\n`);
248
+ io.stdout(m.discovered(id, listed.length, target.url));
263
249
  // models.dev 只读本地(快照 ⊕ `ama models refresh` 的覆盖),不联网。
264
250
  const mdIndex = loadModelsDevIndex(level.dataDir);
265
251
  io.stdout(`${describeModelsDev(level.dataDir)}\n`);
266
- io.stdout(`候选渠道:${candidates.map((c) => `${c.name}(${c.api} ${c.baseUrl})`).join(" · ")}\n`);
252
+ io.stdout(m.candidates(candidates));
267
253
  const existingIds = new Set((existing?.models ?? []).map((m) => m.id));
268
254
  const result = await plan(ctx, {
269
255
  id,
@@ -281,7 +267,7 @@ async function add(ctx, id, refresh) {
281
267
  if (refresh) {
282
268
  const gone = [...existingIds].filter((m) => !listed.some((l) => l.id === m));
283
269
  if (gone.length > 0)
284
- io.stdout(`上游已不再列出(未删除):${gone.join(", ")}\n`);
270
+ io.stdout(m.goneUpstream(gone));
285
271
  }
286
272
  const writable = result.plans.filter((p) => p.status === "ok" || p.status === "unprobed");
287
273
  const legacy = existing !== undefined && existing.channels === undefined;
@@ -296,7 +282,6 @@ async function add(ctx, id, refresh) {
296
282
  models: writable,
297
283
  prefer: list(ctx.values.get("prefer")) ?? [...DEFAULT_PREFER],
298
284
  });
299
- const keyNote = key.store !== undefined ? `;key → ${level.authFile}(0600)` : "";
300
285
  // 还没有缺省模型时按价格规则挑一个写进 defaultModel(default-model.ts 的 pickByPrice);
301
286
  // 探测过时只在探测通过的模型里挑
302
287
  const verified = writable.filter((p) => p.status === "ok");
@@ -308,26 +293,30 @@ async function add(ctx, id, refresh) {
308
293
  toolCall: p.fields.toolCall,
309
294
  })))
310
295
  : undefined;
311
- const defaultNote = defaultPick !== undefined ? `;defaultModel → ${id}/${defaultPick.id}` : "";
312
- const summary = `\n将写入 ${level.userConfigPath}:${id} 新增渠道 ${merged.addedChannels.join(", ") || "无"},` +
313
- `新增模型 ${merged.addedModels.length} 个${keyNote}${defaultNote}`;
314
- io.stdout(`${summary}\n`);
296
+ io.stdout(m.writeSummary({
297
+ path: level.userConfigPath,
298
+ id,
299
+ channels: merged.addedChannels,
300
+ models: merged.addedModels.length,
301
+ authFile: key.store !== undefined ? level.authFile : undefined,
302
+ defaultModel: defaultPick !== undefined ? `${id}/${defaultPick.id}` : undefined,
303
+ }));
315
304
  if (defaultPick !== undefined)
316
- io.stdout(` 选 ${defaultPick.id}:${defaultPick.reason}\n`);
305
+ io.stdout(m.defaultPick(defaultPick.id, defaultPick.reason));
317
306
  else if (level.merged.config.defaultModel === undefined && writable.length > 0)
318
- io.stdout(" 未设置 defaultModel:没有同时支持工具调用、上下文 ≥ 64k 且有价格的模型;用 ama config edit 设置\n");
307
+ io.stdout(m.noDefaultPick);
319
308
  if (merged.addedModels.length === 0 &&
320
309
  merged.addedChannels.length === 0 &&
321
310
  key.store === undefined) {
322
- io.stdout("没有要写入的内容\n");
311
+ io.stdout(m.nothingToWrite);
323
312
  return result.stopped !== undefined ? ExitCode.RuntimeError : ExitCode.Ok;
324
313
  }
325
314
  if (!ctx.flags.has("probe")) {
326
- const ok = await approved(ctx, "确认写入");
315
+ const ok = await approved(ctx, m.confirmWrite);
327
316
  if (ok === "usage")
328
317
  return ExitCode.Usage;
329
318
  if (!ok) {
330
- io.stderr("ama: 已取消\n");
319
+ io.stderr(msg().subcommands.common.cancelled);
331
320
  return ExitCode.Ok;
332
321
  }
333
322
  }
@@ -339,14 +328,14 @@ async function add(ctx, id, refresh) {
339
328
  writeConfigFile(level.userConfigPath, config, { backup: true });
340
329
  if (key.store !== undefined)
341
330
  setAuthKey(level.authFile, id, key.store);
342
- io.stdout(`已写入 ${level.userConfigPath}${backup ? "(原文件备份为 config.json.bak)" : ""}\n`);
331
+ io.stdout(m.written(level.userConfigPath, backup));
343
332
  const sample = defaultPick?.id ??
344
333
  result.plans.find((p) => p.status === "ok" && merged.addedModels.includes(p.id))?.id ??
345
334
  merged.addedModels[0];
346
335
  if (sample !== undefined)
347
- io.stdout(`试试:ama -p "hi" --model ${id}/${sample}\n`);
336
+ io.stdout(m.tryIt(`${id}/${sample}`));
348
337
  if (result.stopped !== undefined) {
349
- io.stderr(`ama: 探测提前停止(${result.stopped})\n`);
338
+ io.stderr(m.probeStopped(result.stopped));
350
339
  return ExitCode.RuntimeError;
351
340
  }
352
341
  return ExitCode.Ok;
@@ -381,7 +370,7 @@ function takeChannels(argv) {
381
370
  if (token === "--channel") {
382
371
  const value = argv[++i];
383
372
  if (value === undefined || value === "")
384
- throw new UsageError("--channel 需要一个值");
373
+ throw new UsageError(msg().subcommands.providers.channelNeedsValue);
385
374
  specs.push(value);
386
375
  }
387
376
  else if (token.startsWith("--channel="))
@@ -396,11 +385,11 @@ export async function runProviders(argv, io, deps) {
396
385
  const { positionals, values, flags } = parseSubArgs(rest, VALUE_OPTIONS, FLAG_OPTIONS);
397
386
  const action = positionals[0];
398
387
  if (flags.has("help") || action === undefined) {
399
- io.stdout(PROVIDERS_USAGE);
388
+ io.stdout(providersUsage());
400
389
  return flags.has("help") ? ExitCode.Ok : ExitCode.Usage;
401
390
  }
402
391
  if (deps === undefined) {
403
- io.stderr("ama: providers 尚未装配(供应商注册表由集成批次注入)\n");
392
+ io.stderr(msg().subcommands.common.notAssembled("providers"));
404
393
  return ExitCode.RuntimeError;
405
394
  }
406
395
  const level = loadUserLevel(io, {
@@ -408,14 +397,14 @@ export async function runProviders(argv, io, deps) {
408
397
  authFile: values.get("auth-file"),
409
398
  });
410
399
  for (const warning of level.warnings)
411
- io.stderr(`ama: 警告:${warning}\n`);
400
+ io.stderr(msg().subcommands.common.warning(warning));
412
401
  const ctx = { io, deps, level, values, flags, channelSpecs: specs };
413
402
  const target = positionals[1];
414
403
  const need = () => {
415
404
  if (target === undefined)
416
- throw new UsageError(`ama providers ${action} 需要 <id>`);
405
+ throw new UsageError(msg().subcommands.common.needsArg(`ama providers ${action}`, "<id>"));
417
406
  if (positionals.length > 2)
418
- throw new UsageError(`多余的参数:${positionals.slice(2).join(" ")}`);
407
+ throw new UsageError(msg().subcommands.common.extraArgs(positionals.slice(2).join(" ")));
419
408
  return target;
420
409
  };
421
410
  switch (action) {
@@ -430,6 +419,6 @@ export async function runProviders(argv, io, deps) {
430
419
  case "remove":
431
420
  return removeProvider(ctx, need());
432
421
  default:
433
- throw new UsageError(`未知的 providers 子命令:${action}`);
422
+ throw new UsageError(msg().subcommands.common.unknownSubcommand("providers", action));
434
423
  }
435
424
  }
@@ -6,5 +6,5 @@
6
6
  * - 导出内容先脱敏(session/redact.ts),格式说明见 docs/sessions.md「导出」。
7
7
  */
8
8
  import type { CliIo } from "../deps.js";
9
- export declare const SESSIONS_EXPORT_USAGE = "\u7528\u6CD5\uFF1Aama sessions export <id> [--format md|json|jsonl] [--output <\u6587\u4EF6>] [--branch leaf|all]\n [--session-dir <\u76EE\u5F55>]\n";
9
+ export declare function sessionsExportUsage(): string;
10
10
  export declare function runSessionsExport(argv: readonly string[], io: CliIo): Promise<number>;
@@ -12,9 +12,10 @@ import { renderExport } from "../../session/export.js";
12
12
  import { findSessionFileReadOnly, readSessionReadOnly } from "../../session/scan.js";
13
13
  import { parseSubArgs, UsageError } from "../args.js";
14
14
  import { ExitCode } from "../exit-codes.js";
15
- export const SESSIONS_EXPORT_USAGE = `用法:ama sessions export <id> [--format md|json|jsonl] [--output <文件>] [--branch leaf|all]
16
- [--session-dir <目录>]
17
- `;
15
+ import { msg } from "../../i18n/index.js";
16
+ export function sessionsExportUsage() {
17
+ return msg().subcommands.sessionsExport.usage;
18
+ }
18
19
  const FORMATS = ["md", "json", "jsonl"];
19
20
  const BRANCHES = ["leaf", "all"];
20
21
  export async function runSessionsExport(argv, io) {
@@ -25,21 +26,21 @@ export async function runSessionsExport(argv, io) {
25
26
  "session-dir",
26
27
  ]);
27
28
  if (flags.has("help")) {
28
- io.stdout(SESSIONS_EXPORT_USAGE);
29
+ io.stdout(sessionsExportUsage());
29
30
  return ExitCode.Ok;
30
31
  }
31
32
  const [id, extra] = positionals;
32
33
  if (id === undefined)
33
- throw new UsageError("ama sessions export 需要 <id>");
34
+ throw new UsageError(msg().subcommands.common.needsArg("ama sessions export", "<id>"));
34
35
  if (extra !== undefined)
35
- throw new UsageError(`多余的参数:${extra}`);
36
+ throw new UsageError(msg().subcommands.common.extraArgs(extra));
36
37
  const format = (values.get("format") ?? "md");
37
38
  if (!FORMATS.includes(format)) {
38
- throw new UsageError(`--format 的取值应为 ${FORMATS.join(" | ")}(收到 ${format})`);
39
+ throw new UsageError(msg().subcommands.common.invalidChoice("--format", FORMATS, format));
39
40
  }
40
41
  const branch = (values.get("branch") ?? "leaf");
41
42
  if (!BRANCHES.includes(branch)) {
42
- throw new UsageError(`--branch 的取值应为 ${BRANCHES.join(" | ")}(收到 ${branch})`);
43
+ throw new UsageError(msg().subcommands.common.invalidChoice("--branch", BRANCHES, branch));
43
44
  }
44
45
  const dirFlag = values.get("session-dir");
45
46
  const root = dirFlag !== undefined
@@ -54,6 +55,6 @@ export async function runSessionsExport(argv, io) {
54
55
  }
55
56
  const target = resolve(io.cwd, expandHome(output, { env: io.env }));
56
57
  writeFileSync(target, text, { mode: 0o600 });
57
- io.stderr(`已导出到 ${target}\n`);
58
+ io.stderr(msg().subcommands.sessionsExport.exported(target));
58
59
  return ExitCode.Ok;
59
60
  }
@@ -8,6 +8,6 @@
8
8
  */
9
9
  import { type SearchHit } from "../../session/search.js";
10
10
  import type { CliIo } from "../deps.js";
11
- export declare const SESSIONS_SEARCH_USAGE = "\u7528\u6CD5\uFF1Aama sessions search <\u5173\u952E\u8BCD|/\u6B63\u5219/\u6807\u5FD7> [--all] [--role user|assistant|tool]\n [--since 7d|today|YYYY-MM-DD] [--limit N] [--json] [--session-dir <\u76EE\u5F55>]\n";
11
+ export declare function sessionsSearchUsage(): string;
12
12
  export declare function renderHit(hit: SearchHit, color: boolean): string;
13
13
  export declare function runSessionsSearch(argv: readonly string[], io: CliIo): Promise<number>;
@@ -13,9 +13,10 @@ import { compileQuery, searchSessions, } from "../../session/search.js";
13
13
  import { parseSubArgs, UsageError } from "../args.js";
14
14
  import { ExitCode } from "../exit-codes.js";
15
15
  import { parseDaySpec } from "./stats.js";
16
- export const SESSIONS_SEARCH_USAGE = `用法:ama sessions search <关键词|/正则/标志> [--all] [--role user|assistant|tool]
17
- [--since 7d|today|YYYY-MM-DD] [--limit N] [--json] [--session-dir <目录>]
18
- `;
16
+ import { msg } from "../../i18n/index.js";
17
+ export function sessionsSearchUsage() {
18
+ return msg().subcommands.sessionsSearch.usage;
19
+ }
19
20
  const ROLES = ["user", "assistant", "tool"];
20
21
  function highlight(text, ranges, color) {
21
22
  if (!color || ranges.length === 0)
@@ -44,18 +45,18 @@ export function renderHit(hit, color) {
44
45
  export async function runSessionsSearch(argv, io) {
45
46
  const { positionals, values, flags } = parseSubArgs(argv, ["role", "since", "limit", "session-dir"], ["all", "json"]);
46
47
  if (flags.has("help")) {
47
- io.stdout(SESSIONS_SEARCH_USAGE);
48
+ io.stdout(sessionsSearchUsage());
48
49
  return ExitCode.Ok;
49
50
  }
50
51
  const pattern = positionals.join(" ");
51
52
  if (pattern.trim() === "")
52
- throw new UsageError("ama sessions search 需要关键词或 /正则/");
53
+ throw new UsageError(msg().subcommands.sessionsSearch.needsPattern);
53
54
  let query;
54
55
  try {
55
56
  query = compileQuery(pattern);
56
57
  }
57
58
  catch (error) {
58
- throw new UsageError(`正则无效:${error.message}`);
59
+ throw new UsageError(msg().subcommands.sessionsSearch.invalidRegex(error.message));
59
60
  }
60
61
  let roles;
61
62
  const roleRaw = values.get("role");
@@ -63,14 +64,14 @@ export async function runSessionsSearch(argv, io) {
63
64
  roles = new Set();
64
65
  for (const role of roleRaw.split(",").map((r) => r.trim())) {
65
66
  if (!ROLES.includes(role)) {
66
- throw new UsageError(`--role 的取值应为 ${ROLES.join(" | ")}(收到 ${role})`);
67
+ throw new UsageError(msg().subcommands.common.invalidChoice("--role", ROLES, role));
67
68
  }
68
69
  roles.add(role);
69
70
  }
70
71
  }
71
72
  const limit = Number(values.get("limit") ?? "20");
72
73
  if (!Number.isInteger(limit) || limit < 1)
73
- throw new UsageError("--limit 应为正整数");
74
+ throw new UsageError(msg().subcommands.sessionsSearch.limitPositive);
74
75
  const sinceRaw = values.get("since");
75
76
  const sinceIso = sinceRaw === undefined
76
77
  ? undefined
@@ -91,13 +92,13 @@ export async function runSessionsSearch(argv, io) {
91
92
  return ExitCode.Ok;
92
93
  }
93
94
  if (hits.length === 0) {
94
- io.stdout(flags.has("all") ? "没有命中\n" : "没有命中(只搜了当前目录的会话,--all 搜全部)\n");
95
+ io.stdout(msg().subcommands.sessionsSearch.noHits(flags.has("all")));
95
96
  return ExitCode.Ok;
96
97
  }
97
98
  const color = io.stdoutIsTTY && (io.env["NO_COLOR"] ?? "") === "";
98
99
  for (const hit of hits)
99
100
  io.stdout(renderHit(hit, color));
100
101
  if (truncated)
101
- io.stdout(`(已到 --limit ${limit},可能还有更多)\n`);
102
+ io.stdout(msg().subcommands.sessionsSearch.truncated(limit));
102
103
  return ExitCode.Ok;
103
104
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * `ama sessions trace <id|文件>`:会话轨迹导出(docs/wave6-plan.md §2.5、D7)。[W6-T2]
3
+ *
4
+ * - 缺省 / `--html [文件]` / `--format html`:自包含 HTML(`trace/html.ts`);`--json` / `--format json`:与 RPC
5
+ * `get_trace` 同形的 JSON(全部回合、已加载子会话、`previews` 只含本会话节点;`--no-content` 时没有)。
6
+ * - 输出:`--html <文件>` 或 `--output <文件>` 写文件(0600),否则 stdout;`--open` 写好后用系统浏览器打开
7
+ * (没给文件时写到临时目录)。
8
+ * - `--branch leaf|all`、`--no-content`(只留结构与数字)、`--children`(HTML 内嵌子会话预览)、
9
+ * `--now <ms>`(生成时间,确定性)。
10
+ * - 只读:不加锁、不改会话文件(推算出的时间不写回);子会话缺失只标 childMissing。
11
+ */
12
+ import { type TraceInput } from "../../trace/build.js";
13
+ import type { CliIo } from "../deps.js";
14
+ export declare function sessionsTraceUsage(): string;
15
+ export interface SessionsTraceDeps {
16
+ /** 打开浏览器(测试替身;缺省 detached spawn)。 */
17
+ open?: (command: OpenCommand) => Promise<void>;
18
+ /** 生成时间(缺省 `Date.now()`;`--now` 优先)。 */
19
+ now?: () => number;
20
+ platform?: NodeJS.Platform;
21
+ /** 读子会话(测试替身)。 */
22
+ readChild?: (file: string) => TraceInput | undefined;
23
+ }
24
+ export interface OpenCommand {
25
+ command: string;
26
+ args: string[];
27
+ }
28
+ /** 各平台「用缺省程序打开文件」的命令。 */
29
+ export declare function openCommand(platform: NodeJS.Platform, file: string): OpenCommand;
30
+ export declare function runSessionsTrace(argv: readonly string[], io: CliIo, deps?: SessionsTraceDeps): Promise<number>;