@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
@@ -9,12 +9,16 @@
9
9
  * - 所有选择器底部一行按键提示(dim),模型选择器带 (i/n) 并给当前模型打 ✓。
10
10
  */
11
11
  import { THINKING_LEVELS } from "../../ai/thinking.js";
12
+ import { msg } from "../../i18n/index.js";
12
13
  import { PERMISSION_MODE_INFO, PERMISSION_MODE_ORDER, RECOMMENDED_PERMISSION_MODE, } from "../../permissions/modes.js";
13
14
  import { Box, SelectList, } from "../../tui.js";
14
15
  import { contentText } from "./message-view.js";
15
16
  import { relativeTime } from "./startup-ui.js";
16
17
  export { modelItems, sessionItems } from "./startup-ui.js";
17
- export const PICKER_FOOTER = "↑↓ 选择 · Enter 确认 · Esc 取消";
18
+ /** 列表下的缺省按键提示(`arrows` 缺省 `↑↓`)。 */
19
+ export function pickerFooter(arrows = "↑↓") {
20
+ return msg().panels.picker.footer(arrows);
21
+ }
18
22
  /** 打开一个居中选择器;Enter 返回选中项,Esc / Ctrl+C 返回 undefined。 */
19
23
  export function openPicker(host, spec) {
20
24
  return new Promise((resolve) => {
@@ -33,7 +37,7 @@ export function openPicker(host, spec) {
33
37
  ...(spec.stacked === true ? { stacked: true } : {}),
34
38
  ...(spec.currentValue !== undefined ? { currentValue: spec.currentValue } : {}),
35
39
  ...(spec.showCount === true ? { showCount: true } : {}),
36
- footer: spec.footer ?? PICKER_FOOTER,
40
+ footer: spec.footer ?? pickerFooter(),
37
41
  onSelect: (item) => close(item),
38
42
  onCancel: () => close(undefined),
39
43
  });
@@ -73,14 +77,14 @@ export function permissionItems(_current, configDefault = "default") {
73
77
  }
74
78
  export function permissionPickerSpec(current, configDefault = "default") {
75
79
  return {
76
- title: "权限模式",
80
+ title: msg().panels.picker.permissionTitle,
77
81
  items: permissionItems(current, configDefault),
78
82
  selected: current,
79
83
  currentValue: current,
80
84
  filterable: false,
81
85
  numberKeys: true,
82
86
  stacked: true,
83
- footer: "↑↓ 选择 · 1-6 直接选 · Enter 确认 · Esc 取消",
87
+ footer: msg().panels.picker.permissionFooter("↑↓"),
84
88
  paddingY: 1,
85
89
  };
86
90
  }
@@ -88,7 +92,7 @@ export function thinkingItems(reasoning) {
88
92
  return THINKING_LEVELS.map((level) => {
89
93
  const item = { value: level, label: level };
90
94
  if (!reasoning && level !== "off")
91
- item.description = "当前模型不支持思考";
95
+ item.description = msg().panels.picker.thinkingUnsupported;
92
96
  return item;
93
97
  });
94
98
  }
@@ -136,7 +140,7 @@ export function treeItems(entries, activeIds, now) {
136
140
  const text = node.text.length > 60 ? `${node.text.slice(0, 59)}…` : node.text;
137
141
  items.push({
138
142
  value: node.entry.id,
139
- label: `${" ".repeat(level)}${mark}${text === "" ? "(空)" : text}`,
143
+ label: `${" ".repeat(level)}${mark}${text === "" ? msg().panels.picker.emptyText : text}`,
140
144
  description: relativeTime(node.entry.timestamp, now),
141
145
  });
142
146
  visit(node.children, level);
@@ -12,7 +12,7 @@ import type { AgentSession, PlanData } from "../../agent/types.js";
12
12
  import type { SwitchRequest } from "../../cli/compose-session.js";
13
13
  import type { PermissionMode } from "../../permissions/types.js";
14
14
  import { type PlanController } from "../../plan/controller.js";
15
- export declare const PLAN_USAGE = "\u7528\u6CD5\uFF1A/plan [\u76EE\u6807] | /plan approve [\u6A21\u5F0F|fresh] | /plan reject";
15
+ export declare function planUsage(): string;
16
16
  export declare function planStatusText(status: PlanData["status"]): string;
17
17
  /** 计划的标题:第一个 `#` 标题,没有时取第一行非空文本。 */
18
18
  export declare function planTitle(plan: Pick<PlanData, "markdown">): string;
@@ -9,18 +9,15 @@
9
9
  * - `/plan <目标>`:进入 Plan 模式并把目标作为提示发出。
10
10
  */
11
11
  import { AmaError } from "../../errors.js";
12
+ import { msg } from "../../i18n/index.js";
12
13
  import { parsePermissionMode, permissionModeLabel } from "../../permissions/modes.js";
13
14
  import { planController } from "../../plan/controller.js";
14
15
  import { executionMode } from "../../plan/store.js";
15
- export const PLAN_USAGE = "用法:/plan [目标] | /plan approve [模式|fresh] | /plan reject";
16
- const STATUS_TEXT = {
17
- proposed: "待审批",
18
- approved: "已批准",
19
- rejected: "已放弃",
20
- superseded: "已被新版本取代",
21
- };
16
+ export function planUsage() {
17
+ return msg().plan.usage;
18
+ }
22
19
  export function planStatusText(status) {
23
- return STATUS_TEXT[status];
20
+ return msg().plan.status[status];
24
21
  }
25
22
  /** 计划的标题:第一个 `#` 标题,没有时取第一行非空文本。 */
26
23
  export function planTitle(plan) {
@@ -28,7 +25,7 @@ export function planTitle(plan) {
28
25
  const heading = lines.find((l) => /^#{1,6}\s+\S/.test(l));
29
26
  if (heading !== undefined)
30
27
  return heading.replace(/^#{1,6}\s+/, "");
31
- return lines.find((l) => l !== "" && !/^<\/?proposed_plan>$/.test(l)) ?? "(无标题)";
28
+ return lines.find((l) => l !== "" && !/^<\/?proposed_plan>$/.test(l)) ?? msg().plan.untitled;
32
29
  }
33
30
  /** 批准后的执行模式(缺省回到进入 plan 前的模式;进入前就是 plan 则 default)。 */
34
31
  export function defaultExecutionMode(controller) {
@@ -39,21 +36,20 @@ export function describePlan(controller, session) {
39
36
  const plan = controller.current();
40
37
  const mode = session.state.permissionMode;
41
38
  const pre = controller.prePlanMode();
39
+ const m = msg().plan.command;
42
40
  const modeLine = mode === "plan"
43
- ? `模式:Plan(批准后回到 ${permissionModeLabel(executionMode(undefined, pre))})`
44
- : `模式:${permissionModeLabel(mode)}`;
41
+ ? m.modePlan(permissionModeLabel(executionMode(undefined, pre)))
42
+ : m.mode(permissionModeLabel(mode));
45
43
  if (plan === null) {
46
- return mode === "plan"
47
- ? [modeLine, "还没有计划:模型给出 <proposed_plan> 后在这里审批"].join("\n")
48
- : "没有计划。/plan <目标> 进入 Plan 模式";
44
+ return mode === "plan" ? [modeLine, m.noPlanYet].join("\n") : m.noPlan;
49
45
  }
50
46
  const lines = [
51
- `计划 v${plan.version} · ${planStatusText(plan.status)} · ${planTitle(plan)}`,
52
- ...(plan.filePath !== undefined ? [`文件:${plan.filePath}`] : []),
47
+ m.head(plan.version, planStatusText(plan.status), planTitle(plan)),
48
+ ...(plan.filePath !== undefined ? [m.file(plan.filePath)] : []),
53
49
  modeLine,
54
50
  ];
55
51
  if (plan.steps.length > 0) {
56
- lines.push(`步骤(${plan.steps.length}):`);
52
+ lines.push(m.steps(plan.steps.length));
57
53
  for (const step of plan.steps)
58
54
  lines.push(` ${step.id} ${step.text}`);
59
55
  }
@@ -61,10 +57,10 @@ export function describePlan(controller, session) {
61
57
  if (todos.length > 0) {
62
58
  const done = todos.filter((t) => t.status === "done").length;
63
59
  const current = todos.find((t) => t.status === "in_progress");
64
- lines.push(`待办:${done}/${todos.length} 完成${current !== undefined ? ` · 进行中 ${current.text}` : ""}`);
60
+ lines.push(m.todos(done, todos.length, current?.text));
65
61
  }
66
62
  if (plan.status === "proposed")
67
- lines.push("/plan approve [模式|fresh] 批准 · /plan reject 放弃 · 直接输入修改意见");
63
+ lines.push(m.actions);
68
64
  return lines.join("\n");
69
65
  }
70
66
  /** 「新上下文执行」:新建会话、记下计划与 todo、切到执行模式,返回首条消息。 */
@@ -83,22 +79,23 @@ export async function approveFresh(controller, plan, mode, ctx, editedMarkdown)
83
79
  function pendingOrLastReply(controller) {
84
80
  const plan = controller.pending() ?? controller.proposeFromLastReply();
85
81
  if (plan === undefined)
86
- throw new AmaError("plan_not_found", "没有待审批的计划");
82
+ throw new AmaError("plan_not_found", msg().plan.command.notFound);
87
83
  return plan;
88
84
  }
89
85
  export async function planCommand(session, args, ctx) {
90
86
  const controller = planController(session);
87
+ const m = msg().plan.command;
91
88
  const [verb = "", ...rest] = args.split(/\s+/).filter((s) => s !== "");
92
89
  if (controller === undefined) {
93
90
  if (args === "")
94
- return { kind: "handled", message: "当前会话没有 Plan 能力" };
95
- throw new AmaError("invalid_arguments", "当前会话没有 Plan 能力");
91
+ return { kind: "handled", message: m.unavailable };
92
+ throw new AmaError("invalid_arguments", m.unavailable);
96
93
  }
97
94
  if (verb === "")
98
95
  return { kind: "handled", message: describePlan(controller, session) };
99
96
  if (verb === "approve") {
100
97
  if (rest.length > 1)
101
- throw new AmaError("invalid_arguments", PLAN_USAGE);
98
+ throw new AmaError("invalid_arguments", planUsage());
102
99
  const plan = pendingOrLastReply(controller);
103
100
  const arg = rest[0];
104
101
  if (arg === "fresh") {
@@ -107,20 +104,20 @@ export async function planCommand(session, args, ctx) {
107
104
  }
108
105
  const mode = arg === undefined ? defaultExecutionMode(controller) : parsePermissionMode(arg);
109
106
  if (mode === undefined || mode === "plan")
110
- throw new AmaError("invalid_arguments", `执行模式无效:${arg ?? ""}(${PLAN_USAGE})`);
107
+ throw new AmaError("invalid_arguments", m.invalidMode(arg ?? "", planUsage()));
111
108
  const result = await controller.respond({ planId: plan.id, decision: "approve", mode });
112
109
  return {
113
110
  kind: "handled",
114
- message: `已批准计划 v${result.plan.version},以 ${permissionModeLabel(result.mode ?? mode)} 执行`,
111
+ message: m.approved(result.plan.version, permissionModeLabel(result.mode ?? mode)),
115
112
  wait: true,
116
113
  };
117
114
  }
118
115
  if (verb === "reject" && rest.length === 0) {
119
116
  const plan = controller.pending();
120
117
  if (plan === undefined)
121
- throw new AmaError("plan_not_found", "没有待审批的计划");
118
+ throw new AmaError("plan_not_found", m.notFound);
122
119
  await controller.respond({ planId: plan.id, decision: "reject" });
123
- return { kind: "handled", message: `已放弃计划 v${plan.version}(仍在 Plan 模式)` };
120
+ return { kind: "handled", message: m.rejected(plan.version) };
124
121
  }
125
122
  // 其余:目标文本
126
123
  if (session.state.permissionMode !== "plan")
@@ -26,6 +26,7 @@
26
26
  * (§6.1)。
27
27
  * - 宽 < 56 时紧凑:去掉空行、按键提示缩短。ASCII 字形走 theme.glyphs。
28
28
  */
29
+ import { msg } from "../../i18n/index.js";
29
30
  import { permissionModeLabel } from "../../permissions/modes.js";
30
31
  import { Box, defaultKeybindings, isPasteData, isPrintableText, matchesKey, padToWidth, truncateToWidth, unwrapPaste, wrapTextWithAnsi, } from "../../tui.js";
31
32
  import { planTitle } from "./plan-command.js";
@@ -33,7 +34,8 @@ import { planTitle } from "./plan-command.js";
33
34
  export const PLAN_DIALOG_STEPS = 6;
34
35
  const COMPACT_WIDTH = 56;
35
36
  function mainOptions(ellipsis) {
36
- return ["批准并执行", "批准,在新上下文执行", `继续修改${ellipsis}`, "放弃,退出 Plan 模式"];
37
+ const m = msg().plan.dialog;
38
+ return [m.optionApprove, m.optionApproveFresh, m.optionRevise(ellipsis), m.optionReject];
37
39
  }
38
40
  const MAIN_COUNT = 4;
39
41
  export class PlanDialog {
@@ -56,7 +58,7 @@ export class PlanDialog {
56
58
  modes() {
57
59
  const pre = this.input.preMode;
58
60
  return [
59
- { mode: pre, label: `回到进入前的模式(${permissionModeLabel(pre)})` },
61
+ { mode: pre, label: msg().plan.dialog.modeBack(permissionModeLabel(pre)) },
60
62
  { mode: "auto-edit", label: permissionModeLabel("auto-edit") },
61
63
  { mode: "auto", label: permissionModeLabel("auto") },
62
64
  ];
@@ -195,14 +197,14 @@ export class PlanDialog {
195
197
  lines.push(...this.optionLines(mainOptions(this.host.theme.glyphs.ellipsis), this.selected, width));
196
198
  break;
197
199
  case "mode":
198
- push(this.host.theme.bold(this.fresh ? "在新上下文执行,执行模式" : "执行模式"));
200
+ push(this.host.theme.bold(this.fresh ? msg().plan.dialog.modeHeadingFresh : msg().plan.dialog.modeHeading));
199
201
  lines.push(...this.optionLines(this.modes().map((m) => m.label), this.modeSelected, width));
200
202
  break;
201
203
  case "revise":
202
204
  lines.push(...this.reviseLines(width, compact));
203
205
  break;
204
206
  case "editing":
205
- push(this.host.theme.fg("dim", `正在外部编辑器里编辑${this.host.theme.glyphs.ellipsis}`));
207
+ push(this.host.theme.fg("dim", msg().plan.dialog.editing(this.host.theme.glyphs.ellipsis)));
206
208
  break;
207
209
  }
208
210
  blank();
@@ -214,20 +216,21 @@ export class PlanDialog {
214
216
  const { theme } = this.host;
215
217
  const plan = this.input.plan;
216
218
  const sep = theme.fg("dim", " · ");
217
- const head = [`计划 v${plan.version}`, `${plan.steps.length} 步`];
219
+ const m = msg().plan.dialog;
220
+ const head = [m.version(plan.version), m.stepCount(plan.steps.length)];
218
221
  if (plan.filePath !== undefined)
219
222
  head.push(this.host.displayPath?.(plan.filePath) ?? plan.filePath);
220
223
  const out = [theme.fg("muted", head.join(sep))];
221
224
  out.push(theme.bold(planTitle({ markdown: this.edited ?? plan.markdown })));
222
225
  if (this.edited !== undefined) {
223
- out.push(theme.fg("warning", "已在编辑器里修改:批准时以修改后的计划执行"));
226
+ out.push(theme.fg("warning", m.edited));
224
227
  return out;
225
228
  }
226
229
  for (const step of plan.steps.slice(0, PLAN_DIALOG_STEPS))
227
230
  out.push(` ${theme.fg("dim", step.id)} ${step.text}`);
228
231
  const hidden = plan.steps.length - PLAN_DIALOG_STEPS;
229
232
  if (hidden > 0)
230
- out.push(theme.fg("dim", ` ${theme.glyphs.ellipsis} 另 ${hidden} 步(/plan 查看全部)`));
233
+ out.push(theme.fg("dim", m.moreSteps(theme.glyphs.ellipsis, hidden)));
231
234
  return out;
232
235
  }
233
236
  optionLines(labels, selected, width) {
@@ -243,7 +246,8 @@ export class PlanDialog {
243
246
  reviseLines(width, compact) {
244
247
  const { theme } = this.host;
245
248
  const g = theme.glyphs;
246
- const out = [theme.bold(compact ? "修改意见" : "修改意见(留在 Plan 模式,模型据此重写计划)")];
249
+ const m = msg().plan.dialog;
250
+ const out = [theme.bold(compact ? m.feedbackCompact : m.feedback)];
247
251
  const cursor = "\x1b[7m \x1b[27m";
248
252
  const text = this.feedback.replace(/\n/g, " ⏎ ");
249
253
  const body = `${theme.fg("user", g.prompt)} ${text}${cursor}`;
@@ -254,19 +258,16 @@ export class PlanDialog {
254
258
  const g = this.host.theme.glyphs;
255
259
  const arrows = g.arrowUp + g.arrowDown;
256
260
  const edit = this.host.editExternal !== undefined;
261
+ const m = msg().plan.dialog;
257
262
  switch (this.stage) {
258
263
  case "main":
259
- return compact
260
- ? `${arrows} Enter${edit ? " · e 编辑" : ""} · Esc 留在 Plan`
261
- : `${arrows} 选择 · Enter 确认${edit ? " · e 编辑计划" : ""} · Esc 留在 Plan`;
264
+ return compact ? m.hintMainCompact(arrows, edit) : m.hintMain(arrows, edit);
262
265
  case "mode":
263
- return compact ? `${arrows} Enter · Esc 返回` : `${arrows} 选择 · Enter 确认 · Esc 返回`;
266
+ return compact ? m.hintModeCompact(arrows) : m.hintMode(arrows);
264
267
  case "revise":
265
- return compact
266
- ? `Enter 发送${edit ? " · Ctrl+E 编辑器" : ""} · Esc 返回`
267
- : `Enter 发送${edit ? " · Ctrl+E 外部编辑器" : ""} · Esc 返回`;
268
+ return compact ? m.hintReviseCompact(edit) : m.hintRevise(edit);
268
269
  case "editing":
269
- return "保存并关闭编辑器后回到这里";
270
+ return m.hintEditing;
270
271
  }
271
272
  }
272
273
  invalidate() { }
@@ -285,6 +286,6 @@ export function openPlanDialog(host, input) {
285
286
  resolve(choice);
286
287
  });
287
288
  host.onOpen?.();
288
- handle = host.showOverlay(new Box(dialog, { title: "计划待审批", theme: host.theme }));
289
+ handle = host.showOverlay(new Box(dialog, { title: msg().plan.dialog.title, theme: host.theme }));
289
290
  });
290
291
  }
@@ -8,6 +8,7 @@
8
8
  * 普通用户消息)、放弃(4 退出 Plan 模式;Esc 留在 Plan);「新上下文执行」先新建会话、`adopt(plan)`、
9
9
  * 切执行模式,再发 `freshPrompt`。
10
10
  */
11
+ import { msg } from "../../i18n/index.js";
11
12
  import { permissionModeLabel } from "../../permissions/modes.js";
12
13
  import { planController } from "../../plan/controller.js";
13
14
  import { executionMode } from "../../plan/store.js";
@@ -30,7 +31,7 @@ export class PlanFlow {
30
31
  });
31
32
  const pending = controller.pending();
32
33
  if (pending !== undefined)
33
- this.deps.notice("info", `计划 v${pending.version} 待审批:/plan 打开审批框`);
34
+ this.deps.notice("info", msg().plan.flow.pending(pending.version));
34
35
  }
35
36
  get isOpen() {
36
37
  return this.opened !== undefined;
@@ -66,12 +67,12 @@ export class PlanFlow {
66
67
  ...(choice.editedMarkdown !== undefined ? { editedMarkdown: choice.editedMarkdown } : {}),
67
68
  });
68
69
  const mode = permissionModeLabel(result.mode ?? choice.mode);
69
- this.deps.notice("info", `已批准计划 v${result.plan.version},以 ${mode} 执行`);
70
+ this.deps.notice("info", msg().plan.flow.approved(result.plan.version, mode));
70
71
  return;
71
72
  }
72
73
  case "approve_fresh": {
73
74
  const fresh = await approveFresh(controller, plan, choice.mode, { switchSession: (request) => this.deps.switchSession(request) }, choice.editedMarkdown);
74
- this.deps.notice("info", `已批准计划 v${fresh.plan.version},在新会话 ${fresh.session.state.sessionId.slice(0, 8)} 以 ${permissionModeLabel(choice.mode)} 执行`);
75
+ this.deps.notice("info", msg().plan.flow.approvedFresh(fresh.plan.version, fresh.session.state.sessionId.slice(0, 8), permissionModeLabel(choice.mode)));
75
76
  this.deps.prompt(fresh.prompt);
76
77
  return;
77
78
  }
@@ -87,10 +88,10 @@ export class PlanFlow {
87
88
  await controller.respond({ planId: plan.id, decision: "reject" });
88
89
  if (choice.exit) {
89
90
  session.setPermissionMode(pre);
90
- this.deps.notice("info", `已放弃计划 v${plan.version},回到 ${permissionModeLabel(pre)}`);
91
+ this.deps.notice("info", msg().plan.flow.rejectedExit(plan.version, permissionModeLabel(pre)));
91
92
  }
92
93
  else
93
- this.deps.notice("info", `已放弃计划 v${plan.version}(仍在 Plan 模式,/plan 查看)`);
94
+ this.deps.notice("info", msg().plan.flow.rejectedStay(plan.version));
94
95
  return;
95
96
  }
96
97
  }
@@ -10,7 +10,7 @@
10
10
  import type { AgentSession, RewindDraftText } from "../../agent/types.js";
11
11
  import type { RewindPoint } from "../../checkpoints/types.js";
12
12
  import type { RewindAction } from "./rewind-panel.js";
13
- export declare const REWIND_USAGE = "\u7528\u6CD5\uFF1A/rewind\uFF0C/rewind <n> [both|conversation|code] [overwrite]\uFF0C/rewind <n> summarize-from|summarize-up-to [\u8BF4\u660E]";
13
+ export declare function rewindUsage(): string;
14
14
  export interface RewindArgs {
15
15
  /** 1 起的编号。 */
16
16
  index: number;
@@ -8,10 +8,13 @@
8
8
  * 错误码换成中文说明后照原 code 抛出。
9
9
  */
10
10
  import { AmaError } from "../../errors.js";
11
+ import { msg } from "../../i18n/index.js";
11
12
  import { oneLine, rewindErrorText, rewindResultLines } from "./rewind-text.js";
12
13
  import { relativeTime } from "./startup-ui.js";
13
- const FORMS = "/rewind <n> [both|conversation|code] [overwrite],/rewind <n> summarize-from|summarize-up-to [说明]";
14
- export const REWIND_USAGE = `用法:/rewind,${FORMS}`;
14
+ export function rewindUsage() {
15
+ const m = msg().rewind.command;
16
+ return m.usage(m.forms);
17
+ }
15
18
  const ACTIONS = [
16
19
  "both",
17
20
  "conversation",
@@ -23,7 +26,7 @@ export function parseRewindArgs(args) {
23
26
  const m = /^(\d+)(?:\s+(\S+))?(?:\s+([\s\S]*))?$/.exec(args.trim());
24
27
  const index = m === null ? NaN : Number(m[1]);
25
28
  if (m === null || !Number.isInteger(index) || index < 1) {
26
- throw new AmaError("invalid_arguments", REWIND_USAGE);
29
+ throw new AmaError("invalid_arguments", rewindUsage());
27
30
  }
28
31
  const out = { index };
29
32
  const action = m[2];
@@ -31,7 +34,7 @@ export function parseRewindArgs(args) {
31
34
  if (action === undefined)
32
35
  return out;
33
36
  if (!ACTIONS.includes(action)) {
34
- throw new AmaError("invalid_arguments", REWIND_USAGE);
37
+ throw new AmaError("invalid_arguments", rewindUsage());
35
38
  }
36
39
  out.action = action;
37
40
  if (action === "summarize-from" || action === "summarize-up-to") {
@@ -41,43 +44,44 @@ export function parseRewindArgs(args) {
41
44
  else if (rest === "overwrite" && action !== "conversation")
42
45
  out.overwrite = true;
43
46
  else if (rest !== "")
44
- throw new AmaError("invalid_arguments", REWIND_USAGE);
47
+ throw new AmaError("invalid_arguments", rewindUsage());
45
48
  return out;
46
49
  }
47
50
  export function rewindListText(points, now) {
51
+ const m = msg().rewind.command;
48
52
  if (points.length === 0)
49
- return "还没有可回滚的消息";
53
+ return m.empty;
50
54
  const lines = points.map((point, i) => {
51
55
  const time = relativeTime(new Date(point.timestamp).toISOString(), now);
52
- const only = point.hasCheckpoint ? "" : " [仅对话]";
53
- return ` ${i + 1}. ${time} ${oneLine(point.text, 60) || "(空)"}${only}`;
56
+ const only = point.hasCheckpoint ? "" : m.conversationOnly;
57
+ return ` ${i + 1}. ${time} ${oneLine(point.text, 60) || m.emptyText}${only}`;
54
58
  });
55
- return [`回滚点(${FORMS}):`, ...lines].join("\n");
59
+ return [m.pointsHeading(m.forms), ...lines].join("\n");
56
60
  }
57
61
  /** 执行 `/rewind <args>`;args 为空时只列出回滚点。 */
58
62
  export async function rewindCommand(session, args, now = Date.now()) {
63
+ const m = msg().rewind.command;
59
64
  const points = session.rewindPoints();
60
65
  if (args.trim() === "")
61
66
  return { message: rewindListText(points, now) };
62
67
  const parsed = parseRewindArgs(args);
63
68
  const point = points[parsed.index - 1];
64
69
  if (point === undefined) {
65
- throw new AmaError("invalid_arguments", `没有第 ${parsed.index} 个回滚点(共 ${points.length} 个,/rewind 查看)`);
70
+ throw new AmaError("invalid_arguments", m.noSuchPoint(parsed.index, points.length));
66
71
  }
67
72
  const action = parsed.action ?? (point.hasCheckpoint ? "both" : "conversation");
68
73
  try {
69
74
  if (action === "summarize-from") {
70
75
  const result = await session.summarizeFrom(point.entryId, parsed.instructions);
71
76
  return {
72
- message: `已从这里分叉,离开的部分写成了摘要;原消息:${oneLine(result.draft.text, 80)}`,
77
+ message: m.summarizedFrom(oneLine(result.draft.text, 80)),
73
78
  draft: result.draft,
74
79
  reload: true,
75
80
  };
76
81
  }
77
82
  if (action === "summarize-up-to") {
78
83
  const result = await session.summarizeUpTo(point.entryId, parsed.instructions);
79
- const after = result.tokensAfter !== undefined ? ` → ${result.tokensAfter}` : "";
80
- return { message: `已摘要到这里:${result.tokensBefore}${after} token` };
84
+ return { message: m.summarizedUpTo(result.tokensBefore, result.tokensAfter) };
81
85
  }
82
86
  const result = await session.rewind({
83
87
  entryId: point.entryId,
@@ -89,9 +93,7 @@ export async function rewindCommand(session, args, now = Date.now()) {
89
93
  const draft = result.conversation?.draft;
90
94
  const lines = rewindResultLines(result, {
91
95
  overwrite: parsed.overwrite === true,
92
- ...(draft !== undefined
93
- ? { conversation: `对话已回到这条消息之前;原消息:${oneLine(draft.text, 80)}` }
94
- : {}),
96
+ ...(draft !== undefined ? { conversation: m.conversationBack(oneLine(draft.text, 80)) } : {}),
95
97
  });
96
98
  return draft !== undefined
97
99
  ? { message: lines.join("\n"), draft, reload: true }
@@ -25,7 +25,6 @@ export interface RewindFlowHost extends RewindListHost {
25
25
  /** 终端行数(面板放不下时紧凑排版)。 */
26
26
  rows?(): number;
27
27
  }
28
- export declare const REFILLED = "\u539F\u6D88\u606F\u5DF2\u653E\u56DE\u8F93\u5165\u6846";
29
28
  /** 打开确认面板(底部覆盖层);返回选择或 undefined(取消)。 */
30
29
  export declare function openRewindPanel(host: RewindFlowHost, model: RewindPanelModel): Promise<RewindChoice | undefined>;
31
30
  /** 执行面板里的选择,结果与错误都写成通知。 */
@@ -8,10 +8,10 @@
8
8
  * (`ui.restoreOnCancel`、本回合没有任何助手文本 / 工具调用)→ 撤回并回填原消息。
9
9
  */
10
10
  import { AgentSessionImpl } from "../../agent/session.js";
11
+ import { msg } from "../../i18n/index.js";
11
12
  import { PreviewCache, openRewindList } from "./rewind-list.js";
12
13
  import { RewindPanel } from "./rewind-panel.js";
13
14
  import { rewindErrorText, rewindResultLines } from "./rewind-text.js";
14
- export const REFILLED = "原消息已放回输入框";
15
15
  /** 打开确认面板(底部覆盖层);返回选择或 undefined(取消)。 */
16
16
  export function openRewindPanel(host, model) {
17
17
  return new Promise((resolve) => {
@@ -29,17 +29,19 @@ export function openRewindPanel(host, model) {
29
29
  }
30
30
  function draftNote(draft) {
31
31
  const images = draft.images?.length ?? 0;
32
- return images > 0 ? `${REFILLED}(${images} 张图片随下一条消息发送)` : REFILLED;
32
+ const m = msg().rewind.flow;
33
+ return images > 0 ? m.refilledImages(images) : m.refilled;
33
34
  }
34
35
  /** 执行面板里的选择,结果与错误都写成通知。 */
35
36
  export async function executeRewind(host, point, choice) {
36
37
  const session = host.session();
38
+ const m = msg().rewind.flow;
37
39
  try {
38
40
  switch (choice.action) {
39
41
  case "both":
40
42
  case "conversation":
41
43
  case "code": {
42
- host.hint("回滚中…");
44
+ host.hint(m.rewinding);
43
45
  const result = await session.rewind({
44
46
  entryId: point.entryId,
45
47
  mode: choice.action,
@@ -55,9 +57,7 @@ export async function executeRewind(host, point, choice) {
55
57
  delete shown.gitHint;
56
58
  const lines = rewindResultLines(shown, {
57
59
  overwrite: choice.onConflict === "overwrite",
58
- ...(draft !== undefined
59
- ? { conversation: `对话已回到这条消息之前,${draftNote(draft)}` }
60
- : {}),
60
+ ...(draft !== undefined ? { conversation: m.conversationBack(draftNote(draft)) } : {}),
61
61
  });
62
62
  const code = result.code;
63
63
  const nothing = code !== undefined &&
@@ -67,18 +67,17 @@ export async function executeRewind(host, point, choice) {
67
67
  break;
68
68
  }
69
69
  case "summarize-from": {
70
- host.hint("正在为离开的部分写摘要…");
70
+ host.hint(m.summarizingFrom);
71
71
  const result = await session.summarizeFrom(point.entryId, choice.instructions);
72
72
  host.reload();
73
73
  host.setDraft(result.draft);
74
- host.notice("info", `已从这里分叉,离开的部分写成了摘要;${draftNote(result.draft)}`);
74
+ host.notice("info", m.summarizedFrom(draftNote(result.draft)));
75
75
  break;
76
76
  }
77
77
  case "summarize-up-to": {
78
- host.hint("正在摘要…");
78
+ host.hint(m.summarizing);
79
79
  const result = await session.summarizeUpTo(point.entryId, choice.instructions);
80
- const after = result.tokensAfter !== undefined ? ` → ${result.tokensAfter}` : "";
81
- host.notice("info", `已摘要到这里:${result.tokensBefore}${after} token`);
80
+ host.notice("info", msg().rewind.command.summarizedUpTo(result.tokensBefore, result.tokensAfter));
82
81
  break;
83
82
  }
84
83
  }
@@ -96,7 +95,7 @@ export function createRewindFlow(host) {
96
95
  async open() {
97
96
  const session = host.session();
98
97
  if (session.state.isStreaming) {
99
- host.notice("warn", "正在运行,不能回滚(先按 Esc 中断)");
98
+ host.notice("warn", msg().rewind.flow.busy);
100
99
  return;
101
100
  }
102
101
  if (opening)
@@ -105,7 +104,7 @@ export function createRewindFlow(host) {
105
104
  try {
106
105
  const points = session.rewindPoints();
107
106
  if (points.length === 0) {
108
- host.notice("info", "还没有可回滚的消息");
107
+ host.notice("info", msg().rewind.flow.empty);
109
108
  return;
110
109
  }
111
110
  const cache = new PreviewCache((entryId) => session.rewind({ entryId, mode: "code", dryRun: true }));
@@ -141,7 +140,7 @@ export function createRewindFlow(host) {
141
140
  return;
142
141
  host.reload();
143
142
  host.setDraft(draft);
144
- host.notice("info", `已撤回被中断的消息,${draftNote(draft)}`);
143
+ host.notice("info", msg().rewind.flow.undone(draftNote(draft)));
145
144
  }
146
145
  catch (error) {
147
146
  host.notice("error", rewindErrorText(error));
@@ -5,8 +5,9 @@
5
5
  * - 右侧徽标:没有检查点的行一律「仅对话」;有检查点的只给高亮行算——对它做一次代码 dry-run,
6
6
  * 结果按 entryId 缓存,算好后异步刷新:`N 文件 +x −y` / `无代码改动`,计算中 `…`,失败 `—`。
7
7
  */
8
+ import { msg } from "../../i18n/index.js";
8
9
  import { Box, SelectList } from "../../tui.js";
9
- import { PICKER_FOOTER } from "./pickers.js";
10
+ import { pickerFooter } from "./pickers.js";
10
11
  import { badgeText, hasCodeChanges, oneLine, rewindErrorText } from "./rewind-text.js";
11
12
  import { relativeTime } from "./startup-ui.js";
12
13
  /** 代码 dry-run 的缓存:每个回滚点最多算一次。 */
@@ -44,11 +45,11 @@ export function rewindListItems(points, cache, highlighted, now, ascii = false)
44
45
  const text = oneLine(point.text, 60, ascii ? "..." : "…");
45
46
  const item = {
46
47
  value: point.entryId,
47
- label: text === "" ? "(空)" : text,
48
+ label: text === "" ? msg().rewind.command.emptyText : text,
48
49
  description: relativeTime(new Date(point.timestamp).toISOString(), now),
49
50
  };
50
51
  if (!point.hasCheckpoint) {
51
- item.badge = "仅对话";
52
+ item.badge = msg().rewind.badge.conversationOnly;
52
53
  item.badgeColor = "dim";
53
54
  }
54
55
  else if (point.entryId === highlighted) {
@@ -63,7 +64,7 @@ export function rewindListItems(points, cache, highlighted, now, ascii = false)
63
64
  }
64
65
  else {
65
66
  const code = state.result.code;
66
- item.badge = code === undefined ? "无代码改动" : badgeText(code, ascii);
67
+ item.badge = code === undefined ? msg().rewind.badge.noCode : badgeText(code, ascii);
67
68
  item.badgeColor = hasCodeChanges(code) ? "accent" : "dim";
68
69
  }
69
70
  }
@@ -103,7 +104,7 @@ export function openRewindList(host, points, cache) {
103
104
  maxVisible: 10,
104
105
  filterable: points.length > 8,
105
106
  ...(host.keybindings !== undefined ? { keybindings: host.keybindings } : {}),
106
- footer: PICKER_FOOTER.replace("↑↓", host.theme.glyphs.arrowUp + host.theme.glyphs.arrowDown),
107
+ footer: pickerFooter(host.theme.glyphs.arrowUp + host.theme.glyphs.arrowDown),
107
108
  onSelect: (item) => close(points.find((p) => p.entryId === item.value)),
108
109
  onCancel: () => close(undefined),
109
110
  onSelectionChange: (item) => {
@@ -114,7 +115,7 @@ export function openRewindList(host, points, cache) {
114
115
  if (highlighted !== undefined)
115
116
  list.selectValue(highlighted);
116
117
  const width = Math.max(20, Math.min(host.columns() - 2, 72));
117
- const handle = host.showOverlay(new Box(list, { title: "回滚到哪条消息之前", theme: host.theme }), {
118
+ const handle = host.showOverlay(new Box(list, { title: msg().rewind.list.title, theme: host.theme }), {
118
119
  anchor: "center",
119
120
  width,
120
121
  });