@armadra/agent 0.5.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/CHANGELOG.md +203 -304
  2. package/CHANGELOG.zh-CN.md +462 -0
  3. package/README.md +408 -364
  4. package/README.zh-CN.md +705 -0
  5. package/dist/agent/session-plan.js +2 -2
  6. package/dist/agent/session-state.d.ts +3 -0
  7. package/dist/agent/session-state.js +20 -0
  8. package/dist/agent/session-subagent.d.ts +15 -1
  9. package/dist/agent/session-subagent.js +26 -3
  10. package/dist/agent/session-telemetry.d.ts +16 -2
  11. package/dist/agent/session-telemetry.js +29 -7
  12. package/dist/agent/session-tools.js +5 -2
  13. package/dist/agent/session-trace-writer.d.ts +27 -0
  14. package/dist/agent/session-trace-writer.js +253 -0
  15. package/dist/agent/session.d.ts +2 -0
  16. package/dist/agent/session.js +12 -0
  17. package/dist/agent/subagent-direct.d.ts +20 -0
  18. package/dist/agent/subagent-direct.js +76 -0
  19. package/dist/agent/subagent-registry.d.ts +8 -1
  20. package/dist/agent/subagent-registry.js +28 -1
  21. package/dist/agent/system-prompt.d.ts +3 -1
  22. package/dist/agent/system-prompt.js +3 -0
  23. package/dist/agent/tool-runner.d.ts +2 -1
  24. package/dist/agent/tool-runner.js +5 -4
  25. package/dist/agent/types-w6.d.ts +39 -0
  26. package/dist/agent/types-w6.js +4 -0
  27. package/dist/agent/types.d.ts +5 -2
  28. package/dist/agents/external.js +1 -1
  29. package/dist/agents/task-record.d.ts +74 -1
  30. package/dist/agents/task-record.js +100 -0
  31. package/dist/ai/apis/cache-params.js +2 -1
  32. package/dist/ai/apis/chatgpt-backend.d.ts +52 -0
  33. package/dist/ai/apis/chatgpt-backend.js +224 -0
  34. package/dist/ai/apis/chatgpt-rate-limits.d.ts +26 -0
  35. package/dist/ai/apis/chatgpt-rate-limits.js +91 -0
  36. package/dist/ai/apis/openai-responses-request.d.ts +2 -1
  37. package/dist/ai/apis/openai-responses-request.js +8 -2
  38. package/dist/ai/apis/openai-responses.d.ts +2 -0
  39. package/dist/ai/apis/openai-responses.js +51 -16
  40. package/dist/ai/overflow.d.ts +1 -1
  41. package/dist/ai/overflow.js +10 -7
  42. package/dist/ai/providers/auth.d.ts +15 -2
  43. package/dist/ai/providers/auth.js +69 -2
  44. package/dist/ai/providers/builtin.js +27 -0
  45. package/dist/ai/providers/catalog-data.js +1 -0
  46. package/dist/ai/providers/discovered-cache.d.ts +48 -0
  47. package/dist/ai/providers/discovered-cache.js +102 -0
  48. package/dist/ai/providers/enrich.js +2 -7
  49. package/dist/ai/providers/model-visibility.d.ts +33 -0
  50. package/dist/ai/providers/model-visibility.js +70 -0
  51. package/dist/ai/providers/models-dev-cache.js +15 -19
  52. package/dist/ai/providers/models-dev-snapshot.js +8 -7
  53. package/dist/ai/providers/models-dev.js +5 -15
  54. package/dist/ai/providers/registry.d.ts +2 -0
  55. package/dist/ai/providers/registry.js +6 -1
  56. package/dist/ai/providers/suggest.js +2 -16
  57. package/dist/ai/types.d.ts +27 -1
  58. package/dist/auth/chatgpt/backend-client.d.ts +26 -0
  59. package/dist/auth/chatgpt/backend-client.js +74 -0
  60. package/dist/auth/chatgpt/claims.d.ts +17 -0
  61. package/dist/auth/chatgpt/claims.js +46 -0
  62. package/dist/auth/chatgpt/cli.d.ts +35 -0
  63. package/dist/auth/chatgpt/cli.js +279 -0
  64. package/dist/auth/chatgpt/doctor.d.ts +17 -0
  65. package/dist/auth/chatgpt/doctor.js +36 -0
  66. package/dist/auth/chatgpt/host-id.d.ts +7 -0
  67. package/dist/auth/chatgpt/host-id.js +26 -0
  68. package/dist/auth/chatgpt/login.d.ts +30 -0
  69. package/dist/auth/chatgpt/login.js +130 -0
  70. package/dist/auth/chatgpt/presets.d.ts +66 -0
  71. package/dist/auth/chatgpt/presets.js +120 -0
  72. package/dist/auth/chatgpt/quota-text.d.ts +13 -0
  73. package/dist/auth/chatgpt/quota-text.js +36 -0
  74. package/dist/auth/oauth/browser.d.ts +12 -0
  75. package/dist/auth/oauth/browser.js +27 -0
  76. package/dist/auth/oauth/callback-server.d.ts +47 -0
  77. package/dist/auth/oauth/callback-server.js +147 -0
  78. package/dist/auth/oauth/flows.d.ts +62 -0
  79. package/dist/auth/oauth/flows.js +113 -0
  80. package/dist/auth/oauth/jwt.d.ts +24 -0
  81. package/dist/auth/oauth/jwt.js +81 -0
  82. package/dist/auth/oauth/live.d.ts +21 -0
  83. package/dist/auth/oauth/live.js +25 -0
  84. package/dist/auth/oauth/oidc.d.ts +26 -0
  85. package/dist/auth/oauth/oidc.js +72 -0
  86. package/dist/auth/oauth/pkce.d.ts +15 -0
  87. package/dist/auth/oauth/pkce.js +20 -0
  88. package/dist/auth/oauth/refresh.d.ts +35 -0
  89. package/dist/auth/oauth/refresh.js +129 -0
  90. package/dist/auth/oauth/token-client.d.ts +33 -0
  91. package/dist/auth/oauth/token-client.js +121 -0
  92. package/dist/auth/oauth/token-store.d.ts +23 -0
  93. package/dist/auth/oauth/token-store.js +125 -0
  94. package/dist/auth/testing/fake-oauth.d.ts +73 -0
  95. package/dist/auth/testing/fake-oauth.js +271 -0
  96. package/dist/auth/testing/refresh-child.d.ts +5 -0
  97. package/dist/auth/testing/refresh-child.js +16 -0
  98. package/dist/bundle/ama.cjs +26532 -11045
  99. package/dist/checkpoints/backend.js +6 -5
  100. package/dist/checkpoints/restore.js +3 -2
  101. package/dist/checkpoints/settings.js +2 -1
  102. package/dist/checkpoints/shadow-git.js +7 -6
  103. package/dist/checkpoints/shadow-restore.js +3 -2
  104. package/dist/checkpoints/tracker.js +4 -3
  105. package/dist/cli/args.d.ts +9 -2
  106. package/dist/cli/args.js +74 -27
  107. package/dist/cli/bootstrap.js +53 -31
  108. package/dist/cli/choice-prompt.js +8 -6
  109. package/dist/cli/codemode-notice.js +2 -2
  110. package/dist/cli/compose-agents.js +2 -1
  111. package/dist/cli/compose-extensions.js +2 -0
  112. package/dist/cli/compose-memory.d.ts +53 -0
  113. package/dist/cli/compose-memory.js +127 -0
  114. package/dist/cli/compose-providers.d.ts +6 -0
  115. package/dist/cli/compose-providers.js +38 -2
  116. package/dist/cli/compose-session.d.ts +5 -0
  117. package/dist/cli/compose-session.js +27 -13
  118. package/dist/cli/compose-store.d.ts +2 -0
  119. package/dist/cli/compose-store.js +9 -5
  120. package/dist/cli/compose.d.ts +2 -0
  121. package/dist/cli/compose.js +13 -5
  122. package/dist/cli/default-model.d.ts +0 -2
  123. package/dist/cli/default-model.js +5 -8
  124. package/dist/cli/deps.d.ts +5 -1
  125. package/dist/cli/exit-codes.d.ts +1 -1
  126. package/dist/cli/exit-codes.js +7 -16
  127. package/dist/cli/from-prompt.js +3 -2
  128. package/dist/cli/help-text.d.ts +2 -1
  129. package/dist/cli/help-text.js +5 -99
  130. package/dist/cli/main.d.ts +5 -0
  131. package/dist/cli/main.js +21 -2
  132. package/dist/cli/proxy.js +14 -9
  133. package/dist/cli/runtime.d.ts +5 -0
  134. package/dist/cli/startup-screen.js +20 -27
  135. package/dist/cli/startup-steps.js +6 -8
  136. package/dist/cli/subcommands/auth.d.ts +6 -3
  137. package/dist/cli/subcommands/auth.js +52 -22
  138. package/dist/cli/subcommands/config-set.d.ts +21 -0
  139. package/dist/cli/subcommands/config-set.js +145 -0
  140. package/dist/cli/subcommands/config.d.ts +2 -1
  141. package/dist/cli/subcommands/config.js +51 -37
  142. package/dist/cli/subcommands/doctor.d.ts +2 -1
  143. package/dist/cli/subcommands/doctor.js +97 -58
  144. package/dist/cli/subcommands/init.d.ts +1 -1
  145. package/dist/cli/subcommands/init.js +8 -7
  146. package/dist/cli/subcommands/memory.d.ts +18 -0
  147. package/dist/cli/subcommands/memory.js +189 -0
  148. package/dist/cli/subcommands/model-meta.js +11 -9
  149. package/dist/cli/subcommands/models-cache-probe.js +23 -20
  150. package/dist/cli/subcommands/models-discover.d.ts +4 -0
  151. package/dist/cli/subcommands/models-discover.js +60 -21
  152. package/dist/cli/subcommands/models-enable.d.ts +13 -0
  153. package/dist/cli/subcommands/models-enable.js +145 -0
  154. package/dist/cli/subcommands/models.d.ts +3 -1
  155. package/dist/cli/subcommands/models.js +39 -24
  156. package/dist/cli/subcommands/probe-runner.js +8 -7
  157. package/dist/cli/subcommands/providers-list.js +32 -21
  158. package/dist/cli/subcommands/providers-plan.js +24 -25
  159. package/dist/cli/subcommands/providers-probe.js +5 -6
  160. package/dist/cli/subcommands/providers.d.ts +1 -1
  161. package/dist/cli/subcommands/providers.js +45 -50
  162. package/dist/cli/subcommands/sessions-export.d.ts +1 -1
  163. package/dist/cli/subcommands/sessions-export.js +10 -9
  164. package/dist/cli/subcommands/sessions-search.d.ts +1 -1
  165. package/dist/cli/subcommands/sessions-search.js +11 -10
  166. package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
  167. package/dist/cli/subcommands/sessions-trace.js +156 -0
  168. package/dist/cli/subcommands/sessions.d.ts +4 -3
  169. package/dist/cli/subcommands/sessions.js +40 -37
  170. package/dist/cli/subcommands/stats.d.ts +1 -1
  171. package/dist/cli/subcommands/stats.js +49 -30
  172. package/dist/cli/system-prompt-arg.js +3 -2
  173. package/dist/codemode/capability.js +3 -2
  174. package/dist/compaction/post-compact.d.ts +1 -0
  175. package/dist/compaction/post-compact.js +15 -1
  176. package/dist/compaction/prune-tier.d.ts +1 -1
  177. package/dist/compaction/prune-tier.js +3 -3
  178. package/dist/compaction/serialize.js +2 -1
  179. package/dist/config/auth-file.d.ts +12 -2
  180. package/dist/config/auth-file.js +32 -10
  181. package/dist/config/checker.js +12 -11
  182. package/dist/config/context-files.js +3 -2
  183. package/dist/config/edit.d.ts +106 -0
  184. package/dist/config/edit.js +350 -0
  185. package/dist/config/init.d.ts +4 -3
  186. package/dist/config/init.js +10 -18
  187. package/dist/config/json-schema.d.ts +2 -1
  188. package/dist/config/json-schema.js +102 -69
  189. package/dist/config/key-docs.d.ts +18 -7
  190. package/dist/config/key-docs.js +43 -128
  191. package/dist/config/load.js +7 -6
  192. package/dist/config/merge.d.ts +4 -1
  193. package/dist/config/merge.js +42 -22
  194. package/dist/config/paths.js +6 -5
  195. package/dist/config/profile.d.ts +5 -1
  196. package/dist/config/profile.js +7 -2
  197. package/dist/config/schema-w5.js +12 -4
  198. package/dist/config/schema-w6.d.ts +19 -0
  199. package/dist/config/schema-w6.js +115 -0
  200. package/dist/config/schema.js +34 -20
  201. package/dist/config/settings-registry.d.ts +81 -0
  202. package/dist/config/settings-registry.js +185 -0
  203. package/dist/config/types-w5.d.ts +7 -0
  204. package/dist/config/types-w5.js +2 -0
  205. package/dist/config/types-w6.d.ts +109 -0
  206. package/dist/config/types-w6.js +19 -0
  207. package/dist/config/types.d.ts +11 -8
  208. package/dist/config/types.js +1 -0
  209. package/dist/drivers/acp/client.js +1 -1
  210. package/dist/drivers/acp/driver.js +13 -8
  211. package/dist/drivers/agents.js +4 -3
  212. package/dist/drivers/base.js +3 -2
  213. package/dist/drivers/host-runners.js +2 -1
  214. package/dist/drivers/native/claude-stream.js +12 -11
  215. package/dist/drivers/native/codex-app-server.js +17 -12
  216. package/dist/drivers/native/oneshot.js +8 -7
  217. package/dist/drivers/pool.js +1 -1
  218. package/dist/drivers/runner.d.ts +3 -1
  219. package/dist/drivers/runner.js +68 -20
  220. package/dist/drivers/turn.js +1 -1
  221. package/dist/hooks/config.js +3 -2
  222. package/dist/hooks/protocol.js +18 -12
  223. package/dist/host/api-impl.js +11 -10
  224. package/dist/host/loader.js +9 -8
  225. package/dist/host/types.d.ts +3 -0
  226. package/dist/i18n/catalog.d.ts +2209 -0
  227. package/dist/i18n/catalog.js +72 -0
  228. package/dist/i18n/format.d.ts +21 -0
  229. package/dist/i18n/format.js +58 -0
  230. package/dist/i18n/index.d.ts +58 -0
  231. package/dist/i18n/index.js +72 -0
  232. package/dist/i18n/messages/agents.d.ts +84 -0
  233. package/dist/i18n/messages/agents.js +85 -0
  234. package/dist/i18n/messages/approval.d.ts +99 -0
  235. package/dist/i18n/messages/approval.js +100 -0
  236. package/dist/i18n/messages/auth.d.ts +189 -0
  237. package/dist/i18n/messages/auth.js +201 -0
  238. package/dist/i18n/messages/cli-args.d.ts +46 -0
  239. package/dist/i18n/messages/cli-args.js +46 -0
  240. package/dist/i18n/messages/cli-help.d.ts +12 -0
  241. package/dist/i18n/messages/cli-help.js +248 -0
  242. package/dist/i18n/messages/cli.d.ts +336 -0
  243. package/dist/i18n/messages/cli.js +311 -0
  244. package/dist/i18n/messages/config-keys.d.ts +293 -0
  245. package/dist/i18n/messages/config-keys.js +296 -0
  246. package/dist/i18n/messages/config.d.ts +508 -0
  247. package/dist/i18n/messages/config.js +241 -0
  248. package/dist/i18n/messages/drivers.d.ts +123 -0
  249. package/dist/i18n/messages/drivers.js +124 -0
  250. package/dist/i18n/messages/errors.d.ts +83 -0
  251. package/dist/i18n/messages/errors.js +171 -0
  252. package/dist/i18n/messages/interactive-line.d.ts +61 -0
  253. package/dist/i18n/messages/interactive-line.js +69 -0
  254. package/dist/i18n/messages/interactive-startup.d.ts +99 -0
  255. package/dist/i18n/messages/interactive-startup.js +100 -0
  256. package/dist/i18n/messages/interactive-view.d.ts +140 -0
  257. package/dist/i18n/messages/interactive-view.js +141 -0
  258. package/dist/i18n/messages/interactive.d.ts +489 -0
  259. package/dist/i18n/messages/interactive.js +248 -0
  260. package/dist/i18n/messages/memory.d.ts +123 -0
  261. package/dist/i18n/messages/memory.js +128 -0
  262. package/dist/i18n/messages/panels.d.ts +233 -0
  263. package/dist/i18n/messages/panels.js +232 -0
  264. package/dist/i18n/messages/permissions.d.ts +126 -0
  265. package/dist/i18n/messages/permissions.js +151 -0
  266. package/dist/i18n/messages/plan.d.ts +123 -0
  267. package/dist/i18n/messages/plan.js +124 -0
  268. package/dist/i18n/messages/print.d.ts +86 -0
  269. package/dist/i18n/messages/print.js +91 -0
  270. package/dist/i18n/messages/report.d.ts +391 -0
  271. package/dist/i18n/messages/report.js +490 -0
  272. package/dist/i18n/messages/rewind.d.ts +198 -0
  273. package/dist/i18n/messages/rewind.js +217 -0
  274. package/dist/i18n/messages/session.d.ts +230 -0
  275. package/dist/i18n/messages/session.js +258 -0
  276. package/dist/i18n/messages/settings.d.ts +355 -0
  277. package/dist/i18n/messages/settings.js +343 -0
  278. package/dist/i18n/messages/subcommands-config.d.ts +113 -0
  279. package/dist/i18n/messages/subcommands-config.js +129 -0
  280. package/dist/i18n/messages/subcommands-models.d.ts +34 -0
  281. package/dist/i18n/messages/subcommands-models.js +34 -0
  282. package/dist/i18n/messages/subcommands.d.ts +576 -0
  283. package/dist/i18n/messages/subcommands.js +477 -0
  284. package/dist/i18n/messages/trace.d.ts +243 -0
  285. package/dist/i18n/messages/trace.js +238 -0
  286. package/dist/i18n/types.d.ts +15 -0
  287. package/dist/i18n/types.js +7 -0
  288. package/dist/index.d.ts +6 -0
  289. package/dist/index.js +2 -0
  290. package/dist/memory/edit.d.ts +24 -0
  291. package/dist/memory/edit.js +63 -0
  292. package/dist/memory/frontmatter.d.ts +37 -0
  293. package/dist/memory/frontmatter.js +79 -0
  294. package/dist/memory/index.d.ts +28 -0
  295. package/dist/memory/index.js +126 -0
  296. package/dist/memory/lock.d.ts +17 -0
  297. package/dist/memory/lock.js +62 -0
  298. package/dist/memory/paths.d.ts +57 -0
  299. package/dist/memory/paths.js +175 -0
  300. package/dist/memory/report.d.ts +36 -0
  301. package/dist/memory/report.js +86 -0
  302. package/dist/memory/runtime.d.ts +42 -0
  303. package/dist/memory/runtime.js +36 -0
  304. package/dist/memory/secrets.d.ts +8 -0
  305. package/dist/memory/secrets.js +27 -0
  306. package/dist/memory/section.d.ts +28 -0
  307. package/dist/memory/section.js +59 -0
  308. package/dist/memory/store.d.ts +70 -0
  309. package/dist/memory/store.js +284 -0
  310. package/dist/memory/tool.d.ts +31 -0
  311. package/dist/memory/tool.js +94 -0
  312. package/dist/modes/acp/acp-events.js +2 -1
  313. package/dist/modes/acp/acp-server.js +13 -12
  314. package/dist/modes/commands-core.d.ts +11 -0
  315. package/dist/modes/commands-core.js +93 -62
  316. package/dist/modes/image-input.js +20 -6
  317. package/dist/modes/interactive/agent-bar.d.ts +95 -0
  318. package/dist/modes/interactive/agent-bar.js +248 -0
  319. package/dist/modes/interactive/agent-panels.js +27 -26
  320. package/dist/modes/interactive/agent-transcript.d.ts +47 -0
  321. package/dist/modes/interactive/agent-transcript.js +191 -0
  322. package/dist/modes/interactive/agent-ui.d.ts +36 -1
  323. package/dist/modes/interactive/agent-ui.js +180 -14
  324. package/dist/modes/interactive/agent-view.d.ts +72 -0
  325. package/dist/modes/interactive/agent-view.js +281 -0
  326. package/dist/modes/interactive/approval-dialog.js +46 -34
  327. package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
  328. package/dist/modes/interactive/clipboard-paste.js +9 -4
  329. package/dist/modes/interactive/commands.d.ts +22 -1
  330. package/dist/modes/interactive/commands.js +100 -49
  331. package/dist/modes/interactive/completion.js +2 -1
  332. package/dist/modes/interactive/config-panel.d.ts +70 -0
  333. package/dist/modes/interactive/config-panel.js +319 -0
  334. package/dist/modes/interactive/config-ui.d.ts +96 -0
  335. package/dist/modes/interactive/config-ui.js +397 -0
  336. package/dist/modes/interactive/confirm-dialog.js +6 -7
  337. package/dist/modes/interactive/event-notices.js +11 -9
  338. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  339. package/dist/modes/interactive/interactive-mode.js +21 -22
  340. package/dist/modes/interactive/key-dispatch.d.ts +12 -0
  341. package/dist/modes/interactive/key-dispatch.js +24 -9
  342. package/dist/modes/interactive/line/line-editor.js +2 -1
  343. package/dist/modes/interactive/line/line-mode.js +18 -7
  344. package/dist/modes/interactive/line/line-render.js +25 -24
  345. package/dist/modes/interactive/memory-panel.d.ts +64 -0
  346. package/dist/modes/interactive/memory-panel.js +221 -0
  347. package/dist/modes/interactive/message-view.d.ts +4 -2
  348. package/dist/modes/interactive/message-view.js +42 -33
  349. package/dist/modes/interactive/model-items.d.ts +45 -0
  350. package/dist/modes/interactive/model-items.js +134 -0
  351. package/dist/modes/interactive/model-picker.d.ts +57 -0
  352. package/dist/modes/interactive/model-picker.js +191 -0
  353. package/dist/modes/interactive/panels.js +39 -31
  354. package/dist/modes/interactive/pickers.d.ts +2 -1
  355. package/dist/modes/interactive/pickers.js +10 -6
  356. package/dist/modes/interactive/plan-command.d.ts +1 -1
  357. package/dist/modes/interactive/plan-command.js +24 -27
  358. package/dist/modes/interactive/plan-dialog.js +18 -17
  359. package/dist/modes/interactive/plan-flow.js +6 -5
  360. package/dist/modes/interactive/rewind-command.d.ts +1 -1
  361. package/dist/modes/interactive/rewind-command.js +18 -16
  362. package/dist/modes/interactive/rewind-flow.d.ts +0 -1
  363. package/dist/modes/interactive/rewind-flow.js +13 -14
  364. package/dist/modes/interactive/rewind-list.js +7 -6
  365. package/dist/modes/interactive/rewind-panel.js +40 -40
  366. package/dist/modes/interactive/rewind-text.d.ts +5 -3
  367. package/dist/modes/interactive/rewind-text.js +48 -38
  368. package/dist/modes/interactive/run-indicator.js +15 -12
  369. package/dist/modes/interactive/session-events.js +3 -2
  370. package/dist/modes/interactive/startup-header.js +22 -23
  371. package/dist/modes/interactive/startup-ui.d.ts +3 -9
  372. package/dist/modes/interactive/startup-ui.js +44 -88
  373. package/dist/modes/interactive/status-area.d.ts +2 -0
  374. package/dist/modes/interactive/status-area.js +8 -2
  375. package/dist/modes/interactive/status-bar.js +4 -3
  376. package/dist/modes/interactive/subagent-view.js +9 -7
  377. package/dist/modes/interactive/tasks-report.d.ts +6 -0
  378. package/dist/modes/interactive/tasks-report.js +28 -31
  379. package/dist/modes/interactive/terminal-setup.d.ts +9 -0
  380. package/dist/modes/interactive/terminal-setup.js +23 -0
  381. package/dist/modes/interactive/tool-summary.js +19 -17
  382. package/dist/modes/interactive/tool-view.js +7 -4
  383. package/dist/modes/interactive/trace-view.d.ts +89 -0
  384. package/dist/modes/interactive/trace-view.js +332 -0
  385. package/dist/modes/print/print-mode.js +14 -15
  386. package/dist/modes/rpc/commands.js +7 -3
  387. package/dist/modes/rpc/rpc-mode.js +9 -3
  388. package/dist/modes/session-report.d.ts +2 -0
  389. package/dist/modes/session-report.js +101 -105
  390. package/dist/modes/startup-ui-text.js +11 -6
  391. package/dist/permissions/bypass.d.ts +8 -10
  392. package/dist/permissions/bypass.js +19 -10
  393. package/dist/permissions/memory-class.d.ts +23 -0
  394. package/dist/permissions/memory-class.js +54 -0
  395. package/dist/permissions/modes.d.ts +3 -3
  396. package/dist/permissions/modes.js +21 -16
  397. package/dist/permissions/pipeline.d.ts +1 -1
  398. package/dist/permissions/pipeline.js +9 -2
  399. package/dist/permissions/preview.js +49 -42
  400. package/dist/permissions/rules.js +5 -2
  401. package/dist/permissions/types.d.ts +4 -0
  402. package/dist/plan/store.js +2 -1
  403. package/dist/rpc.d.ts +39 -1
  404. package/dist/rpc.js +3 -0
  405. package/dist/sandbox/bash.js +11 -8
  406. package/dist/sandbox/detect.js +14 -11
  407. package/dist/sdk.d.ts +17 -1
  408. package/dist/sdk.js +29 -7
  409. package/dist/session/export.js +31 -30
  410. package/dist/session/manager.d.ts +1 -1
  411. package/dist/session/manager.js +5 -3
  412. package/dist/session/reuse.js +5 -4
  413. package/dist/session/scan.js +3 -2
  414. package/dist/session/stats-aggregate.d.ts +3 -1
  415. package/dist/session/stats-aggregate.js +5 -1
  416. package/dist/session/stats-index.js +2 -1
  417. package/dist/session/stats-scan.d.ts +4 -1
  418. package/dist/session/stats-scan.js +6 -2
  419. package/dist/session/store.d.ts +11 -0
  420. package/dist/session/store.js +48 -1
  421. package/dist/session/types.d.ts +2 -0
  422. package/dist/skills/builtin.js +2 -1
  423. package/dist/tools/image-file.d.ts +26 -1
  424. package/dist/tools/image-file.js +55 -13
  425. package/dist/tools/presets.d.ts +14 -1
  426. package/dist/tools/presets.js +3 -3
  427. package/dist/tools/registry.js +1 -1
  428. package/dist/tools/truncate.d.ts +1 -1
  429. package/dist/tools/truncate.js +2 -2
  430. package/dist/tools/types.d.ts +17 -1
  431. package/dist/trace/build-index.d.ts +91 -0
  432. package/dist/trace/build-index.js +127 -0
  433. package/dist/trace/build-nodes.d.ts +24 -0
  434. package/dist/trace/build-nodes.js +279 -0
  435. package/dist/trace/build-util.d.ts +43 -0
  436. package/dist/trace/build-util.js +120 -0
  437. package/dist/trace/build.d.ts +82 -0
  438. package/dist/trace/build.js +382 -0
  439. package/dist/trace/detail.d.ts +35 -0
  440. package/dist/trace/detail.js +205 -0
  441. package/dist/trace/flatten.d.ts +69 -0
  442. package/dist/trace/flatten.js +173 -0
  443. package/dist/trace/format.d.ts +47 -0
  444. package/dist/trace/format.js +329 -0
  445. package/dist/trace/html-template.d.ts +19 -0
  446. package/dist/trace/html-template.js +150 -0
  447. package/dist/trace/html.d.ts +104 -0
  448. package/dist/trace/html.js +292 -0
  449. package/dist/trace/preview.d.ts +29 -0
  450. package/dist/trace/preview.js +59 -0
  451. package/dist/trace/query-session.d.ts +14 -0
  452. package/dist/trace/query-session.js +38 -0
  453. package/dist/trace/query.d.ts +55 -0
  454. package/dist/trace/query.js +188 -0
  455. package/dist/trace/session.d.ts +40 -0
  456. package/dist/trace/session.js +168 -0
  457. package/dist/trace/types.d.ts +243 -0
  458. package/dist/trace/types.js +13 -0
  459. package/dist/tui/components/editor-paste.d.ts +2 -0
  460. package/dist/tui/components/editor-paste.js +6 -3
  461. package/dist/tui/components/editor.js +2 -2
  462. package/dist/tui/components/loader.d.ts +3 -0
  463. package/dist/tui/components/loader.js +14 -0
  464. package/dist/tui/components/select-list.d.ts +2 -0
  465. package/dist/tui/components/select-list.js +7 -0
  466. package/dist/tui/components/settings-list.d.ts +61 -0
  467. package/dist/tui/components/settings-list.js +135 -0
  468. package/dist/tui/keybindings.d.ts +5 -0
  469. package/dist/tui/keybindings.js +17 -5
  470. package/dist/tui.d.ts +1 -0
  471. package/dist/tui.js +2 -0
  472. package/docs/en/host-api.md +167 -0
  473. package/docs/en/permissions.md +214 -0
  474. package/docs/en/providers.md +627 -0
  475. package/docs/en/rpc.md +361 -0
  476. package/docs/en/sessions.md +219 -0
  477. package/docs/en/tui.md +534 -0
  478. package/docs/host-api.md +18 -17
  479. package/docs/memory.md +172 -0
  480. package/docs/permissions.md +2 -2
  481. package/docs/providers.md +73 -1
  482. package/docs/rpc.md +31 -3
  483. package/docs/session-format.md +8 -2
  484. package/docs/sessions.md +29 -1
  485. package/docs/tui.md +140 -4
  486. package/package.json +8 -3
