@armadra/agent 0.5.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/CHANGELOG.md +203 -304
  2. package/CHANGELOG.zh-CN.md +462 -0
  3. package/README.md +408 -364
  4. package/README.zh-CN.md +705 -0
  5. package/dist/agent/session-plan.js +2 -2
  6. package/dist/agent/session-state.d.ts +3 -0
  7. package/dist/agent/session-state.js +20 -0
  8. package/dist/agent/session-subagent.d.ts +15 -1
  9. package/dist/agent/session-subagent.js +26 -3
  10. package/dist/agent/session-telemetry.d.ts +16 -2
  11. package/dist/agent/session-telemetry.js +29 -7
  12. package/dist/agent/session-tools.js +5 -2
  13. package/dist/agent/session-trace-writer.d.ts +27 -0
  14. package/dist/agent/session-trace-writer.js +253 -0
  15. package/dist/agent/session.d.ts +2 -0
  16. package/dist/agent/session.js +12 -0
  17. package/dist/agent/subagent-direct.d.ts +20 -0
  18. package/dist/agent/subagent-direct.js +76 -0
  19. package/dist/agent/subagent-registry.d.ts +8 -1
  20. package/dist/agent/subagent-registry.js +28 -1
  21. package/dist/agent/system-prompt.d.ts +3 -1
  22. package/dist/agent/system-prompt.js +3 -0
  23. package/dist/agent/tool-runner.d.ts +2 -1
  24. package/dist/agent/tool-runner.js +5 -4
  25. package/dist/agent/types-w6.d.ts +39 -0
  26. package/dist/agent/types-w6.js +4 -0
  27. package/dist/agent/types.d.ts +5 -2
  28. package/dist/agents/external.js +1 -1
  29. package/dist/agents/task-record.d.ts +74 -1
  30. package/dist/agents/task-record.js +100 -0
  31. package/dist/ai/apis/cache-params.js +2 -1
  32. package/dist/ai/apis/chatgpt-backend.d.ts +52 -0
  33. package/dist/ai/apis/chatgpt-backend.js +224 -0
  34. package/dist/ai/apis/chatgpt-rate-limits.d.ts +26 -0
  35. package/dist/ai/apis/chatgpt-rate-limits.js +91 -0
  36. package/dist/ai/apis/openai-responses-request.d.ts +2 -1
  37. package/dist/ai/apis/openai-responses-request.js +8 -2
  38. package/dist/ai/apis/openai-responses.d.ts +2 -0
  39. package/dist/ai/apis/openai-responses.js +51 -16
  40. package/dist/ai/overflow.d.ts +1 -1
  41. package/dist/ai/overflow.js +10 -7
  42. package/dist/ai/providers/auth.d.ts +15 -2
  43. package/dist/ai/providers/auth.js +69 -2
  44. package/dist/ai/providers/builtin.js +27 -0
  45. package/dist/ai/providers/catalog-data.js +1 -0
  46. package/dist/ai/providers/discovered-cache.d.ts +48 -0
  47. package/dist/ai/providers/discovered-cache.js +102 -0
  48. package/dist/ai/providers/enrich.js +2 -7
  49. package/dist/ai/providers/model-visibility.d.ts +33 -0
  50. package/dist/ai/providers/model-visibility.js +70 -0
  51. package/dist/ai/providers/models-dev-cache.js +15 -19
  52. package/dist/ai/providers/models-dev-snapshot.js +8 -7
  53. package/dist/ai/providers/models-dev.js +5 -15
  54. package/dist/ai/providers/registry.d.ts +2 -0
  55. package/dist/ai/providers/registry.js +6 -1
  56. package/dist/ai/providers/suggest.js +2 -16
  57. package/dist/ai/types.d.ts +27 -1
  58. package/dist/auth/chatgpt/backend-client.d.ts +26 -0
  59. package/dist/auth/chatgpt/backend-client.js +74 -0
  60. package/dist/auth/chatgpt/claims.d.ts +17 -0
  61. package/dist/auth/chatgpt/claims.js +46 -0
  62. package/dist/auth/chatgpt/cli.d.ts +35 -0
  63. package/dist/auth/chatgpt/cli.js +279 -0
  64. package/dist/auth/chatgpt/doctor.d.ts +17 -0
  65. package/dist/auth/chatgpt/doctor.js +36 -0
  66. package/dist/auth/chatgpt/host-id.d.ts +7 -0
  67. package/dist/auth/chatgpt/host-id.js +26 -0
  68. package/dist/auth/chatgpt/login.d.ts +30 -0
  69. package/dist/auth/chatgpt/login.js +130 -0
  70. package/dist/auth/chatgpt/presets.d.ts +66 -0
  71. package/dist/auth/chatgpt/presets.js +120 -0
  72. package/dist/auth/chatgpt/quota-text.d.ts +13 -0
  73. package/dist/auth/chatgpt/quota-text.js +36 -0
  74. package/dist/auth/oauth/browser.d.ts +12 -0
  75. package/dist/auth/oauth/browser.js +27 -0
  76. package/dist/auth/oauth/callback-server.d.ts +47 -0
  77. package/dist/auth/oauth/callback-server.js +147 -0
  78. package/dist/auth/oauth/flows.d.ts +62 -0
  79. package/dist/auth/oauth/flows.js +113 -0
  80. package/dist/auth/oauth/jwt.d.ts +24 -0
  81. package/dist/auth/oauth/jwt.js +81 -0
  82. package/dist/auth/oauth/live.d.ts +21 -0
  83. package/dist/auth/oauth/live.js +25 -0
  84. package/dist/auth/oauth/oidc.d.ts +26 -0
  85. package/dist/auth/oauth/oidc.js +72 -0
  86. package/dist/auth/oauth/pkce.d.ts +15 -0
  87. package/dist/auth/oauth/pkce.js +20 -0
  88. package/dist/auth/oauth/refresh.d.ts +35 -0
  89. package/dist/auth/oauth/refresh.js +129 -0
  90. package/dist/auth/oauth/token-client.d.ts +33 -0
  91. package/dist/auth/oauth/token-client.js +121 -0
  92. package/dist/auth/oauth/token-store.d.ts +23 -0
  93. package/dist/auth/oauth/token-store.js +125 -0
  94. package/dist/auth/testing/fake-oauth.d.ts +73 -0
  95. package/dist/auth/testing/fake-oauth.js +271 -0
  96. package/dist/auth/testing/refresh-child.d.ts +5 -0
  97. package/dist/auth/testing/refresh-child.js +16 -0
  98. package/dist/bundle/ama.cjs +26532 -11045
  99. package/dist/checkpoints/backend.js +6 -5
  100. package/dist/checkpoints/restore.js +3 -2
  101. package/dist/checkpoints/settings.js +2 -1
  102. package/dist/checkpoints/shadow-git.js +7 -6
  103. package/dist/checkpoints/shadow-restore.js +3 -2
  104. package/dist/checkpoints/tracker.js +4 -3
  105. package/dist/cli/args.d.ts +9 -2
  106. package/dist/cli/args.js +74 -27
  107. package/dist/cli/bootstrap.js +53 -31
  108. package/dist/cli/choice-prompt.js +8 -6
  109. package/dist/cli/codemode-notice.js +2 -2
  110. package/dist/cli/compose-agents.js +2 -1
  111. package/dist/cli/compose-extensions.js +2 -0
  112. package/dist/cli/compose-memory.d.ts +53 -0
  113. package/dist/cli/compose-memory.js +127 -0
  114. package/dist/cli/compose-providers.d.ts +6 -0
  115. package/dist/cli/compose-providers.js +38 -2
  116. package/dist/cli/compose-session.d.ts +5 -0
  117. package/dist/cli/compose-session.js +27 -13
  118. package/dist/cli/compose-store.d.ts +2 -0
  119. package/dist/cli/compose-store.js +9 -5
  120. package/dist/cli/compose.d.ts +2 -0
  121. package/dist/cli/compose.js +13 -5
  122. package/dist/cli/default-model.d.ts +0 -2
  123. package/dist/cli/default-model.js +5 -8
  124. package/dist/cli/deps.d.ts +5 -1
  125. package/dist/cli/exit-codes.d.ts +1 -1
  126. package/dist/cli/exit-codes.js +7 -16
  127. package/dist/cli/from-prompt.js +3 -2
  128. package/dist/cli/help-text.d.ts +2 -1
  129. package/dist/cli/help-text.js +5 -99
  130. package/dist/cli/main.d.ts +5 -0
  131. package/dist/cli/main.js +21 -2
  132. package/dist/cli/proxy.js +14 -9
  133. package/dist/cli/runtime.d.ts +5 -0
  134. package/dist/cli/startup-screen.js +20 -27
  135. package/dist/cli/startup-steps.js +6 -8
  136. package/dist/cli/subcommands/auth.d.ts +6 -3
  137. package/dist/cli/subcommands/auth.js +52 -22
  138. package/dist/cli/subcommands/config-set.d.ts +21 -0
  139. package/dist/cli/subcommands/config-set.js +145 -0
  140. package/dist/cli/subcommands/config.d.ts +2 -1
  141. package/dist/cli/subcommands/config.js +51 -37
  142. package/dist/cli/subcommands/doctor.d.ts +2 -1
  143. package/dist/cli/subcommands/doctor.js +97 -58
  144. package/dist/cli/subcommands/init.d.ts +1 -1
  145. package/dist/cli/subcommands/init.js +8 -7
  146. package/dist/cli/subcommands/memory.d.ts +18 -0
  147. package/dist/cli/subcommands/memory.js +189 -0
  148. package/dist/cli/subcommands/model-meta.js +11 -9
  149. package/dist/cli/subcommands/models-cache-probe.js +23 -20
  150. package/dist/cli/subcommands/models-discover.d.ts +4 -0
  151. package/dist/cli/subcommands/models-discover.js +60 -21
  152. package/dist/cli/subcommands/models-enable.d.ts +13 -0
  153. package/dist/cli/subcommands/models-enable.js +145 -0
  154. package/dist/cli/subcommands/models.d.ts +3 -1
  155. package/dist/cli/subcommands/models.js +39 -24
  156. package/dist/cli/subcommands/probe-runner.js +8 -7
  157. package/dist/cli/subcommands/providers-list.js +32 -21
  158. package/dist/cli/subcommands/providers-plan.js +24 -25
  159. package/dist/cli/subcommands/providers-probe.js +5 -6
  160. package/dist/cli/subcommands/providers.d.ts +1 -1
  161. package/dist/cli/subcommands/providers.js +45 -50
  162. package/dist/cli/subcommands/sessions-export.d.ts +1 -1
  163. package/dist/cli/subcommands/sessions-export.js +10 -9
  164. package/dist/cli/subcommands/sessions-search.d.ts +1 -1
  165. package/dist/cli/subcommands/sessions-search.js +11 -10
  166. package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
  167. package/dist/cli/subcommands/sessions-trace.js +156 -0
  168. package/dist/cli/subcommands/sessions.d.ts +4 -3
  169. package/dist/cli/subcommands/sessions.js +40 -37
  170. package/dist/cli/subcommands/stats.d.ts +1 -1
  171. package/dist/cli/subcommands/stats.js +49 -30
  172. package/dist/cli/system-prompt-arg.js +3 -2
  173. package/dist/codemode/capability.js +3 -2
  174. package/dist/compaction/post-compact.d.ts +1 -0
  175. package/dist/compaction/post-compact.js +15 -1
  176. package/dist/compaction/prune-tier.d.ts +1 -1
  177. package/dist/compaction/prune-tier.js +3 -3
  178. package/dist/compaction/serialize.js +2 -1
  179. package/dist/config/auth-file.d.ts +12 -2
  180. package/dist/config/auth-file.js +32 -10
  181. package/dist/config/checker.js +12 -11
  182. package/dist/config/context-files.js +3 -2
  183. package/dist/config/edit.d.ts +106 -0
  184. package/dist/config/edit.js +350 -0
  185. package/dist/config/init.d.ts +4 -3
  186. package/dist/config/init.js +10 -18
  187. package/dist/config/json-schema.d.ts +2 -1
  188. package/dist/config/json-schema.js +102 -69
  189. package/dist/config/key-docs.d.ts +18 -7
  190. package/dist/config/key-docs.js +43 -128
  191. package/dist/config/load.js +7 -6
  192. package/dist/config/merge.d.ts +4 -1
  193. package/dist/config/merge.js +42 -22
  194. package/dist/config/paths.js +6 -5
  195. package/dist/config/profile.d.ts +5 -1
  196. package/dist/config/profile.js +7 -2
  197. package/dist/config/schema-w5.js +12 -4
  198. package/dist/config/schema-w6.d.ts +19 -0
  199. package/dist/config/schema-w6.js +115 -0
  200. package/dist/config/schema.js +34 -20
  201. package/dist/config/settings-registry.d.ts +81 -0
  202. package/dist/config/settings-registry.js +185 -0
  203. package/dist/config/types-w5.d.ts +7 -0
  204. package/dist/config/types-w5.js +2 -0
  205. package/dist/config/types-w6.d.ts +109 -0
  206. package/dist/config/types-w6.js +19 -0
  207. package/dist/config/types.d.ts +11 -8
  208. package/dist/config/types.js +1 -0
  209. package/dist/drivers/acp/client.js +1 -1
  210. package/dist/drivers/acp/driver.js +13 -8
  211. package/dist/drivers/agents.js +4 -3
  212. package/dist/drivers/base.js +3 -2
  213. package/dist/drivers/host-runners.js +2 -1
  214. package/dist/drivers/native/claude-stream.js +12 -11
  215. package/dist/drivers/native/codex-app-server.js +17 -12
  216. package/dist/drivers/native/oneshot.js +8 -7
  217. package/dist/drivers/pool.js +1 -1
  218. package/dist/drivers/runner.d.ts +3 -1
  219. package/dist/drivers/runner.js +68 -20
  220. package/dist/drivers/turn.js +1 -1
  221. package/dist/hooks/config.js +3 -2
  222. package/dist/hooks/protocol.js +18 -12
  223. package/dist/host/api-impl.js +11 -10
  224. package/dist/host/loader.js +9 -8
  225. package/dist/host/types.d.ts +3 -0
  226. package/dist/i18n/catalog.d.ts +2209 -0
  227. package/dist/i18n/catalog.js +72 -0
  228. package/dist/i18n/format.d.ts +21 -0
  229. package/dist/i18n/format.js +58 -0
  230. package/dist/i18n/index.d.ts +58 -0
  231. package/dist/i18n/index.js +72 -0
  232. package/dist/i18n/messages/agents.d.ts +84 -0
  233. package/dist/i18n/messages/agents.js +85 -0
  234. package/dist/i18n/messages/approval.d.ts +99 -0
  235. package/dist/i18n/messages/approval.js +100 -0
  236. package/dist/i18n/messages/auth.d.ts +189 -0
  237. package/dist/i18n/messages/auth.js +201 -0
  238. package/dist/i18n/messages/cli-args.d.ts +46 -0
  239. package/dist/i18n/messages/cli-args.js +46 -0
  240. package/dist/i18n/messages/cli-help.d.ts +12 -0
  241. package/dist/i18n/messages/cli-help.js +248 -0
  242. package/dist/i18n/messages/cli.d.ts +336 -0
  243. package/dist/i18n/messages/cli.js +311 -0
  244. package/dist/i18n/messages/config-keys.d.ts +293 -0
  245. package/dist/i18n/messages/config-keys.js +296 -0
  246. package/dist/i18n/messages/config.d.ts +508 -0
  247. package/dist/i18n/messages/config.js +241 -0
  248. package/dist/i18n/messages/drivers.d.ts +123 -0
  249. package/dist/i18n/messages/drivers.js +124 -0
  250. package/dist/i18n/messages/errors.d.ts +83 -0
  251. package/dist/i18n/messages/errors.js +171 -0
  252. package/dist/i18n/messages/interactive-line.d.ts +61 -0
  253. package/dist/i18n/messages/interactive-line.js +69 -0
  254. package/dist/i18n/messages/interactive-startup.d.ts +99 -0
  255. package/dist/i18n/messages/interactive-startup.js +100 -0
  256. package/dist/i18n/messages/interactive-view.d.ts +140 -0
  257. package/dist/i18n/messages/interactive-view.js +141 -0
  258. package/dist/i18n/messages/interactive.d.ts +489 -0
  259. package/dist/i18n/messages/interactive.js +248 -0
  260. package/dist/i18n/messages/memory.d.ts +123 -0
  261. package/dist/i18n/messages/memory.js +128 -0
  262. package/dist/i18n/messages/panels.d.ts +233 -0
  263. package/dist/i18n/messages/panels.js +232 -0
  264. package/dist/i18n/messages/permissions.d.ts +126 -0
  265. package/dist/i18n/messages/permissions.js +151 -0
  266. package/dist/i18n/messages/plan.d.ts +123 -0
  267. package/dist/i18n/messages/plan.js +124 -0
  268. package/dist/i18n/messages/print.d.ts +86 -0
  269. package/dist/i18n/messages/print.js +91 -0
  270. package/dist/i18n/messages/report.d.ts +391 -0
  271. package/dist/i18n/messages/report.js +490 -0
  272. package/dist/i18n/messages/rewind.d.ts +198 -0
  273. package/dist/i18n/messages/rewind.js +217 -0
  274. package/dist/i18n/messages/session.d.ts +230 -0
  275. package/dist/i18n/messages/session.js +258 -0
  276. package/dist/i18n/messages/settings.d.ts +355 -0
  277. package/dist/i18n/messages/settings.js +343 -0
  278. package/dist/i18n/messages/subcommands-config.d.ts +113 -0
  279. package/dist/i18n/messages/subcommands-config.js +129 -0
  280. package/dist/i18n/messages/subcommands-models.d.ts +34 -0
  281. package/dist/i18n/messages/subcommands-models.js +34 -0
  282. package/dist/i18n/messages/subcommands.d.ts +576 -0
  283. package/dist/i18n/messages/subcommands.js +477 -0
  284. package/dist/i18n/messages/trace.d.ts +243 -0
  285. package/dist/i18n/messages/trace.js +238 -0
  286. package/dist/i18n/types.d.ts +15 -0
  287. package/dist/i18n/types.js +7 -0
  288. package/dist/index.d.ts +6 -0
  289. package/dist/index.js +2 -0
  290. package/dist/memory/edit.d.ts +24 -0
  291. package/dist/memory/edit.js +63 -0
  292. package/dist/memory/frontmatter.d.ts +37 -0
  293. package/dist/memory/frontmatter.js +79 -0
  294. package/dist/memory/index.d.ts +28 -0
  295. package/dist/memory/index.js +126 -0
  296. package/dist/memory/lock.d.ts +17 -0
  297. package/dist/memory/lock.js +62 -0
  298. package/dist/memory/paths.d.ts +57 -0
  299. package/dist/memory/paths.js +175 -0
  300. package/dist/memory/report.d.ts +36 -0
  301. package/dist/memory/report.js +86 -0
  302. package/dist/memory/runtime.d.ts +42 -0
  303. package/dist/memory/runtime.js +36 -0
  304. package/dist/memory/secrets.d.ts +8 -0
  305. package/dist/memory/secrets.js +27 -0
  306. package/dist/memory/section.d.ts +28 -0
  307. package/dist/memory/section.js +59 -0
  308. package/dist/memory/store.d.ts +70 -0
  309. package/dist/memory/store.js +284 -0
  310. package/dist/memory/tool.d.ts +31 -0
  311. package/dist/memory/tool.js +94 -0
  312. package/dist/modes/acp/acp-events.js +2 -1
  313. package/dist/modes/acp/acp-server.js +13 -12
  314. package/dist/modes/commands-core.d.ts +11 -0
  315. package/dist/modes/commands-core.js +93 -62
  316. package/dist/modes/image-input.js +20 -6
  317. package/dist/modes/interactive/agent-bar.d.ts +95 -0
  318. package/dist/modes/interactive/agent-bar.js +248 -0
  319. package/dist/modes/interactive/agent-panels.js +27 -26
  320. package/dist/modes/interactive/agent-transcript.d.ts +47 -0
  321. package/dist/modes/interactive/agent-transcript.js +191 -0
  322. package/dist/modes/interactive/agent-ui.d.ts +36 -1
  323. package/dist/modes/interactive/agent-ui.js +180 -14
  324. package/dist/modes/interactive/agent-view.d.ts +72 -0
  325. package/dist/modes/interactive/agent-view.js +281 -0
  326. package/dist/modes/interactive/approval-dialog.js +46 -34
  327. package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
  328. package/dist/modes/interactive/clipboard-paste.js +9 -4
  329. package/dist/modes/interactive/commands.d.ts +22 -1
  330. package/dist/modes/interactive/commands.js +100 -49
  331. package/dist/modes/interactive/completion.js +2 -1
  332. package/dist/modes/interactive/config-panel.d.ts +70 -0
  333. package/dist/modes/interactive/config-panel.js +319 -0
  334. package/dist/modes/interactive/config-ui.d.ts +96 -0
  335. package/dist/modes/interactive/config-ui.js +397 -0
  336. package/dist/modes/interactive/confirm-dialog.js +6 -7
  337. package/dist/modes/interactive/event-notices.js +11 -9
  338. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  339. package/dist/modes/interactive/interactive-mode.js +21 -22
  340. package/dist/modes/interactive/key-dispatch.d.ts +12 -0
  341. package/dist/modes/interactive/key-dispatch.js +24 -9
  342. package/dist/modes/interactive/line/line-editor.js +2 -1
  343. package/dist/modes/interactive/line/line-mode.js +18 -7
  344. package/dist/modes/interactive/line/line-render.js +25 -24
  345. package/dist/modes/interactive/memory-panel.d.ts +64 -0
  346. package/dist/modes/interactive/memory-panel.js +221 -0
  347. package/dist/modes/interactive/message-view.d.ts +4 -2
  348. package/dist/modes/interactive/message-view.js +42 -33
  349. package/dist/modes/interactive/model-items.d.ts +45 -0
  350. package/dist/modes/interactive/model-items.js +134 -0
  351. package/dist/modes/interactive/model-picker.d.ts +57 -0
  352. package/dist/modes/interactive/model-picker.js +191 -0
  353. package/dist/modes/interactive/panels.js +39 -31
  354. package/dist/modes/interactive/pickers.d.ts +2 -1
  355. package/dist/modes/interactive/pickers.js +10 -6
  356. package/dist/modes/interactive/plan-command.d.ts +1 -1
  357. package/dist/modes/interactive/plan-command.js +24 -27
  358. package/dist/modes/interactive/plan-dialog.js +18 -17
  359. package/dist/modes/interactive/plan-flow.js +6 -5
  360. package/dist/modes/interactive/rewind-command.d.ts +1 -1
  361. package/dist/modes/interactive/rewind-command.js +18 -16
  362. package/dist/modes/interactive/rewind-flow.d.ts +0 -1
  363. package/dist/modes/interactive/rewind-flow.js +13 -14
  364. package/dist/modes/interactive/rewind-list.js +7 -6
  365. package/dist/modes/interactive/rewind-panel.js +40 -40
  366. package/dist/modes/interactive/rewind-text.d.ts +5 -3
  367. package/dist/modes/interactive/rewind-text.js +48 -38
  368. package/dist/modes/interactive/run-indicator.js +15 -12
  369. package/dist/modes/interactive/session-events.js +3 -2
  370. package/dist/modes/interactive/startup-header.js +22 -23
  371. package/dist/modes/interactive/startup-ui.d.ts +3 -9
  372. package/dist/modes/interactive/startup-ui.js +44 -88
  373. package/dist/modes/interactive/status-area.d.ts +2 -0
  374. package/dist/modes/interactive/status-area.js +8 -2
  375. package/dist/modes/interactive/status-bar.js +4 -3
  376. package/dist/modes/interactive/subagent-view.js +9 -7
  377. package/dist/modes/interactive/tasks-report.d.ts +6 -0
  378. package/dist/modes/interactive/tasks-report.js +28 -31
  379. package/dist/modes/interactive/terminal-setup.d.ts +9 -0
  380. package/dist/modes/interactive/terminal-setup.js +23 -0
  381. package/dist/modes/interactive/tool-summary.js +19 -17
  382. package/dist/modes/interactive/tool-view.js +7 -4
  383. package/dist/modes/interactive/trace-view.d.ts +89 -0
  384. package/dist/modes/interactive/trace-view.js +332 -0
  385. package/dist/modes/print/print-mode.js +14 -15
  386. package/dist/modes/rpc/commands.js +7 -3
  387. package/dist/modes/rpc/rpc-mode.js +9 -3
  388. package/dist/modes/session-report.d.ts +2 -0
  389. package/dist/modes/session-report.js +101 -105
  390. package/dist/modes/startup-ui-text.js +11 -6
  391. package/dist/permissions/bypass.d.ts +8 -10
  392. package/dist/permissions/bypass.js +19 -10
  393. package/dist/permissions/memory-class.d.ts +23 -0
  394. package/dist/permissions/memory-class.js +54 -0
  395. package/dist/permissions/modes.d.ts +3 -3
  396. package/dist/permissions/modes.js +21 -16
  397. package/dist/permissions/pipeline.d.ts +1 -1
  398. package/dist/permissions/pipeline.js +9 -2
  399. package/dist/permissions/preview.js +49 -42
  400. package/dist/permissions/rules.js +5 -2
  401. package/dist/permissions/types.d.ts +4 -0
  402. package/dist/plan/store.js +2 -1
  403. package/dist/rpc.d.ts +39 -1
  404. package/dist/rpc.js +3 -0
  405. package/dist/sandbox/bash.js +11 -8
  406. package/dist/sandbox/detect.js +14 -11
  407. package/dist/sdk.d.ts +17 -1
  408. package/dist/sdk.js +29 -7
  409. package/dist/session/export.js +31 -30
  410. package/dist/session/manager.d.ts +1 -1
  411. package/dist/session/manager.js +5 -3
  412. package/dist/session/reuse.js +5 -4
  413. package/dist/session/scan.js +3 -2
  414. package/dist/session/stats-aggregate.d.ts +3 -1
  415. package/dist/session/stats-aggregate.js +5 -1
  416. package/dist/session/stats-index.js +2 -1
  417. package/dist/session/stats-scan.d.ts +4 -1
  418. package/dist/session/stats-scan.js +6 -2
  419. package/dist/session/store.d.ts +11 -0
  420. package/dist/session/store.js +48 -1
  421. package/dist/session/types.d.ts +2 -0
  422. package/dist/skills/builtin.js +2 -1
  423. package/dist/tools/image-file.d.ts +26 -1
  424. package/dist/tools/image-file.js +55 -13
  425. package/dist/tools/presets.d.ts +14 -1
  426. package/dist/tools/presets.js +3 -3
  427. package/dist/tools/registry.js +1 -1
  428. package/dist/tools/truncate.d.ts +1 -1
  429. package/dist/tools/truncate.js +2 -2
  430. package/dist/tools/types.d.ts +17 -1
  431. package/dist/trace/build-index.d.ts +91 -0
  432. package/dist/trace/build-index.js +127 -0
  433. package/dist/trace/build-nodes.d.ts +24 -0
  434. package/dist/trace/build-nodes.js +279 -0
  435. package/dist/trace/build-util.d.ts +43 -0
  436. package/dist/trace/build-util.js +120 -0
  437. package/dist/trace/build.d.ts +82 -0
  438. package/dist/trace/build.js +382 -0
  439. package/dist/trace/detail.d.ts +35 -0
  440. package/dist/trace/detail.js +205 -0
  441. package/dist/trace/flatten.d.ts +69 -0
  442. package/dist/trace/flatten.js +173 -0
  443. package/dist/trace/format.d.ts +47 -0
  444. package/dist/trace/format.js +329 -0
  445. package/dist/trace/html-template.d.ts +19 -0
  446. package/dist/trace/html-template.js +150 -0
  447. package/dist/trace/html.d.ts +104 -0
  448. package/dist/trace/html.js +292 -0
  449. package/dist/trace/preview.d.ts +29 -0
  450. package/dist/trace/preview.js +59 -0
  451. package/dist/trace/query-session.d.ts +14 -0
  452. package/dist/trace/query-session.js +38 -0
  453. package/dist/trace/query.d.ts +55 -0
  454. package/dist/trace/query.js +188 -0
  455. package/dist/trace/session.d.ts +40 -0
  456. package/dist/trace/session.js +168 -0
  457. package/dist/trace/types.d.ts +243 -0
  458. package/dist/trace/types.js +13 -0
  459. package/dist/tui/components/editor-paste.d.ts +2 -0
  460. package/dist/tui/components/editor-paste.js +6 -3
  461. package/dist/tui/components/editor.js +2 -2
  462. package/dist/tui/components/loader.d.ts +3 -0
  463. package/dist/tui/components/loader.js +14 -0
  464. package/dist/tui/components/select-list.d.ts +2 -0
  465. package/dist/tui/components/select-list.js +7 -0
  466. package/dist/tui/components/settings-list.d.ts +61 -0
  467. package/dist/tui/components/settings-list.js +135 -0
  468. package/dist/tui/keybindings.d.ts +5 -0
  469. package/dist/tui/keybindings.js +17 -5
  470. package/dist/tui.d.ts +1 -0
  471. package/dist/tui.js +2 -0
  472. package/docs/en/host-api.md +167 -0
  473. package/docs/en/permissions.md +214 -0
  474. package/docs/en/providers.md +627 -0
  475. package/docs/en/rpc.md +361 -0
  476. package/docs/en/sessions.md +219 -0
  477. package/docs/en/tui.md +534 -0
  478. package/docs/host-api.md +18 -17
  479. package/docs/memory.md +172 -0
  480. package/docs/permissions.md +2 -2
  481. package/docs/providers.md +73 -1
  482. package/docs/rpc.md +31 -3
  483. package/docs/session-format.md +8 -2
  484. package/docs/sessions.md +29 -1
  485. package/docs/tui.md +140 -4
  486. package/package.json +8 -3
