@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,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
  });
@@ -11,55 +11,57 @@
11
11
  * 覆盖对应 `onConflict: "overwrite"`。
12
12
  * - 明细:冲突与无法恢复的文件(各最多 5 个)、git HEAD 变化提示与两条命令(只显示,不执行)。
13
13
  */
14
+ import { msg } from "../../i18n/index.js";
14
15
  import { Card, defaultKeybindings, isPasteData, isPrintableText, matchesKey, padToWidth, truncateToWidth, unwrapPaste, wrapTextWithAnsi, } from "../../tui.js";
15
- import { REWIND_DETAIL_MAX, SKIP_REASON_TEXT, gitHintLines, hasCodeChanges, restorePreview, } from "./rewind-text.js";
16
+ import { REWIND_DETAIL_MAX, skipReasonText, gitHintLines, hasCodeChanges, restorePreview, } from "./rewind-text.js";
16
17
  import { relativeTime } from "./startup-ui.js";
17
18
  /** 宽度低于它(覆盖层外宽)时紧凑布局。 */
18
19
  const COMPACT_WIDTH = 56;
19
20
  const MESSAGE_LINES = 3;
20
- const DIVERGE = "对话将分叉";
21
21
  /** 面板的选项(按显示顺序)。 */
22
22
  export function rewindOptions(model, ascii = false) {
23
23
  const code = model.preview?.code;
24
24
  const withCode = hasCodeChanges(code);
25
+ const m = msg().rewind.panel;
25
26
  const options = [];
26
27
  if (withCode) {
27
28
  options.push({
28
29
  action: "both",
29
- label: "恢复代码和对话",
30
- preview: `${restorePreview(code, ascii)} · ${DIVERGE}`,
30
+ label: m.optionBoth,
31
+ preview: m.previewBoth(restorePreview(code, ascii)),
31
32
  });
32
33
  }
33
34
  options.push({
34
35
  action: "conversation",
35
- label: "恢复对话",
36
- preview: withCode ? `代码不变(保留之后的修改)· ${DIVERGE}` : `代码不变 · ${DIVERGE}`,
36
+ label: m.optionConversation,
37
+ preview: withCode ? m.previewConversationKeep : m.previewConversation,
37
38
  });
38
39
  if (withCode) {
39
40
  options.push({
40
41
  action: "code",
41
- label: "恢复代码",
42
- preview: `${restorePreview(code, ascii)} · 对话不变`,
42
+ label: m.optionCode,
43
+ preview: m.previewCode(restorePreview(code, ascii)),
43
44
  });
44
45
  }
45
46
  options.push({
46
47
  action: "summarize-from",
47
- label: "从这里摘要",
48
- preview: `${DIVERGE},离开的部分写成摘要`,
48
+ label: m.optionSummarizeFrom,
49
+ preview: m.previewSummarizeFrom,
49
50
  input: true,
50
51
  }, {
51
52
  action: "summarize-up-to",
52
- label: "摘要到这里",
53
- preview: "之前的对话压缩成摘要,之后的保留",
53
+ label: m.optionSummarizeUpTo,
54
+ preview: m.previewSummarizeUpTo,
54
55
  input: true,
55
- }, { action: "cancel", label: "取消" });
56
+ }, { action: "cancel", label: m.optionCancel });
56
57
  return options;
57
58
  }
58
- const CONFLICT_OPTIONS = [
59
- { value: "skip", label: "跳过冲突文件,恢复其余" },
60
- { value: "overwrite", label: "覆盖冲突文件" },
61
- { value: "back", label: "返回" },
62
- ];
59
+ const CONFLICT_VALUES = ["skip", "overwrite", "back"];
60
+ function conflictOptions() {
61
+ const m = msg().rewind.panel;
62
+ const labels = { skip: m.conflictSkip, overwrite: m.conflictOverwrite, back: m.conflictBack };
63
+ return CONFLICT_VALUES.map((value) => ({ value, label: labels[value] }));
64
+ }
63
65
  /** 行数组组件(交给 Card 加竖条)。 */
