@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
@@ -2,9 +2,9 @@
2
2
  * `ama sessions list|show|prune`(设计 §1.2、§8)。[B5]
3
3
  *
4
4
  * 会话存储是 B2 的实现,经 RuntimeDeps.sessions 注入;这里只做参数、目录解析与输出格式。
5
- * - list [--all]:缺省只列当前目录的会话;`--all` 列全部。
5
+ * - list [--all]:缺省只列当前目录的会话、不列子 Agent 会话;`--all` 列全部目录并带上子 Agent 会话(标 `↳`)。
6
6
  * - show <id>:头信息 + 条目类型统计 + 首条提示 + 用户消息编号(`--from <id>#<编号>` 复用)。
7
- * - search / export:见 sessions-search.ts、sessions-export.ts(只读扫描,不经会话存储)。
7
+ * - search / export / trace:见 sessions-search.ts、sessions-export.ts、sessions-trace.ts(只读扫描,不经会话存储)。
8
8
  * - prune [--older-than <天>] [--dry-run]:缺省 30 天,移到 trash(不删除);之后清理检查点备份
9
9
  * (未被任何会话引用且超过 1 天的 blob,docs/rewind-plan.md §1.4)与超过 7 天的剪贴板图片
10
10
  * (`<数据目录>/clipboard/`,W5-I),`--dry-run` 时只报告。
@@ -18,12 +18,12 @@ import { numberUserMessages } from "../../session/reuse.js";
18
18
  import { gcClipboardImages } from "../../tools/clipboard-image.js";
19
19
  import { runSessionsExport } from "./sessions-export.js";
20
20
  import { runSessionsSearch } from "./sessions-search.js";
21
- export const SESSIONS_USAGE = `用法:ama sessions list [--all] [--session-dir <目录>]
22
- ama sessions show <id> [--session-dir <目录>]
23
- ama sessions prune [--older-than <天>] [--dry-run] [--all] [--session-dir <目录>]
24
- ama sessions search <关键词|/正则/> [--all] [--role user|assistant|tool] [--since 7d] [--limit N]
25
- ama sessions export <id> [--format md|json|jsonl] [--output <文件>] [--branch leaf|all]
26
- `;
21
+ import { runSessionsTrace } from "./sessions-trace.js";
22
+ import { msg } from "../../i18n/index.js";
23
+ /** 用法(随界面语言)。 */
24
+ export function sessionsUsage() {
25
+ return msg().session.cli.usage;
26
+ }
27
27
  function shortTime(iso) {
28
28
  return iso.replace("T", " ").replace(/\.\d+Z$|Z$/, "");
29
29
  }