@@ -30,6 +30,7 @@ import { errorText, lastAssistant, onStdoutClosed, onTerminationSignals } from "
30
30
  import { toJsonLine, toWireEvent } from "./json-event.js";
31
31
  import { formatUsd } from "../../agent/limits.js";
32
32
  import { promptImages, sessionModel } from "../image-input.js";
33
+ import { msg } from "../../i18n/index.js";
33
34
  export function joinPrompt(argument, piped) {
34
35
  const parts = [argument ?? "", piped.replace(/\s+$/, "")].filter((p) => p.trim() !== "");
35
36
  return parts.join("\n\n");
@@ -75,14 +76,14 @@ export async function readPromptStdin(io, prompt, mode, hintMs = STDIN_WAIT_HINT
75
76
  return "";
76
77
  const text = await readWithin(io, waitMs);
77
78
  if (text === undefined) {
78
- io.stderr(`ama: 未在 ${formatSeconds(waitMs)}内收到管道输入,已忽略;需要等待请在末尾加 -\n`);
79
+ io.stderr(msg().print.print.stdinIgnored(formatSeconds(waitMs)));
79
80
  return "";
80
81
  }
81
82
  return text;
82
83
  }
83
84
  const timer = safe
84
85
  ? undefined
85
- : setTimeout(() => io.stderr("ama: 正在等待 stdin 输入结束(Ctrl+D 结束;提示也可以直接写成参数)…\n"), hintMs);
86
+ : setTimeout(() => io.stderr(msg().print.print.stdinWaiting), hintMs);
86
87
  try {
87
88
  return await io.readStdin();
88
89
  }
@@ -91,7 +92,8 @@ export async function readPromptStdin(io, prompt, mode, hintMs = STDIN_WAIT_HINT
91
92
  }
92
93
  }
