@armadra/agent 0.5.1 → 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 (467) hide show
  1. package/CHANGELOG.md +177 -304
  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 +25928 -11144
  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.js +8 -6
  103. package/dist/cli/codemode-notice.js +2 -2
  104. package/dist/cli/compose-agents.js +2 -1
  105. package/dist/cli/compose-extensions.js +2 -0
  106. package/dist/cli/compose-memory.d.ts +53 -0
  107. package/dist/cli/compose-memory.js +127 -0
  108. package/dist/cli/compose-providers.d.ts +5 -0
  109. package/dist/cli/compose-providers.js +32 -2
  110. package/dist/cli/compose-session.d.ts +5 -0
  111. package/dist/cli/compose-session.js +27 -13
  112. package/dist/cli/compose-store.d.ts +2 -0
  113. package/dist/cli/compose-store.js +9 -5
  114. package/dist/cli/compose.d.ts +2 -0
  115. package/dist/cli/compose.js +13 -5
  116. package/dist/cli/default-model.d.ts +0 -2
  117. package/dist/cli/default-model.js +5 -8
  118. package/dist/cli/deps.d.ts +5 -1
  119. package/dist/cli/exit-codes.d.ts +1 -1
  120. package/dist/cli/exit-codes.js +7 -16
  121. package/dist/cli/from-prompt.js +3 -2
  122. package/dist/cli/help-text.d.ts +2 -1
  123. package/dist/cli/help-text.js +5 -99
  124. package/dist/cli/main.d.ts +5 -0
  125. package/dist/cli/main.js +21 -2
  126. package/dist/cli/proxy.js +14 -9
  127. package/dist/cli/runtime.d.ts +5 -0
  128. package/dist/cli/startup-screen.js +20 -27
  129. package/dist/cli/startup-steps.js +6 -8
  130. package/dist/cli/subcommands/auth.d.ts +6 -3
  131. package/dist/cli/subcommands/auth.js +52 -22
  132. package/dist/cli/subcommands/config-set.d.ts +21 -0
  133. package/dist/cli/subcommands/config-set.js +137 -0
  134. package/dist/cli/subcommands/config.d.ts +2 -1
  135. package/dist/cli/subcommands/config.js +51 -37
  136. package/dist/cli/subcommands/doctor.d.ts +2 -1
  137. package/dist/cli/subcommands/doctor.js +97 -58
  138. package/dist/cli/subcommands/init.d.ts +1 -1
  139. package/dist/cli/subcommands/init.js +8 -7
  140. package/dist/cli/subcommands/memory.d.ts +18 -0
  141. package/dist/cli/subcommands/memory.js +189 -0
  142. package/dist/cli/subcommands/model-meta.js +11 -9
  143. package/dist/cli/subcommands/models-cache-probe.js +23 -20
  144. package/dist/cli/subcommands/models-discover.d.ts +3 -0
  145. package/dist/cli/subcommands/models-discover.js +44 -21
  146. package/dist/cli/subcommands/models.d.ts +1 -1
  147. package/dist/cli/subcommands/models.js +29 -22
  148. package/dist/cli/subcommands/probe-runner.js +8 -7
  149. package/dist/cli/subcommands/providers-list.js +32 -21
  150. package/dist/cli/subcommands/providers-plan.js +24 -25
  151. package/dist/cli/subcommands/providers-probe.js +5 -6
  152. package/dist/cli/subcommands/providers.d.ts +1 -1
  153. package/dist/cli/subcommands/providers.js +45 -50
  154. package/dist/cli/subcommands/sessions-export.d.ts +1 -1
  155. package/dist/cli/subcommands/sessions-export.js +10 -9
  156. package/dist/cli/subcommands/sessions-search.d.ts +1 -1
  157. package/dist/cli/subcommands/sessions-search.js +11 -10
  158. package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
  159. package/dist/cli/subcommands/sessions-trace.js +156 -0
  160. package/dist/cli/subcommands/sessions.d.ts +4 -3
  161. package/dist/cli/subcommands/sessions.js +40 -37
  162. package/dist/cli/subcommands/stats.d.ts +1 -1
  163. package/dist/cli/subcommands/stats.js +49 -30
  164. package/dist/cli/system-prompt-arg.js +3 -2
  165. package/dist/codemode/capability.js +3 -2
  166. package/dist/compaction/post-compact.d.ts +1 -0
  167. package/dist/compaction/post-compact.js +15 -1
  168. package/dist/compaction/prune-tier.d.ts +1 -1
  169. package/dist/compaction/prune-tier.js +3 -3
  170. package/dist/compaction/serialize.js +2 -1
  171. package/dist/config/auth-file.d.ts +12 -2
  172. package/dist/config/auth-file.js +32 -10
  173. package/dist/config/checker.js +12 -11
  174. package/dist/config/context-files.js +3 -2
  175. package/dist/config/edit.d.ts +106 -0
  176. package/dist/config/edit.js +350 -0
  177. package/dist/config/init.d.ts +4 -3
  178. package/dist/config/init.js +10 -18
  179. package/dist/config/json-schema.d.ts +2 -1
  180. package/dist/config/json-schema.js +101 -68
  181. package/dist/config/key-docs.d.ts +18 -7
  182. package/dist/config/key-docs.js +43 -128
  183. package/dist/config/load.js +7 -6
  184. package/dist/config/merge.d.ts +4 -1
  185. package/dist/config/merge.js +42 -22
  186. package/dist/config/paths.js +6 -5
  187. package/dist/config/profile.d.ts +5 -1
  188. package/dist/config/profile.js +7 -2
  189. package/dist/config/schema-w5.js +3 -2
  190. package/dist/config/schema-w6.d.ts +19 -0
  191. package/dist/config/schema-w6.js +115 -0
  192. package/dist/config/schema.js +34 -20
  193. package/dist/config/settings-registry.d.ts +78 -0
  194. package/dist/config/settings-registry.js +184 -0
  195. package/dist/config/types-w6.d.ts +109 -0
  196. package/dist/config/types-w6.js +19 -0
  197. package/dist/config/types.d.ts +11 -8
  198. package/dist/config/types.js +1 -0
  199. package/dist/drivers/acp/client.js +1 -1
  200. package/dist/drivers/acp/driver.js +13 -8
  201. package/dist/drivers/agents.js +4 -3
  202. package/dist/drivers/base.js +3 -2
  203. package/dist/drivers/host-runners.js +2 -1
  204. package/dist/drivers/native/claude-stream.js +12 -11
  205. package/dist/drivers/native/codex-app-server.js +17 -12
  206. package/dist/drivers/native/oneshot.js +8 -7
  207. package/dist/drivers/pool.js +1 -1
  208. package/dist/drivers/runner.d.ts +3 -1
  209. package/dist/drivers/runner.js +68 -20
  210. package/dist/drivers/turn.js +1 -1
  211. package/dist/hooks/config.js +3 -2
  212. package/dist/hooks/protocol.js +18 -12
  213. package/dist/host/api-impl.js +11 -10
  214. package/dist/host/loader.js +9 -8
  215. package/dist/host/types.d.ts +3 -0
  216. package/dist/i18n/catalog.d.ts +2169 -0
  217. package/dist/i18n/catalog.js +72 -0
  218. package/dist/i18n/format.d.ts +21 -0
  219. package/dist/i18n/format.js +58 -0
  220. package/dist/i18n/index.d.ts +58 -0
  221. package/dist/i18n/index.js +72 -0
  222. package/dist/i18n/messages/agents.d.ts +84 -0
  223. package/dist/i18n/messages/agents.js +85 -0
  224. package/dist/i18n/messages/approval.d.ts +99 -0
  225. package/dist/i18n/messages/approval.js +100 -0
  226. package/dist/i18n/messages/auth.d.ts +187 -0
  227. package/dist/i18n/messages/auth.js +189 -0
  228. package/dist/i18n/messages/cli-args.d.ts +46 -0
  229. package/dist/i18n/messages/cli-args.js +46 -0
  230. package/dist/i18n/messages/cli-help.d.ts +12 -0
  231. package/dist/i18n/messages/cli-help.js +244 -0
  232. package/dist/i18n/messages/cli.d.ts +336 -0
  233. package/dist/i18n/messages/cli.js +311 -0
  234. package/dist/i18n/messages/config-keys.d.ts +289 -0
  235. package/dist/i18n/messages/config-keys.js +292 -0
  236. package/dist/i18n/messages/config.d.ts +502 -0
  237. package/dist/i18n/messages/config.js +239 -0
  238. package/dist/i18n/messages/drivers.d.ts +123 -0
  239. package/dist/i18n/messages/drivers.js +124 -0
  240. package/dist/i18n/messages/errors.d.ts +83 -0
  241. package/dist/i18n/messages/errors.js +171 -0
  242. package/dist/i18n/messages/interactive-line.d.ts +61 -0
  243. package/dist/i18n/messages/interactive-line.js +69 -0
  244. package/dist/i18n/messages/interactive-startup.d.ts +103 -0
  245. package/dist/i18n/messages/interactive-startup.js +104 -0
  246. package/dist/i18n/messages/interactive-view.d.ts +140 -0
  247. package/dist/i18n/messages/interactive-view.js +141 -0
  248. package/dist/i18n/messages/interactive.d.ts +493 -0
  249. package/dist/i18n/messages/interactive.js +248 -0
  250. package/dist/i18n/messages/memory.d.ts +123 -0
  251. package/dist/i18n/messages/memory.js +128 -0
  252. package/dist/i18n/messages/panels.d.ts +190 -0
  253. package/dist/i18n/messages/panels.js +189 -0
  254. package/dist/i18n/messages/permissions.d.ts +126 -0
  255. package/dist/i18n/messages/permissions.js +151 -0
  256. package/dist/i18n/messages/plan.d.ts +123 -0
  257. package/dist/i18n/messages/plan.js +124 -0
  258. package/dist/i18n/messages/print.d.ts +86 -0
  259. package/dist/i18n/messages/print.js +91 -0
  260. package/dist/i18n/messages/report.d.ts +391 -0
  261. package/dist/i18n/messages/report.js +490 -0
  262. package/dist/i18n/messages/rewind.d.ts +198 -0
  263. package/dist/i18n/messages/rewind.js +217 -0
  264. package/dist/i18n/messages/session.d.ts +230 -0
  265. package/dist/i18n/messages/session.js +258 -0
  266. package/dist/i18n/messages/settings.d.ts +348 -0
  267. package/dist/i18n/messages/settings.js +336 -0
  268. package/dist/i18n/messages/subcommands-config.d.ts +111 -0
  269. package/dist/i18n/messages/subcommands-config.js +127 -0
  270. package/dist/i18n/messages/subcommands.d.ts +548 -0
  271. package/dist/i18n/messages/subcommands.js +474 -0
  272. package/dist/i18n/messages/trace.d.ts +243 -0
  273. package/dist/i18n/messages/trace.js +238 -0
  274. package/dist/i18n/types.d.ts +15 -0
  275. package/dist/i18n/types.js +7 -0
  276. package/dist/index.d.ts +6 -0
  277. package/dist/index.js +2 -0
  278. package/dist/memory/edit.d.ts +24 -0
  279. package/dist/memory/edit.js +63 -0
  280. package/dist/memory/frontmatter.d.ts +37 -0
  281. package/dist/memory/frontmatter.js +79 -0
  282. package/dist/memory/index.d.ts +28 -0
  283. package/dist/memory/index.js +126 -0
  284. package/dist/memory/lock.d.ts +17 -0
  285. package/dist/memory/lock.js +62 -0
  286. package/dist/memory/paths.d.ts +57 -0
  287. package/dist/memory/paths.js +175 -0
  288. package/dist/memory/report.d.ts +36 -0
  289. package/dist/memory/report.js +86 -0
  290. package/dist/memory/runtime.d.ts +42 -0
  291. package/dist/memory/runtime.js +36 -0
  292. package/dist/memory/secrets.d.ts +8 -0
  293. package/dist/memory/secrets.js +27 -0
  294. package/dist/memory/section.d.ts +28 -0
  295. package/dist/memory/section.js +59 -0
  296. package/dist/memory/store.d.ts +70 -0
  297. package/dist/memory/store.js +284 -0
  298. package/dist/memory/tool.d.ts +31 -0
  299. package/dist/memory/tool.js +94 -0
  300. package/dist/modes/acp/acp-events.js +2 -1
  301. package/dist/modes/acp/acp-server.js +13 -12
  302. package/dist/modes/commands-core.d.ts +11 -0
  303. package/dist/modes/commands-core.js +93 -62
  304. package/dist/modes/image-input.js +20 -6
  305. package/dist/modes/interactive/agent-bar.d.ts +95 -0
  306. package/dist/modes/interactive/agent-bar.js +248 -0
  307. package/dist/modes/interactive/agent-panels.js +27 -26
  308. package/dist/modes/interactive/agent-transcript.d.ts +47 -0
  309. package/dist/modes/interactive/agent-transcript.js +191 -0
  310. package/dist/modes/interactive/agent-ui.d.ts +36 -1
  311. package/dist/modes/interactive/agent-ui.js +180 -14
  312. package/dist/modes/interactive/agent-view.d.ts +72 -0
  313. package/dist/modes/interactive/agent-view.js +281 -0
  314. package/dist/modes/interactive/approval-dialog.js +46 -34
  315. package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
  316. package/dist/modes/interactive/clipboard-paste.js +9 -4
  317. package/dist/modes/interactive/commands.d.ts +19 -1
  318. package/dist/modes/interactive/commands.js +84 -40
  319. package/dist/modes/interactive/completion.js +2 -1
  320. package/dist/modes/interactive/config-panel.d.ts +70 -0
  321. package/dist/modes/interactive/config-panel.js +319 -0
  322. package/dist/modes/interactive/config-ui.d.ts +96 -0
  323. package/dist/modes/interactive/config-ui.js +397 -0
  324. package/dist/modes/interactive/confirm-dialog.js +6 -7
  325. package/dist/modes/interactive/event-notices.js +11 -9
  326. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  327. package/dist/modes/interactive/interactive-mode.js +19 -22
  328. package/dist/modes/interactive/key-dispatch.d.ts +12 -0
  329. package/dist/modes/interactive/key-dispatch.js +24 -9
  330. package/dist/modes/interactive/line/line-editor.js +2 -1
  331. package/dist/modes/interactive/line/line-mode.js +18 -7
  332. package/dist/modes/interactive/line/line-render.js +25 -24
  333. package/dist/modes/interactive/memory-panel.d.ts +64 -0
  334. package/dist/modes/interactive/memory-panel.js +221 -0
  335. package/dist/modes/interactive/message-view.d.ts +4 -2
  336. package/dist/modes/interactive/message-view.js +42 -33
  337. package/dist/modes/interactive/panels.js +39 -31
  338. package/dist/modes/interactive/pickers.d.ts +2 -1
  339. package/dist/modes/interactive/pickers.js +10 -6
  340. package/dist/modes/interactive/plan-command.d.ts +1 -1
  341. package/dist/modes/interactive/plan-command.js +24 -27
  342. package/dist/modes/interactive/plan-dialog.js +18 -17
  343. package/dist/modes/interactive/plan-flow.js +6 -5
  344. package/dist/modes/interactive/rewind-command.d.ts +1 -1
  345. package/dist/modes/interactive/rewind-command.js +18 -16
  346. package/dist/modes/interactive/rewind-flow.d.ts +0 -1
  347. package/dist/modes/interactive/rewind-flow.js +13 -14
  348. package/dist/modes/interactive/rewind-list.js +7 -6
  349. package/dist/modes/interactive/rewind-panel.js +40 -40
  350. package/dist/modes/interactive/rewind-text.d.ts +5 -3
  351. package/dist/modes/interactive/rewind-text.js +48 -38
  352. package/dist/modes/interactive/run-indicator.js +15 -12
  353. package/dist/modes/interactive/session-events.js +3 -2
  354. package/dist/modes/interactive/startup-header.js +22 -23
  355. package/dist/modes/interactive/startup-ui.js +38 -30
  356. package/dist/modes/interactive/status-area.d.ts +2 -0
  357. package/dist/modes/interactive/status-area.js +8 -2
  358. package/dist/modes/interactive/status-bar.js +4 -3
  359. package/dist/modes/interactive/subagent-view.js +9 -7
  360. package/dist/modes/interactive/tasks-report.d.ts +6 -0
  361. package/dist/modes/interactive/tasks-report.js +28 -31
  362. package/dist/modes/interactive/terminal-setup.d.ts +9 -0
  363. package/dist/modes/interactive/terminal-setup.js +23 -0
  364. package/dist/modes/interactive/tool-summary.js +19 -17
  365. package/dist/modes/interactive/tool-view.js +7 -4
  366. package/dist/modes/interactive/trace-view.d.ts +89 -0
  367. package/dist/modes/interactive/trace-view.js +332 -0
  368. package/dist/modes/print/print-mode.js +14 -15
  369. package/dist/modes/rpc/commands.js +7 -3
  370. package/dist/modes/rpc/rpc-mode.js +9 -3
  371. package/dist/modes/session-report.d.ts +2 -0
  372. package/dist/modes/session-report.js +101 -105
  373. package/dist/modes/startup-ui-text.js +11 -6
  374. package/dist/permissions/bypass.d.ts +8 -10
  375. package/dist/permissions/bypass.js +19 -10
  376. package/dist/permissions/memory-class.d.ts +23 -0
  377. package/dist/permissions/memory-class.js +54 -0
  378. package/dist/permissions/modes.d.ts +3 -3
  379. package/dist/permissions/modes.js +21 -16
  380. package/dist/permissions/pipeline.d.ts +1 -1
  381. package/dist/permissions/pipeline.js +9 -2
  382. package/dist/permissions/preview.js +49 -42
  383. package/dist/permissions/rules.js +5 -2
  384. package/dist/permissions/types.d.ts +4 -0
  385. package/dist/plan/store.js +2 -1
  386. package/dist/rpc.d.ts +39 -1
  387. package/dist/rpc.js +3 -0
  388. package/dist/sandbox/bash.js +11 -8
  389. package/dist/sandbox/detect.js +14 -11
  390. package/dist/sdk.d.ts +17 -1
  391. package/dist/sdk.js +29 -7
  392. package/dist/session/export.js +31 -30
  393. package/dist/session/manager.d.ts +1 -1
  394. package/dist/session/manager.js +5 -3
  395. package/dist/session/reuse.js +5 -4
  396. package/dist/session/scan.js +3 -2
  397. package/dist/session/stats-aggregate.d.ts +3 -1
  398. package/dist/session/stats-aggregate.js +5 -1
  399. package/dist/session/stats-index.js +2 -1
  400. package/dist/session/stats-scan.d.ts +4 -1
  401. package/dist/session/stats-scan.js +6 -2
  402. package/dist/session/store.d.ts +11 -0
  403. package/dist/session/store.js +48 -1
  404. package/dist/session/types.d.ts +2 -0
  405. package/dist/skills/builtin.js +2 -1
  406. package/dist/tools/image-file.d.ts +26 -1
  407. package/dist/tools/image-file.js +55 -13
  408. package/dist/tools/presets.d.ts +14 -1
  409. package/dist/tools/presets.js +3 -3
  410. package/dist/tools/registry.js +1 -1
  411. package/dist/tools/truncate.d.ts +1 -1
  412. package/dist/tools/truncate.js +2 -2
  413. package/dist/tools/types.d.ts +17 -1
  414. package/dist/trace/build-index.d.ts +91 -0
  415. package/dist/trace/build-index.js +127 -0
  416. package/dist/trace/build-nodes.d.ts +24 -0
  417. package/dist/trace/build-nodes.js +279 -0
  418. package/dist/trace/build-util.d.ts +43 -0
  419. package/dist/trace/build-util.js +120 -0
  420. package/dist/trace/build.d.ts +82 -0
  421. package/dist/trace/build.js +382 -0
  422. package/dist/trace/detail.d.ts +35 -0
  423. package/dist/trace/detail.js +205 -0
  424. package/dist/trace/flatten.d.ts +69 -0
  425. package/dist/trace/flatten.js +173 -0
  426. package/dist/trace/format.d.ts +47 -0
  427. package/dist/trace/format.js +329 -0
  428. package/dist/trace/html-template.d.ts +19 -0
  429. package/dist/trace/html-template.js +150 -0
  430. package/dist/trace/html.d.ts +104 -0
  431. package/dist/trace/html.js +292 -0
  432. package/dist/trace/preview.d.ts +29 -0
  433. package/dist/trace/preview.js +59 -0
  434. package/dist/trace/query-session.d.ts +14 -0
  435. package/dist/trace/query-session.js +38 -0
  436. package/dist/trace/query.d.ts +55 -0
  437. package/dist/trace/query.js +188 -0
  438. package/dist/trace/session.d.ts +40 -0
  439. package/dist/trace/session.js +168 -0
  440. package/dist/trace/types.d.ts +243 -0
  441. package/dist/trace/types.js +13 -0
  442. package/dist/tui/components/editor-paste.d.ts +2 -0
  443. package/dist/tui/components/editor-paste.js +6 -3
  444. package/dist/tui/components/editor.js +2 -2
  445. package/dist/tui/components/loader.d.ts +3 -0
  446. package/dist/tui/components/loader.js +14 -0
  447. package/dist/tui/components/settings-list.d.ts +61 -0
  448. package/dist/tui/components/settings-list.js +135 -0
  449. package/dist/tui/keybindings.d.ts +5 -0
  450. package/dist/tui/keybindings.js +17 -5
  451. package/dist/tui.d.ts +1 -0
  452. package/dist/tui.js +2 -0
  453. package/docs/en/host-api.md +167 -0
  454. package/docs/en/permissions.md +214 -0
  455. package/docs/en/providers.md +625 -0
  456. package/docs/en/rpc.md +361 -0
  457. package/docs/en/sessions.md +219 -0
  458. package/docs/en/tui.md +527 -0
  459. package/docs/host-api.md +18 -17
  460. package/docs/memory.md +172 -0
  461. package/docs/permissions.md +2 -2
  462. package/docs/providers.md +67 -1
  463. package/docs/rpc.md +31 -3
  464. package/docs/session-format.md +8 -2
  465. package/docs/sessions.md +29 -1
  466. package/docs/tui.md +132 -3
  467. package/package.json +8 -3