@@ -8,7 +8,8 @@
8
8
  * - `/permissions`:权限模式、判定顺序(折行对齐值列)、规则(allow success、deny error、来源 dim)、
9
9
  * 最近的 auto 判定。
10
10
  */
11
- import { AUTO_LAYER_TEXT, permissionModeLabel } from "../../permissions/modes.js";
11
+ import { msg } from "../../i18n/index.js";
12
+ import { autoLayerText, permissionModeLabel } from "../../permissions/modes.js";
12
13
  import { Card, KeyValue, Meter, } from "../../tui.js";
13
14
  import { cacheRows, externalRows, formatTokenCount, formatUsd, taskStatsText, } from "../session-report.js";
14
15
  import { tildePath } from "../../cli/startup-screen.js";
@@ -49,9 +50,13 @@ export function keyValue(rows, theme, wrap = false) {
49
50
  return new KeyValue(rows, { theme, maxKeyRatio: 0.3, ...(wrap ? { wrap: true } : {}) });
50
51
  }
51
52
  function cacheSection(session, theme, now) {
52
- return [theme.bold("缓存"), new Indent(keyValue(cacheRows(session, now), theme), 2)];
53
+ return [
54
+ theme.bold(msg().panels.cache.title),
55
+ new Indent(keyValue(cacheRows(session, now), theme), 2),
56
+ ];
53
57
  }