93
94
  function formatSeconds(ms) {
94
- return ms % 1000 === 0 ? `${ms / 1000} 秒` : `${ms} 毫秒`;
95
+ const m = msg().print.print;
96
+ return ms % 1000 === 0 ? m.seconds(ms / 1000) : m.millis(ms);
95
97
  }
96
98
  export async function runPrintMode(runtime, context) {
97
99
  const { io } = context;
@@ -100,7 +102,7 @@ export async function runPrintMode(runtime, context) {
100
102
  const piped = await readPromptStdin(io, context.prompt, stdinMode);
101
103
  const prompt = joinPrompt(context.prompt, piped);
102
104
  if (prompt === "") {
103
- io.stderr("ama: -p 需要提示(位置参数或 stdin 管道)\n");
105
+ io.stderr(msg().print.print.needsPrompt);
104
106
  return ExitCode.Usage;
105
107
  }
106
108
  const session = currentSession(runtime);
@@ -132,7 +134,7 @@ export async function runPrintMode(runtime, context) {
132
134
  if (format === "stream-json")
133
135
  io.stdout(`${toJsonLine(toWireEvent(event))}\n`);
134
136
  else if (event.type === "auto_retry_start")
135
- io.stderr(`ama: ↻ 重试 ${event.attempt}/${event.maxAttempts}(${Math.round(event.delayMs / 1000)}s 后):${event.errorMessage}\n`);
137
+ io.stderr(msg().print.print.retry(event.attempt, event.maxAttempts, Math.round(event.delayMs / 1000), event.errorMessage));
136
138
  });
137
139
  let signalled;
138
140
  const offSignals = onTerminationSignals((code) => {
@@ -215,7 +217,7 @@ export async function runPrintMode(runtime, context) {
215
217
  return ExitCode.LimitReached;
216
218
  }
217
219
  if (last?.stopReason === "error" || last?.stopReason === "aborted") {
218
- io.stderr(`ama: ${last.errorMessage ?? "模型调用失败"}\n`);
220
+ io.stderr(`ama: ${last.errorMessage ?? msg().print.print.modelFailed}\n`);
219
221
  return ExitCode.RuntimeError;
220
222
  }
221
223
  if (denied.length > 0)
@@ -231,15 +233,14 @@ export async function runPrintMode(runtime, context) {
231
233
  /** stderr 一行:计划已落盘待审批(-p 不替人批准)。 */
232
234
  export function describePlanPending(plan) {
233
235
  const where = plan.filePath ?? plan.planId;
234
- return (`ama: 计划 v${plan.version} 已落盘、待审批(未执行):${where};-p 不替人批准——` +
235
- "在交互界面或 RPC plan_response 里审批,或设 plan.unattended: approve 让 -p 批准后接着执行");
236
+ return msg().print.print.planPending(plan.version, where);
236
237
  }
237
238
  /** stderr 一行:哪个预算到限。 */
238
239
  export function describeLimit(event) {
240
+ const m = msg().print.print;
239
241
  return event.kind === "turns"
240
- ? `ama: 已达到回合上限 ${event.limit}(--max-turns / limits.maxTurns),运行在完成前结束`
241
- : `ama: 已达到费用上限 ${formatUsd(event.limit)}(累计 ${formatUsd(event.value)};` +
242
- "--max-cost / limits.maxCostUsd),运行在完成前结束";
242
+ ? m.limitTurns(event.limit)
243
+ : m.limitCost(formatUsd(event.limit), formatUsd(event.value));
243
244
  }
244
245
  function textOf(event) {
245
246
  const content = event.result.content;
@@ -253,8 +254,6 @@ export function describeDenied(denied) {
253
254
  const counts = new Map();
254
255
  for (const item of denied)
255
256
  counts.set(item.toolName, (counts.get(item.toolName) ?? 0) + 1);
256
- const tools = [...counts].map(([name, n]) => `${name} ×${n}`).join("、");
257
- const reason = denied[0]?.reason ?? "";
258
- return (`ama: ${denied.length} 次工具调用被拒:${tools}${reason !== "" ? `(${reason})` : ""};` +
259
- "-p 没有人审批,需要放行时用 --permission-mode auto-edit|auto 或 --allow <规则>");
257
+ const tools = [...counts].map(([name, n]) => `${name} ×${n}`);
258
+ return msg().print.print.denied(denied.length, tools, denied[0]?.reason ?? "");
260
259
  }
@@ -22,6 +22,8 @@ import { AmaError } from "../../errors.js";
22
22
  import { isPermissionMode } from "../../permissions/modes.js";
23
23
  import { PERMISSION_MODES_STRICT_FIRST } from "../../permissions/types.js";
24
24
  import { BUILTIN_COMMANDS } from "../commands-core.js";
25
+ import { msg } from "../../i18n/index.js";
26
+ import { sessionTrace } from "../../trace/query-session.js";
25
27
  /** 审批 broker:等客户端 `permission_response`。 */
26
28
  export class RpcApprovals {
27
29
  pending = new Map();
@@ -65,13 +67,13 @@ export class RpcApprovals {
65
67
  function impl(session) {
66
68
  if (session instanceof AgentSessionImpl)
67
69
  return session;
68
- throw new AmaError("not_implemented", "该会话不支持此命令");
70
+ throw new AmaError("not_implemented", msg().print.rpc.unsupported);
69
71
  }
70
72
  /** [W5-F] 当前会话的计划控制面;会话没有装配 plan 扩展时报 not_implemented。 */
71
73
  function plans(ctx) {
72
74
  const controller = planController(ctx.session());
73
75
  if (controller === undefined)
74
- throw new AmaError("not_implemented", "该会话没有装配 plan 扩展");
76
+ throw new AmaError("not_implemented", msg().print.rpc.noPlan);
75
77
  return controller;
76
78
  }
77
79
  /** 声明了 `plans` 能力 → 客户端作答;否则按 `plan.unattended`。换会话后重新应用。 */
@@ -286,7 +288,7 @@ export const handlers = {
286
288
  },
287
289
  set_permission_mode: async (p, ctx) => {
288
290
  if (!isPermissionMode(p.mode)) {
289
- throw new AmaError("invalid_arguments", `mode 应为 ${PERMISSION_MODES_STRICT_FIRST.join(" | ")}`);
291
+ throw new AmaError("invalid_arguments", msg().print.rpc.badMode(PERMISSION_MODES_STRICT_FIRST));
290
292
  }
291
293
  ctx.session().setPermissionMode(p.mode);
292
294
  return { mode: p.mode };
@@ -308,5 +310,7 @@ export const handlers = {
308
310
  get_todos: async (_p, ctx) => ({ items: currentTodos(impl(ctx.session()).manager.branch()) }),
309
311
  get_tasks: async (_p, ctx) => ({ tasks: [...(ctx.tasks?.()?.list() ?? [])] }),
310
312
  get_agents: async (_p, ctx) => ({ agents: [...(ctx.agents?.() ?? [])] }),
313
+ // [W6-T2] 轨迹(docs/wave6-plan.md §2.6;分页 / 增量 / 脱敏见 trace/query.ts)
314
+ get_trace: async (p, ctx) => sessionTrace(ctx.session(), p ?? {}),
311
315
  };
312
316
  export const RPC_COMMAND_TYPES = Object.keys(handlers);
@@ -23,6 +23,7 @@ import { sessionAgents, taskRegistryView } from "../../agent/subagent-registry.j
23
23
  import { cachedAgentInfos } from "../../agents/external.js";
24
24
  import { RpcApprovals, handlers } from "./commands.js";
25
25
  import { createLineReader, writeChunked } from "./jsonl.js";
26
+ import { msg } from "../../i18n/index.js";
26
27
  export const RPC_CAPABILITIES = ["approvals", "images", "hooks", "plans"];
27
28
  export async function runRpcMode(runtime, context, options = {}) {
28
29
  const stdin = options.stdin ?? process.stdin;
@@ -79,7 +80,7 @@ export async function runRpcMode(runtime, context, options = {}) {
79
80
  type: "response",
80
81
  command: type,
81
82
  success: false,
82
- error: `未知命令:${String(type)}`,
83
+ error: msg().print.rpc.unknownCommand(String(type)),
83
84
  code: "invalid_arguments",
84
85
  });
85
86
  return;
@@ -116,12 +117,17 @@ export async function runRpcMode(runtime, context, options = {}) {
116
117
  type: "response",
117
118
  command: "parse",
118
119
  success: false,
119
- error: `JSON 解析失败:${errorText(error)}`,
120
+ error: msg().print.rpc.parseFailed(errorText(error)),
120
121
  });
121
122
  return;
122
123
  }
123
124
  if (typeof command !== "object" || command === null || typeof command.type !== "string") {
124
- void write({ type: "response", command: "parse", success: false, error: "缺少 type" });
125
+ void write({
126
+ type: "response",
127
+ command: "parse",
128
+ success: false,
129
+ error: msg().print.rpc.missingType,
130
+ });
125
131
  return;
126
132
  }
127
133
  const task = respond(command).finally(() => inflight.delete(task));
@@ -58,6 +58,8 @@ export declare function externalUsageText(usage: {
58
58
  export declare function externalRows(session: AgentSession): KeyValueRow[];
59
59
  /** [W5-U] 子 Agent 任务汇总(`getStats().tasks`);没有任务时 undefined。 */
60
60
  export declare function taskStatsText(session: AgentSession): string | undefined;
61
+ /** [W6-O] 「订阅用量」段(`getStats().subscription`):按供应商列请求与 token、缓存只给命中率;附最近配额。 */
62
+ export declare function subscriptionRows(session: AgentSession, now?: number): KeyValueRow[];
61
63
  /** 键值行 → 纯文本(键列对齐、去行尾空白)。 */
62
64
  export declare function renderRows(rows: readonly KeyValueRow[], indent?: string): string[];
63
65
  export declare function describeCache(session: AgentSession, now?: number): string;
@@ -12,6 +12,8 @@
12
12
  import { AgentSessionImpl } from "../agent/session.js";
13
13
  import { MISS_NOTICE_TOKENS, MISS_NOTICE_USD } from "../ai/cache/miss.js";
14
14
  import { KeyValue } from "../tui/components/key-value.js";
15
+ import { quotaParts } from "../auth/chatgpt/quota-text.js";
16
+ import { msg } from "../i18n/index.js";
15
17
  const REPORT_WIDTH = 240;
16
18
  /** `950`、`38.2k`、`150k`、`1.05M`(比状态栏多一位精度,面板与提示用)。 */
17
19
  export function formatTokenCount(count) {
@@ -44,33 +46,28 @@ export function formatDuration(ms) {
44
46
  return rest === 0 ? `${minutes}m` : `${minutes}m ${rest}s`;
45
47
  }
46
48
  export function reportingLabel(reporting) {
47
- return reporting === "reported" ? "reported" : reporting === "silent" ? "未报告" : "未知";
49
+ const m = msg().report.cache;
50
+ return reporting === "reported" ? "reported" : reporting === "silent" ? m.unreported : m.unknown;
48
51
  }
49
- const REASON_LABELS = {
50
- prefix_changed: "前缀变化",
51
- model_changed: "切换模型",
52
- idle: "空闲超时",
53
- subtask: "子任务",
54
- evicted: "服务端淘汰",
55
- };
56
52
  /** 未命中原因的短语(提示行括号里那段)。 */
57
53
  export function missReasonText(miss) {
58
54
  const minutes = Math.max(1, Math.round(miss.idleMs / 60_000));
55
+ const m = msg().report.cache;
59
56
  switch (miss.reason) {
60
57
  case "idle":
61
- return `空闲 ${minutes} 分钟后`;
58
+ return m.missIdle(minutes);
62
59
  case "subtask":
63
- return `子任务运行 ${minutes} 分钟后`;
60
+ return m.missSubtask(minutes);
64
61
  case "model_changed":
65
- return "切换模型后";
62
+ return m.missModel;
66
63
  case "prefix_changed":
67
64
  return miss.detail === "tools"
68
- ? "工具表变化"
65
+ ? m.missTools
69
66
  : miss.detail === "system"
70
- ? "系统提示变化"
71
- : "前缀变化";
67
+ ? m.missSystem
68
+ : m.missPrefix;
72
69
  case "evicted":
73
- return "服务端已淘汰";
70
+ return m.missEvicted;
74
71
  }
75
72
  }
76
73
  export function shouldNotifyMiss(miss) {
@@ -79,17 +76,17 @@ export function shouldNotifyMiss(miss) {
79
76
  }
80
77
  /** `缓存未命中(空闲 7 分钟后):重计费 38.2k token(约 $0.11)`。 */
81
78
  export function cacheMissNotice(miss) {
82
- const cost = miss.missedCost === undefined ? "" : `(约 ${formatUsd(miss.missedCost)})`;
83
- return `缓存未命中(${missReasonText(miss)}):重计费 ${formatTokenCount(miss.missedTokens)} token${cost}`;
79
+ return msg().report.cache.missNotice(missReasonText(miss), formatTokenCount(miss.missedTokens), miss.missedCost === undefined ? undefined : formatUsd(miss.missedCost));
84
80
  }
85
81
  /** `上下文已用 72%,约剩 9 回合(按最近 5 回合均值)`;估不出回合时给余量 token。 */
86
82
  export function contextPressureNotice(event) {
87
- const head = `上下文已用 ${Math.round(event.percent)}%`;
83
+ const m = msg().report.cache;
84
+ const percent = Math.round(event.percent);
88
85
  if (event.estimatedTurnsLeft !== undefined)
89
- return `${head},约剩 ${event.estimatedTurnsLeft} 回合(按最近 5 回合均值)`;
86
+ return m.pressureTurns(percent, event.estimatedTurnsLeft);
90
87
  if (event.remainingTokens !== undefined)
91
- return `${head},余量 ${formatTokenCount(event.remainingTokens)} token`;
92
- return head;
88
+ return m.pressureTokens(percent, formatTokenCount(event.remainingTokens));
89
+ return m.pressure(percent);
93
90
  }
94
91
  /**
95
92
  * 缓存事件 → 消息区 / stderr 的一行提示;不提示时 undefined。`enabled` = `cache.missNotices`。
@@ -111,67 +108,50 @@ export function cacheEventNotice(event, enabled) {
111
108
  export function warmSentNotice(event) {
112
109
  if (event.phase !== "sent")
113
110
  return undefined;
114
- const read = event.usage === undefined ? "" : `读 ${formatTokenCount(event.usage.cacheRead)} token`;
115
- const cost = event.cost === undefined ? "" : `${read !== "" ? "," : ""}${formatUsd(event.cost)}`;
116
- return `缓存保温已刷新${read + cost !== "" ? `(${read}${cost})` : ""}`;
111
+ return msg().report.cache.warmSent(event.usage === undefined ? undefined : formatTokenCount(event.usage.cacheRead), event.cost === undefined ? undefined : formatUsd(event.cost));
117
112
  }
118
113
  /** 消息区 / stderr 是否提示未命中与上下文余量(`cache.missNotices`,缺省 true)。 */
119
114
  export function cacheNoticesEnabled(session) {
120
115
  return session instanceof AgentSessionImpl ? session.cache.cacheSettings.missNotices : true;
121
116
  }
122
- const STOP_REASONS = {
123
- retention_none: "缓存保留为 none",
124
- payload_replaced: "请求体被 onPayload 替换",
125
- thinking_budget: "思考预算随 max_tokens,不可重放",
126
- reporting_unknown: "端点还没报过缓存",
127
- reporting_silent: "端点不报缓存",
128
- no_ttl: "模型目录没有缓存 TTL",
129
- ttl_too_short: "缓存 TTL 太短",
130
- max_duration: "已达保温时长上限",
131
- late: "计时器迟到",
132
- off: "已关闭",
133
- stale: "上下文已变",
134
- declined: "宿主否决",
135
- error: "保温请求失败",
136
- no_cache_hits: "连续保温零命中",
137
- no_price: "缺价格,经济性不可算",
138
- below_min_savings: "期望节省低于门槛",
139
- };
140
117
  export function warmStopText(reason) {
118
+ const m = msg().report.cache;
141
119
  if (reason === undefined)
142
- return "已停止";
143
- return `已停止:${STOP_REASONS[reason] ?? reason}`;
120
+ return m.stopped;
121
+ return m.stoppedWith(m.stopReason(reason));
144
122
  }
145
123
  /** `streaming · 下次 2m 10s · 期望节省 $0.18 ≥ $0.05 · 已发 2 次 $0.01`。 */
146
124
  export function warmingText(status, now, minSavingsUsd) {
147
125
  if (status.mode === "off")
148
126
  return "off";
127
+ const m = msg().report.cache;
149
128
  const parts = [status.mode];
150
129
  if (status.state === "scheduled") {
151
130
  if (status.nextWarmAt !== undefined)
152
- parts.push(`下次 ${formatDuration(status.nextWarmAt - now)}`);
131
+ parts.push(m.next(formatDuration(status.nextWarmAt - now)));
153
132
  if (status.expectedSavingsUsd !== undefined) {
154
- const floor = minSavingsUsd === undefined ? "" : ` ≥ ${formatUsd(minSavingsUsd)}`;
155
- parts.push(`期望节省 ${formatUsd(status.expectedSavingsUsd)}${floor}`);
133
+ const floor = minSavingsUsd === undefined ? undefined : formatUsd(minSavingsUsd);
134
+ parts.push(m.savings(formatUsd(status.expectedSavingsUsd), floor));
156
135
  }
157
136
  }
158
137
  else if (status.state === "stopped")
159
138
  parts.push(warmStopText(status.reason));
160
139
  else
161
- parts.push("待下一次请求");
140
+ parts.push(m.pending);
162
141
  if (status.sent !== undefined && status.sent > 0)
163
- parts.push(`已发 ${status.sent} 次 ${formatUsd(status.costUsd)}`);
142
+ parts.push(m.sent(status.sent, formatUsd(status.costUsd)));
164
143
  return parts.join(" · ");
165
144
  }
166
145
  function missesText(cache) {
146
+ const m = msg().report.cache;
167
147
  if (cache.misses.count === 0)
168
- return "0 次";
148
+ return m.missesNone;
169
149
  const by = Object.entries(cache.misses.byReason)
170
150
  .filter(([, n]) => n !== undefined && n > 0)
171
- .map(([reason, n]) => `${REASON_LABELS[reason] ?? reason} ${n}`)
151
+ .map(([reason, n]) => `${m.reason(reason) ?? reason} ${n}`)
172
152
  .join(" · ");
173
153
  const cost = cache.reBilledUsd === undefined ? "$?" : formatUsd(cache.reBilledUsd);
174
- return `${cache.misses.count} 次,重计费 ${formatTokenCount(cache.reBilledTokens)} token ≈ ${cost}${by !== "" ? `(${by})` : ""}`;
154
+ return m.misses(cache.misses.count, formatTokenCount(cache.reBilledTokens), cost, by);
175
155
  }
176
156
  /** 缓存段的键值行(`/session` 与 `/cache` 共用)。 */
177
157
  export function cacheRows(session, now = Date.now()) {
@@ -179,57 +159,57 @@ export function cacheRows(session, now = Date.now()) {
179
159
  const t = stats.tokens;
180
160
  const prompt = t.input + t.cacheRead + t.cacheWrite;
181
161
  const uncached = t.input + t.cacheWrite;
182
- const readShare = prompt > 0 ? `(${formatPercent(t.cacheRead / prompt)})` : " ";
183
- const write = t.cacheWrite > 0 ? `(其中写入 ${formatTokenCount(t.cacheWrite)})` : "";
162
+ const m = msg().report.cache;
184
163
  const rows = [
185
164
  {
186
- key: "输入",
187
- value: `${formatTokenCount(prompt)} = 缓存读 ${formatTokenCount(t.cacheRead)}${readShare}+ 未缓存 ${formatTokenCount(uncached)}${write}`,
165
+ key: m.keyInput,
166
+ value: m.input(formatTokenCount(prompt), formatTokenCount(t.cacheRead), prompt > 0 ? formatPercent(t.cacheRead / prompt) : undefined, formatTokenCount(uncached), t.cacheWrite > 0 ? formatTokenCount(t.cacheWrite) : undefined),
188
167
  },
189
168
  ];
190
169
  const cache = stats.cache;
191
170
  if (cache === undefined) {
192
- rows.push({ key: "命中率", value: `会话 ${formatPercent(stats.cacheHitRate)}` });
171
+ rows.push({ key: m.keyHitRate, value: m.sessionRate(formatPercent(stats.cacheHitRate)) });
193
172
  return rows;
194
173
  }
195
- rows.push({ key: "报告状态", value: reportingLabel(cache.reporting) });
174
+ rows.push({ key: m.keyReporting, value: reportingLabel(cache.reporting) });
196
175
  if (cache.reporting === "reported") {
197
176
  rows.push({
198
- key: "命中率",
199
- value: `最近 ${formatPercent(cache.lastHitRate)} · 会话 ${formatPercent(cache.hitRate)}`,
177
+ key: m.keyHitRate,
178
+ value: m.rates(formatPercent(cache.lastHitRate), formatPercent(cache.hitRate)),
200
179
  });
201
180
  }
202
- rows.push({ key: "未命中", value: missesText(cache) });
181
+ rows.push({ key: m.keyMisses, value: missesText(cache) });
203
182
  const minSavings = session instanceof AgentSessionImpl ? session.cache.cacheSettings.minSavingsUsd : undefined;
204
- rows.push({ key: "保温", value: warmingText(cache.warming, now, minSavings) });
183
+ rows.push({ key: m.keyWarming, value: warmingText(cache.warming, now, minSavings) });
205
184
  if (stats.contextPercent !== undefined) {
206
- const remaining = cache.contextRemainingTokens === undefined
207
- ? ""
208
- : `,余量 ≈ ${formatTokenCount(cache.contextRemainingTokens)} token`;
209
- const turns = cache.estimatedTurnsLeft === undefined ? "" : ` ≈ ${cache.estimatedTurnsLeft} 回合`;
210
- rows.push({ key: "上下文", value: `${Math.round(stats.contextPercent)}%${remaining}${turns}` });
185
+ rows.push({
186
+ key: m.keyContext,
187
+ value: m.context(Math.round(stats.contextPercent), cache.contextRemainingTokens === undefined
188
+ ? undefined
189
+ : formatTokenCount(cache.contextRemainingTokens), cache.estimatedTurnsLeft),
190
+ });
211
191
  }
212
192
  if (cache.subagents !== undefined) {
213
193
  const sub = cache.subagents;
214
- const rebill = sub.reBilledTokens > 0 ? `,重计费 ${formatTokenCount(sub.reBilledTokens)} token` : "";
215
194
  rows.push({
216
- key: "子任务",
217
- value: `${sub.count} 个会话,命中率 ${formatPercent(sub.hitRate)}${rebill}`,
195
+ key: m.keySubtasks,
196
+ value: m.subtasks(sub.count, formatPercent(sub.hitRate), sub.reBilledTokens > 0 ? formatTokenCount(sub.reBilledTokens) : undefined),
218
197
  });
219
198
  }
220
199
  return rows;
221
200
  }
222
201
  /** [W5-U] 外部 Agent 用量一项:美元 / token / 请求数按各自单位,不换算。 */
223
202
  export function externalUsageText(usage) {
203
+ const m = msg().report.session;
224
204
  const amount = usage.unit === "usd"
225
205
  ? formatUsd(usage.amount)
226
206
  : usage.unit === "tokens"
227
- ? `${formatTokenCount(usage.amount)} token`
228
- : `${usage.amount} 次请求`;
207
+ ? m.externalTokens(formatTokenCount(usage.amount))
208
+ : m.externalRequests(usage.amount);
229
209
  const tokens = usage.unit !== "tokens" && usage.tokens !== undefined && usage.tokens > 0
230
- ? ` · ${formatTokenCount(usage.tokens)} token`
231
- : "";
232
- return `${usage.runs} 次运行 · ${amount}${tokens}`;
210
+ ? formatTokenCount(usage.tokens)
211
+ : undefined;
212
+ return m.external(usage.runs, amount, tokens);
233
213
  }
234
214
  /** [W5-U] 「外部 Agent」段(`getStats().external.byAgent`);没有外部运行时为空。 */
235
215
  export function externalRows(session) {
@@ -243,20 +223,34 @@ export function taskStatsText(session) {
243
223
  const tasks = session.getStats().tasks;
244
224
  if (tasks === undefined || tasks.total === 0)
245
225
  return undefined;
246
- const parts = [`${tasks.total} 个任务`];
226
+ const m = msg().report.session;
227
+ const parts = [m.tasks(tasks.total)];
247
228
  if (tasks.running > 0)
248
- parts.push(`运行中 ${tasks.running}`);
249
- const labels = {
250
- completed: "完成",
251
- failed: "失败",
252
- aborted: "已停止",
253
- max_turns: "轮数耗尽",
254
- interrupted: "已中断",
255
- };
229
+ parts.push(m.running(tasks.running));
256
230
  for (const [status, count] of Object.entries(tasks.byStatus))
257
231
  if (count !== undefined && count > 0)
258
- parts.push(`${labels[status] ?? status} ${count}`);
259
- return `${parts.join(" · ")}(/tasks)`;
232
+ parts.push(m.status(status, count));
233
+ return m.tasksLine(parts);
234
+ }
235
+ /** [W6-O] 「订阅用量」段(`getStats().subscription`):按供应商列请求与 token、缓存只给命中率;附最近配额。 */
236
+ export function subscriptionRows(session, now = Date.now()) {
237
+ const sub = session.getStats().subscription;
238
+ if (sub === undefined)
239
+ return [];
240
+ const m = msg().auth.report;
241
+ const rows = Object.entries(sub.byProvider)
242
+ .sort(([a], [b]) => a.localeCompare(b))
243
+ .map(([provider, u]) => {
244
+ const prompt = u.input + u.cacheRead;
245
+ return {
246
+ key: provider,
247
+ value: m.row(u.requests, formatTokenCount(u.input), formatTokenCount(u.output), formatTokenCount(u.cacheRead), formatPercent(prompt > 0 ? u.cacheRead / prompt : undefined)),
248
+ };
249
+ });
250
+ const quota = sub.quota === undefined ? undefined : quotaParts(sub.quota, now);
251
+ if (quota !== undefined)
252
+ rows.push({ key: m.quotaKey, value: quota });
253
+ return rows;
260
254
  }
261
255
  /** 键值行 → 纯文本(键列对齐、去行尾空白)。 */
262
256
  export function renderRows(rows, indent = "") {
@@ -265,7 +259,7 @@ export function renderRows(rows, indent = "") {
265
259
  .map((line) => (line === "" ? "" : `${indent}${line}`.replace(/\s+$/, "")));
266
260
  }
267
261
  export function describeCache(session, now = Date.now()) {
268
- return ["缓存", ...renderRows(cacheRows(session, now), " ")].join("\n");
262
+ return [msg().report.cache.title, ...renderRows(cacheRows(session, now), " ")].join("\n");
269
263
  }
270
264
  export function describeSession(session, now = Date.now()) {
271
265
  const state = session.state;
@@ -273,49 +267,51 @@ export function describeSession(session, now = Date.now()) {
273
267
  const model = state.model === undefined ? "?" : `${state.model.provider}/${state.model.id}`;
274
268
  const t = stats.tokens;
275
269
  const percent = stats.contextPercent === undefined ? "?" : `${Math.round(stats.contextPercent)}`;
270
+ const m = msg().report.session;
276
271
  const rows = [
272
+ { key: m.keySession, value: m.session(state.sessionId, state.sessionFile) },
277
273
  {
278
- key: "会话",
279
- value: `${state.sessionId}${state.sessionFile !== undefined ? `(${state.sessionFile})` : "(未落盘)"}`,
280
- },
281
- {
282
- key: "模型",
283
- value: `${model} · 思考 ${state.thinkingLevel} · 权限 ${state.permissionMode}`,
274
+ key: m.keyModel,
275
+ value: m.model(model, state.thinkingLevel, state.permissionMode),
284
276
  },
285
277
  {
286
- key: "消息",
287
- value: `用户 ${stats.userMessages} · 助手 ${stats.assistantMessages} · 工具调用 ${stats.toolCalls}`,
278
+ key: m.keyMessages,
279
+ value: m.messages(stats.userMessages, stats.assistantMessages, stats.toolCalls),
288
280
  },
289
281
  {
290
- key: "用量",
291
- value: `输入 ${t.input} · 输出 ${t.output} · 缓存读 ${t.cacheRead} · 缓存写 ${t.cacheWrite}` +
292
- (stats.cost !== undefined ? ` · $${stats.cost.toFixed(4)}` : " · $?"),
282
+ key: m.keyUsage,
283
+ value: m.usage(t.input, t.output, t.cacheRead, t.cacheWrite, stats.cost !== undefined ? `$${stats.cost.toFixed(4)}` : "$?"),
293
284
  },
294
285
  {
295
- key: "上下文",
296
- value: `${stats.contextTokens ?? "?"} / ${stats.contextWindow ?? "?"}(${percent}%)`,
286
+ key: m.keyContext,
287
+ value: m.context(String(stats.contextTokens ?? "?"), String(stats.contextWindow ?? "?"), percent),
297
288
  },
298
289
  ];
299
290
  const tasks = taskStatsText(session);
300
291
  if (tasks !== undefined)
301
- rows.push({ key: "子 Agent", value: tasks });
292
+ rows.push({ key: m.keyAgents, value: tasks });
302
293
  const external = externalRows(session);
294
+ const subscription = subscriptionRows(session, now);
303
295
  return [
304
296
  ...renderRows(rows),
305
297
  describeCache(session, now),
306
- ...(external.length > 0 ? ["外部 Agent", ...renderRows(external, " ")] : []),
298
+ ...(subscription.length > 0
299
+ ? [msg().auth.report.section, ...renderRows(subscription, " ")]
300
+ : []),
301
+ ...(external.length > 0 ? [m.externalTitle, ...renderRows(external, " ")] : []),
307
302
  ].join("\n");
308
303
  }
309
304
  /** `/cache fingerprint`:最近一次真实请求的前缀指纹(system / tools 哈希与模型)。 */
310
305
  export function describeFingerprint(session) {
306
+ const m = msg().report.session;
311
307
  if (!(session instanceof AgentSessionImpl))
312
- return "当前会话不提供前缀指纹";
308
+ return m.noFingerprint;
313
309
  const record = session.cache.lastTurn;
314
310
  if (record === undefined)
315
- return "还没有真实请求(指纹在第一次请求后记录)";
311
+ return m.noRequestYet;
316
312
  const f = record.fingerprint;
317
313
  return [
318
- "前缀指纹(最近一次请求)",
314
+ m.fingerprintTitle,
319
315
  ...renderRows([
320
316
  { key: "system", value: f.system },
321
317
  { key: "tools", value: f.tools },
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import { existsSync, statSync } from "node:fs";
8
8
  import { resolve } from "node:path";
9
+ import { msg } from "../i18n/index.js";
9
10
  /** 读一行(不含行尾);EOF 且无内容返回 undefined。 */
10
11
  export function readOneLine(stdin) {
11
12
  if (stdin.readableEnded === true)
@@ -61,10 +62,11 @@ export function createTextStartupUi(io) {
61
62
  const list = (values, labels) => values.map((_, i) => ` ${i + 1}. ${labels[i]}`);
62
63
  return {
63
64
  async promptTrust(cwd, resources) {
65
+ const m = msg().report.startup;
64
66
  const shown = resources.slice(0, 6).map((p) => ` ${p}`);
65
67
  if (resources.length > shown.length)
66
- shown.push(` …另有 ${resources.length - shown.length} 项`);
67
- const answer = await ask([`信任这个目录的项目资源?${cwd}`, ...shown], "[y 仅本次 / a 信任并记住 / N 不信任] ");
68
+ shown.push(m.more(resources.length - shown.length));
69
+ const answer = await ask([m.trustQuestion(cwd), ...shown], m.trustChoices);
68
70
  const key = answer?.trim().toLowerCase();
69
71
  if (key === "a")
70
72
  return { trusted: true, remember: true };
@@ -76,7 +78,8 @@ export function createTextStartupUi(io) {
76
78
  const sorted = [...items].sort((a, b) => b.modifiedAt.localeCompare(a.modifiedAt));
77
79
  const ids = sorted.map((item) => item.id);
78
80
  const labels = sorted.map((item) => `${item.id.slice(0, 8)} ${(item.name ?? item.firstPrompt ?? "").replace(/\s+/g, " ").slice(0, 60)}`);
79
- return choose(await ask(["恢复哪个会话?", ...list(ids, labels)], "编号或 id:"), ids);
81
+ const m = msg().report.startup;
82
+ return choose(await ask([m.resumeQuestion, ...list(ids, labels)], m.resumeAnswer), ids);
80
83
  },
81
84
  async pickModel(providers, reason) {
82
85
  const refs = [];
@@ -85,16 +88,18 @@ export function createTextStartupUi(io) {
85
88
  refs.push(`${provider.id}/${model.id}`);
86
89
  if (refs.length === 0)
87
90
  return undefined;
88
- const answer = await ask([reason, "选择模型:", ...list(refs, refs)], "编号或 provider/id:");
91
+ const m = msg().report.startup;
92
+ const answer = await ask([reason, m.pickModel, ...list(refs, refs)], m.pickModelAnswer);
89
93
  return choose(answer, refs);
90
94
  },
91
95
  async askCwd(missing) {
92
- const answer = (await ask([`会话的工作目录不存在:${missing}`], "替代目录(空行取消):"))?.trim();
96
+ const m = msg().report.startup;
97
+ const answer = (await ask([m.cwdMissing(missing)], m.cwdAnswer))?.trim();
93
98
  if (answer === undefined || answer === "")
94
99
  return undefined;
95
100
  const abs = resolve(answer);
96
101
  if (!existsSync(abs) || !isDirectory(abs)) {
97
- io.write(`不是目录:${abs}\n`);
102
+ io.write(m.notDirectory(abs));
98
103
  return undefined;
99
104
  }
100
105
  return abs;
@@ -9,20 +9,18 @@
9
9
  */
10
10
  import type { PermissionMode } from "./types.js";
11
11
  export declare const BYPASS_MODE: PermissionMode;
12
- export declare const BYPASS_CONFIRM_TITLE = "\u8FDB\u5165 Bypass permissions\uFF1F";
12
+ /** 确认框标题(随界面语言)。 */
13
+ export declare function bypassConfirmTitle(): string;
13
14
  /** 确认框正文:Bypass 意味着什么(一两条关键风险)。 */
14
- export declare const BYPASS_RISK_LINES: readonly string[];
15
+ export declare function bypassRiskLines(): string[];
15
16
  /** 选项:缺省选中「取消」。 */
16
- export declare const BYPASS_CHOICES: readonly [{
17
- readonly label: "进入 Bypass";
18
- readonly keys: "y";
19
- }, {
20
- readonly label: "取消";
21
- readonly keys: "n Esc";
22
- }];
17
+ export declare function bypassChoices(): {
18
+ label: string;
19
+ keys: string;
20
+ }[];
23
21
  export declare const BYPASS_DEFAULT_CHOICE = 1;
24
22
  /** 行式界面的问句(单键 y/N,缺省 N)。 */
25
- export declare const BYPASS_LINE_QUESTION = "\u786E\u8BA4\u8FDB\u5165 Bypass\uFF1F[y/N] ";
23
+ export declare function bypassLineQuestion(): string;
26
24
  /** 不用问时同步返回 true(切换立即生效);要问时返回等用户回答的 Promise。 */
27
25
  export type BypassGate = (mode: PermissionMode) => boolean | Promise<boolean>;
28
26
  /**