@@ -11,55 +11,57 @@
11
11
  * 覆盖对应 `onConflict: "overwrite"`。
12
12
  * - 明细:冲突与无法恢复的文件(各最多 5 个)、git HEAD 变化提示与两条命令(只显示,不执行)。
13
13
  */
14
+ import { msg } from "../../i18n/index.js";
14
15
  import { Card, defaultKeybindings, isPasteData, isPrintableText, matchesKey, padToWidth, truncateToWidth, unwrapPaste, wrapTextWithAnsi, } from "../../tui.js";
15
- import { REWIND_DETAIL_MAX, SKIP_REASON_TEXT, gitHintLines, hasCodeChanges, restorePreview, } from "./rewind-text.js";
16
+ import { REWIND_DETAIL_MAX, skipReasonText, gitHintLines, hasCodeChanges, restorePreview, } from "./rewind-text.js";
16
17
  import { relativeTime } from "./startup-ui.js";
17
18
  /** 宽度低于它(覆盖层外宽)时紧凑布局。 */
18
19
  const COMPACT_WIDTH = 56;
19
20
  const MESSAGE_LINES = 3;
20
- const DIVERGE = "对话将分叉";
21
21
  /** 面板的选项(按显示顺序)。 */
22
22
  export function rewindOptions(model, ascii = false) {
23
23
  const code = model.preview?.code;
24
24
  const withCode = hasCodeChanges(code);
25
+ const m = msg().rewind.panel;
25
26
  const options = [];
26
27
  if (withCode) {
27
28
  options.push({
28
29
  action: "both",
29
- label: "恢复代码和对话",
30
- preview: `${restorePreview(code, ascii)} · ${DIVERGE}`,
30
+ label: m.optionBoth,
31
+ preview: m.previewBoth(restorePreview(code, ascii)),
31
32
  });
32
33
  }
33
34
  options.push({
34
35
  action: "conversation",
35
- label: "恢复对话",
36
- preview: withCode ? `代码不变(保留之后的修改)· ${DIVERGE}` : `代码不变 · ${DIVERGE}`,
36
+ label: m.optionConversation,
37
+ preview: withCode ? m.previewConversationKeep : m.previewConversation,
37
38
  });
38
39
  if (withCode) {
39
40
  options.push({
40
41
  action: "code",
41
- label: "恢复代码",
42
- preview: `${restorePreview(code, ascii)} · 对话不变`,
42
+ label: m.optionCode,
43
+ preview: m.previewCode(restorePreview(code, ascii)),
43
44
  });
44
45
  }
45
46
  options.push({
46
47
  action: "summarize-from",
47
- label: "从这里摘要",
48
- preview: `${DIVERGE},离开的部分写成摘要`,
48
+ label: m.optionSummarizeFrom,
49
+ preview: m.previewSummarizeFrom,
49
50
  input: true,
50
51
  }, {
51
52
  action: "summarize-up-to",
52
- label: "摘要到这里",
53
- preview: "之前的对话压缩成摘要,之后的保留",
53
+ label: m.optionSummarizeUpTo,
54
+ preview: m.previewSummarizeUpTo,
54
55
  input: true,
55
- }, { action: "cancel", label: "取消" });
56
+ }, { action: "cancel", label: m.optionCancel });
56
57
  return options;
