@armadra/agent 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (467) hide show
  1. package/CHANGELOG.md +177 -304
  2. package/CHANGELOG.zh-CN.md +442 -0
  3. package/README.md +408 -364
  4. package/README.zh-CN.md +705 -0
  5. package/dist/agent/session-plan.js +2 -2
  6. package/dist/agent/session-state.d.ts +3 -0
  7. package/dist/agent/session-state.js +20 -0
  8. package/dist/agent/session-subagent.d.ts +15 -1
  9. package/dist/agent/session-subagent.js +26 -3
  10. package/dist/agent/session-telemetry.d.ts +16 -2
  11. package/dist/agent/session-telemetry.js +29 -7
  12. package/dist/agent/session-tools.js +5 -2
  13. package/dist/agent/session-trace-writer.d.ts +27 -0
  14. package/dist/agent/session-trace-writer.js +253 -0
  15. package/dist/agent/session.d.ts +2 -0
  16. package/dist/agent/session.js +12 -0
  17. package/dist/agent/subagent-direct.d.ts +20 -0
  18. package/dist/agent/subagent-direct.js +76 -0
  19. package/dist/agent/subagent-registry.d.ts +8 -1
  20. package/dist/agent/subagent-registry.js +28 -1
  21. package/dist/agent/system-prompt.d.ts +3 -1
  22. package/dist/agent/system-prompt.js +3 -0
  23. package/dist/agent/tool-runner.d.ts +2 -1
  24. package/dist/agent/tool-runner.js +5 -4
  25. package/dist/agent/types-w6.d.ts +39 -0
  26. package/dist/agent/types-w6.js +4 -0
  27. package/dist/agent/types.d.ts +5 -2
  28. package/dist/agents/external.js +1 -1
  29. package/dist/agents/task-record.d.ts +74 -1
  30. package/dist/agents/task-record.js +100 -0
  31. package/dist/ai/apis/cache-params.js +2 -1
  32. package/dist/ai/apis/chatgpt-backend.d.ts +52 -0
  33. package/dist/ai/apis/chatgpt-backend.js +224 -0
  34. package/dist/ai/apis/chatgpt-rate-limits.d.ts +26 -0
  35. package/dist/ai/apis/chatgpt-rate-limits.js +91 -0
  36. package/dist/ai/apis/openai-responses-request.d.ts +2 -1
  37. package/dist/ai/apis/openai-responses-request.js +8 -2
  38. package/dist/ai/apis/openai-responses.d.ts +2 -0
  39. package/dist/ai/apis/openai-responses.js +51 -16
  40. package/dist/ai/overflow.d.ts +1 -1
  41. package/dist/ai/overflow.js +10 -7
  42. package/dist/ai/providers/auth.d.ts +15 -2
  43. package/dist/ai/providers/auth.js +69 -2
  44. package/dist/ai/providers/builtin.js +27 -0
  45. package/dist/ai/providers/catalog-data.js +1 -0
  46. package/dist/ai/providers/enrich.js +2 -7
  47. package/dist/ai/providers/models-dev-cache.js +15 -19
  48. package/dist/ai/providers/models-dev-snapshot.js +8 -7
  49. package/dist/ai/providers/models-dev.js +5 -15
  50. package/dist/ai/providers/suggest.js +2 -16
  51. package/dist/ai/types.d.ts +27 -1
  52. package/dist/auth/chatgpt/backend-client.d.ts +26 -0
  53. package/dist/auth/chatgpt/backend-client.js +74 -0
  54. package/dist/auth/chatgpt/claims.d.ts +17 -0
  55. package/dist/auth/chatgpt/claims.js +46 -0
  56. package/dist/auth/chatgpt/cli.d.ts +33 -0
  57. package/dist/auth/chatgpt/cli.js +252 -0
  58. package/dist/auth/chatgpt/doctor.d.ts +17 -0
  59. package/dist/auth/chatgpt/doctor.js +36 -0
  60. package/dist/auth/chatgpt/host-id.d.ts +7 -0
  61. package/dist/auth/chatgpt/host-id.js +26 -0
  62. package/dist/auth/chatgpt/login.d.ts +30 -0
  63. package/dist/auth/chatgpt/login.js +130 -0
  64. package/dist/auth/chatgpt/presets.d.ts +66 -0
  65. package/dist/auth/chatgpt/presets.js +120 -0
  66. package/dist/auth/chatgpt/quota-text.d.ts +13 -0
  67. package/dist/auth/chatgpt/quota-text.js +36 -0
  68. package/dist/auth/oauth/browser.d.ts +12 -0
  69. package/dist/auth/oauth/browser.js +27 -0
  70. package/dist/auth/oauth/callback-server.d.ts +47 -0
  71. package/dist/auth/oauth/callback-server.js +147 -0
  72. package/dist/auth/oauth/flows.d.ts +62 -0
  73. package/dist/auth/oauth/flows.js +113 -0
  74. package/dist/auth/oauth/jwt.d.ts +24 -0
  75. package/dist/auth/oauth/jwt.js +81 -0
  76. package/dist/auth/oauth/live.d.ts +21 -0
  77. package/dist/auth/oauth/live.js +25 -0
  78. package/dist/auth/oauth/oidc.d.ts +26 -0
  79. package/dist/auth/oauth/oidc.js +72 -0
  80. package/dist/auth/oauth/pkce.d.ts +15 -0
  81. package/dist/auth/oauth/pkce.js +20 -0
  82. package/dist/auth/oauth/refresh.d.ts +35 -0
  83. package/dist/auth/oauth/refresh.js +129 -0
  84. package/dist/auth/oauth/token-client.d.ts +33 -0
  85. package/dist/auth/oauth/token-client.js +121 -0
  86. package/dist/auth/oauth/token-store.d.ts +23 -0
  87. package/dist/auth/oauth/token-store.js +125 -0
  88. package/dist/auth/testing/fake-oauth.d.ts +73 -0
  89. package/dist/auth/testing/fake-oauth.js +271 -0
  90. package/dist/auth/testing/refresh-child.d.ts +5 -0
  91. package/dist/auth/testing/refresh-child.js +16 -0
  92. package/dist/bundle/ama.cjs +25928 -11144
  93. package/dist/checkpoints/backend.js +6 -5
  94. package/dist/checkpoints/restore.js +3 -2
  95. package/dist/checkpoints/settings.js +2 -1
  96. package/dist/checkpoints/shadow-git.js +7 -6
  97. package/dist/checkpoints/shadow-restore.js +3 -2
  98. package/dist/checkpoints/tracker.js +4 -3
  99. package/dist/cli/args.d.ts +9 -2
  100. package/dist/cli/args.js +74 -27
  101. package/dist/cli/bootstrap.js +53 -31
  102. package/dist/cli/choice-prompt.js +8 -6
  103. package/dist/cli/codemode-notice.js +2 -2
  104. package/dist/cli/compose-agents.js +2 -1
  105. package/dist/cli/compose-extensions.js +2 -0
  106. package/dist/cli/compose-memory.d.ts +53 -0
  107. package/dist/cli/compose-memory.js +127 -0
  108. package/dist/cli/compose-providers.d.ts +5 -0
  109. package/dist/cli/compose-providers.js +32 -2
  110. package/dist/cli/compose-session.d.ts +5 -0
  111. package/dist/cli/compose-session.js +27 -13
  112. package/dist/cli/compose-store.d.ts +2 -0
  113. package/dist/cli/compose-store.js +9 -5
  114. package/dist/cli/compose.d.ts +2 -0
  115. package/dist/cli/compose.js +13 -5
  116. package/dist/cli/default-model.d.ts +0 -2
  117. package/dist/cli/default-model.js +5 -8
  118. package/dist/cli/deps.d.ts +5 -1
  119. package/dist/cli/exit-codes.d.ts +1 -1
  120. package/dist/cli/exit-codes.js +7 -16
  121. package/dist/cli/from-prompt.js +3 -2
  122. package/dist/cli/help-text.d.ts +2 -1
  123. package/dist/cli/help-text.js +5 -99
  124. package/dist/cli/main.d.ts +5 -0
  125. package/dist/cli/main.js +21 -2
  126. package/dist/cli/proxy.js +14 -9
  127. package/dist/cli/runtime.d.ts +5 -0
  128. package/dist/cli/startup-screen.js +20 -27
  129. package/dist/cli/startup-steps.js +6 -8
  130. package/dist/cli/subcommands/auth.d.ts +6 -3
  131. package/dist/cli/subcommands/auth.js +52 -22
  132. package/dist/cli/subcommands/config-set.d.ts +21 -0
  133. package/dist/cli/subcommands/config-set.js +137 -0
  134. package/dist/cli/subcommands/config.d.ts +2 -1
  135. package/dist/cli/subcommands/config.js +51 -37
  136. package/dist/cli/subcommands/doctor.d.ts +2 -1
  137. package/dist/cli/subcommands/doctor.js +97 -58
  138. package/dist/cli/subcommands/init.d.ts +1 -1
  139. package/dist/cli/subcommands/init.js +8 -7
  140. package/dist/cli/subcommands/memory.d.ts +18 -0
  141. package/dist/cli/subcommands/memory.js +189 -0
  142. package/dist/cli/subcommands/model-meta.js +11 -9
  143. package/dist/cli/subcommands/models-cache-probe.js +23 -20
  144. package/dist/cli/subcommands/models-discover.d.ts +3 -0
  145. package/dist/cli/subcommands/models-discover.js +44 -21
  146. package/dist/cli/subcommands/models.d.ts +1 -1
  147. package/dist/cli/subcommands/models.js +29 -22
  148. package/dist/cli/subcommands/probe-runner.js +8 -7
  149. package/dist/cli/subcommands/providers-list.js +32 -21
  150. package/dist/cli/subcommands/providers-plan.js +24 -25
  151. package/dist/cli/subcommands/providers-probe.js +5 -6
  152. package/dist/cli/subcommands/providers.d.ts +1 -1
  153. package/dist/cli/subcommands/providers.js +45 -50
  154. package/dist/cli/subcommands/sessions-export.d.ts +1 -1
  155. package/dist/cli/subcommands/sessions-export.js +10 -9
  156. package/dist/cli/subcommands/sessions-search.d.ts +1 -1
  157. package/dist/cli/subcommands/sessions-search.js +11 -10
  158. package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
  159. package/dist/cli/subcommands/sessions-trace.js +156 -0
  160. package/dist/cli/subcommands/sessions.d.ts +4 -3
  161. package/dist/cli/subcommands/sessions.js +40 -37
  162. package/dist/cli/subcommands/stats.d.ts +1 -1
  163. package/dist/cli/subcommands/stats.js +49 -30
  164. package/dist/cli/system-prompt-arg.js +3 -2
  165. package/dist/codemode/capability.js +3 -2
  166. package/dist/compaction/post-compact.d.ts +1 -0
  167. package/dist/compaction/post-compact.js +15 -1
  168. package/dist/compaction/prune-tier.d.ts +1 -1
  169. package/dist/compaction/prune-tier.js +3 -3
  170. package/dist/compaction/serialize.js +2 -1
  171. package/dist/config/auth-file.d.ts +12 -2
  172. package/dist/config/auth-file.js +32 -10
  173. package/dist/config/checker.js +12 -11
  174. package/dist/config/context-files.js +3 -2
  175. package/dist/config/edit.d.ts +106 -0
  176. package/dist/config/edit.js +350 -0
  177. package/dist/config/init.d.ts +4 -3
  178. package/dist/config/init.js +10 -18
  179. package/dist/config/json-schema.d.ts +2 -1
  180. package/dist/config/json-schema.js +101 -68
  181. package/dist/config/key-docs.d.ts +18 -7
  182. package/dist/config/key-docs.js +43 -128
  183. package/dist/config/load.js +7 -6
  184. package/dist/config/merge.d.ts +4 -1
  185. package/dist/config/merge.js +42 -22
  186. package/dist/config/paths.js +6 -5
  187. package/dist/config/profile.d.ts +5 -1
  188. package/dist/config/profile.js +7 -2
  189. package/dist/config/schema-w5.js +3 -2
  190. package/dist/config/schema-w6.d.ts +19 -0
  191. package/dist/config/schema-w6.js +115 -0
  192. package/dist/config/schema.js +34 -20
  193. package/dist/config/settings-registry.d.ts +78 -0
  194. package/dist/config/settings-registry.js +184 -0
  195. package/dist/config/types-w6.d.ts +109 -0
  196. package/dist/config/types-w6.js +19 -0
  197. package/dist/config/types.d.ts +11 -8
  198. package/dist/config/types.js +1 -0
  199. package/dist/drivers/acp/client.js +1 -1
  200. package/dist/drivers/acp/driver.js +13 -8
  201. package/dist/drivers/agents.js +4 -3
  202. package/dist/drivers/base.js +3 -2
  203. package/dist/drivers/host-runners.js +2 -1
  204. package/dist/drivers/native/claude-stream.js +12 -11
  205. package/dist/drivers/native/codex-app-server.js +17 -12
  206. package/dist/drivers/native/oneshot.js +8 -7
  207. package/dist/drivers/pool.js +1 -1
  208. package/dist/drivers/runner.d.ts +3 -1
  209. package/dist/drivers/runner.js +68 -20
  210. package/dist/drivers/turn.js +1 -1
  211. package/dist/hooks/config.js +3 -2
  212. package/dist/hooks/protocol.js +18 -12
  213. package/dist/host/api-impl.js +11 -10
  214. package/dist/host/loader.js +9 -8
  215. package/dist/host/types.d.ts +3 -0
  216. package/dist/i18n/catalog.d.ts +2169 -0
  217. package/dist/i18n/catalog.js +72 -0
  218. package/dist/i18n/format.d.ts +21 -0
  219. package/dist/i18n/format.js +58 -0
  220. package/dist/i18n/index.d.ts +58 -0
  221. package/dist/i18n/index.js +72 -0
  222. package/dist/i18n/messages/agents.d.ts +84 -0
  223. package/dist/i18n/messages/agents.js +85 -0
  224. package/dist/i18n/messages/approval.d.ts +99 -0
  225. package/dist/i18n/messages/approval.js +100 -0
  226. package/dist/i18n/messages/auth.d.ts +187 -0
  227. package/dist/i18n/messages/auth.js +189 -0
  228. package/dist/i18n/messages/cli-args.d.ts +46 -0
  229. package/dist/i18n/messages/cli-args.js +46 -0
  230. package/dist/i18n/messages/cli-help.d.ts +12 -0
  231. package/dist/i18n/messages/cli-help.js +244 -0
  232. package/dist/i18n/messages/cli.d.ts +336 -0
  233. package/dist/i18n/messages/cli.js +311 -0
  234. package/dist/i18n/messages/config-keys.d.ts +289 -0
  235. package/dist/i18n/messages/config-keys.js +292 -0
  236. package/dist/i18n/messages/config.d.ts +502 -0
  237. package/dist/i18n/messages/config.js +239 -0
  238. package/dist/i18n/messages/drivers.d.ts +123 -0
  239. package/dist/i18n/messages/drivers.js +124 -0
  240. package/dist/i18n/messages/errors.d.ts +83 -0
  241. package/dist/i18n/messages/errors.js +171 -0
  242. package/dist/i18n/messages/interactive-line.d.ts +61 -0
  243. package/dist/i18n/messages/interactive-line.js +69 -0
  244. package/dist/i18n/messages/interactive-startup.d.ts +103 -0
  245. package/dist/i18n/messages/interactive-startup.js +104 -0
  246. package/dist/i18n/messages/interactive-view.d.ts +140 -0
  247. package/dist/i18n/messages/interactive-view.js +141 -0
  248. package/dist/i18n/messages/interactive.d.ts +493 -0
  249. package/dist/i18n/messages/interactive.js +248 -0
  250. package/dist/i18n/messages/memory.d.ts +123 -0
  251. package/dist/i18n/messages/memory.js +128 -0
  252. package/dist/i18n/messages/panels.d.ts +190 -0
  253. package/dist/i18n/messages/panels.js +189 -0
  254. package/dist/i18n/messages/permissions.d.ts +126 -0
  255. package/dist/i18n/messages/permissions.js +151 -0
  256. package/dist/i18n/messages/plan.d.ts +123 -0
  257. package/dist/i18n/messages/plan.js +124 -0
  258. package/dist/i18n/messages/print.d.ts +86 -0
  259. package/dist/i18n/messages/print.js +91 -0
  260. package/dist/i18n/messages/report.d.ts +391 -0
  261. package/dist/i18n/messages/report.js +490 -0
  262. package/dist/i18n/messages/rewind.d.ts +198 -0
  263. package/dist/i18n/messages/rewind.js +217 -0
  264. package/dist/i18n/messages/session.d.ts +230 -0
  265. package/dist/i18n/messages/session.js +258 -0
  266. package/dist/i18n/messages/settings.d.ts +348 -0
  267. package/dist/i18n/messages/settings.js +336 -0
  268. package/dist/i18n/messages/subcommands-config.d.ts +111 -0
  269. package/dist/i18n/messages/subcommands-config.js +127 -0
  270. package/dist/i18n/messages/subcommands.d.ts +548 -0
  271. package/dist/i18n/messages/subcommands.js +474 -0
  272. package/dist/i18n/messages/trace.d.ts +243 -0
  273. package/dist/i18n/messages/trace.js +238 -0
  274. package/dist/i18n/types.d.ts +15 -0
  275. package/dist/i18n/types.js +7 -0
  276. package/dist/index.d.ts +6 -0
  277. package/dist/index.js +2 -0
  278. package/dist/memory/edit.d.ts +24 -0
  279. package/dist/memory/edit.js +63 -0
  280. package/dist/memory/frontmatter.d.ts +37 -0
  281. package/dist/memory/frontmatter.js +79 -0
  282. package/dist/memory/index.d.ts +28 -0
  283. package/dist/memory/index.js +126 -0
  284. package/dist/memory/lock.d.ts +17 -0
  285. package/dist/memory/lock.js +62 -0
  286. package/dist/memory/paths.d.ts +57 -0
  287. package/dist/memory/paths.js +175 -0
  288. package/dist/memory/report.d.ts +36 -0
  289. package/dist/memory/report.js +86 -0
  290. package/dist/memory/runtime.d.ts +42 -0
  291. package/dist/memory/runtime.js +36 -0
  292. package/dist/memory/secrets.d.ts +8 -0
  293. package/dist/memory/secrets.js +27 -0
  294. package/dist/memory/section.d.ts +28 -0
  295. package/dist/memory/section.js +59 -0
  296. package/dist/memory/store.d.ts +70 -0
  297. package/dist/memory/store.js +284 -0
  298. package/dist/memory/tool.d.ts +31 -0
  299. package/dist/memory/tool.js +94 -0
  300. package/dist/modes/acp/acp-events.js +2 -1
  301. package/dist/modes/acp/acp-server.js +13 -12
  302. package/dist/modes/commands-core.d.ts +11 -0
  303. package/dist/modes/commands-core.js +93 -62
  304. package/dist/modes/image-input.js +20 -6
  305. package/dist/modes/interactive/agent-bar.d.ts +95 -0
  306. package/dist/modes/interactive/agent-bar.js +248 -0
  307. package/dist/modes/interactive/agent-panels.js +27 -26
  308. package/dist/modes/interactive/agent-transcript.d.ts +47 -0
  309. package/dist/modes/interactive/agent-transcript.js +191 -0
  310. package/dist/modes/interactive/agent-ui.d.ts +36 -1
  311. package/dist/modes/interactive/agent-ui.js +180 -14
  312. package/dist/modes/interactive/agent-view.d.ts +72 -0
  313. package/dist/modes/interactive/agent-view.js +281 -0
  314. package/dist/modes/interactive/approval-dialog.js +46 -34
  315. package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
  316. package/dist/modes/interactive/clipboard-paste.js +9 -4
  317. package/dist/modes/interactive/commands.d.ts +19 -1
  318. package/dist/modes/interactive/commands.js +84 -40
  319. package/dist/modes/interactive/completion.js +2 -1
  320. package/dist/modes/interactive/config-panel.d.ts +70 -0
  321. package/dist/modes/interactive/config-panel.js +319 -0
  322. package/dist/modes/interactive/config-ui.d.ts +96 -0
  323. package/dist/modes/interactive/config-ui.js +397 -0
  324. package/dist/modes/interactive/confirm-dialog.js +6 -7
  325. package/dist/modes/interactive/event-notices.js +11 -9
  326. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  327. package/dist/modes/interactive/interactive-mode.js +19 -22
  328. package/dist/modes/interactive/key-dispatch.d.ts +12 -0
  329. package/dist/modes/interactive/key-dispatch.js +24 -9
  330. package/dist/modes/interactive/line/line-editor.js +2 -1
  331. package/dist/modes/interactive/line/line-mode.js +18 -7
  332. package/dist/modes/interactive/line/line-render.js +25 -24
  333. package/dist/modes/interactive/memory-panel.d.ts +64 -0
  334. package/dist/modes/interactive/memory-panel.js +221 -0
  335. package/dist/modes/interactive/message-view.d.ts +4 -2
  336. package/dist/modes/interactive/message-view.js +42 -33
  337. package/dist/modes/interactive/panels.js +39 -31
  338. package/dist/modes/interactive/pickers.d.ts +2 -1
  339. package/dist/modes/interactive/pickers.js +10 -6
  340. package/dist/modes/interactive/plan-command.d.ts +1 -1
  341. package/dist/modes/interactive/plan-command.js +24 -27
  342. package/dist/modes/interactive/plan-dialog.js +18 -17
  343. package/dist/modes/interactive/plan-flow.js +6 -5
  344. package/dist/modes/interactive/rewind-command.d.ts +1 -1
  345. package/dist/modes/interactive/rewind-command.js +18 -16
  346. package/dist/modes/interactive/rewind-flow.d.ts +0 -1
  347. package/dist/modes/interactive/rewind-flow.js +13 -14
  348. package/dist/modes/interactive/rewind-list.js +7 -6
  349. package/dist/modes/interactive/rewind-panel.js +40 -40
  350. package/dist/modes/interactive/rewind-text.d.ts +5 -3
  351. package/dist/modes/interactive/rewind-text.js +48 -38
  352. package/dist/modes/interactive/run-indicator.js +15 -12
  353. package/dist/modes/interactive/session-events.js +3 -2
  354. package/dist/modes/interactive/startup-header.js +22 -23
  355. package/dist/modes/interactive/startup-ui.js +38 -30
  356. package/dist/modes/interactive/status-area.d.ts +2 -0
  357. package/dist/modes/interactive/status-area.js +8 -2
  358. package/dist/modes/interactive/status-bar.js +4 -3
  359. package/dist/modes/interactive/subagent-view.js +9 -7
  360. package/dist/modes/interactive/tasks-report.d.ts +6 -0
  361. package/dist/modes/interactive/tasks-report.js +28 -31
  362. package/dist/modes/interactive/terminal-setup.d.ts +9 -0
  363. package/dist/modes/interactive/terminal-setup.js +23 -0
  364. package/dist/modes/interactive/tool-summary.js +19 -17
  365. package/dist/modes/interactive/tool-view.js +7 -4
  366. package/dist/modes/interactive/trace-view.d.ts +89 -0
  367. package/dist/modes/interactive/trace-view.js +332 -0
  368. package/dist/modes/print/print-mode.js +14 -15
  369. package/dist/modes/rpc/commands.js +7 -3
  370. package/dist/modes/rpc/rpc-mode.js +9 -3
  371. package/dist/modes/session-report.d.ts +2 -0
  372. package/dist/modes/session-report.js +101 -105
  373. package/dist/modes/startup-ui-text.js +11 -6
  374. package/dist/permissions/bypass.d.ts +8 -10
  375. package/dist/permissions/bypass.js +19 -10
  376. package/dist/permissions/memory-class.d.ts +23 -0
  377. package/dist/permissions/memory-class.js +54 -0
  378. package/dist/permissions/modes.d.ts +3 -3
  379. package/dist/permissions/modes.js +21 -16
  380. package/dist/permissions/pipeline.d.ts +1 -1
  381. package/dist/permissions/pipeline.js +9 -2
  382. package/dist/permissions/preview.js +49 -42
  383. package/dist/permissions/rules.js +5 -2
  384. package/dist/permissions/types.d.ts +4 -0
  385. package/dist/plan/store.js +2 -1
  386. package/dist/rpc.d.ts +39 -1
  387. package/dist/rpc.js +3 -0
  388. package/dist/sandbox/bash.js +11 -8
  389. package/dist/sandbox/detect.js +14 -11
  390. package/dist/sdk.d.ts +17 -1
  391. package/dist/sdk.js +29 -7
  392. package/dist/session/export.js +31 -30
  393. package/dist/session/manager.d.ts +1 -1
  394. package/dist/session/manager.js +5 -3
  395. package/dist/session/reuse.js +5 -4
  396. package/dist/session/scan.js +3 -2
  397. package/dist/session/stats-aggregate.d.ts +3 -1
  398. package/dist/session/stats-aggregate.js +5 -1
  399. package/dist/session/stats-index.js +2 -1
  400. package/dist/session/stats-scan.d.ts +4 -1
  401. package/dist/session/stats-scan.js +6 -2
  402. package/dist/session/store.d.ts +11 -0
  403. package/dist/session/store.js +48 -1
  404. package/dist/session/types.d.ts +2 -0
  405. package/dist/skills/builtin.js +2 -1
  406. package/dist/tools/image-file.d.ts +26 -1
  407. package/dist/tools/image-file.js +55 -13
  408. package/dist/tools/presets.d.ts +14 -1
  409. package/dist/tools/presets.js +3 -3
  410. package/dist/tools/registry.js +1 -1
  411. package/dist/tools/truncate.d.ts +1 -1
  412. package/dist/tools/truncate.js +2 -2
  413. package/dist/tools/types.d.ts +17 -1
  414. package/dist/trace/build-index.d.ts +91 -0
  415. package/dist/trace/build-index.js +127 -0
  416. package/dist/trace/build-nodes.d.ts +24 -0
  417. package/dist/trace/build-nodes.js +279 -0
  418. package/dist/trace/build-util.d.ts +43 -0
  419. package/dist/trace/build-util.js +120 -0
  420. package/dist/trace/build.d.ts +82 -0
  421. package/dist/trace/build.js +382 -0
  422. package/dist/trace/detail.d.ts +35 -0
  423. package/dist/trace/detail.js +205 -0
  424. package/dist/trace/flatten.d.ts +69 -0
  425. package/dist/trace/flatten.js +173 -0
  426. package/dist/trace/format.d.ts +47 -0
  427. package/dist/trace/format.js +329 -0
  428. package/dist/trace/html-template.d.ts +19 -0
  429. package/dist/trace/html-template.js +150 -0
  430. package/dist/trace/html.d.ts +104 -0
  431. package/dist/trace/html.js +292 -0
  432. package/dist/trace/preview.d.ts +29 -0
  433. package/dist/trace/preview.js +59 -0
  434. package/dist/trace/query-session.d.ts +14 -0
  435. package/dist/trace/query-session.js +38 -0
  436. package/dist/trace/query.d.ts +55 -0
  437. package/dist/trace/query.js +188 -0
  438. package/dist/trace/session.d.ts +40 -0
  439. package/dist/trace/session.js +168 -0
  440. package/dist/trace/types.d.ts +243 -0
  441. package/dist/trace/types.js +13 -0
  442. package/dist/tui/components/editor-paste.d.ts +2 -0
  443. package/dist/tui/components/editor-paste.js +6 -3
  444. package/dist/tui/components/editor.js +2 -2
  445. package/dist/tui/components/loader.d.ts +3 -0
  446. package/dist/tui/components/loader.js +14 -0
  447. package/dist/tui/components/settings-list.d.ts +61 -0
  448. package/dist/tui/components/settings-list.js +135 -0
  449. package/dist/tui/keybindings.d.ts +5 -0
  450. package/dist/tui/keybindings.js +17 -5
  451. package/dist/tui.d.ts +1 -0
  452. package/dist/tui.js +2 -0
  453. package/docs/en/host-api.md +167 -0
  454. package/docs/en/permissions.md +214 -0
  455. package/docs/en/providers.md +625 -0
  456. package/docs/en/rpc.md +361 -0
  457. package/docs/en/sessions.md +219 -0
  458. package/docs/en/tui.md +527 -0
  459. package/docs/host-api.md +18 -17
  460. package/docs/memory.md +172 -0
  461. package/docs/permissions.md +2 -2
  462. package/docs/providers.md +67 -1
  463. package/docs/rpc.md +31 -3
  464. package/docs/session-format.md +8 -2
  465. package/docs/sessions.md +29 -1
  466. package/docs/tui.md +132 -3
  467. package/package.json +8 -3