64
66
  class Lines {
65
67
  build;
@@ -155,9 +157,9 @@ export class RewindPanel {
155
157
  }
156
158
  conflictInput(data, keys) {
157
159
  const stage = this.stage;
158
- const n = CONFLICT_OPTIONS.length;
160
+ const n = CONFLICT_VALUES.length;
159
161
  const pick = (index) => {
160
- const value = CONFLICT_OPTIONS[index].value;
162
+ const value = CONFLICT_VALUES[index];
161
163
  if (value === "back")
162
164
  this.stage = undefined;
163
165
  else
@@ -181,7 +183,7 @@ export class RewindPanel {
181
183
  this.tight = tight;
182
184
  return new Card(new Lines((w) => this.body(w, tight || width < COMPACT_WIDTH)), {
183
185
  theme,
184
- title: "回滚到这条消息之前",
186
+ title: msg().rewind.panel.title,
185
187
  ...(time !== "" ? { subtitle: time } : {}),
186
188
  }).render(width);
187
189
  };
@@ -192,6 +194,7 @@ export class RewindPanel {
192
194
  invalidate() { }
193
195
  body(width, compact) {
194
196
  const { theme } = this.host;
197
+ const m = msg().rewind.panel;
195
198
  const arrows = theme.glyphs.arrowUp + theme.glyphs.arrowDown;
196
199
  const out = [...this.messageLines(width)];
197
200
  const gap = () => {
@@ -201,13 +204,11 @@ export class RewindPanel {
201
204
  gap();
202
205
  if (this.stage !== undefined) {
203
206
  const conflicts = this.conflicts;
204
- out.push(...this.fileLines(theme.fg("warning", `${conflicts.length} 个文件在回合外被改过:`), conflicts, width));
207
+ out.push(...this.fileLines(theme.fg("warning", m.conflictHead(conflicts.length)), conflicts, width));
205
208
  gap();
206
- out.push(...CONFLICT_OPTIONS.map((o, i) => this.optionLine(`${i + 1}. ${o.label}`, i === this.stage.selected, width)));
209
+ out.push(...conflictOptions().map((o, i) => this.optionLine(`${i + 1}. ${o.label}`, i === this.stage.selected, width)));
207
210
  gap();
208
- out.push(theme.fg("dim", compact
209
- ? `${arrows} Enter · Esc 返回`
210
- : `${arrows} 选择 · 1-3 直接选 · Enter 确认 · Esc 返回`));
211
+ out.push(theme.fg("dim", compact ? m.hintConflictCompact(arrows) : m.hintConflict(arrows)));
211
212
  return out;
212
213
  }
213
214
  this.options.forEach((option, i) => {
@@ -225,9 +226,7 @@ export class RewindPanel {
225
226
  }
226
227
  gap();
227
228
  const n = this.options.length;
228
- out.push(theme.fg("dim", compact
229
- ? `${arrows} Enter · 1-${n} · Esc 取消`
230
- : `${arrows} 选择 · 1-${n} 直接执行 · Enter 确认 · Esc 取消`));
229
+ out.push(theme.fg("dim", compact ? m.hintCompact(arrows, n) : m.hint(arrows, n)));
231
230
  return out;
232
231
  }
233
232
  messageLines(width) {
@@ -241,7 +240,7 @@ export class RewindPanel {
241
240
  .slice(0, max)
242
241
  .map((line, i) => truncateToWidth(`${i === 0 ? theme.fg("accent", prompt) : " "} ${line}`, width));
243
242
  if (all.length > max && !this.tight) {
244
- shown.push(theme.fg("dim", ` ${theme.glyphs.ellipsis} 另 ${all.length - max} 行`));
243
+ shown.push(theme.fg("dim", msg().rewind.panel.moreLines(theme.glyphs.ellipsis, all.length - max)));
245
244
  }
246
245
  return shown;
247
246
  }
@@ -252,9 +251,9 @@ export class RewindPanel {
252
251
  const text = this.inputs.get(option.action) ?? "";
253
252
  const cursor = selected ? (theme.glyphs.ascii ? "_" : "▏") : "";
254
253
  if (text !== "")
255
- label += ` 说明:${text}${cursor}`;
254
+ label += `${msg().rewind.panel.instructions(text)}${cursor}`;
256
255
  else if (selected)
257
- label += theme.fg("dim", " 可输入说明");
256
+ label += theme.fg("dim", msg().rewind.panel.instructionsHint);
258
257
  }
259
258
  return label;
260
259
  }
@@ -269,34 +268,35 @@ export class RewindPanel {
269
268
  /** 文件清单:每个一行(最多 5 个);紧凑时接在 `head` 后面并成一行。 */
270
269
  fileLines(head, files, width, note) {
271
270
  if (this.tight)
272
- return [truncateToWidth(`${head}${files.join("、")}`, width)];
271
+ return [truncateToWidth(msg().rewind.panel.tightList(head, files), width)];
273
272
  const lines = files
274
273
  .slice(0, REWIND_DETAIL_MAX)
275
274
  .map((f) => truncateToWidth(` ${f}${note !== undefined ? note(f) : ""}`, width));
276
275
  lines.unshift(head);
277
276
  if (files.length > REWIND_DETAIL_MAX) {
278
- lines.push(this.host.theme.fg("dim", ` ${this.host.theme.glyphs.ellipsis} 另 ${files.length - REWIND_DETAIL_MAX} 个`));
277
+ lines.push(this.host.theme.fg("dim", msg().rewind.panel.moreFiles(this.host.theme.glyphs.ellipsis, files.length - REWIND_DETAIL_MAX)));
279
278
  }
280
279
  return lines;
281
280
  }
282
281
  detailLines(width) {
283
282
  const { theme } = this.host;
284
283
  const out = [];
284
+ const m = msg().rewind.panel;
285
285
  const { point, preview, previewError } = this.model;
286
286
  if (!point.hasCheckpoint)
287
- out.push(theme.fg("dim", "仅对话:这条消息没有代码检查点"));
287
+ out.push(theme.fg("dim", m.noCheckpoint));
288
288
  if (previewError !== undefined)
289
- out.push(theme.fg("warning", `代码预览失败:${previewError}`));
289
+ out.push(theme.fg("warning", m.previewFailed(previewError)));
290
290
  const code = preview?.code;
291
291
  if (code !== undefined && code.conflicts.length > 0) {
292
292
  const head = this.tight
293
- ? `冲突 ${code.conflicts.length} 个:`
294
- : `冲突 ${code.conflicts.length} 个(回合外被改过,缺省跳过):`;
293
+ ? m.conflictsTight(code.conflicts.length)
294
+ : m.conflicts(code.conflicts.length);
295
295
  out.push(...this.fileLines(theme.fg("warning", head), code.conflicts, width));
296
296
  }
297
297
  if (code !== undefined && code.skipped.length > 0) {
298
- const reasons = new Map(code.skipped.map((s) => [s.path, SKIP_REASON_TEXT[s.reason]]));
299
- out.push(...this.fileLines(theme.fg("dim", `无法恢复 ${code.skipped.length} 个:`), code.skipped.map((s) => s.path), width, (f) => theme.fg("dim", `:${reasons.get(f) ?? ""}`)));
298
+ const reasons = new Map(code.skipped.map((s) => [s.path, skipReasonText(s.reason)]));
299
+ out.push(...this.fileLines(theme.fg("dim", m.unrestorable(code.skipped.length)), code.skipped.map((s) => s.path), width, (f) => theme.fg("dim", m.fileReason(reasons.get(f) ?? ""))));
300
300
  }
301
301
  if (preview?.gitHint !== undefined) {
302
302
  const [head, ...commands] = gitHintLines(preview.gitHint, theme.glyphs.ascii, this.tight);
@@ -5,12 +5,14 @@
5
5
  * - 结果:`已恢复 N 个文件,跳过 M 个(冲突 1、符号链接 1)` / `没有文件被恢复…` / `代码没有变化`,
6
6
  * 之后最多 5 行跳过明细。
7
7
  * - git:HEAD 与记录不同时给两条命令(只显示,不执行)。
8
- * - 错误码 `busy / no_checkpoint / rewind_failed` 换成中文说明。
8
+ * - 错误码 `busy / no_checkpoint / rewind_failed` 换成界面语言的说明。
9
+ * - 文案在 `msg().rewind`([W6-I2])。
9
10
  */
10
11
  import type { CodeRestoreResult, RewindResult, RewindSkipReason } from "../../checkpoints/types.js";
11
12
  /** 明细最多列出的文件数。 */
12
13
  export declare const REWIND_DETAIL_MAX = 5;
13
- export declare const SKIP_REASON_TEXT: Readonly<Record<RewindSkipReason, string>>;
14
+ /** 跳过原因的说明(随界面语言)。 */
15
+ export declare function skipReasonText(reason: RewindSkipReason): string;
14
16
  /** 一行文本:空白压成一个空格,超长截断。 */
15
17
  export declare function oneLine(text: string, max?: number, ellipsis?: string): string;
16
18
  /** 将恢复 / 已恢复的文件数(恢复 + 删除)。 */
@@ -36,5 +38,5 @@ export declare function gitHintLines(hint: {
36
38
  recordedHead: string;
37
39
  currentHead: string;
38
40
  }, ascii?: boolean, brief?: boolean): string[];
39
- /** 回滚接口的错误 → 中文说明。 */
41
+ /** 回滚接口的错误 → 界面语言的说明。 */
40
42
  export declare function rewindErrorText(error: unknown): string;
@@ -5,19 +5,17 @@
5
5
  * - 结果:`已恢复 N 个文件,跳过 M 个(冲突 1、符号链接 1)` / `没有文件被恢复…` / `代码没有变化`,
6
6
  * 之后最多 5 行跳过明细。
7
7
  * - git:HEAD 与记录不同时给两条命令(只显示,不执行)。
8
- * - 错误码 `busy / no_checkpoint / rewind_failed` 换成中文说明。
8
+ * - 错误码 `busy / no_checkpoint / rewind_failed` 换成界面语言的说明。
9
+ * - 文案在 `msg().rewind`([W6-I2])。
9
10
  */
10
11
  import { isAmaError } from "../../errors.js";
12
+ import { msg } from "../../i18n/index.js";
11
13
  /** 明细最多列出的文件数。 */
12
14
  export const REWIND_DETAIL_MAX = 5;
13
- export const SKIP_REASON_TEXT = {
14
- symlink: "符号链接",
15
- hardlink: "硬链接",
16
- not_regular: "不是普通文件",
17
- parent_moved: "父目录被移动",
18
- too_large: "文件过大未备份",
19
- backup_missing: "备份缺失",
20
- };
15
+ /** 跳过原因的说明(随界面语言)。 */
16
+ export function skipReasonText(reason) {
17
+ return msg().rewind.skip.reason(reason);
18
+ }
21
19
  /** 一行文本:空白压成一个空格,超长截断。 */
22
20
  export function oneLine(text, max = 60, ellipsis = "…") {
23
21
  const flat = text.replace(/\s+/g, " ").trim();
@@ -36,41 +34,54 @@ export function diffStat(code, ascii = false) {
36
34
  }
37
35
  /** 列表高亮行右侧的徽标。 */
38
36
  export function badgeText(code, ascii = false) {
37
+ const m = msg().rewind.badge;
39
38
  if (!hasCodeChanges(code))
40
- return "无代码改动";
39
+ return m.noCode;
41
40
  if (codeFileCount(code) === 0)
42
- return `冲突 ${code.conflicts.length} 个`;
43
- return `${codeFileCount(code)} 文件 ${diffStat(code, ascii)}`;
41
+ return m.conflicts(code.conflicts.length);
42
+ return m.files(codeFileCount(code), diffStat(code, ascii));
44
43
  }
45
44
  /** 面板里代码类选项的预览。 */
46
45
  export function restorePreview(code, ascii = false) {
46
+ const m = msg().rewind.restorePreview;
47
47
  const conflicts = code.conflicts.length;
48
48
  if (codeFileCount(code) === 0)
49
- return `只有冲突文件 ${conflicts} 个(缺省跳过)`;
50
- const suffix = conflicts > 0 ? `,冲突 ${conflicts} 个` : "";
51
- return `将恢复 ${codeFileCount(code)} 个文件 ${diffStat(code, ascii)}${suffix}`;
49
+ return m.onlyConflicts(conflicts);
50
+ return m.files(codeFileCount(code), diffStat(code, ascii), conflicts);
51
+ }
52
+ function skipLabel(code) {
53
+ return msg().rewind.skip.reason(code);
52
54
  }
53
55
  function skips(code, overwrite) {
54
56
  return [
55
- ...(overwrite ? [] : code.conflicts.map((path) => ({ path, reason: "冲突" }))),
56
- ...code.skipped.map((s) => ({ path: s.path, reason: SKIP_REASON_TEXT[s.reason] })),
57
- ...code.failed.map((f) => ({ path: f.path, reason: `失败:${f.message}` })),
57
+ ...(overwrite
58
+ ? []
59
+ : code.conflicts.map((path) => ({
60
+ path,
61
+ code: "conflict",
62
+ reason: skipLabel("conflict"),
63
+ }))),
64
+ ...code.skipped.map((s) => ({ path: s.path, code: s.reason, reason: skipLabel(s.reason) })),
65
+ ...code.failed.map((f) => ({
66
+ path: f.path,
67
+ code: "failed",
68
+ reason: msg().rewind.skip.failed(f.message),
69
+ })),
58
70
  ];
59
71
  }
60
72
  function reasonCounts(list) {
61
73
  const counts = new Map();
62
- for (const skip of list) {
63
- const key = skip.reason.startsWith("失败") ? "失败" : skip.reason;
64
- counts.set(key, (counts.get(key) ?? 0) + 1);
65
- }
66
- return [...counts].map(([reason, n]) => `${reason} ${n}`).join("、");
74
+ for (const skip of list)
75
+ counts.set(skip.code, (counts.get(skip.code) ?? 0) + 1);
76
+ return msg().rewind.skip.counts([...counts]);
67
77
  }
68
78
  /** 跳过明细(最多 5 行,其余计数)。 */
69
79
  export function skipDetailLines(code, overwrite = false) {
70
80
  const list = skips(code, overwrite);
71
- const lines = list.slice(0, REWIND_DETAIL_MAX).map((s) => ` ${s.path}:${s.reason}`);
81
+ const m = msg().rewind.skip;
82
+ const lines = list.slice(0, REWIND_DETAIL_MAX).map((s) => m.detail(s.path, s.reason));
72
83
  if (list.length > REWIND_DETAIL_MAX)
73
- lines.push(` … 另 ${list.length - REWIND_DETAIL_MAX} 个`);
84
+ lines.push(m.more(list.length - REWIND_DETAIL_MAX));
74
85
  return lines;
75
86
  }
76
87
  /** 代码恢复结果一行(不含明细)。overwrite 时冲突文件已被覆盖,算作已恢复。 */
@@ -78,16 +89,16 @@ export function codeResultText(code, overwrite = false) {
78
89
  const done = overwrite
79
90
  ? new Set([...code.restored, ...code.deleted, ...code.conflicts]).size
80
91
  : codeFileCount(code);
92
+ const m = msg().rewind.result;
81
93
  const skipped = skips(code, overwrite);
82
- const why = skipped.length > 0 ? `(${reasonCounts(skipped)})` : "";
83
94
  if (done > 0) {
84
95
  return skipped.length > 0
85
- ? `已恢复 ${done} 个文件,跳过 ${skipped.length} 个${why}`
86
- : `已恢复 ${done} 个文件`;
96
+ ? m.restoredSkipped(done, skipped.length, reasonCounts(skipped))
97
+ : m.restored(done);
87
98
  }
88
99
  if (skipped.length > 0)
89
- return `没有文件被恢复,跳过 ${skipped.length} 个${why}`;
90
- return "代码没有变化";
100
+ return m.noneRestored(skipped.length, reasonCounts(skipped));
101
+ return m.unchanged;
91
102
  }
92
103
  /** 结果通知(多行):代码结果 + 明细 + 对话说明 + git 提示。 */
93
104
  export function rewindResultLines(result, options = {}) {
@@ -111,25 +122,24 @@ export function gitHintLines(hint, ascii = false, brief = false) {
111
122
  const recorded = short(hint.recordedHead, 12);
112
123
  const change = `${short(hint.recordedHead, 7)} ${ascii ? "->" : "→"} ${short(hint.currentHead, 7)}`;
113
124
  return [
114
- `git HEAD 已变化:${change}${brief ? "" : "(ama 不动 git)"}`,
125
+ msg().rewind.gitHint(change, brief),
115
126
  ` git log --oneline ${recorded}..HEAD`,
116
127
  ` git reset --soft ${recorded}`,
117
128
  ];
118
129
  }
119
- /** 回滚接口的错误 → 中文说明。 */
130
+ /** 回滚接口的错误 → 界面语言的说明。 */
120
131
  export function rewindErrorText(error) {
121
132
  if (isAmaError(error)) {
133
+ const m = msg().rewind.error;
122
134
  switch (error.code) {
123
135
  case "busy":
124
- return "正在运行,不能回滚(先按 Esc 中断)";
136
+ return m.busy;
125
137
  case "no_checkpoint":
126
- return "这条消息没有代码检查点,只能恢复对话";
138
+ return m.noCheckpoint;
127
139
  case "rewind_failed": {
128
140
  const detail = error.detail;
129
- const failed = (detail?.failed ?? []).map((f) => `${f.path}:${f.message}`);
130
- return failed.length > 0
131
- ? `没有文件被恢复:${failed.slice(0, REWIND_DETAIL_MAX).join(";")}`
132
- : "没有文件被恢复";
141
+ const failed = (detail?.failed ?? []).map((f) => [f.path, f.message]);
142
+ return failed.length > 0 ? m.failedFiles(failed.slice(0, REWIND_DETAIL_MAX)) : m.failed;
133
143
  }
134
144
  default:
135
145
  return error.message;
@@ -13,8 +13,9 @@
13
13
  * 排队消息:缩进 2 列(挂在当前回合下),`↳ 插话 / 之后 文本` 整体 muted、标签 dim;超过 3 条首行
14
14
  * `… 另 N 条`;末行 `Alt+↑ 取回 · Esc 回填并中断`。
15
15
  */
16
+ import { msg } from "../../i18n/index.js";
16
17
  import { Container, Text } from "../../tui.js";
17
- import { ORIGIN_LABELS } from "./message-view.js";
18
+ import { originLabel } from "./message-view.js";
18
19
  import { formatTokens } from "./status-bar.js";
19
20
  export const QUEUE_PREVIEW = 3;
20
21
  function oneLine(text) {
@@ -129,38 +130,39 @@ export class RunIndicator {
129
130
  }
130
131
  applyVerb() {
131
132
  const { loader, tools } = this.deps;
132
- const esc = ["Esc 中断"];
133
+ const m = msg().interactive.view.run;
134
+ const esc = [m.esc];
133
135
  if (this.approval) {
134
- loader.setVerb("等待确认");
136
+ loader.setVerb(m.awaitingApproval);
135
137
  return;
136
138
  }
137
139
  const running = tools.running();
138
140
  const top = running.filter((view) => !running.some((p) => p.children.includes(view)));
139
141
  if (top.length === 1) {
140
- loader.setVerb(`运行 ${top[0].toolName}`, esc);
142
+ loader.setVerb(m.runningTool(top[0].toolName), esc);
141
143
  return;
142
144
  }
143
145
  if (top.length > 1) {
144
- loader.setVerb(`运行 ${top.length} 个工具`, esc);
146
+ loader.setVerb(m.runningTools(top.length), esc);
145
147
  return;
146
148
  }
147
149
  if (this.retry !== undefined) {
148
150
  const seconds = Math.max(1, Math.round(this.retry.delayMs / 1000));
149
- loader.setVerb(`重试 ${this.retry.attempt}/${this.retry.max}`, [`${seconds}s 后`], {
151
+ loader.setVerb(m.retry(this.retry.attempt, this.retry.max), [m.retryIn(seconds)], {
150
152
  elapsed: false,
151
153
  });
152
154
  return;
153
155
  }
154
156
  if (this.compacting) {
155
- loader.setVerb("压缩上下文", esc);
157
+ loader.setVerb(m.compacting, esc);
156
158
  return;
157
159
  }
158
160
  const stream = this.stream;
159
161
  if (stream !== undefined && !stream.thinking && stream.tokens > 0) {
160
- loader.setVerb("回复中", [`↓≈${formatTokens(stream.tokens)}`, ...esc]);
162
+ loader.setVerb(m.replying, [`↓≈${formatTokens(stream.tokens)}`, ...esc]);
161
163
  return;
162
164
  }
163
- loader.setVerb("思考中", esc);
165
+ loader.setVerb(m.thinking, esc);
164
166
  }
165
167
  }
166
168
  /** 排队消息(插话 / 之后),挂在 Loader 之上。 */
@@ -172,17 +174,18 @@ export class QueueView extends Text {
172
174
  }
173
175
  setQueue(steering, followUp) {
174
176
  const t = this.theme;
175
- const row = (origin, text) => ` ${t.fg("dim", `${t.glyphs.queued} ${ORIGIN_LABELS[origin]}`)} ${t.fg("muted", oneLine(text))}`;
177
+ const row = (origin, text) => ` ${t.fg("dim", `${t.glyphs.queued} ${originLabel(origin)}`)} ${t.fg("muted", oneLine(text))}`;
176
178
  const rows = [
177
179
  ...steering.map((text) => row("steer", text)),
178
180
  ...followUp.map((text) => row("followUp", text)),
179
181
  ];
180
182
  const shown = rows.slice(-QUEUE_PREVIEW);
181
183
  if (rows.length > shown.length) {
182
- shown.unshift(" " + t.fg("dim", `${t.glyphs.ellipsis} 另 ${rows.length - shown.length} 条`));
184
+ shown.unshift(" " +
185
+ t.fg("dim", msg().interactive.view.run.queueMore(t.glyphs.ellipsis, rows.length - shown.length)));
183
186
  }
184
187
  if (rows.length > 0) {
185
- shown.push(" " + t.fg("dim", `Alt+${t.glyphs.arrowUp} 取回 · Esc 回填并中断`));
188
+ shown.push(" " + t.fg("dim", msg().interactive.view.run.queueHint(t.glyphs.arrowUp)));
186
189
  }
187
190
  this.setText(shown.join("\n"));
188
191
  }
@@ -2,6 +2,7 @@
2
2
  * 交互界面的会话事件分派:`SessionEvent` → 消息区、工具视图、状态栏、运行指示。[B7]
3
3
  * 从 interactive-mode.ts 拆出(W5-U:第五波事件先交给 agent-ui.ts,预算到限的 agent_settled warning 不重复显示)。
4
4
  */
5
+ import { msg } from "../../i18n/index.js";
5
6
  import { cacheEventNotice, cacheNoticesEnabled } from "../session-report.js";
6
7
  import { compactionErrorText, ImageBudgetNotices, LIMIT_WARNING } from "./event-notices.js";
7
8
  export function createSessionEventHandler(deps) {
@@ -58,9 +59,9 @@ export function createSessionEventHandler(deps) {
58
59
  if (event.result !== undefined)
59
60
  view.addCompaction(event.result);
60
61
  else if (event.error !== undefined)
61
- view.addNotice("error", `压缩失败:${compactionErrorText(event.error)}`);
62
+ view.addNotice("error", msg().interactive.events.compactionFailed(compactionErrorText(event.error)));
62
63
  else if (event.aborted)
63
- view.addNotice("info", "压缩已取消");
64
+ view.addNotice("info", msg().interactive.events.compactionCancelled);
64
65
  status.refresh();
65
66
  break;
66
67
  case "auto_retry_start":