@@ -38,10 +38,12 @@ export async function runSessions(argv, io, deps) {
38
38
  return runSessionsSearch(argv.slice(1), io);
39
39
  if (argv[0] === "export")
40
40
  return runSessionsExport(argv.slice(1), io);
41
+ if (argv[0] === "trace")
42
+ return runSessionsTrace(argv.slice(1), io); // [W6-T2]
41
43
  const { positionals, values, flags } = parseSubArgs(argv, ["session-dir", "older-than"], ["all", "dry-run"]);
42
44
  const action = positionals[0];
43
45
  if (flags.has("help") || action === undefined) {
44
- io.stdout(SESSIONS_USAGE);
46
+ io.stdout(sessionsUsage());
45
47
  return flags.has("help") ? ExitCode.Ok : ExitCode.Usage;
46
48
  }
47
49
  const dirFlag = values.get("session-dir");
@@ -54,46 +56,47 @@ export async function runSessions(argv, io, deps) {
54
56
  case "list": {
55
57
  if (sessions?.list === undefined)
56
58
  return notWired(io, "sessions list");
57
- const items = await sessions.list({ sessionDir, ...scope });
59
+ const all = flags.has("all");
60
+ const items = await sessions.list({ sessionDir, ...scope, includeSubagents: all });
58
61
  if (items.length === 0) {
59
- io.stdout("没有会话\n");
62
+ io.stdout(msg().session.cli.none);
60
63
  return ExitCode.Ok;
61
64
  }
62
65
  for (const item of items) {
63
- const name = item.name ?? oneLine(item.firstPrompt);
64
- io.stdout(`${item.id.slice(0, 8)} ${shortTime(item.modifiedAt)} ${String(item.messageCount).padStart(4)} 条 ${name}\n`);
66
+ const title = item.name ?? oneLine(item.firstPrompt);
67
+ const name = item.subagent === true ? `${msg().session.cli.subagentTag} ${title}` : title;
68
+ io.stdout(msg().session.cli.listRow(item.id.slice(0, 8), shortTime(item.modifiedAt), item.messageCount, name));
65
69
  }
66
70
  return ExitCode.Ok;
67
71
  }
68
72
  case "show": {
69
73
  const id = positionals[1];
70
74
  if (id === undefined)
71
- throw new UsageError("ama sessions show 需要 <id>");
75
+ throw new UsageError(msg().session.cli.showNeedsId);
72
76
  if (sessions?.show === undefined)
73
77
  return notWired(io, "sessions show");
74
78
  const { item, entries } = await sessions.show(id, { sessionDir });
75
79
  const counts = new Map();
76
80
  for (const entry of entries)
77
81
  counts.set(entry.type, (counts.get(entry.type) ?? 0) + 1);
78
- io.stdout([
79
- `id:${item.id}`,
80
- `文件:${item.file}`,
81
- `目录:${item.cwd}`,
82
- ...(item.name !== undefined ? [`名称:${item.name}`] : []),
83
- `创建:${shortTime(item.createdAt)} · 修改:${shortTime(item.modifiedAt)}`,
84
- `消息:${item.messageCount}`,
85
- `条目:${[...counts].map(([type, n]) => `${type} ${n}`).join(" · ")}`,
86
- ...(item.firstPrompt !== undefined
87
- ? [`首条提示:${oneLine(item.firstPrompt, 200)}`]
88
- : []),
89
- ].join("\n") + "\n");
82
+ io.stdout(msg().session.cli.show({
83
+ id: item.id,
84
+ file: item.file,
85
+ cwd: item.cwd,
86
+ name: item.name,
87
+ created: shortTime(item.createdAt),
88
+ modified: shortTime(item.modifiedAt),
89
+ messages: item.messageCount,
90
+ entries: [...counts].map(([type, n]) => `${type} ${n}`).join(" · "),
91
+ firstPrompt: item.firstPrompt !== undefined ? oneLine(item.firstPrompt, 200) : undefined,
92
+ }));
90
93
  const users = numberUserMessages(entries);
91
94
  if (users.length > 0) {
92
- io.stdout(`用户消息(ama --from ${item.id.slice(0, 8)}#<编号> 复用):\n`);
95
+ io.stdout(msg().session.cli.userMessages(item.id.slice(0, 8)));
93
96
  for (const user of users) {
94
97
  const tags = [
95
98
  ...(user.origin !== undefined ? [`[${user.origin}]`] : []),
96
- ...(user.images.length > 0 ? [`[图片 ${user.images.length}]`] : []),
99
+ ...(user.images.length > 0 ? [msg().session.cli.images(user.images.length)] : []),
97
100
  ];
98
101
  io.stdout(` #${String(user.n).padEnd(3)} ${shortTime(user.timestamp)} ${[...tags, oneLine(user.text, 100)].join(" ")}\n`);
99
102
  }
@@ -104,21 +107,21 @@ export async function runSessions(argv, io, deps) {
104
107
  const raw = values.get("older-than") ?? "30";
105
108
  const olderThanDays = Number(raw);
106
109
  if (!Number.isFinite(olderThanDays) || olderThanDays < 0) {
107
- throw new UsageError(`--older-than 应为非负天数(收到 ${raw})`);
110
+ throw new UsageError(msg().session.cli.olderThanInvalid(raw));
108
111
  }
109
112
  if (sessions?.prune === undefined)
110
113
  return notWired(io, "sessions prune");
111
114
  const dryRun = flags.has("dry-run");
112
115
  const { moved } = await sessions.prune({ sessionDir, olderThanDays, dryRun, ...scope });
113
116
  for (const file of moved)
114
- io.stdout(`${dryRun ? "将移到 trash" : "已移到 trash"}:${file}\n`);
115
- io.stdout(`${moved.length} 个会话${dryRun ? "(演练,未改动)" : ""}\n`);
117
+ io.stdout(msg().session.cli.moved(dryRun, file));
118
+ io.stdout(msg().session.cli.pruned(moved.length, dryRun));
116
119
  await pruneFileHistory(io, sessionDir, dryRun);
117
120
  await pruneClipboard(io, dryRun);
118
121
  return ExitCode.Ok;
119
122
  }
120
123
  default:
121
- throw new UsageError(`未知的 sessions 子命令:${action}`);
124
+ throw new UsageError(msg().session.cli.unknownAction(action));
122
125
  }
123
126
  }
124
127
  /** 检查点备份 GC:扫描本次的会话目录、缺省会话目录与登记过的目录。失败只提示,不影响 prune。 */
@@ -132,10 +135,10 @@ async function pruneFileHistory(io, sessionDir, dryRun) {
132
135
  });
133
136
  if (result.removed.length === 0)
134
137
  return;
135
- io.stdout(`file-history:${dryRun ? "将清除" : "已清除"} ${result.removed.length} 个未引用的备份(${formatBytes(result.removedBytes)})\n`);
138
+ io.stdout(msg().session.cli.fileHistoryPruned(dryRun, result.removed.length, formatBytes(result.removedBytes)));
136
139
  }