54
58
  export function sessionPanel(session, theme, options = {}) {
59
+ const m = msg().panels.session;
55
60
  const now = options.now ?? Date.now();
56
61
  const state = session.state;
57
62
  const stats = session.getStats();
@@ -67,41 +72,41 @@ export function sessionPanel(session, theme, options = {}) {
67
72
  `${stats.contextWindow === undefined ? "?" : formatTokenCount(stats.contextWindow)}`;
68
73
  const rows = [
69
74
  {
70
- key: "模型",
75
+ key: m.model,
71
76
  value: theme.fg("accent", model) +
72
77
  sep +
73
- `思考 ${state.thinkingLevel}` +
78
+ m.thinking(state.thinkingLevel) +
74
79
  sep +
75
- `权限 ${permissionModeLabel(state.permissionMode)}`,
80
+ m.permission(permissionModeLabel(state.permissionMode)),
76
81
  },
77
82
  {
78
- key: "消息",
83
+ key: m.messages,
79
84
  value: [
80
- `用户 ${stats.userMessages}`,
81
- `助手 ${stats.assistantMessages}`,
82
- `工具调用 ${stats.toolCalls}`,
85
+ m.user(stats.userMessages),
86
+ m.assistant(stats.assistantMessages),
87
+ m.toolCalls(stats.toolCalls),
83
88
  ].join(sep),
84
89
  },
85
90
  {
86
- key: "用量",
91
+ key: m.usage,
87
92
  value: [
88
- `输入 ${formatTokenCount(t.input)}`,
89
- `输出 ${formatTokenCount(t.output)}`,
90
- `缓存读 ${formatTokenCount(t.cacheRead)}`,
91
- `缓存写 ${formatTokenCount(t.cacheWrite)}`,
93
+ m.input(formatTokenCount(t.input)),
94
+ m.output(formatTokenCount(t.output)),
95
+ m.cacheRead(formatTokenCount(t.cacheRead)),
96
+ m.cacheWrite(formatTokenCount(t.cacheWrite)),
92
97
  formatUsd(stats.cost),
93
98
  ].join(sep),
94
99
  },
95
- { key: "上下文", value: meter + window },
100
+ { key: m.context, value: meter + window },
96
101
  ];
97
102
  const tasks = taskStatsText(session);
98
103
  if (tasks !== undefined)
99
- rows.push({ key: "子 Agent", value: tasks });
104
+ rows.push({ key: m.subagents, value: tasks });
100
105
  const external = externalRows(session);
101
106
  const externalSection = external.length > 0
102
- ? ["", theme.bold("外部 Agent"), new Indent(keyValue(external, theme), 2)]
107
+ ? ["", theme.bold(m.external), new Indent(keyValue(external, theme), 2)]
103
108
  : [];
104
- const file = state.sessionFile === undefined ? "未落盘" : tildePath(state.sessionFile, options.home);
109
+ const file = state.sessionFile === undefined ? m.notSaved : tildePath(state.sessionFile, options.home);
105
110
  const parts = [
106
111
  keyValue(rows, theme),
107
112
  "",
@@ -110,12 +115,15 @@ export function sessionPanel(session, theme, options = {}) {
110
115
  ];
111
116
  return new Card(new Stack(parts), {
112
117
  theme,
113
- title: `会话 ${state.sessionId.slice(0, 8)}`,
118
+ title: m.title(state.sessionId.slice(0, 8)),
114
119
  subtitle: file,
115
120
  });
116
121
  }
117
122
  export function cachePanel(session, theme, now = Date.now()) {
118
- return new Card(keyValue(cacheRows(session, now), theme), { theme, title: "缓存" });
123
+ return new Card(keyValue(cacheRows(session, now), theme), {
124
+ theme,
125
+ title: msg().panels.cache.title,
126
+ });
119
127
  }
120
128
  const DECISION_COLOR = {
121
129
  allow: "success",
@@ -123,20 +131,20 @@ const DECISION_COLOR = {
123
131
  ask: "warning",
124
132
  };
125
133
  export function permissionsPanel(runtime, session, theme) {
134
+ const m = msg().panels.permissions;
126
135
  const rules = runtime.permission.rules;
127
136
  const mode = session.state.permissionMode;
128
- const order = mode === "auto"
129
- ? "deny 规则 → Hook deny → 危险命令确认 → 规则层(受保护路径、项目外写入、网络、删除类)→ Hook ask → allow 规则 / Hook allow / 本会话记忆 → 静态判定(只读、项目内写入、安全名单)→ 模型分类器 → 询问"
130
- : mode === "allowlist"
131
- ? "deny 规则 → Hook deny → 危险命令(拒绝)→ 只读工具 / allow 规则 / Hook allow 放行 → 其余拒绝(从不询问)"
132
- : "deny 规则 → Hook deny → 危险命令确认 → 权限模式 → allow 规则 / Hook allow / 本会话记忆 → 询问";
137
+ const order = mode === "auto" ? m.orderAuto : mode === "allowlist" ? m.orderAllowlist : m.orderDefault;
133
138
  const effect = (decision) => theme.fg(DECISION_COLOR[decision] ?? "text", decision.padEnd(5));
134
139
  const parts = [
135
140
  keyValue([
136
- { key: "权限模式", value: `${permissionModeLabel(mode)}${theme.fg("dim", `(${mode})`)}` },
137
- { key: "判定顺序", value: order },
141
+ {
142
+ key: m.mode,
143
+ value: m.modeValue(permissionModeLabel(mode), mode, (t) => theme.fg("dim", t)),
144
+ },
145
+ { key: m.order, value: order },
138
146
  ], theme, true),
139
- theme.bold(rules.length === 0 ? "规则(无)" : `规则(${rules.length})`),
147
+ theme.bold(rules.length === 0 ? m.rulesNone : m.rules(rules.length)),
140
148
  ];
141
149
  if (rules.length > 0) {
142
150
  parts.push(new Indent(keyValue(rules.map((r) => ({
@@ -146,11 +154,11 @@ export function permissionsPanel(runtime, session, theme) {
146
154
  }
147
155
  const recent = runtime.permission.autoDecisions?.() ?? [];
148
156
  if (recent.length > 0) {
149
- parts.push(theme.bold(`最近的 auto 判定(${recent.length})`));
157
+ parts.push(theme.bold(m.recentAuto(recent.length)));
150
158
  parts.push(new Indent(keyValue(recent.map((d) => ({
151
- key: AUTO_LAYER_TEXT[d.layer],
159
+ key: autoLayerText(d.layer),
152
160
  value: `${effect(d.decision)} ${d.toolName} ${d.summary} — ${d.reason}` +
153
- (d.cached === true ? theme.fg("dim", "(缓存)") : ""),
161
+ (d.cached === true ? theme.fg("dim", m.cached) : ""),
154
162
  })), theme), 2));
155
163
  }
156
164
  return new Card(new Stack(parts), { theme });
@@ -39,7 +39,8 @@ export interface PickerSpec {
39
39
  /** 框内上下留白行数。 */
40
40
  paddingY?: number;
41
41
  }
42
- export declare const PICKER_FOOTER = "\u2191\u2193 \u9009\u62E9 \u00B7 Enter \u786E\u8BA4 \u00B7 Esc \u53D6\u6D88";
42
+ /** 列表下的缺省按键提示(`arrows` 缺省 `↑↓`)。 */
43
+ export declare function pickerFooter(arrows?: string): string;
43
44
  /** 打开一个居中选择器;Enter 返回选中项,Esc / Ctrl+C 返回 undefined。 */
44
45
  export declare function openPicker(host: PickerHost, spec: PickerSpec): Promise<SelectItem | undefined>;
45
46
  /**
@@ -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
  /** 执行面板里的选择,结果与错误都写成通知。 */