57
58
  }
58
- const CONFLICT_OPTIONS = [
59
- { value: "skip", label: "跳过冲突文件,恢复其余" },
60
- { value: "overwrite", label: "覆盖冲突文件" },
61
- { value: "back", label: "返回" },
62
- ];
59
+ const CONFLICT_VALUES = ["skip", "overwrite", "back"];
60
+ function conflictOptions() {
61
+ const m = msg().rewind.panel;
62
+ const labels = { skip: m.conflictSkip, overwrite: m.conflictOverwrite, back: m.conflictBack };
63
+ return CONFLICT_VALUES.map((value) => ({ value, label: labels[value] }));
64
+ }
63
65
  /** 行数组组件(交给 Card 加竖条)。 */
64
66
  class Lines {
65
67
  build;
@@ -155,9 +157,9 @@ export class RewindPanel {
155
157
  }
156
158
  conflictInput(data, keys) {
157
159
  const stage = this.stage;
158
- const n = CONFLICT_OPTIONS.length;
160
+ const n = CONFLICT_VALUES.length;
159
161
  const pick = (index) => {
160
- const value = CONFLICT_OPTIONS[index].value;
162
+ const value = CONFLICT_VALUES[index];
161
163
  if (value === "back")
162
164
  this.stage = undefined;
163
165
  else
@@ -181,7 +183,7 @@ export class RewindPanel {
181
183
  this.tight = tight;
182
184
  return new Card(new Lines((w) => this.body(w, tight || width < COMPACT_WIDTH)), {
183
185
  theme,
184
- title: "回滚到这条消息之前",
186
+ title: msg().rewind.panel.title,
185
187
  ...(time !== "" ? { subtitle: time } : {}),
186
188
  }).render(width);
187
189
  };
@@ -192,6 +194,7 @@ export class RewindPanel {
192
194
  invalidate() { }
193
195
  body(width, compact) {
194
196
  const { theme } = this.host;
197
+ const m = msg().rewind.panel;
195
198
  const arrows = theme.glyphs.arrowUp + theme.glyphs.arrowDown;
196
199
  const out = [...this.messageLines(width)];
197
200
  const gap = () => {
@@ -201,13 +204,11 @@ export class RewindPanel {
201
204
  gap();
202
205
  if (this.stage !== undefined) {
203
206
  const conflicts = this.conflicts;
204
- out.push(...this.fileLines(theme.fg("warning", `${conflicts.length} 个文件在回合外被改过:`), conflicts, width));
207
+ out.push(...this.fileLines(theme.fg("warning", m.conflictHead(conflicts.length)), conflicts, width));
205
208
  gap();
206
- out.push(...CONFLICT_OPTIONS.map((o, i) => this.optionLine(`${i + 1}. ${o.label}`, i === this.stage.selected, width)));
209
+ out.push(...conflictOptions().map((o, i) => this.optionLine(`${i + 1}. ${o.label}`, i === this.stage.selected, width)));
207
210
  gap();
208
- out.push(theme.fg("dim", compact
209
- ? `${arrows} Enter · Esc 返回`
210
- : `${arrows} 选择 · 1-3 直接选 · Enter 确认 · Esc 返回`));
211
+ out.push(theme.fg("dim", compact ? m.hintConflictCompact(arrows) : m.hintConflict(arrows)));
211
212
  return out;
212
213
  }
213
214
  this.options.forEach((option, i) => {
@@ -225,9 +226,7 @@ export class RewindPanel {
225
226
  }
226
227
  gap();
227
228
  const n = this.options.length;
228
- out.push(theme.fg("dim", compact
229
- ? `${arrows} Enter · 1-${n} · Esc 取消`
230
- : `${arrows} 选择 · 1-${n} 直接执行 · Enter 确认 · Esc 取消`));
229
+ out.push(theme.fg("dim", compact ? m.hintCompact(arrows, n) : m.hint(arrows, n)));
231
230
  return out;
232
231
  }
233
232
  messageLines(width) {
@@ -241,7 +240,7 @@ export class RewindPanel {
241
240
  .slice(0, max)
242
241
  .map((line, i) => truncateToWidth(`${i === 0 ? theme.fg("accent", prompt) : " "} ${line}`, width));
243
242
  if (all.length > max && !this.tight) {
244
- shown.push(theme.fg("dim", ` ${theme.glyphs.ellipsis} 另 ${all.length - max} 行`));
243
+ shown.push(theme.fg("dim", msg().rewind.panel.moreLines(theme.glyphs.ellipsis, all.length - max)));
245
244
  }
246
245
  return shown;
247
246
  }
@@ -252,9 +251,9 @@ export class RewindPanel {
252
251
  const text = this.inputs.get(option.action) ?? "";
253
252
  const cursor = selected ? (theme.glyphs.ascii ? "_" : "▏") : "";
254
253
  if (text !== "")
255
- label += ` 说明:${text}${cursor}`;
254
+ label += `${msg().rewind.panel.instructions(text)}${cursor}`;
256
255
  else if (selected)
257
- label += theme.fg("dim", " 可输入说明");
256
+ label += theme.fg("dim", msg().rewind.panel.instructionsHint);
258
257
  }
259
258
  return label;
260
259
  }
@@ -269,34 +268,35 @@ export class RewindPanel {
269
268
  /** 文件清单:每个一行(最多 5 个);紧凑时接在 `head` 后面并成一行。 */
270
269
  fileLines(head, files, width, note) {
271
270
  if (this.tight)
272
- return [truncateToWidth(`${head}${files.join("、")}`, width)];
271
+ return [truncateToWidth(msg().rewind.panel.tightList(head, files), width)];
273
272
  const lines = files
274
273
  .slice(0, REWIND_DETAIL_MAX)
275
274
  .map((f) => truncateToWidth(` ${f}${note !== undefined ? note(f) : ""}`, width));
276
275
  lines.unshift(head);
277
276
  if (files.length > REWIND_DETAIL_MAX) {
278
- lines.push(this.host.theme.fg("dim", ` ${this.host.theme.glyphs.ellipsis} 另 ${files.length - REWIND_DETAIL_MAX} 个`));
277
+ lines.push(this.host.theme.fg("dim", msg().rewind.panel.moreFiles(this.host.theme.glyphs.ellipsis, files.length - REWIND_DETAIL_MAX)));
279
278
  }
280
279
  return lines;
281
280
  }
282
281
  detailLines(width) {
283
282
  const { theme } = this.host;
284
283
  const out = [];
284
+ const m = msg().rewind.panel;
285
285
  const { point, preview, previewError } = this.model;
286
286
  if (!point.hasCheckpoint)
287
- out.push(theme.fg("dim", "仅对话:这条消息没有代码检查点"));
287
+ out.push(theme.fg("dim", m.noCheckpoint));
288
288
  if (previewError !== undefined)
289
- out.push(theme.fg("warning", `代码预览失败:${previewError}`));
289
+ out.push(theme.fg("warning", m.previewFailed(previewError)));
290
290
  const code = preview?.code;
291
291
  if (code !== undefined && code.conflicts.length > 0) {
292
292
  const head = this.tight
293
- ? `冲突 ${code.conflicts.length} 个:`
294
- : `冲突 ${code.conflicts.length} 个(回合外被改过,缺省跳过):`;
293
+ ? m.conflictsTight(code.conflicts.length)
294
+ : m.conflicts(code.conflicts.length);
295
295
  out.push(...this.fileLines(theme.fg("warning", head), code.conflicts, width));
296
296
  }
297
297
  if (code !== undefined && code.skipped.length > 0) {
298
- const reasons = new Map(code.skipped.map((s) => [s.path, SKIP_REASON_TEXT[s.reason]]));
299
- out.push(...this.fileLines(theme.fg("dim", `无法恢复 ${code.skipped.length} 个:`), code.skipped.map((s) => s.path), width, (f) => theme.fg("dim", `:${reasons.get(f) ?? ""}`)));
298
+ const reasons = new Map(code.skipped.map((s) => [s.path, skipReasonText(s.reason)]));
299
+ out.push(...this.fileLines(theme.fg("dim", m.unrestorable(code.skipped.length)), code.skipped.map((s) => s.path), width, (f) => theme.fg("dim", m.fileReason(reasons.get(f) ?? ""))));
300
300
  }
301
301
  if (preview?.gitHint !== undefined) {
302
302
  const [head, ...commands] = gitHintLines(preview.gitHint, theme.glyphs.ascii, this.tight);
@@ -5,12 +5,14 @@
5
5
  * - 结果:`已恢复 N 个文件,跳过 M 个(冲突 1、符号链接 1)` / `没有文件被恢复…` / `代码没有变化`,
6
6
  * 之后最多 5 行跳过明细。
7
7
  * - git:HEAD 与记录不同时给两条命令(只显示,不执行)。
8
- * - 错误码 `busy / no_checkpoint / rewind_failed` 换成中文说明。
8
+ * - 错误码 `busy / no_checkpoint / rewind_failed` 换成界面语言的说明。
9
+ * - 文案在 `msg().rewind`([W6-I2])。
9
10
  */
10
11
  import type { CodeRestoreResult, RewindResult, RewindSkipReason } from "../../checkpoints/types.js";
11
12
  /** 明细最多列出的文件数。 */
12
13
  export declare const REWIND_DETAIL_MAX = 5;
13
- export declare const SKIP_REASON_TEXT: Readonly<Record<RewindSkipReason, string>>;
14
+ /** 跳过原因的说明(随界面语言)。 */
15
+ export declare function skipReasonText(reason: RewindSkipReason): string;
14
16
  /** 一行文本:空白压成一个空格,超长截断。 */
15
17
  export declare function oneLine(text: string, max?: number, ellipsis?: string): string;
16
18
  /** 将恢复 / 已恢复的文件数(恢复 + 删除)。 */
@@ -36,5 +38,5 @@ export declare function gitHintLines(hint: {
36
38
  recordedHead: string;
37
39
  currentHead: string;
38
40
  }, ascii?: boolean, brief?: boolean): string[];
39
- /** 回滚接口的错误 → 中文说明。 */
41
+ /** 回滚接口的错误 → 界面语言的说明。 */
40
42
  export declare function rewindErrorText(error: unknown): string;
@@ -5,19 +5,17 @@
5
5
  * - 结果:`已恢复 N 个文件,跳过 M 个(冲突 1、符号链接 1)` / `没有文件被恢复…` / `代码没有变化`,
6
6
  * 之后最多 5 行跳过明细。
7
7
  * - git:HEAD 与记录不同时给两条命令(只显示,不执行)。
8
- * - 错误码 `busy / no_checkpoint / rewind_failed` 换成中文说明。
8
+ * - 错误码 `busy / no_checkpoint / rewind_failed` 换成界面语言的说明。
9
+ * - 文案在 `msg().rewind`([W6-I2])。
9
10
  */
10
11
  import { isAmaError } from "../../errors.js";
12
+ import { msg } from "../../i18n/index.js";
11
13
  /** 明细最多列出的文件数。 */
12
14
  export const REWIND_DETAIL_MAX = 5;
13
- export const SKIP_REASON_TEXT = {
14
- symlink: "符号链接",
15
- hardlink: "硬链接",
16
- not_regular: "不是普通文件",
17
- parent_moved: "父目录被移动",
18
- too_large: "文件过大未备份",
19
- backup_missing: "备份缺失",
20
- };
15
+ /** 跳过原因的说明(随界面语言)。 */
16
+ export function skipReasonText(reason) {
17
+ return msg().rewind.skip.reason(reason);
18
+ }
21
19
  /** 一行文本:空白压成一个空格,超长截断。 */
22
20
  export function oneLine(text, max = 60, ellipsis = "…") {
23
21
  const flat = text.replace(/\s+/g, " ").trim();
@@ -36,41 +34,54 @@ export function diffStat(code, ascii = false) {
36
34
  }
37
35
  /** 列表高亮行右侧的徽标。 */
38
36
  export function badgeText(code, ascii = false) {
37
+ const m = msg().rewind.badge;
39
38
  if (!hasCodeChanges(code))
40
- return "无代码改动";
39
+ return m.noCode;
41
40
  if (codeFileCount(code) === 0)
42
- return `冲突 ${code.conflicts.length} 个`;
43
- return `${codeFileCount(code)} 文件 ${diffStat(code, ascii)}`;
41
+ return m.conflicts(code.conflicts.length);
42
+ return m.files(codeFileCount(code), diffStat(code, ascii));
44
43
  }
45
44
  /** 面板里代码类选项的预览。 */
46
45
  export function restorePreview(code, ascii = false) {
46
+ const m = msg().rewind.restorePreview;
47
47
  const conflicts = code.conflicts.length;
48
48
  if (codeFileCount(code) === 0)
49
- return `只有冲突文件 ${conflicts} 个(缺省跳过)`;
50
- const suffix = conflicts > 0 ? `,冲突 ${conflicts} 个` : "";
51
- return `将恢复 ${codeFileCount(code)} 个文件 ${diffStat(code, ascii)}${suffix}`;
49
+ return m.onlyConflicts(conflicts);
50
+ return m.files(codeFileCount(code), diffStat(code, ascii), conflicts);
51
+ }
52
+ function skipLabel(code) {
53
+ return msg().rewind.skip.reason(code);
52
54
  }
53
55
  function skips(code, overwrite) {
54
56
  return [
55
- ...(overwrite ? [] : code.conflicts.map((path) => ({ path, reason: "冲突" }))),
56
- ...code.skipped.map((s) => ({ path: s.path, reason: SKIP_REASON_TEXT[s.reason] })),
57
- ...code.failed.map((f) => ({ path: f.path, reason: `失败:${f.message}` })),
57
+ ...(overwrite
58
+ ? []
59
+ : code.conflicts.map((path) => ({
60
+ path,
61
+ code: "conflict",
62
+ reason: skipLabel("conflict"),
63
+ }))),
64
+ ...code.skipped.map((s) => ({ path: s.path, code: s.reason, reason: skipLabel(s.reason) })),
65
+ ...code.failed.map((f) => ({
66
+ path: f.path,
67
+ code: "failed",
68
+ reason: msg().rewind.skip.failed(f.message),
69
+ })),
58
70
  ];
59
71
  }
60
72
  function reasonCounts(list) {
61
73
  const counts = new Map();
62
- for (const skip of list) {
63
- const key = skip.reason.startsWith("失败") ? "失败" : skip.reason;
64
- counts.set(key, (counts.get(key) ?? 0) + 1);
65
- }
66
- return [...counts].map(([reason, n]) => `${reason} ${n}`).join("、");
74
+ for (const skip of list)
75
+ counts.set(skip.code, (counts.get(skip.code) ?? 0) + 1);
76
+ return msg().rewind.skip.counts([...counts]);
67
77
  }
68
78
  /** 跳过明细(最多 5 行,其余计数)。 */
69
79
  export function skipDetailLines(code, overwrite = false) {
70
80
  const list = skips(code, overwrite);
71
- const lines = list.slice(0, REWIND_DETAIL_MAX).map((s) => ` ${s.path}:${s.reason}`);
81
+ const m = msg().rewind.skip;
82
+ const lines = list.slice(0, REWIND_DETAIL_MAX).map((s) => m.detail(s.path, s.reason));
72
83
  if (list.length > REWIND_DETAIL_MAX)
73
- lines.push(` … 另 ${list.length - REWIND_DETAIL_MAX} 个`);
84
+ lines.push(m.more(list.length - REWIND_DETAIL_MAX));
74
85
  return lines;
75
86
  }
76
87
  /** 代码恢复结果一行(不含明细)。overwrite 时冲突文件已被覆盖,算作已恢复。 */
@@ -78,16 +89,16 @@ export function codeResultText(code, overwrite = false) {
78
89
  const done = overwrite
79
90
  ? new Set([...code.restored, ...code.deleted, ...code.conflicts]).size
80
91
  : codeFileCount(code);
92
+ const m = msg().rewind.result;
81
93
  const skipped = skips(code, overwrite);
82
- const why = skipped.length > 0 ? `(${reasonCounts(skipped)})` : "";
83
94
  if (done > 0) {
84
95
  return skipped.length > 0
85
- ? `已恢复 ${done} 个文件,跳过 ${skipped.length} 个${why}`
86
- : `已恢复 ${done} 个文件`;
96
+ ? m.restoredSkipped(done, skipped.length, reasonCounts(skipped))
97
+ : m.restored(done);
87
98
  }
88
99
  if (skipped.length > 0)
89
- return `没有文件被恢复,跳过 ${skipped.length} 个${why}`;
90
- return "代码没有变化";
100
+ return m.noneRestored(skipped.length, reasonCounts(skipped));
101
+ return m.unchanged;
91
102
  }
92
103
  /** 结果通知(多行):代码结果 + 明细 + 对话说明 + git 提示。 */
93
104
  export function rewindResultLines(result, options = {}) {
@@ -111,25 +122,24 @@ export function gitHintLines(hint, ascii = false, brief = false) {
111
122
  const recorded = short(hint.recordedHead, 12);
112
123
  const change = `${short(hint.recordedHead, 7)} ${ascii ? "->" : "→"} ${short(hint.currentHead, 7)}`;
113
124
  return [
114
- `git HEAD 已变化:${change}${brief ? "" : "(ama 不动 git)"}`,
125
+ msg().rewind.gitHint(change, brief),
115
126
  ` git log --oneline ${recorded}..HEAD`,
116
127
  ` git reset --soft ${recorded}`,
117
128
  ];
118
129
  }
119
- /** 回滚接口的错误 → 中文说明。 */
130
+ /** 回滚接口的错误 → 界面语言的说明。 */
120
131
  export function rewindErrorText(error) {
121
132
  if (isAmaError(error)) {
133
+ const m = msg().rewind.error;
122
134
  switch (error.code) {
123
135
  case "busy":
124
- return "正在运行,不能回滚(先按 Esc 中断)";
136
+ return m.busy;
125
137
  case "no_checkpoint":
126
- return "这条消息没有代码检查点,只能恢复对话";
138
+ return m.noCheckpoint;
127
139
  case "rewind_failed": {
128
140
  const detail = error.detail;
129
- const failed = (detail?.failed ?? []).map((f) => `${f.path}:${f.message}`);
130
- return failed.length > 0
131
- ? `没有文件被恢复:${failed.slice(0, REWIND_DETAIL_MAX).join(";")}`
132
- : "没有文件被恢复";
141
+ const failed = (detail?.failed ?? []).map((f) => [f.path, f.message]);
142
+ return failed.length > 0 ? m.failedFiles(failed.slice(0, REWIND_DETAIL_MAX)) : m.failed;
133
143
  }
134
144
  default:
135
145
  return error.message;
@@ -13,8 +13,9 @@
13
13
  * 排队消息:缩进 2 列(挂在当前回合下),`↳ 插话 / 之后 文本` 整体 muted、标签 dim;超过 3 条首行
14
14
  * `… 另 N 条`;末行 `Alt+↑ 取回 · Esc 回填并中断`。
15
15
  */
16
+ import { msg } from "../../i18n/index.js";
16
17
  import { Container, Text } from "../../tui.js";
17
- import { ORIGIN_LABELS } from "./message-view.js";
18
+ import { originLabel } from "./message-view.js";
18
19
  import { formatTokens } from "./status-bar.js";
19
20
  export const QUEUE_PREVIEW = 3;
20
21
  function oneLine(text) {
@@ -129,38 +130,39 @@ export class RunIndicator {
129
130
  }
130
131
  applyVerb() {
131
132
  const { loader, tools } = this.deps;
132
- const esc = ["Esc 中断"];
133
+ const m = msg().interactive.view.run;
134
+ const esc = [m.esc];
133
135
  if (this.approval) {
134
- loader.setVerb("等待确认");
136
+ loader.setVerb(m.awaitingApproval);
135
137
  return;
136
138
  }
137
139
  const running = tools.running();
138
140
  const top = running.filter((view) => !running.some((p) => p.children.includes(view)));
139
141
  if (top.length === 1) {
140
- loader.setVerb(`运行 ${top[0].toolName}`, esc);
142
+ loader.setVerb(m.runningTool(top[0].toolName), esc);
141
143
  return;
142
144
  }
143
145
  if (top.length > 1) {
144
- loader.setVerb(`运行 ${top.length} 个工具`, esc);
146
+ loader.setVerb(m.runningTools(top.length), esc);
145
147
  return;
146
148
  }
147
149
  if (this.retry !== undefined) {
148
150
  const seconds = Math.max(1, Math.round(this.retry.delayMs / 1000));
149
- loader.setVerb(`重试 ${this.retry.attempt}/${this.retry.max}`, [`${seconds}s 后`], {
151
+ loader.setVerb(m.retry(this.retry.attempt, this.retry.max), [m.retryIn(seconds)], {
150
152
  elapsed: false,
151
153
  });
152
154
  return;
153
155
  }
154
156
  if (this.compacting) {
155
- loader.setVerb("压缩上下文", esc);
157
+ loader.setVerb(m.compacting, esc);
156
158
  return;
157
159
  }
158
160
  const stream = this.stream;
159
161
  if (stream !== undefined && !stream.thinking && stream.tokens > 0) {
160
- loader.setVerb("回复中", [`↓≈${formatTokens(stream.tokens)}`, ...esc]);
162
+ loader.setVerb(m.replying, [`↓≈${formatTokens(stream.tokens)}`, ...esc]);
161
163
  return;
162
164
  }
163
- loader.setVerb("思考中", esc);
165
+ loader.setVerb(m.thinking, esc);
164
166
  }
165
167
  }
166
168
  /** 排队消息(插话 / 之后),挂在 Loader 之上。 */
@@ -172,17 +174,18 @@ export class QueueView extends Text {
172
174
  }
173
175
  setQueue(steering, followUp) {
174
176
  const t = this.theme;
175
- const row = (origin, text) => ` ${t.fg("dim", `${t.glyphs.queued} ${ORIGIN_LABELS[origin]}`)} ${t.fg("muted", oneLine(text))}`;
177
+ const row = (origin, text) => ` ${t.fg("dim", `${t.glyphs.queued} ${originLabel(origin)}`)} ${t.fg("muted", oneLine(text))}`;
176
178
  const rows = [
177
179
  ...steering.map((text) => row("steer", text)),
178
180
  ...followUp.map((text) => row("followUp", text)),
179
181
  ];
180
182
  const shown = rows.slice(-QUEUE_PREVIEW);
181
183
  if (rows.length > shown.length) {
182
- shown.unshift(" " + t.fg("dim", `${t.glyphs.ellipsis} 另 ${rows.length - shown.length} 条`));
184
+ shown.unshift(" " +
185
+ t.fg("dim", msg().interactive.view.run.queueMore(t.glyphs.ellipsis, rows.length - shown.length)));
183
186
  }
184
187
  if (rows.length > 0) {
185
- shown.push(" " + t.fg("dim", `Alt+${t.glyphs.arrowUp} 取回 · Esc 回填并中断`));
188
+ shown.push(" " + t.fg("dim", msg().interactive.view.run.queueHint(t.glyphs.arrowUp)));
186
189
  }
187
190
  this.setText(shown.join("\n"));
188
191
  }
@@ -2,6 +2,7 @@
2
2
  * 交互界面的会话事件分派:`SessionEvent` → 消息区、工具视图、状态栏、运行指示。[B7]
3
3
  * 从 interactive-mode.ts 拆出(W5-U:第五波事件先交给 agent-ui.ts,预算到限的 agent_settled warning 不重复显示)。
4
4
  */
5
+ import { msg } from "../../i18n/index.js";
5
6
  import { cacheEventNotice, cacheNoticesEnabled } from "../session-report.js";
6
7
  import { compactionErrorText, ImageBudgetNotices, LIMIT_WARNING } from "./event-notices.js";
7
8
  export function createSessionEventHandler(deps) {
@@ -58,9 +59,9 @@ export function createSessionEventHandler(deps) {
58
59
  if (event.result !== undefined)
59
60
  view.addCompaction(event.result);
60
61
  else if (event.error !== undefined)
61
- view.addNotice("error", `压缩失败:${compactionErrorText(event.error)}`);
62
+ view.addNotice("error", msg().interactive.events.compactionFailed(compactionErrorText(event.error)));
62
63
  else if (event.aborted)
63
- view.addNotice("info", "压缩已取消");
64
+ view.addNotice("info", msg().interactive.events.compactionCancelled);
64
65
  status.refresh();
65
66
  break;
66
67
  case "auto_retry_start":
@@ -7,6 +7,7 @@
7
7
  * - 着色:`✻` accent、标题粗体;键列 dim;模型 accent;已信任 success / 未信任 warning;Bypass 模式 warning;
8
8
  * 按键提示 dim。路径过长时从左截断(`…/armadra-agent`)。宽度变化时按新宽重算是否去框。
9
9
  */
10
+ import { msg } from "../../i18n/index.js";
10
11
  import { permissionModeLabel } from "../../permissions/modes.js";
11
12
  import { Box, KeyValue, padToWidth, truncateToWidth, visibleWidth, } from "../../tui.js";
12
13
  /** 画框的最小宽度;更窄时去框去键列。 */
@@ -58,7 +59,8 @@ export class StartupHeader {
58
59
  }
59
60
  trustText(withSource) {
60
61
  const { trusted, trustSource } = this.info;
61
- const text = `${trusted ? "已信任" : "未信任"}${withSource ? `(${trustSource})` : ""}`;
62
+ const m = msg().interactive.startup.header;
63
+ const text = `${trusted ? m.trusted : m.untrusted}${withSource ? m.trustSource(trustSource) : ""}`;
62
64
  return this.theme.fg(trusted ? "success" : "warning", text);
63
65
  }
64
66
  loadedText() {
@@ -69,7 +71,7 @@ export class StartupHeader {
69
71
  if (skills > 0)
70
72
  parts.push(`${skills} Skill`);
71
73
  if (prompts > 0)
72
- parts.push(`${prompts} 模板`);
74
+ parts.push(msg().interactive.startup.header.templates(prompts));
73
75
  if (hooks > 0)
74
76
  parts.push(`${hooks} Hook`);
75
77
  return parts.length === 0 ? undefined : parts.join(" · ");
@@ -114,51 +116,48 @@ export class StartupHeader {
114
116
  const loaded = this.loadedText();
115
117
  if (loaded !== undefined)
116
118
  lines.push(loaded);
119
+ const m = msg().interactive.startup.header;
117
120
  if (info.host !== undefined)
118
- lines.push(`宿主 ${info.host}`);
121
+ lines.push(m.host(info.host));
119
122
  if (info.warnings > 0)
120
- lines.push(t.fg("warning", `警告 ${info.warnings} 条(ama doctor)`));
121
- lines.push(t.fg("dim", "/help · Shift+Tab 切模式"));
123
+ lines.push(t.fg("warning", m.warnings(info.warnings)));
124
+ lines.push(t.fg("dim", m.hintCompact));
122
125
  return lines.map((line) => truncateToWidth(line, width));
123
126
  }
124
127
  boxLines(width) {
125
128
  const t = this.theme;
126
129
  const sep = t.fg("dim", " · ");
127
130
  const { info } = this;
131
+ const m = msg().interactive.startup.header;
128
132
  const boxWidth = Math.min(width, HEADER_BOX_MAX_WIDTH);
129
- /** 框内文本宽:边框 2 + 内边距 2;键列 6 + 间隔 1。 */
130
- const valueWidth = boxWidth - 4 - 7;
133
+ // 键列至少 6 列(「已加载」的宽度),没有这一行时也对齐;英文键更宽时按最宽的键
134
+ const keyWidth = Math.max(6, ...[m.keyModel, m.keyDir, m.keyMode, m.keyLoaded, m.keyHost, m.keyWarnings].map((k) => visibleWidth(k)));
135
+ /** 框内文本宽:边框 2 + 内边距 2;键列 + 间隔 1。 */
136
+ const valueWidth = boxWidth - 4 - keyWidth - 1;
131
137
  const trust = this.trustText(true);
132
138
  const cwdRoom = Math.max(4, valueWidth - visibleWidth(trust) - 3);
133
139
  const rows = [
134
- { key: "模型", value: t.fg("accent", info.model) + sep + `思考 ${info.thinking}` },
135
- { key: "目录", value: truncateLeft(info.cwd, cwdRoom, t.glyphs.ellipsis) + sep + trust },
140
+ { key: m.keyModel, value: t.fg("accent", info.model) + sep + m.thinking(info.thinking) },
141
+ { key: m.keyDir, value: truncateLeft(info.cwd, cwdRoom, t.glyphs.ellipsis) + sep + trust },
136
142
  {
137
- key: "模式",
138
- value: [this.modeText(), `预设 ${info.preset}`, this.codemodeText()]
143
+ key: m.keyMode,
144
+ value: [this.modeText(), m.preset(info.preset), this.codemodeText()]
139
145
  .filter((p) => p !== undefined)
140
146
  .join(sep),
141
147
  },
142
148
  ];
143
149
  const loaded = this.loadedText();
144
150
  if (loaded !== undefined)
145
- rows.push({ key: "已加载", value: loaded });
151
+ rows.push({ key: m.keyLoaded, value: loaded });
146
152
  if (info.host !== undefined)
147
- rows.push({ key: "宿主", value: info.host });
153
+ rows.push({ key: m.keyHost, value: info.host });
148
154
  if (info.warnings > 0) {
149
- rows.push({ key: "警告", value: t.fg("warning", `${info.warnings} 条(ama doctor 查看)`) });
155
+ rows.push({ key: m.keyWarnings, value: t.fg("warning", m.warningsValue(info.warnings)) });
150
156
  }
151
- // 键列固定 6 列(「已加载」的宽度),没有这一行时也对齐
152
- const padded = rows.map((row) => ({ ...row, key: padToWidth(row.key, 6) }));
157
+ const padded = rows.map((row) => ({ ...row, key: padToWidth(row.key, keyWidth) }));
153
158
  const kv = new KeyValue(padded, { theme: t, gap: 1, maxKeyRatio: 1 });
154
159
  const body = {
155
- render: (inner) => [
156
- this.title(),
157
- "",
158
- ...kv.render(inner),
159
- "",
160
- t.fg("dim", "/help 命令 · Shift+Tab 切模式 · Ctrl+O 展开工具输出"),
161
- ],
160
+ render: (inner) => [this.title(), "", ...kv.render(inner), "", t.fg("dim", m.hint)],
162
161
  invalidate: () => kv.invalidate(),
163
162
  };
164
163
  return new Box(body, { theme: t }).render(boxWidth);