@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
@@ -26,8 +26,14 @@ import { ExitCode } from "../exit-codes.js";
26
26
  import { describeProxy, inspectProxy } from "../proxy.js";
27
27
  import { describeCodemode, describeModel } from "./config.js";
28
28
  import { buildRegistry, loadUserLevel } from "./context.js";
29
- export const DOCTOR_USAGE = `用法:ama doctor [--profile <文件>] [--auth-file <文件>] [--trust | --no-trust]
30
- `;
29
+ import { apiKeyEntry } from "../../config/types-w6.js";
30
+ import { oauthDoctorLines } from "../../auth/chatgpt/doctor.js";
31
+ import { readOAuthEntry } from "../../auth/oauth/token-store.js";
32
+ import { getLocale, msg, resolveLocaleWithSource } from "../../i18n/index.js";
33
+ /** 用法(随界面语言)。 */
34
+ export function doctorUsage() {
35
+ return msg().report.doctor.usage;
36
+ }
31
37
  class Report {
32
38
  lines = [];
33
39
  problems = 0;
@@ -50,24 +56,25 @@ class Report {
50
56
  function probeLine(report, label, kind, path) {
51
57
  const probe = probeConfigFile(kind, path);
52
58
  if (!probe.exists) {
53
- report.item(`${label}:${path}(不存在)`);
59
+ report.item(msg().report.doctor.missing(label, path));
54
60
  return;
55
61
  }
56
62
  if (!probe.ok) {
57
- report.problem(`${label}:${probe.messages.join("; ")}`);
63
+ report.problem(msg().report.doctor.labeled(label, probe.messages.join("; ")));
58
64
  return;
59
65
  }
60
- report.item(`${label}:${path}`);
66
+ report.item(msg().report.doctor.labeled(label, path));
61
67
  for (const message of probe.messages)
62
- report.item(` 警告:${message}`);
68
+ report.item(` ${msg().report.doctor.warning(message)}`);
63
69
  }
64
70
  function trustSection(report, io, level, flag) {
65
- report.section("信任");
71
+ const m = msg().report.doctor;
72
+ report.section(m.trustTitle);
66
73
  let trusted = false;
67
74
  let from;
68
75
  if (flag !== undefined) {
69
76
  trusted = flag;
70
- from = "命令行";
77
+ from = m.fromCli;
71
78
  }
72
79
  else if (level.profile?.trustProject === true) {
73
80
  trusted = true;
@@ -77,33 +84,34 @@ function trustSection(report, io, level, flag) {
77
84
  try {
78
85
  const entry = findTrustEntry(readTrustFile(level.configDir).entries, io.cwd);
79
86
  trusted = entry?.trusted ?? false;
80
- from = entry === undefined ? "缺省:无记录,交互模式会询问" : `trust.json ${entry.path}`;
87
+ from = entry === undefined ? m.noRecord : `trust.json ${entry.path}`;
81
88
  }
82
89
  catch (error) {
83
90
  report.problem(error.message);
84
- from = "trust.json 无效";
91
+ from = m.trustInvalid;
85
92
  }
86
93
  }
87
- report.item(`${io.cwd}:${trusted ? "已信任" : "未信任"}(${from})`);
94
+ report.item(m.trust(io.cwd, trusted, from));
88
95
  const gated = trustGatedResources(io.cwd);
89
96
  if (gated.length > 0) {
90
- report.item(`需要信任的资源${trusted ? "" : "(当前不加载)"}:`);
97
+ report.item(m.gated(trusted));
91
98
  for (const path of gated)
92
99
  report.item(` ${path}`);
93
100
  }
94
101
  return trusted;
95
102
  }
96
103
  async function keySection(report, io, level, deps) {
97
- report.section("Key 来源(只显示来源,不显示值)");
104
+ const m = msg().report.doctor;
105
+ report.section(m.keysTitle);
98
106
  try {
99
107
  const auth = readAuthFile(level.authFile);
100
108
  const mode = fileMode(level.authFile);
101
109
  if (!auth.exists)
102
- report.item(`auth.json:${level.authFile}(不存在)`);
110
+ report.item(m.missing("auth.json", level.authFile));
103
111
  else if (isModeTooOpen(mode))
104
- report.problem(`auth.json 权限 ${mode?.toString(8)},应为 600:${level.authFile}`);
112
+ report.problem(m.authMode(mode?.toString(8) ?? "?", level.authFile));
105
113
  else
106
- report.item(`auth.json:${level.authFile}`);
114
+ report.item(m.labeled("auth.json", level.authFile));
107
115
  }
108
116
  catch (error) {
109
117
  report.problem(error.message);
@@ -112,29 +120,44 @@ async function keySection(report, io, level, deps) {
112
120
  try {
113
121
  const registry = await buildRegistry(level, io, deps);
114
122
  for (const provider of registry.list()) {
123
+ // [W6-O] OAuth 条目:只读文件,不刷新 token
124
+ const oauth = readOAuthEntry(level.authFile, provider.id);
125
+ if (oauth !== undefined) {
126
+ const lines = await oauthDoctorLines(provider.id, oauth, {
127
+ env: io.env,
128
+ config: level.merged.config.auth?.chatgpt,
129
+ });
130
+ report.item(`${provider.id.padEnd(20)} ${lines.line}`);
131
+ if (lines.quota !== undefined)
132
+ report.item(`${"".padEnd(20)} ${lines.quota}`);
133
+ if (lines.problem !== undefined)
134
+ report.problem(lines.problem);
135
+ continue;
136
+ }
115
137
  const key = await registry.resolveApiKey(provider.id);
116
138
  const text = key.apiKey !== undefined
117
- ? `${key.source}${key.origin !== undefined ? `(${key.origin})` : ""}`
139
+ ? m.keySource(key.source, key.origin)
118
140
  : provider.requiresApiKey
119
- ? "无"
120
- : "无需";
141
+ ? m.none
142
+ : m.notNeeded;
121
143
  report.item(`${provider.id.padEnd(20)} ${text}`);
122
144
  const env = baseUrlEnvOf(registry, provider.id);
123
145
  if (env !== undefined)
124
- report.item(`${"".padEnd(20)} baseUrl 来自环境变量 ${env}:${provider.baseUrl}(compat 按保守缺省)`);
146
+ report.item(`${"".padEnd(20)} ${m.baseUrlEnv(env, provider.baseUrl)}`);
125
147
  }
126
148
  const model = await describeModel(level.merged.config, registry);
127
- report.item(`将使用的模型:${model.ref ?? "(无)"}(${model.reason})`);
149
+ report.item(m.model(model.ref, model.reason));
128
150
  return;
129
151
  }
130
152
  catch (error) {
131
- report.problem(`供应商注册表:${error.message}`);
153
+ report.problem(m.registry(error.message));
132
154
  }
133
155
  }
134
156
  // 未装配注册表:按文件与环境变量名列出能看到的来源。
135
157
  try {
136
158
  for (const [id, entry] of Object.entries(readAuthFile(level.authFile).file.providers)) {
137
- report.item(`${id.padEnd(20)} auth-file(${classifyKeyValue(entry.apiKey)})`);
159
+ const key = apiKeyEntry(entry)?.apiKey;
160
+ report.item(`${id.padEnd(20)} ${m.keySource("auth-file", key === undefined ? "oauth" : classifyKeyValue(key))}`);
138
161
  }
139
162
  }
140
163
  catch {
@@ -142,16 +165,17 @@ async function keySection(report, io, level, deps) {
142
165
  }
143
166
  for (const [id, provider] of Object.entries(level.merged.config.providers ?? {})) {
144
167
  if (provider.apiKey !== undefined) {
145
- report.item(`${id.padEnd(20)} config(${classifyKeyValue(provider.apiKey)})`);
168
+ report.item(`${id.padEnd(20)} ${m.keySource("config", classifyKeyValue(provider.apiKey))}`);
146
169
  }
147
170
  }
148
171
  const envNames = Object.keys(io.env)
149
172
  .filter((n) => /_API_KEY$/.test(n) || n.startsWith("AMA_API_KEY_"))
150
173
  .filter((n) => (io.env[n] ?? "") !== "")
151
174
  .sort();
152
- report.item(`环境变量:${envNames.length > 0 ? envNames.join(", ") : "(无)"}`);
175
+ report.item(m.envVars(envNames));
153
176
  }
154
177
  function hookSection(report, io, level, trusted) {
178
+ const m = msg().report.doctor;
155
179
  report.section("Hook");
156
180
  try {
157
181
  const hooks = loadHookConfigs({
@@ -162,13 +186,13 @@ function hookSection(report, io, level, trusted) {
162
186
  defaultTimeoutMs: level.merged.config.hooks?.timeoutMs,
163
187
  });
164
188
  if (hooks.hooks.length === 0)
165
- report.item("(无)");
189
+ report.item(m.empty);
166
190
  for (const hook of hooks.hooks) {
167
191
  const matcher = hook.matcher !== undefined ? ` [${hook.matcher}]` : "";
168
- report.item(`${hook.source.padEnd(7)} ${hook.event}${matcher} → ${hook.command}(${hook.timeoutMs} ms)`);
192
+ report.item(`${hook.source.padEnd(7)} ${hook.event}${matcher} → ${m.hookCommand(hook.command, hook.timeoutMs)}`);
169
193
  }
170
194
  if (hooks.skippedProject !== undefined) {
171
- report.item(`未信任,跳过:${hooks.skippedProject}`);
195
+ report.item(m.hookSkipped(hooks.skippedProject));
172
196
  }
173
197
  }
174
198
  catch (error) {
@@ -176,22 +200,34 @@ function hookSection(report, io, level, trusted) {
176
200
  }
177
201
  }
178
202
  function terminalSection(report, io) {
179
- report.section("终端");
203
+ const m = msg().report.doctor;
204
+ report.section(m.terminalTitle);
180
205
  const env = io.env;
181
- report.item(`stdin TTY:${io.stdinIsTTY ? "是" : "否"} · stdout TTY:${io.stdoutIsTTY ? "是" : "否"}`);
182
- report.item(`TERM=${env["TERM"] ?? "(未设置)"} · COLORTERM=${env["COLORTERM"] ?? "(未设置)"}`);
206
+ report.item(m.tty(io.stdinIsTTY, io.stdoutIsTTY));
207
+ report.item(m.term(env["TERM"], env["COLORTERM"]));
183
208
  if (env["NO_COLOR"] !== undefined)
184
- report.item("NO_COLOR 已设置:不输出颜色");
209
+ report.item(m.noColor);
185
210
  if (env["TMUX"] !== undefined)
186
- report.item("在 tmux 中运行");
211
+ report.item(m.tmux);
187
212
  const columns = process.stdout.columns;
188
213
  if (io.stdoutIsTTY && columns !== undefined)
189
- report.item(`尺寸:${columns}×${process.stdout.rows}`);
214
+ report.item(m.size(columns, process.stdout.rows));
190
215
  const tui = io.stdinIsTTY && io.stdoutIsTTY && env["TERM"] !== "dumb";
191
- report.item(`缺省界面:${tui ? "终端界面" : "行式(--no-tui 等价)"}`);
216
+ report.item(m.defaultUi(tui));
217
+ }
218
+ /** [W6-I3] 「界面语言:zh(来源 LANG=zh_CN.UTF-8)」;按环境与配置重算,与实际语言不同时说明来自 --lang。 */
219
+ function languageLine(report, io, level) {
220
+ const m = msg().report.doctor;
221
+ const language = level.profile?.language ?? level.merged.config.ui?.language;
222
+ const found = resolveLocaleWithSource(io.env, { language });
223
+ const locale = getLocale();
224
+ const source = found.locale === locale ? found.source : { kind: "cli" };
225
+ const name = source.kind === "env" || source.kind === "locale" ? source.name : undefined;
226
+ const value = source.kind === "env" || source.kind === "locale" ? source.value : undefined;
227
+ report.item(m.language(locale, m.languageSource(source.kind, name, value)));
192
228
  }
193
229
  function proxySection(report, io) {
194
- report.section("代理");
230
+ report.section(msg().report.doctor.proxyTitle);
195
231
  for (const line of describeProxy(inspectProxy(io.env)))
196
232
  report.item(line);
197
233
  }
@@ -200,17 +236,18 @@ async function fileHistoryLine(report, dataDir) {
200
236
  try {
201
237
  const usage = await blobUsage(dataDir);
202
238
  const shadow = await shadowUsage(dataDir);
203
- const shadowText = shadow.repos === 0 ? "" : `;影子仓库 ${shadow.repos} 个,${formatBytes(shadow.bytes)}`;
204
- report.item(`file-history:${usage.blobs} 个备份,${formatBytes(usage.bytes)}${shadowText}(${fileHistoryDir(dataDir)};ama sessions prune 清理)`);
239
+ const m = msg().report.doctor;
240
+ const shadowText = shadow.repos === 0 ? undefined : m.shadowRepos(shadow.repos, formatBytes(shadow.bytes));
241
+ report.item(m.fileHistory(usage.blobs, formatBytes(usage.bytes), shadowText, fileHistoryDir(dataDir)));
205
242
  }
206
243
  catch (error) {
207
- report.item(`file-history:读取失败(${error.message})`);
244
+ report.item(msg().report.doctor.fileHistoryFailed(error.message));
208
245
  }
209
246
  }
210
247
  export async function runDoctor(argv, io, deps) {
211
248
  const { values, flags } = parseSubArgs(argv, ["profile", "auth-file"], ["trust", "no-trust"]);
212
249
  if (flags.has("help")) {
213
- io.stdout(DOCTOR_USAGE);
250
+ io.stdout(doctorUsage());
214
251
  return ExitCode.Ok;
215
252
  }
216
253
  const report = new Report();
@@ -227,52 +264,54 @@ export async function runDoctor(argv, io, deps) {
227
264
  io.stdout(report.text());
228
265
  return ExitCode.Config;
229
266
  }
230
- report.section("目录");
231
- report.item(`配置目录:${level.configDir}`);
232
- report.item(`数据目录:${level.dataDir}${existsSync(level.dataDir) ? "" : "(尚未创建)"}`);
267
+ const m = msg().report.doctor;
268
+ report.section(m.dirsTitle);
269
+ report.item(m.configDir(level.configDir));
270
+ report.item(m.dataDir(level.dataDir, existsSync(level.dataDir)));
233
271
  await fileHistoryLine(report, level.dataDir);
234
- report.section("配置层级(缺省 ← 用户级 ← profile ← 项目级(只能收紧)← 命令行)");
235
- report.item("缺省:内置");
236
- probeLine(report, "用户级", "config", level.userConfigPath);
272
+ report.section(m.layersTitle);
273
+ report.item(m.builtinDefaults);
274
+ probeLine(report, m.userLevel, "config", level.userConfigPath);
237
275
  if (level.profile !== undefined) {
238
- report.item(`profile:${level.profile.path}`);
276
+ report.item(m.labeled("profile", level.profile.path));
239
277
  if (level.profile.configFile !== undefined)
240
278
  probeLine(report, "profile.config", "config", level.profile.configFile);
241
279
  }
242
280
  const projectPath = projectFile(io.cwd, CONFIG_FILE);
243
- probeLine(report, "项目级", "config", projectPath);
281
+ probeLine(report, m.projectLevel, "config", projectPath);
244
282
  try {
245
283
  const project = loadConfigFile("config", projectPath);
246
284
  const merged = mergeProjectAndCli(level.merged, project?.value, undefined);
247
285
  for (const warning of merged.warnings)
248
- report.item(` 收紧:${warning}`);
249
- report.item(`有效权限模式:${merged.config.permission?.mode ?? "default"}`);
286
+ report.item(m.tightened(warning));
287
+ report.item(m.permissionMode(merged.config.permission?.mode ?? "default"));
250
288
  const codemode = describeCodemode(merged.config);
251
- report.item(`codemode:${codemode.mode}(${codemode.reason})`);
289
+ report.item(m.codemode(codemode.mode, codemode.reason));
252
290
  if (codemode.unavailable !== undefined)
253
291
  report.item(` ${codemode.unavailable}`);
254
292
  const os = osSandboxStatus(merged.config.sandbox?.enabled ?? "auto");
255
- report.item(`操作系统沙箱:${os.kind === "none" ? "无" : os.kind}(${os.detail}${os.kind !== "none" && !os.restrictsWrites ? ";只隔离网络" : ""})`);
256
- report.item(`bash 沙箱:${resolveBashSandbox(merged.config.sandbox, { status: os }).detail}`);
293
+ report.item(m.osSandbox(os.kind, os.detail, os.kind !== "none" && !os.restrictsWrites));
294
+ report.item(m.bashSandbox(resolveBashSandbox(merged.config.sandbox, { status: os }).detail));
257
295
  }
258
296
  catch {
259
297
  // probeLine 已报告
260
298
  }
261
299
  for (const warning of level.warnings)
262
- report.item(`警告:${warning}`);
300
+ report.item(m.warning(warning));
263
301
  const flag = flags.has("trust") ? true : flags.has("no-trust") ? false : undefined;
264
302
  const trusted = trustSection(report, io, level, flag);
265
- report.section("上下文文件(AGENTS.md,外层在前)");
303
+ report.section(m.contextTitle);
266
304
  const context = findContextFiles({ cwd: io.cwd, configDir: level.configDir });
267
305
  if (context.files.length === 0)
268
- report.item("(无)");
306
+ report.item(m.empty);
269
307
  for (const file of context.files)
270
- report.item(`${file.scope === "user" ? "用户级" : "项目"} ${file.path}`);
308
+ report.item(`${file.scope === "user" ? m.contextUser : m.contextProject} ${file.path}`);
271
309
  await keySection(report, io, level, deps);
272
310
  hookSection(report, io, level, trusted);
273
- report.item(`用户级 hooks.json:${userFile(level, HOOKS_FILE)}`);
311
+ report.item(m.userHooks(userFile(level, HOOKS_FILE)));
274
312
  proxySection(report, io);
275
313
  terminalSection(report, io);
314
+ languageLine(report, io, level);
276
315
  io.stdout(report.text());
277
316
  return report.problems > 0 ? ExitCode.Config : ExitCode.Ok;
278
317
  }
@@ -2,5 +2,5 @@
2
2
  * `ama init [--force]`(docs/providers.md「配置目录」):建配置目录与缺省文件,逐个报告状态。
3
3
  */
4
4
  import type { CliIo } from "../deps.js";
5
- export declare const INIT_USAGE = "\u7528\u6CD5\uFF1Aama init [--force] \u5EFA\u914D\u7F6E\u76EE\u5F55\uFF080700\uFF09\u4E0E config.json\u3001config.schema.json\n \u5DF2\u6709\u7684 config.json \u4E0D\u8986\u76D6\uFF08--force \u5148\u5907\u4EFD\u4E3A .bak \u518D\u91CD\u5199\uFF09\uFF1B\u4E0D\u521B\u5EFA auth.json\n";
5
+ export declare function initUsage(): string;
6
6
  export declare function runInit(argv: readonly string[], io: CliIo): number;
@@ -1,23 +1,24 @@
1
1
  /**
2
2
  * `ama init [--force]`(docs/providers.md「配置目录」):建配置目录与缺省文件,逐个报告状态。
3
3
  */
4
- import { INIT_NEXT_STEPS, describeInit, initConfigDir } from "../../config/init.js";
4
+ import { describeInit, initConfigDir, initNextSteps } from "../../config/init.js";
5
5
  import { resolveConfigDir } from "../../config/paths.js";
6
6
  import { parseSubArgs, UsageError } from "../args.js";
7
7
  import { ExitCode } from "../exit-codes.js";
8
- export const INIT_USAGE = `用法:ama init [--force] 建配置目录(0700)与 config.json、config.schema.json
9
- 已有的 config.json 不覆盖(--force 先备份为 .bak 再重写);不创建 auth.json
10
- `;
8
+ import { msg } from "../../i18n/index.js";
9
+ export function initUsage() {
10
+ return msg().subcommands.init.usage;
11
+ }
11
12
  export function runInit(argv, io) {
12
13
  const { positionals, flags } = parseSubArgs(argv, [], ["force"]);
13
14
  if (flags.has("help")) {
14
- io.stdout(INIT_USAGE);
15
+ io.stdout(initUsage());
15
16
  return ExitCode.Ok;
16
17
  }
17
18
  if (positionals.length > 0)
18
- throw new UsageError(`多余的参数:${positionals.join(" ")}`);
19
+ throw new UsageError(msg().subcommands.common.extraArgs(positionals.join(" ")));
19
20
  const result = initConfigDir(resolveConfigDir({ env: io.env }), { force: flags.has("force") });
20
21
  io.stdout(describeInit(result));
21
- io.stdout(`\n${INIT_NEXT_STEPS.join("\n")}\n`);
22
+ io.stdout(`\n${initNextSteps().join("\n")}\n`);
22
23
  return ExitCode.Ok;
23
24
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `ama memory list|show|edit|rm|path|enable|disable`(docs/wave6-plan.md §3.5)。[W6-M]
3
+ *
4
+ * - 作用域按用户级配置(`memory.scopes`,缺省 user + project);项目作用域以 cwd 定位,需项目已受信任
5
+ * (trust.json 记录),否则跳过并提示。`memory.enabled` 为 false 时照样能看、能改(条目保留但不使用)。
6
+ * - `list` / `show` / `path` 只读;`edit` 在 `$EDITOR` 里改副本,存回时同样查凭据与上限;`rm` 在终端里确认,
7
+ * 非终端需 `--yes`。
8
+ * - `enable` / `disable` 经 `config/edit.ts`(W6-S)改用户级 `config.json` 的 `memory.enabled`(校验、原子写 + `.bak`)。
9
+ */
10
+ import { type EditText } from "../../memory/edit.js";
11
+ import type { CliIo } from "../deps.js";
12
+ export interface MemoryCliDeps {
13
+ /** 测试注入:代替真实编辑器。 */
14
+ edit?: EditText;
15
+ /** 测试注入:终端里的删除确认。 */
16
+ confirm?(question: string): Promise<boolean>;
17
+ }
18
+ export declare function runMemory(argv: readonly string[], io: CliIo, deps?: MemoryCliDeps): Promise<number>;
@@ -0,0 +1,189 @@
1
+ /**
2
+ * `ama memory list|show|edit|rm|path|enable|disable`(docs/wave6-plan.md §3.5)。[W6-M]
3
+ *
4
+ * - 作用域按用户级配置(`memory.scopes`,缺省 user + project);项目作用域以 cwd 定位,需项目已受信任
5
+ * (trust.json 记录),否则跳过并提示。`memory.enabled` 为 false 时照样能看、能改(条目保留但不使用)。
6
+ * - `list` / `show` / `path` 只读;`edit` 在 `$EDITOR` 里改副本,存回时同样查凭据与上限;`rm` 在终端里确认,
7
+ * 非终端需 `--yes`。
8
+ * - `enable` / `disable` 经 `config/edit.ts`(W6-S)改用户级 `config.json` 的 `memory.enabled`(校验、原子写 + `.bak`)。
9
+ */
10
+ import { loadConfigFile } from "../../config/load.js";
11
+ import { CONFIG_FILE, resolveConfigDir, resolveDataDir, userFile } from "../../config/paths.js";
12
+ import { findTrustEntry, readTrustFile } from "../../config/trust.js";
13
+ import { ConfigEditError, setConfigValue } from "../../config/edit.js";
14
+ import { msg } from "../../i18n/index.js";
15
+ import { editMemory } from "../../memory/edit.js";
16
+ import { logicalPath, projectRootOf, standaloneRoots, } from "../../memory/paths.js";
17
+ import { findOne, listText, memoryErrorText, scopeSummaries } from "../../memory/report.js";
18
+ import { DEFAULT_MEMORY_LIMITS, MemoryStore } from "../../memory/store.js";
19
+ import { editExternally } from "../../modes/interactive/external-editor.js";
20
+ import { parseSubArgs, UsageError } from "../args.js";
21
+ import { confirmContinue } from "../choice-prompt.js";
22
+ import { ExitCode } from "../exit-codes.js";
23
+ function load(io) {
24
+ const configDir = resolveConfigDir({ env: io.env });
25
+ const dataDir = resolveDataDir({ env: io.env });
26
+ const configPath = userFile({ configDir }, CONFIG_FILE);
27
+ const memory = loadConfigFile("config", configPath)?.value.memory ?? {};
28
+ const scopes = memory.scopes ?? ["user", "project"];
29
+ const notes = [];
30
+ let projectRoot;
31
+ if (scopes.includes("project")) {
32
+ const trusted = findTrustEntry(readTrustFile(configDir).entries, io.cwd)?.trusted === true;
33
+ if (trusted)
34
+ projectRoot = projectRootOf(io.cwd);
35
+ else
36
+ notes.push(msg().memory.cli.untrusted(io.cwd));
37
+ }
38
+ if (memory.enabled !== true)
39
+ notes.push(msg().memory.cli.disabledNote);
40
+ const roots = standaloneRoots({ dataDir, projectRoot, user: scopes.includes("user") });
41
+ const limits = {
42
+ indexMaxBytes: memory.indexMaxBytes ?? DEFAULT_MEMORY_LIMITS.indexMaxBytes,
43
+ fileMaxBytes: memory.fileMaxBytes ?? DEFAULT_MEMORY_LIMITS.fileMaxBytes,
44
+ maxFiles: memory.maxFiles ?? DEFAULT_MEMORY_LIMITS.maxFiles,
45
+ };
46
+ const store = new MemoryStore(roots, limits, projectRoot === undefined ? {} : { projectRoot });
47
+ return { store, notes };
48
+ }
49
+ function scopeFilter(store, raw) {
50
+ if (raw === undefined || raw === "all")
51
+ return store.scopes();
52
+ if (raw !== "user" && raw !== "project")
53
+ throw new UsageError(msg().memory.cli.unknownScope(raw));
54
+ return store.scopes().filter((s) => s === raw);
55
+ }
56
+ /** 改用户级 `memory.enabled`(W6-S 的编辑核心:写前重读、只改这一项、校验、原子写 + `.bak`)。 */
57
+ function setEnabled(io, enabled) {
58
+ const m = msg().memory.cli;
59
+ try {
60
+ const result = setConfigValue({
61
+ configDir: resolveConfigDir({ env: io.env }),
62
+ cwd: io.cwd,
63
+ env: io.env,
64
+ scope: "user",
65
+ key: "memory.enabled",
66
+ value: enabled,
67
+ });
68
+ io.stdout(`${enabled ? m.enabled(result.path) : m.disabled(result.path)}\n`);
69
+ return ExitCode.Ok;
70
+ }
71
+ catch (error) {
72
+ if (!(error instanceof ConfigEditError))
73
+ throw error;
74
+ io.stderr(`${error.message}\n`);
75
+ return ExitCode.Config;
76
+ }
77
+ }
78
+ export async function runMemory(argv, io, deps = {}) {
79
+ const m = msg().memory;
80
+ const { positionals, values, flags } = parseSubArgs(argv, ["scope"], ["json", "yes"]);
81
+ const [sub, ...rest] = positionals;
82
+ if (flags.has("help") || sub === undefined) {
83
+ io.stdout(m.cli.usage);
84
+ return sub === undefined && !flags.has("help") ? ExitCode.Usage : ExitCode.Ok;
85
+ }
86
+ const ctx = load(io);
87
+ const { store } = ctx;
88
+ const name = rest.join(" ");
89
+ const notes = () => {
90
+ for (const note of ctx.notes)
91
+ io.stderr(`${note}\n`);
92
+ };
93
+ try {
94
+ switch (sub) {
95
+ case "list": {
96
+ const scopes = scopeFilter(store, values.get("scope"));
97
+ if (flags.has("json")) {
98
+ const out = scopeSummaries(store, scopes).map((s) => ({
99
+ scope: s.scope,
100
+ path: logicalPath(s.scope),
101
+ dir: store.root(s.scope),
102
+ indexBytes: s.indexBytes,
103
+ omitted: s.omitted,
104
+ entries: s.entries,
105
+ }));
106
+ io.stdout(`${JSON.stringify(out, null, 2)}\n`);
107
+ }
108
+ else
109
+ io.stdout(`${listText(store, { scopes })}\n`);
110
+ notes();
111
+ return ExitCode.Ok;
112
+ }
113
+ case "path": {
114
+ for (const scope of scopeFilter(store, values.get("scope")))
115
+ io.stdout(`${scope}\t${store.root(scope) ?? ""}\n`);
116
+ notes();
117
+ return ExitCode.Ok;
118
+ }
119
+ case "show": {
120
+ if (name === "")
121
+ throw new UsageError(m.cli.needName(sub));
122
+ const found = findOne(store, name);
123
+ if (!found.ok) {
124
+ io.stderr(`${found.message}\n`);
125
+ return ExitCode.Usage;
126
+ }
127
+ io.stdout(`${(store.readRaw(found.entry) ?? "").trimEnd()}\n`);
128
+ return ExitCode.Ok;
129
+ }
130
+ case "edit": {
131
+ const scope = values.get("scope");
132
+ const target = name !== "" ? name : scope === undefined ? undefined : scopeFilter(store, scope)[0];
133
+ const edit = deps.edit ??
134
+ ((text, file) => editExternally(text, file, {
135
+ env: io.env,
136
+ suspend: () => undefined,
137
+ resume: () => undefined,
138
+ }));
139
+ const outcome = await editMemory(store, target, edit);
140
+ if (outcome.status === "not_found") {
141
+ io.stderr(`${outcome.message}\n`);
142
+ return ExitCode.Usage;
143
+ }
144
+ io.stdout(`${outcome.status === "saved"
145
+ ? m.command.saved(outcome.path)
146
+ : outcome.status === "cancelled"
147
+ ? m.command.editCancelled
148
+ : m.command.unchanged}\n`);
149
+ return ExitCode.Ok;
150
+ }
151
+ case "rm": {
152
+ if (name === "")
153
+ throw new UsageError(m.cli.needName(sub));
154
+ const found = findOne(store, name);
155
+ if (!found.ok) {
156
+ io.stderr(`${found.message}\n`);
157
+ return ExitCode.Usage;
158
+ }
159
+ const path = logicalPath(found.entry.scope, found.entry.file);
160
+ if (!flags.has("yes")) {
161
+ if (!io.stdinIsTTY && deps.confirm === undefined) {
162
+ io.stderr(`${m.cli.needsYes}\n`);
163
+ return ExitCode.Usage;
164
+ }
165
+ const question = m.cli.confirmRemove(path);
166
+ const ok = await (deps.confirm ?? ((q) => confirmContinue({ question: q, env: io.env })))(question);
167
+ if (!ok)
168
+ return ExitCode.Ok;
169
+ }
170
+ await store.remove(found.entry);
171
+ io.stdout(`${m.command.deleted(path)}\n`);
172
+ return ExitCode.Ok;
173
+ }
174
+ case "enable":
175
+ case "disable":
176
+ return setEnabled(io, sub === "enable");
177
+ default:
178
+ throw new UsageError(m.cli.usage.trimEnd());
179
+ }
180
+ }
181
+ catch (error) {
182
+ if (error instanceof UsageError) {
183
+ io.stderr(`${error.message}\n`);
184
+ return ExitCode.Usage;
185
+ }
186
+ io.stderr(`${memoryErrorText(error)}\n`);
187
+ return ExitCode.RuntimeError;
188
+ }
189
+ }
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { sourceText } from "../../ai/providers/enrich.js";
6
6
  import { matchLabel } from "../../ai/providers/models-dev.js";
7
+ import { msg } from "../../i18n/index.js";
7
8
  export function compactTokens(n) {
8
9
  if (n === undefined)
9
10
  return "?";
@@ -20,12 +21,13 @@ export function metadataOf(registry, providerId, modelId) {
20
21
  }
21
22
  /** `ctx 262k · out 64k · 思考 · 图片 · 渠道 chat,messages`。 */
22
23
  export function modelFlags(model) {
24
+ const t = msg().subcommands.modelMeta;
23
25
  return [
24
26
  `ctx ${compactTokens(model.contextWindow)}`,
25
27
  `out ${compactTokens(model.maxTokens)}`,
26
- model.reasoning ? "思考" : undefined,
27
- model.input.includes("image") ? "图片" : undefined,
28
- model.channels !== undefined ? `渠道 ${model.channels.join(",")}` : undefined,
28
+ model.reasoning ? t.reasoning : undefined,
29
+ model.input.includes("image") ? t.image : undefined,
30
+ model.channels !== undefined ? t.channels(model.channels) : undefined,
29
31
  ]
30
32
  .filter((x) => x !== undefined)
31
33
  .join(" · ");
@@ -40,15 +42,15 @@ export function sourcesLine(metadata) {
40
42
  const values = Object.values(metadata.sources);
41
43
  if (values.every((s) => s === "catalog" || s === "default") && !metadata.looked)
42
44
  return undefined;
45
+ const t = msg().subcommands.modelMeta;
43
46
  const label = {
44
47
  contextWindow: "ctx",
45
48
  maxTokens: "out",
46
- input: "图片",
47
- reasoning: "思考",
48
- cost: "价格",
49
+ input: t.image,
50
+ reasoning: t.reasoning,
51
+ cost: t.price,
49
52
  };
50
53
  const parts = Object.keys(label).map((field) => `${label[field]} ${sourceText(metadata.sources[field])}`);
51
- const match = metadata.looked ? `;models.dev ${matchLabel(metadata.match)}` : "";
52
- const tools = metadata.toolCall === false ? ";不支持工具调用" : "";
53
- return `来源 ${parts.join(" · ")}${match}${tools}`;
54
+ const match = metadata.looked ? matchLabel(metadata.match) : undefined;
55
+ return t.sources(parts, match, metadata.toolCall === false);
54
56
  }