137
140
  catch (error) {
138
- io.stderr(`ama: file-history 清理跳过(${error instanceof Error ? error.message : String(error)})\n`);
141
+ io.stderr(msg().session.cli.fileHistorySkipped(error instanceof Error ? error.message : String(error)));
139
142
  }
140
143
  }
141
144
  /** [W5-I] `<数据目录>/clipboard/` 超过 7 天的剪贴板图片。失败只提示。 */
@@ -143,13 +146,13 @@ async function pruneClipboard(io, dryRun) {
143
146
  try {
144
147
  const removed = await gcClipboardImages(resolveDataDir({ env: io.env }), { dryRun });
145
148
  if (removed.length > 0)
146
- io.stdout(`clipboard:${dryRun ? "将清除" : "已清除"} ${removed.length} 个超过 7 天的剪贴板图片\n`);
149
+ io.stdout(msg().session.cli.clipboardPruned(dryRun, removed.length));
147
150
  }
148
151
  catch (error) {
149
- io.stderr(`ama: clipboard 清理跳过(${error instanceof Error ? error.message : String(error)})\n`);
152
+ io.stderr(msg().session.cli.clipboardSkipped(error instanceof Error ? error.message : String(error)));
150
153
  }
151
154
  }
152
155
  function notWired(io, what) {
153
- io.stderr(`ama: ${what} 尚未装配(会话存储由集成批次注入)\n`);
156
+ io.stderr(msg().session.cli.notWired(what));
154
157
  return ExitCode.RuntimeError;
155
158
  }
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import { type StatsReport } from "../../session/stats-aggregate.js";
11
11
  import type { CliIo } from "../deps.js";
12
- export declare const STATS_USAGE = "\u7528\u6CD5\uFF1Aama stats [--since 7d|30d|today|YYYY-MM-DD] [--until \u2026]\n [--by day|week|month|provider|channel|model|project]\n [--project <\u76EE\u5F55> | --all] [--top N] [--json] [--no-cache] [--session-dir <\u76EE\u5F55>]\n";
12
+ export declare function statsUsage(): string;
13
13
  /** `7d` / `today` / `YYYY-MM-DD` → 本地日期。 */
14
14
  export declare function parseDaySpec(option: string, raw: string, now?: Date): string;
15
15
  export declare function formatTokens(count: number): string;
@@ -15,10 +15,10 @@ import { STATS_INDEX_FILE, collectSummaries } from "../../session/stats-index.js
15
15
  import { localDay } from "../../session/stats-scan.js";
16
16
  import { parseSubArgs, UsageError } from "../args.js";
17
17
  import { ExitCode } from "../exit-codes.js";
18
- export const STATS_USAGE = `用法:ama stats [--since 7d|30d|today|YYYY-MM-DD] [--until …]
19
- [--by day|week|month|provider|channel|model|project]
20
- [--project <目录> | --all] [--top N] [--json] [--no-cache] [--session-dir <目录>]
21
- `;
18
+ import { msg } from "../../i18n/index.js";
19
+ export function statsUsage() {
20
+ return msg().subcommands.stats.usage;
21
+ }
22
22
  /** `7d` / `today` / `YYYY-MM-DD` → 本地日期。 */