@@ -0,0 +1,94 @@
1
+ /**
2
+ * `memory` 工具(docs/wave6-plan.md §3.3、D10)。[W6-M] 模型侧模块:不得 import src/i18n。
3
+ *
4
+ * 自定义工具(不声明供应商原生的 memory 工具类型),四个命令:`view / create / str_replace / delete`,路径限定
5
+ * 在 `/memories/<scope>/`。权限类 `memory`:view 按读放行,写命令按 execute 判定(permissions/memory-class.ts)。
6
+ * 执行层额外拒绝:
7
+ * - 子会话(depth > 0):`memory.subagents: "read"` 拒绝写命令,`"off"` 连 view 也拒绝——工具定义与父会话
8
+ * 一致,保住子会话首请求命中父前缀;
9
+ * - `/memory off`:本会话禁止写;
10
+ * - 凭据、大小、条数上限、路径越界(store.ts)。
11
+ * 写入只落盘:结果提示「下次会话起出现在索引」,本会话的 `memory` 节不变(前缀稳定)。
12
+ */
13
+ import { MemoryLockError } from "./lock.js";
14
+ import { MemoryError } from "./store.js";
15
+ export const MEMORY_TOOL = "memory";
16
+ export const MEMORY_GUIDELINES = [
17
+ "memory: save only when the user asks you to remember something or states a durable preference or correction; never store secrets or facts that can be read from the repository or git history.",
18
+ "memory: entries can be stale; verify names, paths and commands against the current project before relying on them.",
19
+ "memory: one topic per file; update an existing entry instead of adding a duplicate.",
20
+ ];
21
+ function fail(input, code, message) {
22
+ const details = { command: String(input.command ?? ""), code };
23
+ if (typeof input.path === "string")
24
+ details.path = input.path;
25
+ return { content: message, isError: true, details };
26
+ }
27
+ export function createMemoryTool(runtime) {
28
+ return {
29
+ name: MEMORY_TOOL,
30
+ label: "Memory",
31
+ description: "Notes that persist across sessions, stored as Markdown files under /memories/<scope>/ (scopes and entries are listed in the memory index). " +
32
+ "Commands: view a directory or file, create (or overwrite) a file, str_replace a unique string, delete a file.",
33
+ parameters: {
34
+ type: "object",
35
+ properties: {
36
+ command: { type: "string", enum: ["view", "create", "str_replace", "delete"] },
37
+ path: { type: "string", description: "e.g. /memories/user/prefers-pnpm.md" },
38
+ view_range: { type: "array", items: { type: "integer" } },
39
+ file_text: { type: "string", description: "create: full Markdown content" },
40
+ old_str: { type: "string" },
41
+ new_str: { type: "string" },
42
+ },
43
+ required: ["command", "path"],
44
+ additionalProperties: false,
45
+ },
46
+ permission: "memory",
47
+ executionMode: "sequential",
48
+ promptSnippet: "memory: read and save notes that persist across sessions",
49
+ promptGuidelines: MEMORY_GUIDELINES,
50
+ async execute(input, ctx) {
51
+ const command = input?.command;
52
+ const write = command !== "view";
53
+ if (ctx.depth > 0) {
54
+ if (runtime.subagents === "off")
55
+ return fail(input, "subagent", "subagents cannot access memory");
56
+ if (write)
57
+ return fail(input, "subagent", "subagents cannot modify memory");
58
+ }
59
+ if (write && !runtime.writesEnabled)
60
+ return fail(input, "disabled", "memory writes are turned off for this session");
61
+ const store = runtime.store;
62
+ try {
63
+ switch (command) {
64
+ case "view":
65
+ return {
66
+ content: store.view(input.path, input.view_range),
67
+ details: { command, path: input.path },
68
+ };
69
+ case "create":
70
+ case "str_replace":
71
+ case "delete": {
72
+ const result = command === "create"
73
+ ? await store.create(input.path, input.file_text)
74
+ : command === "str_replace"
75
+ ? await store.strReplace(input.path, input.old_str, input.new_str)
76
+ : await store.delete(input.path);
77
+ const verb = command === "delete" ? "Deleted" : result.created ? "Saved new entry" : "Updated";
78
+ return {
79
+ content: `${verb} ${result.path}. The memory index will show it from the next session.`,
80
+ details: { command, path: result.path },
81
+ };
82
+ }
83
+ default:
84
+ return fail(input, "invalid_command", 'command must be "view", "create", "str_replace" or "delete"');
85
+ }
86
+ }
87
+ catch (error) {
88
+ if (error instanceof MemoryError || error instanceof MemoryLockError)
89
+ return fail(input, error.code, error.message);
90
+ throw error;
91
+ }
92
+ },
93
+ };
94
+ }
@@ -17,6 +17,7 @@
17
17
  import { isAbsolute, resolve } from "node:path";
18
18
  import { PERMISSION_MODES_STRICT_FIRST } from "../../permissions/types.js";
19
19
  import { oneLine } from "../../drivers/turn.js";
20
+ import { msg } from "../../i18n/index.js";
20
21
  export const TOOL_OUTPUT_LIMIT = 4 * 1024;
21
22
  const KINDS = {
22
23
  read: "read",
@@ -61,7 +62,7 @@ function resultText(result) {
61
62
  ? result.content
62
63
  : result.content.map((b) => (b.type === "text" ? b.text : `[${b.type}]`)).join("");
63
64
  return text.length > TOOL_OUTPUT_LIMIT
64
- ? `${text.slice(0, TOOL_OUTPUT_LIMIT)}\n…(已截断,共 ${text.length} 字符)`
65
+ ? `${text.slice(0, TOOL_OUTPUT_LIMIT)}\n${msg().print.acp.truncated(text.length)}`
65
66
  : text;
66
67
  }
67
68
  export function permissionModes(currentModeId) {
@@ -24,6 +24,7 @@ import { isPermissionMode } from "../../permissions/modes.js";
24
24
  import { AMA_VERSION } from "../../version.js";
25
25
  import { errorText } from "../shared.js";
26
26
  import { AcpEventMapper, permissionModes, toolKind, toolLocations, toolTitle, } from "./acp-events.js";
27
+ import { msg } from "../../i18n/index.js";
27
28
  export const ACP_AGENT_CAPABILITIES = {
28
29
  loadSession: true,
29
30
  promptCapabilities: { image: true, audio: false, embeddedContext: true },
@@ -42,13 +43,13 @@ function canonical(path) {
42
43
  function str(params, key) {
43
44
  const value = params[key];
44
45
  if (typeof value !== "string" || value === "")
45
- throw new RpcError(RPC_ERRORS.invalidParams, `缺少 ${key}`);
46
+ throw new RpcError(RPC_ERRORS.invalidParams, msg().print.acp.missingParam(key));
46
47
  return value;
47
48
  }
48
49
  /** ACP 提示 → ama 的文本与图片。 */
49
50
  export function promptOf(blocks) {
50
51
  if (!Array.isArray(blocks))
51
- throw new RpcError(RPC_ERRORS.invalidParams, "prompt 应为内容块数组");
52
+ throw new RpcError(RPC_ERRORS.invalidParams, msg().print.acp.promptNotArray);
52
53
  const parts = [];
53
54
  const images = [];
54
55
  for (const block of blocks) {
@@ -87,7 +88,7 @@ export class AcpServer {
87
88
  if (method === ACP_METHODS.sessionCancel)
88
89
  void this.cancel((params ?? {}));
89
90
  },
90
- onProtocolError: (_line, reason) => this.log(`ACP:无法解析的输入(${reason})`),
91
+ onProtocolError: (_line, reason) => this.log(msg().print.acp.unparsable(reason)),
91
92
  });
92
93
  this.subscribe();
93
94
  }
@@ -138,7 +139,7 @@ export class AcpServer {
138
139
  }
139
140
  initialize(params) {
140
141
  if (typeof params["protocolVersion"] !== "number")
141
- throw new RpcError(RPC_ERRORS.invalidParams, "缺少 protocolVersion");
142
+ throw new RpcError(RPC_ERRORS.invalidParams, msg().print.acp.missingProtocolVersion);
142
143
  return {
143
144
  protocolVersion: ACP_PROTOCOL_VERSION,
144
145
  agentCapabilities: ACP_AGENT_CAPABILITIES,
@@ -151,7 +152,7 @@ export class AcpServer {
151
152
  if (cwd === undefined)
152
153
  return;
153
154
  if (typeof cwd !== "string" || canonical(cwd) !== this.cwd)
154
- throw new RpcError(RPC_ERRORS.invalidParams, `ama --mode acp 的会话目录固定为启动目录 ${this.cwd}(收到 ${String(cwd)})`);
155
+ throw new RpcError(RPC_ERRORS.invalidParams, msg().print.acp.fixedCwd(this.cwd, String(cwd)));
155
156
  }
156
157
  modes() {
157
158
  return permissionModes(this.session().state.permissionMode);
@@ -185,7 +186,7 @@ export class AcpServer {
185
186
  await this.switchTo(switchSession(this.runtime, { kind: "resume", id }), "resume");
186
187
  }
187
188
  catch (error) {
188
- throw new RpcError(RPC_ERRORS.resourceNotFound, `找不到会话 ${id}:${errorText(error)}`);
189
+ throw new RpcError(RPC_ERRORS.resourceNotFound, msg().print.acp.sessionNotFound(id, errorText(error)));
189
190
  }
190
191
  }
191
192
  this.freshUnclaimed = false;
@@ -222,7 +223,7 @@ export class AcpServer {
222
223
  }
223
224
  ensureIdle() {
224
225
  if (this.session().state.isStreaming)
225
- throw new RpcError(RPC_ERRORS.invalidRequest, "当前会话正在运行,先 session/cancel");
226
+ throw new RpcError(RPC_ERRORS.invalidRequest, msg().print.acp.busy);
226
227
  }
227
228
  async prompt(params) {
228
229
  const id = str(params, "sessionId");
@@ -253,7 +254,7 @@ export class AcpServer {
253
254
  return { stopReason: "cancelled", usage };
254
255
  if (reason === "error") {
255
256
  const message = last !== undefined && "errorMessage" in last ? last.errorMessage : undefined;
256
- throw new RpcError(RPC_ERRORS.internalError, message ?? "模型请求失败");
257
+ throw new RpcError(RPC_ERRORS.internalError, message ?? msg().print.acp.modelFailed);
257
258
  }
258
259
  return { stopReason: reason === "length" ? "max_tokens" : "end_turn", usage };
259
260
  }
@@ -269,7 +270,7 @@ export class AcpServer {
269
270
  str(params, "sessionId");
270
271
  const mode = params["modeId"];
271
272
  if (!isPermissionMode(mode))
272
- throw new RpcError(RPC_ERRORS.invalidParams, `未知模式:${String(mode)}`);
273
+ throw new RpcError(RPC_ERRORS.invalidParams, msg().print.acp.unknownMode(String(mode)));
273
274
  this.session().setPermissionMode(mode);
274
275
  return {};
275
276
  }
@@ -292,9 +293,9 @@ export class AcpServer {
292
293
  ...(locations !== undefined ? { locations } : {}),
293
294
  },
294
295
  options: [
295
- { optionId: "allow_once", name: "允许", kind: "allow_once" },
296
- { optionId: "allow_always", name: "本会话允许", kind: "allow_always" },
297
- { optionId: "reject_once", name: "拒绝", kind: "reject_once" },
296
+ { optionId: "allow_once", name: msg().print.acp.allowOnce, kind: "allow_once" },
297
+ { optionId: "allow_always", name: msg().print.acp.allowAlways, kind: "allow_always" },
298
+ { optionId: "reject_once", name: msg().print.acp.rejectOnce, kind: "reject_once" },
298
299
  ],
299
300
  }, signal);
300
301
  }
@@ -10,6 +10,8 @@
10
10
  * 会话切换(/new /resume /fork)经 `ctx.switchSession`,调用方据返回的新会话重新订阅事件。
11
11
  * `/rewind`(RW-C):无参数列出回滚点,带参数执行(interactive/rewind-command.ts);对话变了时
12
12
  * `handled` 带 `draft`(原消息)与 `reload`,界面据此回填输入框、重画消息区。
13
+ * [W6-C0] `/config`、`/trace`、`/memory` 登记在表里,由各功能批次经 `CommandContext.extra`(line 模式)或
14
+ * `CommandUi` 的面板钩子(交互模式,interactive/commands.ts)实现;没有实现时回「尚未提供」。
13
15
  */
14
16
  import type { AgentSession, RewindDraftText } from "../agent/types.js";
15
17
  import type { SwitchRequest } from "../cli/compose-session.js";
@@ -42,7 +44,16 @@ export interface CommandContext {
42
44
  * 保持原模式。没有时直接切换(管道、RPC 等无人值守入口)。
43
45
  */
44
46
  confirmPermissionMode?(mode: PermissionMode): boolean | Promise<boolean>;
47
+ /**
48
+ * [W6-C0] 第六波命令的处理器(命令名 → 处理器):line 模式 `/config`(W6-S)、`/trace`(W6-T1)、
49
+ * `/memory`(W6-M)等在这里挂;命中时先于内置分派。交互模式走 `CommandUi` 的面板钩子。
50
+ */
51
+ extra?: Readonly<Record<string, CommandHandler>>;
45
52
  }
53
+ /** [W6-C0] `CommandContext.extra` 的处理器。 */
54
+ export type CommandHandler = (args: string, ctx: CommandContext) => Promise<CommandResult>;
55
+ /** [W6-C0] 各功能批次实现的第六波命令(没有处理器时回「尚未提供」)。 */
56
+ export declare const W6_COMMANDS: readonly ["config", "trace", "memory"];
46
57
  export interface CommandInfo {
47
58
  name: string;
48
59
  args?: string;
@@ -10,6 +10,8 @@
10
10
  * 会话切换(/new /resume /fork)经 `ctx.switchSession`,调用方据返回的新会话重新订阅事件。
11
11
  * `/rewind`(RW-C):无参数列出回滚点,带参数执行(interactive/rewind-command.ts);对话变了时
12
12
  * `handled` 带 `draft`(原消息)与 `reload`,界面据此回填输入框、重画消息区。
13
+ * [W6-C0] `/config`、`/trace`、`/memory` 登记在表里,由各功能批次经 `CommandContext.extra`(line 模式)或
14
+ * `CommandUi` 的面板钩子(交互模式,interactive/commands.ts)实现;没有实现时回「尚未提供」。
13
15
  */
14
16
  import { AgentSessionImpl } from "../agent/session.js";
15
17
  import { WARMING_MODES } from "../ai/cache/types.js";
@@ -21,47 +23,54 @@ import { planCommand } from "./interactive/plan-command.js";
21
23
  import { rewindCommand } from "./interactive/rewind-command.js";
22
24
  import { describeAgents, describeTaskOutput, describeTasks, stopTask, } from "./interactive/tasks-report.js";
23
25
  import { describeCache, describeFingerprint, describeSession } from "./session-report.js";
26
+ import { msg } from "../i18n/index.js";
24
27
  export { describeSession } from "./session-report.js";
28
+ /** [W6-C0] 各功能批次实现的第六波命令(没有处理器时回「尚未提供」)。 */
29
+ export const W6_COMMANDS = ["config", "trace", "memory"];
30
+ /**
31
+ * 说明与需要翻译的参数占位按界面语言取(getter,不在 import 时定死,docs/i18n.md);
32
+ * `args` 是字符串时原样(不含要翻译的词),是 `{ key }` 时取目录里的占位。
33
+ */
34
+ function command(name, key, args) {
35
+ const info = {
36
+ name,
37
+ get description() {
38
+ return msg().report.commands[key];
39
+ },
40
+ };
41
+ if (typeof args === "string")
42
+ info.args = args;
43
+ else if (args !== undefined)
44
+ Object.defineProperty(info, "args", {
45
+ enumerable: true,
46
+ get: () => msg().report.commands[args.key],
47
+ });
48
+ return info;
49
+ }
25
50
  export const BUILTIN_COMMANDS = [
26
- { name: "help", description: "列出命令" },
27
- { name: "new", description: "新建会话" },
28
- { name: "resume", args: "[id]", description: "恢复会话(无 id 时选择)" },
29
- { name: "fork", args: "[条目 id]", description: "从某条目分叉出新会话" },
30
- { name: "compact", args: "[说明]", description: "压缩上下文" },
31
- {
32
- name: "rewind",
33
- args: "[n] [both|conversation|code|summarize-from|summarize-up-to]",
34
- description: "回滚对话与代码到某条消息之前",
35
- },
36
- { name: "model", args: "[provider/id]", description: "切换模型" },
37
- {
38
- name: "thinking",
39
- args: "[级别]",
40
- description: "思考级别 off | minimal | low | medium | high | xhigh",
41
- },
42
- {
43
- name: "permission",
44
- args: "[模式]",
45
- description: "权限模式 plan | default | auto-edit | full-auto",
46
- },
47
- { name: "tools", args: "[名字…]", description: "列出 / 设置活动工具" },
48
- { name: "hooks", description: "列出已加载的 Hook" },
49
- { name: "session", description: "会话信息、用量与缓存" },
50
- {
51
- name: "cache",
52
- args: "[warm off|streaming|idle | fingerprint]",
53
- description: "缓存统计;切换本会话保温;打印前缀指纹",
54
- },
55
- { name: "statusline", args: "[full|compact]", description: "底部信息行两行 / 一行(Ctrl+G)" },
56
- {
57
- name: "plan",
58
- args: "[目标] | approve [模式|fresh] | reject",
59
- description: "查看计划与状态;带目标进入 Plan 模式;批准 / 放弃待审批的计划",
60
- },
61
- { name: "tasks", args: "[id] | stop <id>", description: "子 Agent 任务:状态、输出、停止" },
62
- { name: "agents", description: "子 Agent 类型与外部 Agent(安装状态、版本)" },
63
- { name: "paste", description: "粘贴剪贴板里的图片(Ctrl+V)" },
64
- { name: "exit", description: "退出" },
51
+ command("help", "help"),
52
+ command("new", "new"),
53
+ command("resume", "resume", "[id]"),
54
+ command("fork", "fork", { key: "forkArgs" }),
55
+ command("compact", "compact", { key: "compactArgs" }),
56
+ command("rewind", "rewind", "[n] [both|conversation|code|summarize-from|summarize-up-to]"),
57
+ command("model", "model", "[provider/id]"),
58
+ command("thinking", "thinking", { key: "thinkingArgs" }),
59
+ command("permission", "permission", { key: "permissionArgs" }),
60
+ command("tools", "tools", { key: "toolsArgs" }),
61
+ command("hooks", "hooks"),
62
+ command("session", "session"),
63
+ command("cache", "cache", "[warm off|streaming|idle | fingerprint]"),
64
+ command("statusline", "statusline", "[full|compact]"),
65
+ command("plan", "plan", { key: "planArgs" }),
66
+ command("tasks", "tasks", "[id] | stop <id>"),
67
+ command("agents", "agents"),
68
+ command("paste", "paste"),
69
+ command("exit", "exit"),
70
+ // [W6-C0] 第六波(W6-S / W6-T1 / W6-M 实现)
71
+ command("config", "config", "[key=value]"),
72
+ command("trace", "trace", { key: "traceArgs" }),
73
+ command("memory", "memory", { key: "memoryArgs" }),
65
74
  ];
66
75
  const ALIASES = { quit: "exit", q: "exit", "?": "help" };
67
76
  export function parseSlash(line) {
@@ -73,7 +82,8 @@ export function parseSlash(line) {
73
82
  }
74
83
  function helpText() {
75
84
  const lines = BUILTIN_COMMANDS.map((c) => `/${c.name}${c.args !== undefined ? ` ${c.args}` : ""} ${c.description}`);
76
- return [...lines, "/skill:<名字> [参数] 使用 Skill", "/<模板名> [参数] 展开提示模板"].join("\n");
85
+ const m = msg().report.commands;
86
+ return [...lines, m.skillLine, m.templateLine].join("\n");
77
87
  }
78
88
  function toolNames(args) {
79
89
  return args
@@ -90,15 +100,15 @@ function cacheCommand(session, args) {
90
100
  return describeFingerprint(session);
91
101
  if (sub === "warm" && extra === undefined) {
92
102
  if (!(session instanceof AgentSessionImpl))
93
- throw new AmaError("invalid_arguments", "当前会话不支持切换保温");
103
+ throw new AmaError("invalid_arguments", msg().report.command.warmingUnsupported);
94
104
  if (value === undefined)
95
- return `保温:${session.cache.mode()}`;
105
+ return msg().report.command.warming(session.cache.mode());
96
106
  if (!WARMING_MODES.includes(value))
97
- throw new AmaError("invalid_arguments", `保温模式应为 ${WARMING_MODES.join(" | ")}`);
107
+ throw new AmaError("invalid_arguments", msg().report.command.warmingInvalid(WARMING_MODES));
98
108
  session.cache.setWarming(value);
99
- return `保温:${session.cache.mode()}(本会话)`;
109
+ return msg().report.command.warmingSet(session.cache.mode());
100
110
  }
101
- throw new AmaError("invalid_arguments", "用法:/cache [warm off|streaming|idle | fingerprint]");
111
+ throw new AmaError("invalid_arguments", msg().report.command.cacheUsage);
102
112
  }
103
113
  /** `/tasks`、`/tasks <id>`、`/tasks stop <id>`。 */
104
114
  async function tasksCommand(sessionId, args) {
@@ -108,17 +118,20 @@ async function tasksCommand(sessionId, args) {
108
118
  return describeTasks(sessionId, now);
109
119
  if (first === "stop" && second !== undefined && extra === undefined) {
110
120
  await stopTask(sessionId, second);
111
- return `已停止 ${second}`;
121
+ return msg().report.command.taskStopped(second);
112
122
  }
113
123
  if (second === undefined)
114
124
  return describeTaskOutput(sessionId, first, now);
115
- throw new AmaError("invalid_arguments", "用法:/tasks [id] | /tasks stop <id>");
125
+ throw new AmaError("invalid_arguments", msg().report.command.tasksUsage);
116
126
  }
117
127
  export async function runSlashCommand(line, ctx) {
118
128
  const parsed = parseSlash(line);
119
129
  if (parsed === undefined)
120
130
  return undefined;
121
131
  const { name, args } = parsed;
132
+ const handler = ctx.extra?.[name];
133
+ if (handler !== undefined)
134
+ return handler(args, ctx);
122
135
  const session = ctx.session();
123
136
  switch (name) {
124
137
  case "help":
@@ -127,7 +140,10 @@ export async function runSlashCommand(line, ctx) {
127
140
  return { kind: "exit" };
128
141
  case "new": {
129
142
  const next = await ctx.switchSession({ kind: "new" });
130
- return { kind: "handled", message: `已新建会话 ${next.state.sessionId.slice(0, 8)}` };
143
+ return {
144
+ kind: "handled",
145
+ message: msg().report.command.newSession(next.state.sessionId.slice(0, 8)),
146
+ };
131
147
  }
132
148
  case "resume": {
133
149
  if (args === "")
@@ -135,53 +151,64 @@ export async function runSlashCommand(line, ctx) {
135
151
  const next = await ctx.switchSession({ kind: "resume", id: args });
136
152
  return {
137
153
  kind: "handled",
138
- message: `已恢复会话 ${next.state.sessionId.slice(0, 8)}(${next.messages.length} 条消息)`,
154
+ message: msg().report.command.resumed(next.state.sessionId.slice(0, 8), next.messages.length),
139
155
  };
140
156
  }
141
157
  case "fork": {
142
158
  if (args === "")
143
159
  return { kind: "pick", what: "tree" };
144
160
  const next = await ctx.switchSession({ kind: "fork", entryId: args });
145
- return { kind: "handled", message: `已分叉到新会话 ${next.state.sessionId.slice(0, 8)}` };
161
+ return {
162
+ kind: "handled",
163
+ message: msg().report.command.forked(next.state.sessionId.slice(0, 8)),
164
+ };
146
165
  }
147
166
  case "compact": {
148
167
  const result = await session.compact(args === "" ? undefined : args);
149
- const after = result.tokensAfter !== undefined ? ` → ${result.tokensAfter}` : "";
150
- return { kind: "handled", message: `已压缩:${result.tokensBefore}${after} token` };
168
+ return {
169
+ kind: "handled",
170
+ message: msg().report.command.compacted(result.tokensBefore, result.tokensAfter),
171
+ };
151
172
  }
152
173
  case "model": {
153
174
  if (args === "")
154
175
  return { kind: "pick", what: "model" };
155
176
  await session.setModel(args);
156
177
  const model = session.state.model;
157
- return { kind: "handled", message: `模型:${model?.provider}/${model?.id}` };
178
+ return {
179
+ kind: "handled",
180
+ message: msg().report.command.model(`${model?.provider}/${model?.id}`),
181
+ };
158
182
  }
159
183
  case "thinking": {
160
184
  if (args === "")
161
185
  return { kind: "pick", what: "thinking" };
162
186
  if (!THINKING_LEVELS.includes(args))
163
- throw new AmaError("invalid_arguments", `思考级别应为 ${THINKING_LEVELS.join(" | ")}`);
187
+ throw new AmaError("invalid_arguments", msg().report.command.thinkingInvalid(THINKING_LEVELS));
164
188
  session.setThinkingLevel(args);
165
- return { kind: "handled", message: `思考级别:${args}` };
189
+ return { kind: "handled", message: msg().report.command.thinking(args) };
166
190
  }
167
191
  case "permission": {
168
192
  if (args === "")
169
193
  return { kind: "pick", what: "permission" };
170
194
  const mode = parsePermissionMode(args);
171
195
  if (mode === undefined) {
172
- throw new AmaError("invalid_arguments", `权限模式应为 ${PERMISSION_MODE_ORDER.join(" | ")}(也可写显示名,如 "Accept edits")`);
196
+ throw new AmaError("invalid_arguments", msg().report.command.permissionInvalid(PERMISSION_MODE_ORDER));
173
197
  }
174
198
  const current = session.state.permissionMode;
175
199
  if (mode !== current && ctx.confirmPermissionMode !== undefined) {
176
200
  if (!(await ctx.confirmPermissionMode(mode))) {
177
201
  return {
178
202
  kind: "handled",
179
- message: `已取消,权限模式仍为 ${permissionModeLabel(current)}`,
203
+ message: msg().report.command.permissionCancelled(permissionModeLabel(current)),
180
204
  };
181
205
  }
182
206
  }
183
207
  session.setPermissionMode(mode);
184
- return { kind: "handled", message: `权限模式:${permissionModeLabel(mode)}` };
208
+ return {
209
+ kind: "handled",
210
+ message: msg().report.command.permission(permissionModeLabel(mode)),
211
+ };
185
212
  }
186
213
  case "tools": {
187
214
  if (args !== "")
@@ -191,13 +218,13 @@ export async function runSlashCommand(line, ctx) {
191
218
  const inactive = all.filter((n) => !active.includes(n));
192
219
  return {
193
220
  kind: "handled",
194
- message: `活动:${active.join(", ") || "(无)"}${inactive.length > 0 ? `\n可用:${inactive.join(", ")}` : ""}`,
221
+ message: msg().report.command.tools(active, inactive),
195
222
  };
196
223
  }
197
224
  case "hooks": {
198
225
  const hooks = ctx.runtime.hooks.list();
199
226
  if (hooks.length === 0)
200
- return { kind: "handled", message: "没有已加载的 Hook" };
227
+ return { kind: "handled", message: msg().report.command.noHooks };
201
228
  return {
202
229
  kind: "handled",
203
230
  message: hooks
@@ -222,14 +249,18 @@ export async function runSlashCommand(line, ctx) {
222
249
  return pasted.ok
223
250
  ? {
224
251
  kind: "handled",
225
- message: `已粘贴图片:${pasted.path}`,
252
+ message: msg().report.command.pasted(pasted.path),
226
253
  draft: { text: `${pasted.ref} ` },
227
254
  }
228
255
  : { kind: "handled", message: pasted.message };
229
256
  }
230
257
  case "statusline":
231
258
  // [W5-A] 交互界面在 commands-core 之前自己处理;line 模式没有底部信息行
232
- return { kind: "handled", message: "/statusline 只在交互界面可用" };
259
+ return { kind: "handled", message: msg().report.command.statuslineOnly };
260
+ case "config":
261
+ case "trace":
262
+ case "memory":
263
+ return { kind: "handled", message: msg().interactive.commands.unavailable(name) };
233
264
  default:
234
265
  return undefined;
235
266
  }
@@ -15,7 +15,8 @@ import { resolve } from "node:path";
15
15
  import { formatModelRef } from "../ai/providers/channels.js";
16
16
  import { AmaError } from "../errors.js";
17
17
  import { imageLimits } from "../ai/image-limits.js";
18
- import { imageMimeFromPath, loadImageFile } from "../tools/image-file.js";
18
+ import { imageMimeFromPath, isImageFileErrorDetail, loadImageFile, } from "../tools/image-file.js";
19
+ import { msg } from "../i18n/index.js";
19
20
  const TOKEN = /@?"([^"]+)"|@?'([^']+)'|((?:\\ |\S)+)/g;
20
21
  function expand(path, cwd) {
21
22
  const home = path === "~" || path.startsWith("~/") ? homedir() + path.slice(1) : path;
@@ -30,7 +31,8 @@ export function findImageRefs(text, cwd) {
30
31
  const explicit = m[0].startsWith("@");
31
32
  if (m[3] !== undefined && explicit)
32
33
  token = token.slice(1);
33
- token = token.replace(/\\ /g, " ").replace(/[,,。;;))]+$/, "");
34
+ // 结尾标点(含全角,写成转义:输入识别与界面语言无关)
35
+ token = token.replace(/\\ /g, " ").replace(/[,\uFF0C\u3002;\uFF1B)\uFF09]+$/, "");
34
36
  if (token === "" || imageMimeFromPath(token) === undefined)
35
37
  continue;
36
38
  const path = expand(token, cwd);
@@ -60,9 +62,7 @@ export async function loadPromptImages(refs, model, options = {}) {
60
62
  if (wanted.length === 0)
61
63
  return [];
62
64
  if (!accepts) {
63
- const name = model === undefined ? "当前模型" : `${model.provider}/${model.id}`;
64
- throw new AmaError("invalid_arguments", `${name} 不接受图片输入(模型 input 没有 image);换一个支持图像的模型再试` +
65
- `(ama models list 里标「图片」的,或在配置里给该模型写 "input": ["text", "image"])`);
65
+ throw new AmaError("invalid_arguments", msg().errors.imageUnsupported(model === undefined ? undefined : `${model.provider}/${model.id}`));
66
66
  }
67
67
  const fit = {
68
68
  ...(model !== undefined ? { maxBase64Bytes: imageLimits(model).perImageBase64 } : {}),
@@ -70,7 +70,7 @@ export async function loadPromptImages(refs, model, options = {}) {
70
70
  };
71
71
  const blocks = [];
72
72
  for (const ref of wanted)
73
- blocks.push((await loadImageFile(ref.path, fit)).block);
73
+ blocks.push((await loadLocalized(ref.path, fit)).block);
74
74
  return blocks;
75
75
  }
76
76
  /** 提示 + 额外的显式图片路径(`--image`)→ 附件。 */
@@ -93,3 +93,17 @@ export function imageFitOptionsFor(providers, ref, images) {
93
93
  const found = providers.findModel(formatModelRef(ref));
94
94
  return found.ok ? { maxBase64Bytes: imageLimits(found.model).perImageBase64, ...resize } : resize;
95
95
  }
96
+ /** [W6-C0] `loadImageFile` 的错误固定英文(模型侧模块);给人看时按 `detail.reason` 换成界面语言。 */
97
+ async function loadLocalized(path, options) {
98
+ try {
99
+ return await loadImageFile(path, options);
100
+ }
101
+ catch (error) {
102
+ if (error instanceof AmaError && isImageFileErrorDetail(error.detail))
103
+ throw new AmaError(error.code, msg().errors.imageFile(error.detail), {
104
+ detail: error.detail,
105
+ ...(error.exitCode !== undefined ? { exitCode: error.exitCode } : {}),
106
+ });
107
+ throw error;
108
+ }
109
+ }