23
23
  export function parseDaySpec(option, raw, now = new Date()) {
24
24
  if (raw === "today")
@@ -27,14 +27,14 @@ export function parseDaySpec(option, raw, now = new Date()) {
27
27
  if (rel !== null) {
28
28
  const days = Number(rel[1]);
29
29
  if (days < 1)
30
- throw new UsageError(`--${option} 的天数至少为 1(收到 ${raw})`);
30
+ throw new UsageError(msg().subcommands.stats.daysAtLeastOne(option, raw));
31
31
  const d = new Date(now);
32
32
  d.setDate(d.getDate() - (days - 1));
33
33
  return localDay(d.toISOString()) ?? "";
34
34
  }
35
35
  if (/^\d{4}-\d{2}-\d{2}$/.test(raw) && Number.isFinite(Date.parse(`${raw}T00:00:00`)))
36
36
  return raw;
37
- throw new UsageError(`--${option} 应为 7d、today 或 YYYY-MM-DD(收到 ${raw})`);
37
+ throw new UsageError(msg().subcommands.stats.daySpec(option, raw));
38
38
  }
39
39
  export function formatTokens(count) {
40
40
  const trim = (text) => text.replace(/\.?0+$/, "");
@@ -79,40 +79,58 @@ function table(rows, rightAlign) {
79
79
  }
80
80
  export function renderStats(report, scope) {
81
81
  const t = report.totals;
82
+ const m = msg().subcommands.stats;
82
83
  const range = report.since === undefined && report.until === undefined
83
- ? "全部时间"
84
- : `${report.since ?? "最早"} – ${report.until ?? "今天"}`;
85
- const lines = [`${range} · ${scope} · ${report.sessions} 个会话`];
84
+ ? m.allTime
85
+ : m.range(report.since, report.until);
86
+ const lines = [m.header(range, scope, report.sessions)];
86
87
  if (t.requests === 0) {
87
- lines.push("没有模型请求");
88
+ lines.push(m.noRequests);
88
89
  return lines.join("\n") + "\n";
89
90
  }
90
91
  const kinds = Object.entries(report.byKind)
91
92
  .sort((a, b) => b[1] - a[1])
92
- .map(([kind, n]) => `${kind === "turn" ? "对话" : kind} ${n}`)
93
+ .map(([kind, n]) => `${kind === "turn" ? m.kindTurn : kind} ${n}`)
93
94
  .join(" · ");
94
95
  const costLine = t.cost === undefined
95
- ? "— (所有请求的模型都无价格,见 token)"
96
+ ? t.unpriced > 0
97
+ ? m.costUnpriced
98
+ : "—"
96
99
  : t.unpriced > 0
97
- ? `${usd(t)}(另有 ${t.unpriced} 次请求无价,未计入)`
100
+ ? m.costPartial(usd(t), t.unpriced)
98
101
  : usd(t);
99
102
  const rows = [
100
- ["请求", `${t.requests}(${kinds})`],
101
- ["回合", `${t.turns} · 平均耗时 ${seconds(t.avgTurnMs)}`],
103
+ [m.rows.requests, m.requestsValue(t.requests, kinds)],
104
+ [m.rows.turns, m.turnsValue(t.turns, seconds(t.avgTurnMs))],
102
105
  [
103
- "Token",
104
- `输入 ${formatTokens(t.input)} · 输出 ${formatTokens(t.output)} · 缓存读 ${formatTokens(t.cacheRead)} · 缓存写 ${formatTokens(t.cacheWrite)}`,
106
+ m.rows.tokens,
107
+ m.tokensValue(formatTokens(t.input), formatTokens(t.output), formatTokens(t.cacheRead), formatTokens(t.cacheWrite)),
105
108
  ],
106
109
  [
107
- "缓存命中率",
108
- `${percent(t.hitRate)}(报告缓存的端点 ${report.endpoints.reported}/${report.endpoints.total},其余不进分母)`,
110
+ m.rows.hitRate,
111
+ m.hitRateValue(percent(t.hitRate), report.endpoints.reported, report.endpoints.total),
109
112
  ],
110
- ["费用", costLine],
111
- ["错误 / 重试", `${t.errors} / ${t.retries}`],
113
+ [m.rows.cost, costLine],
114
+ ...(t.subscription !== undefined
115
+ ? [[m.rows.subscription, m.subscriptionValue(t.subscription)]]
116
+ : []),
117
+ [m.rows.errors, `${t.errors} / ${t.retries}`],
112
118
  ];
113
119
  lines.push(table(rows, () => false));
114
120
  if (report.groups !== undefined && report.groups.length > 0) {
115
- const head = ["", "会话", "请求", "回合", "输入", "输出", "缓存读", "缓存写", "命中率", "费用"];
121
+ const gh = m.groupHead;
122
+ const head = [
123
+ "",
124
+ gh.sessions,
125
+ gh.requests,
126
+ gh.turns,
127
+ gh.input,
128
+ gh.output,
129
+ gh.cacheRead,
130
+ gh.cacheWrite,
131
+ gh.hitRate,
132
+ gh.cost,
133
+ ];
116
134
  const body = report.groups.map((g) => [
117
135
  g.key,
118
136
  String(g.sessions),
@@ -128,7 +146,7 @@ export function renderStats(report, scope) {
128
146
  lines.push("", table([head, ...body], (i) => i > 0));
129
147
  }
130
148
  if (report.tools.length > 0) {
131
- lines.push("", `工具调用 Top ${report.tools.length}`);
149
+ lines.push("", m.topTools(report.tools.length));
132
150
  lines.push(table(report.tools.map((tool) => [` ${tool.name}`, String(tool.count)]), (i) => i > 0));
133
151
  }
134
152
  return lines.join("\n") + "\n";
@@ -136,24 +154,24 @@ export function renderStats(report, scope) {
136
154
  export async function runStats(argv, io) {
137
155
  const { positionals, values, flags } = parseSubArgs(argv, ["since", "until", "by", "project", "session-dir", "top"], ["all", "json", "no-cache"]);
138
156
  if (flags.has("help")) {
139
- io.stdout(STATS_USAGE);
157
+ io.stdout(statsUsage());
140
158
  return ExitCode.Ok;
141
159
  }
142
160
  if (positionals.length > 0)
143
- throw new UsageError(`ama stats 不接受位置参数:${positionals[0]}`);
161
+ throw new UsageError(msg().subcommands.stats.noPositionals(positionals[0] ?? ""));
144
162
  const now = new Date();
145
163
  const since = values.has("since") ? parseDaySpec("since", values.get("since"), now) : undefined;
146
164
  const until = values.has("until") ? parseDaySpec("until", values.get("until"), now) : undefined;
147
165
  const byRaw = values.get("by");
148
166
  if (byRaw !== undefined && !STATS_GROUPS.includes(byRaw)) {
149
- throw new UsageError(`--by 的取值应为 ${STATS_GROUPS.join(" | ")}(收到 ${byRaw})`);
167
+ throw new UsageError(msg().subcommands.common.invalidChoice("--by", STATS_GROUPS, byRaw));
150
168
  }
151
169
  const by = byRaw;
152
170
  const top = Number(values.get("top") ?? "10");
153
171
  if (!Number.isInteger(top) || top < 0)
154
- throw new UsageError("--top 应为非负整数");
172
+ throw new UsageError(msg().subcommands.stats.topNonNegative);
155
173
  if (flags.has("all") && values.has("project")) {
156
- throw new UsageError("--project 与 --all 不能同时使用");
174
+ throw new UsageError(msg().cli.args.flagConflict("--project", "--all"));
157
175
  }
158
176
  const dataDir = resolveDataDir({ env: io.env });
159
177
  const dirFlag = values.get("session-dir");
@@ -191,8 +209,9 @@ export async function runStats(argv, io) {
191
209
  }, null, 2) + "\n");
192
210
  return ExitCode.Ok;
193
211
  }
194
- io.stdout(renderStats(report, project === undefined ? "全部项目" : `项目 ${project}`));
212
+ const m = msg().subcommands.stats;
213
+ io.stdout(renderStats(report, project === undefined ? m.allProjects : m.project(project)));
195
214
  if (collected.invalid > 0)
196
- io.stderr(`ama: 跳过 ${collected.invalid} 个无法读取的会话文件\n`);
215
+ io.stderr(m.skippedInvalid(collected.invalid));
197
216
  return ExitCode.Ok;
198
217
  }
@@ -11,6 +11,7 @@ import { readFileSync, statSync } from "node:fs";
11
11
  import { isAbsolute, resolve } from "node:path";
12
12
  import { StartupError } from "../errors.js";
13
13
  import { ExitCode } from "./exit-codes.js";
14
+ import { msg } from "../i18n/index.js";
14
15
  export function resolveSystemPromptArg(value, mode, cwd) {
15
16
  if (value === undefined)
16
17
  return undefined;
@@ -24,11 +25,11 @@ export function resolveSystemPromptArg(value, mode, cwd) {
24
25
  text = readFileSync(path, "utf8");
25
26
  }
26
27
  catch {
27
- throw new StartupError("config_invalid", `--system-prompt 文件不存在:${path}`, ExitCode.Config);
28
+ throw new StartupError("config_invalid", msg().cli.systemPrompt.fileMissing(path), ExitCode.Config);
28
29
  }
29
30
  }
30
31
  text = text.trim();
31
32
  if (text === "")
32
- throw new StartupError("config_invalid", "--system-prompt 的内容为空", ExitCode.Config);
33
+ throw new StartupError("config_invalid", msg().cli.systemPrompt.empty, ExitCode.Config);
33
34
  return { text, mode: mode ?? "append" };
34
35
  }
@@ -13,6 +13,7 @@
13
13
  * `detectSandboxCapability()`(不经宿主 status);组装根先用 `configureOsSandbox` 记下 `sandbox.enabled`。
14
14
  */
15
15
  import { NO_OS_SANDBOX, osSandboxStatus } from "../sandbox/detect.js";
16
+ import { msg } from "../i18n/index.js";
16
17
  export const NETWORK_NOT_ISOLATED = "network not isolated";
17
18
  export function parseNodeMajor(version) {
18
19
  const major = Number.parseInt(version.replace(/^v/, "").split(".")[0] ?? "", 10);
@@ -72,12 +73,12 @@ export function codemodeAvailability(requireStrict, capability = detectSandboxCa
72
73
  return {
73
74
  available: false,
74
75
  capability,
75
- warning: `codemode 已禁用:Node ${capability.nodeMajor} 的权限模型不隔离网络,也没有可用的操作系统沙箱(${capability.os.detail};codemode.requireStrict 为 true;Node ≥ 25 或 macOS sandbox-exec / Linux bwrap 可隔离)`,
76
+ warning: msg().session.codemode.disabled(capability.nodeMajor, capability.os.detail),
76
77
  };
77
78
  }
78
79
  return {
79
80
  available: true,
80
81
  capability,
81
- warning: `codemode:Node ${capability.nodeMajor} 下网络未隔离(没有可用的操作系统沙箱:${capability.os.detail};要求隔离可设 codemode.requireStrict)`,
82
+ warning: msg().session.codemode.unisolated(capability.nodeMajor, capability.os.detail),
82
83
  };
83
84
  }
@@ -6,6 +6,7 @@
6
6
  * - 当前计划(最近一条未被拒绝 / 取代的 `ama.plan`:编号、状态、文件路径与步骤标题);
7
7
  * - 已加载的 Skill(用 `read` 读过的索引路径,或 `skill` 工具的调用);
8
8
  * - 最近修改 / 读取的文件路径(按最近使用排序,各至多 20 个);
9
+ * - [W6-M] 本会话读写过的记忆路径(`memory` 工具的 `/memories/…` 逻辑路径,只给路径不给正文);
9
10
  * - 完整转录与 `outputs/` 路径(模型需要细节时自己 `read`);
10
11
  * - 续接说明。
11
12
  *
@@ -6,6 +6,7 @@
6
6
  * - 当前计划(最近一条未被拒绝 / 取代的 `ama.plan`:编号、状态、文件路径与步骤标题);
7
7
  * - 已加载的 Skill(用 `read` 读过的索引路径,或 `skill` 工具的调用);
8
8
  * - 最近修改 / 读取的文件路径(按最近使用排序,各至多 20 个);
9
+ * - [W6-M] 本会话读写过的记忆路径(`memory` 工具的 `/memories/…` 逻辑路径,只给路径不给正文);
9
10
  * - 完整转录与 `outputs/` 路径(模型需要细节时自己 `read`);
10
11
  * - 续接说明。
11
12
  *
@@ -78,6 +79,7 @@ function fileActivity(input) {
78
79
  const read = new Map();
79
80
  const modified = new Map();
80
81
  const skills = new Map();
82
+ const memory = new Map();
81
83
  let order = 0;
82
84
  for (const entry of input.branch) {
83
85
  if (entry.type !== "message" || entry.message.role !== "assistant")
@@ -95,6 +97,11 @@ function fileActivity(input) {
95
97
  const path = block.arguments["path"];
96
98
  if (typeof path !== "string" || path === "")
97
99
  continue;
100
+ if (block.name === "memory") {
101
+ if (path.startsWith("/memories/"))
102
+ memory.set(clip(path), order);
103
+ continue;
104
+ }
98
105
  const abs = resolve(input.cwd, path);
99
106
  if (WRITE_TOOLS.has(block.name))
100
107
  modified.set(path, order);
@@ -109,7 +116,12 @@ function fileActivity(input) {
109
116
  for (const path of modified.keys())
110
117
  read.delete(path);
111
118
  const recent = (map) => [...map.entries()].sort((a, b) => b[1] - a[1]).map(([key]) => key);
112
- return { read: recent(read), modified: recent(modified), skills: recent(skills) };
119
+ return {
120
+ read: recent(read),
121
+ modified: recent(modified),
122
+ skills: recent(skills),
123
+ memory: recent(memory),
124
+ };
113
125
  }
114
126
  function capped(paths) {
115
127
  const shown = paths.slice(0, MAX_RECENT_FILES);
@@ -143,6 +155,8 @@ export function buildPostCompactContent(input) {
143
155
  parts.push(`<recently-modified-files>\n${capped(files.modified)}\n</recently-modified-files>`);
144
156
  if (files.read.length > 0)
145
157
  parts.push(`<recently-read-files>\n${capped(files.read)}\n</recently-read-files>`);
158
+ if (files.memory.length > 0)
159
+ parts.push(`<memory-files>\n${capped(files.memory)}\n</memory-files>`);
146
160
  if (input.transcriptPath !== undefined)
147
161
  parts.push(`<transcript>${input.transcriptPath}</transcript> (full history before compaction, JSONL; read it only if the summary lacks a detail you need)`);
148
162
  if (input.outputDir !== undefined)
@@ -9,7 +9,7 @@
9
9
  * 打断一次缓存。缓存已冷时(C3,调用方判断)`need` 为 undefined:全部候选一次换掉。
10
10
  * 保护集(C4):调用方给 `isProtected`(Skill 文件、AGENTS.md、todo、`keepInContext` 工具、
11
11
  * `compaction.pruneExclude`),见 `protect.ts`。
12
- * 动作:返回 `context_edit{reason:"prune", replacement:"[已裁剪 …全文 path]"}` 计划;有 outputDir 时
12
+ * 动作:返回 `context_edit{reason:"prune", replacement:"[pruned: … full text at path]"}` 计划([W6-C0] 固定英文);有 outputDir 时
13
13
  * 把全文写到 `<outputDir>/<toolCallId>.txt`(已存在则不覆盖),模型可用 read 取回。
14
14
  */
15
15
  import type { ContentBlock } from "../ai/types.js";
@@ -9,7 +9,7 @@
9
9
  * 打断一次缓存。缓存已冷时(C3,调用方判断)`need` 为 undefined:全部候选一次换掉。
10
10
  * 保护集(C4):调用方给 `isProtected`(Skill 文件、AGENTS.md、todo、`keepInContext` 工具、
11
11
  * `compaction.pruneExclude`),见 `protect.ts`。
12
- * 动作:返回 `context_edit{reason:"prune", replacement:"[已裁剪 …全文 path]"}` 计划;有 outputDir 时
12
+ * 动作:返回 `context_edit{reason:"prune", replacement:"[pruned: … full text at path]"}` 计划([W6-C0] 固定英文);有 outputDir 时
13
13
  * 把全文写到 `<outputDir>/<toolCallId>.txt`(已存在则不覆盖),模型可用 read 取回。
14
14
  */
15
15
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
@@ -114,8 +114,8 @@ function materialize(candidate, outputDir) {
114
114
  }
115
115
  }
116
116
  const replacement = fullTextPath === undefined
117
- ? `[已裁剪:${message.toolName} 的结果原有 ${bytes} 字节,全文不可用]`
118
- : `[已裁剪:${message.toolName} 的结果原有 ${bytes} 字节,全文 ${fullTextPath}]`;
117
+ ? `[pruned: ${message.toolName} result was ${bytes} bytes; full text unavailable]`
118
+ : `[pruned: ${message.toolName} result was ${bytes} bytes; full text at ${fullTextPath}]`;
119
119
  const planned = {
120
120
  targetId: entry.id,
121
121
  replacement,
@@ -9,7 +9,8 @@ export const TOOL_RESULT_SERIALIZE_LIMIT = 2000;
9
9
  function truncate(text, limit) {
10
10
  if (text.length <= limit)
11
11
  return text;
12
- return `${text.slice(0, limit)}… [截断,原 ${text.length} 字符]`;
12
+ // [W6-C0] 送摘要模型的文本,固定英文
13
+ return `${text.slice(0, limit)}… [truncated; ${text.length} chars originally]`;
13
14
  }
14
15
  function formatArgs(args) {
15
16
  return Object.entries(args)
@@ -7,6 +7,7 @@
7
7
  * 也不把 key 写进任何日志或返回给展示层(`describeAuthFile` 只给来源与形态)。
8
8
  */
9
9
  import type { AuthFile } from "./types.js";
10
+ import { type ChatGptFlavor } from "./types-w6.js";
10
11
  export declare function defaultAuthFilePath(configDir: string): string;
11
12
  export declare const PROVIDER_ID_PATTERN: RegExp;
12
13
  export interface ReadAuthResult {
@@ -32,8 +33,17 @@ export type AuthValueKind = "literal" | "command" | "env-ref";
32
33
  export declare function classifyKeyValue(value: string): AuthValueKind;
33
34
  export interface AuthEntrySummary {
34
35
  provider: string;
35
- kind: AuthValueKind;
36
+ /** `oauth`:OAuth 条目(只给 flavor / plan / expiresIn / needsLogin,从不给 token、邮箱、账户 id)。 */
37
+ kind: AuthValueKind | "oauth";
36
38
  hasBaseUrl: boolean;
37
39
  envNames: string[];
40
+ /** [W6-O] OAuth 条目:登录路径。 */
41
+ flavor?: ChatGptFlavor;
42
+ /** [W6-O] OAuth 条目:计划类型(plus / pro …)。 */
43
+ plan?: string;
44
+ /** [W6-O] OAuth 条目:access token 剩余毫秒(已过期为负;刷新会自动续)。 */
45
+ expiresIn?: number;
46
+ /** [W6-O] OAuth 条目:刷新永久失败,需要重新登录。 */
47
+ needsLogin?: boolean;
38
48
  }
39
- export declare function describeAuthFile(file: AuthFile): AuthEntrySummary[];
49
+ export declare function describeAuthFile(file: AuthFile, now?: number): AuthEntrySummary[];
@@ -10,7 +10,9 @@ import { chmodSync, mkdirSync, renameSync, statSync, writeFileSync } from "node:
10
10
  import { dirname, join } from "node:path";
11
11
  import { loadConfigFile } from "./load.js";
12
12
  import { AUTH_FILE } from "./paths.js";
13
- import { CONFIG_FILE_VERSION } from "./types.js";
13
+ import { CONFIG_FILE_VERSION, apiKeyEntry } from "./types.js";
14
+ import { isOAuthEntry } from "./types-w6.js";
15
+ import { msg } from "../i18n/index.js";
14
16
  export function defaultAuthFilePath(configDir) {
15
17
  return join(configDir, AUTH_FILE);
16
18
  }
@@ -41,7 +43,7 @@ export function readAuthFile(path) {
41
43
  const warnings = [...loaded.warnings];
42
44
  const mode = fileMode(path);
43
45
  if (isModeTooOpen(mode)) {
44
- warnings.push(`${path}: 权限为 ${mode?.toString(8).padStart(4, "0")},应为 0600(chmod 600 ${path})`);
46
+ warnings.push(msg().config.authFile.modeTooOpen(path, mode?.toString(8).padStart(4, "0") ?? ""));
45
47
  }
46
48
  const result = { path, exists: true, file: loaded.value, warnings };
47
49
  if (mode !== undefined && process.platform !== "win32")
@@ -59,7 +61,8 @@ export function writeAuthFile(path, file) {
59
61
  /** `ama auth set`:设置 / 替换一家的 key(保留该条目的 env / baseUrl)。 */
60
62
  export function setAuthKey(path, provider, apiKey) {
61
63
  const { file } = readAuthFile(path);
62
- const previous = file.providers[provider];
64
+ // [W6-C0] 覆盖 OAuth 条目时不带走它的字段
65
+ const previous = apiKeyEntry(file.providers[provider]);
63
66
  file.providers[provider] = { ...previous, apiKey };
64
67
  writeAuthFile(path, { version: CONFIG_FILE_VERSION, providers: file.providers });
65
68
  }
@@ -80,13 +83,32 @@ export function classifyKeyValue(value) {
80
83
  return "env-ref";
81
84
  return "literal";
82
85
  }
83
- export function describeAuthFile(file) {
86
+ export function describeAuthFile(file, now = Date.now()) {
84
87
  return Object.entries(file.providers)
85
- .map(([provider, entry]) => ({
86
- provider,
87
- kind: classifyKeyValue(entry.apiKey),
88
- hasBaseUrl: entry.baseUrl !== undefined,
89
- envNames: Object.keys(entry.env ?? {}).sort(),
90
- }))
88
+ .map(([provider, raw]) => {
89
+ if (isOAuthEntry(raw)) {
90
+ const summary = {
91
+ provider,
92
+ kind: "oauth",
93
+ hasBaseUrl: false,
94
+ envNames: [],
95
+ flavor: raw.flavor,
96
+ expiresIn: raw.expiresAt - now,
97
+ needsLogin: raw.needsLogin === true,
98
+ };
99
+ if (raw.planType !== undefined)
100
+ summary.plan = raw.planType;
101
+ return summary;
102
+ }
103
+ const entry = apiKeyEntry(raw);
104
+ if (entry === undefined)
105
+ return { provider, kind: "oauth", hasBaseUrl: false, envNames: [] };
106
+ return {
107
+ provider,
108
+ kind: classifyKeyValue(entry.apiKey),
109
+ hasBaseUrl: entry.baseUrl !== undefined,
110
+ envNames: Object.keys(entry.env ?? {}).sort(),
111
+ };
112
+ })
91
113
  .sort((a, b) => a.provider.localeCompare(b.provider));
92
114
  }