@armadra/agent 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (467) hide show
  1. package/CHANGELOG.md +177 -304
  2. package/CHANGELOG.zh-CN.md +442 -0
  3. package/README.md +408 -364
  4. package/README.zh-CN.md +705 -0
  5. package/dist/agent/session-plan.js +2 -2
  6. package/dist/agent/session-state.d.ts +3 -0
  7. package/dist/agent/session-state.js +20 -0
  8. package/dist/agent/session-subagent.d.ts +15 -1
  9. package/dist/agent/session-subagent.js +26 -3
  10. package/dist/agent/session-telemetry.d.ts +16 -2
  11. package/dist/agent/session-telemetry.js +29 -7
  12. package/dist/agent/session-tools.js +5 -2
  13. package/dist/agent/session-trace-writer.d.ts +27 -0
  14. package/dist/agent/session-trace-writer.js +253 -0
  15. package/dist/agent/session.d.ts +2 -0
  16. package/dist/agent/session.js +12 -0
  17. package/dist/agent/subagent-direct.d.ts +20 -0
  18. package/dist/agent/subagent-direct.js +76 -0
  19. package/dist/agent/subagent-registry.d.ts +8 -1
  20. package/dist/agent/subagent-registry.js +28 -1
  21. package/dist/agent/system-prompt.d.ts +3 -1
  22. package/dist/agent/system-prompt.js +3 -0
  23. package/dist/agent/tool-runner.d.ts +2 -1
  24. package/dist/agent/tool-runner.js +5 -4
  25. package/dist/agent/types-w6.d.ts +39 -0
  26. package/dist/agent/types-w6.js +4 -0
  27. package/dist/agent/types.d.ts +5 -2
  28. package/dist/agents/external.js +1 -1
  29. package/dist/agents/task-record.d.ts +74 -1
  30. package/dist/agents/task-record.js +100 -0
  31. package/dist/ai/apis/cache-params.js +2 -1
  32. package/dist/ai/apis/chatgpt-backend.d.ts +52 -0
  33. package/dist/ai/apis/chatgpt-backend.js +224 -0
  34. package/dist/ai/apis/chatgpt-rate-limits.d.ts +26 -0
  35. package/dist/ai/apis/chatgpt-rate-limits.js +91 -0
  36. package/dist/ai/apis/openai-responses-request.d.ts +2 -1
  37. package/dist/ai/apis/openai-responses-request.js +8 -2
  38. package/dist/ai/apis/openai-responses.d.ts +2 -0
  39. package/dist/ai/apis/openai-responses.js +51 -16
  40. package/dist/ai/overflow.d.ts +1 -1
  41. package/dist/ai/overflow.js +10 -7
  42. package/dist/ai/providers/auth.d.ts +15 -2
  43. package/dist/ai/providers/auth.js +69 -2
  44. package/dist/ai/providers/builtin.js +27 -0
  45. package/dist/ai/providers/catalog-data.js +1 -0
  46. package/dist/ai/providers/enrich.js +2 -7
  47. package/dist/ai/providers/models-dev-cache.js +15 -19
  48. package/dist/ai/providers/models-dev-snapshot.js +8 -7
  49. package/dist/ai/providers/models-dev.js +5 -15
  50. package/dist/ai/providers/suggest.js +2 -16
  51. package/dist/ai/types.d.ts +27 -1
  52. package/dist/auth/chatgpt/backend-client.d.ts +26 -0
  53. package/dist/auth/chatgpt/backend-client.js +74 -0
  54. package/dist/auth/chatgpt/claims.d.ts +17 -0
  55. package/dist/auth/chatgpt/claims.js +46 -0
  56. package/dist/auth/chatgpt/cli.d.ts +33 -0
  57. package/dist/auth/chatgpt/cli.js +252 -0
  58. package/dist/auth/chatgpt/doctor.d.ts +17 -0
  59. package/dist/auth/chatgpt/doctor.js +36 -0
  60. package/dist/auth/chatgpt/host-id.d.ts +7 -0
  61. package/dist/auth/chatgpt/host-id.js +26 -0
  62. package/dist/auth/chatgpt/login.d.ts +30 -0
  63. package/dist/auth/chatgpt/login.js +130 -0
  64. package/dist/auth/chatgpt/presets.d.ts +66 -0
  65. package/dist/auth/chatgpt/presets.js +120 -0
  66. package/dist/auth/chatgpt/quota-text.d.ts +13 -0
  67. package/dist/auth/chatgpt/quota-text.js +36 -0
  68. package/dist/auth/oauth/browser.d.ts +12 -0
  69. package/dist/auth/oauth/browser.js +27 -0
  70. package/dist/auth/oauth/callback-server.d.ts +47 -0
  71. package/dist/auth/oauth/callback-server.js +147 -0
  72. package/dist/auth/oauth/flows.d.ts +62 -0
  73. package/dist/auth/oauth/flows.js +113 -0
  74. package/dist/auth/oauth/jwt.d.ts +24 -0
  75. package/dist/auth/oauth/jwt.js +81 -0
  76. package/dist/auth/oauth/live.d.ts +21 -0
  77. package/dist/auth/oauth/live.js +25 -0
  78. package/dist/auth/oauth/oidc.d.ts +26 -0
  79. package/dist/auth/oauth/oidc.js +72 -0
  80. package/dist/auth/oauth/pkce.d.ts +15 -0
  81. package/dist/auth/oauth/pkce.js +20 -0
  82. package/dist/auth/oauth/refresh.d.ts +35 -0
  83. package/dist/auth/oauth/refresh.js +129 -0
  84. package/dist/auth/oauth/token-client.d.ts +33 -0
  85. package/dist/auth/oauth/token-client.js +121 -0
  86. package/dist/auth/oauth/token-store.d.ts +23 -0
  87. package/dist/auth/oauth/token-store.js +125 -0
  88. package/dist/auth/testing/fake-oauth.d.ts +73 -0
  89. package/dist/auth/testing/fake-oauth.js +271 -0
  90. package/dist/auth/testing/refresh-child.d.ts +5 -0
  91. package/dist/auth/testing/refresh-child.js +16 -0
  92. package/dist/bundle/ama.cjs +25928 -11144
  93. package/dist/checkpoints/backend.js +6 -5
  94. package/dist/checkpoints/restore.js +3 -2
  95. package/dist/checkpoints/settings.js +2 -1
  96. package/dist/checkpoints/shadow-git.js +7 -6
  97. package/dist/checkpoints/shadow-restore.js +3 -2
  98. package/dist/checkpoints/tracker.js +4 -3
  99. package/dist/cli/args.d.ts +9 -2
  100. package/dist/cli/args.js +74 -27
  101. package/dist/cli/bootstrap.js +53 -31
  102. package/dist/cli/choice-prompt.js +8 -6
  103. package/dist/cli/codemode-notice.js +2 -2
  104. package/dist/cli/compose-agents.js +2 -1
  105. package/dist/cli/compose-extensions.js +2 -0
  106. package/dist/cli/compose-memory.d.ts +53 -0
  107. package/dist/cli/compose-memory.js +127 -0
  108. package/dist/cli/compose-providers.d.ts +5 -0
  109. package/dist/cli/compose-providers.js +32 -2
  110. package/dist/cli/compose-session.d.ts +5 -0
  111. package/dist/cli/compose-session.js +27 -13
  112. package/dist/cli/compose-store.d.ts +2 -0
  113. package/dist/cli/compose-store.js +9 -5
  114. package/dist/cli/compose.d.ts +2 -0
  115. package/dist/cli/compose.js +13 -5
  116. package/dist/cli/default-model.d.ts +0 -2
  117. package/dist/cli/default-model.js +5 -8
  118. package/dist/cli/deps.d.ts +5 -1
  119. package/dist/cli/exit-codes.d.ts +1 -1
  120. package/dist/cli/exit-codes.js +7 -16
  121. package/dist/cli/from-prompt.js +3 -2
  122. package/dist/cli/help-text.d.ts +2 -1
  123. package/dist/cli/help-text.js +5 -99
  124. package/dist/cli/main.d.ts +5 -0
  125. package/dist/cli/main.js +21 -2
  126. package/dist/cli/proxy.js +14 -9
  127. package/dist/cli/runtime.d.ts +5 -0
  128. package/dist/cli/startup-screen.js +20 -27
  129. package/dist/cli/startup-steps.js +6 -8
  130. package/dist/cli/subcommands/auth.d.ts +6 -3
  131. package/dist/cli/subcommands/auth.js +52 -22
  132. package/dist/cli/subcommands/config-set.d.ts +21 -0
  133. package/dist/cli/subcommands/config-set.js +137 -0
  134. package/dist/cli/subcommands/config.d.ts +2 -1
  135. package/dist/cli/subcommands/config.js +51 -37
  136. package/dist/cli/subcommands/doctor.d.ts +2 -1
  137. package/dist/cli/subcommands/doctor.js +97 -58
  138. package/dist/cli/subcommands/init.d.ts +1 -1
  139. package/dist/cli/subcommands/init.js +8 -7
  140. package/dist/cli/subcommands/memory.d.ts +18 -0
  141. package/dist/cli/subcommands/memory.js +189 -0
  142. package/dist/cli/subcommands/model-meta.js +11 -9
  143. package/dist/cli/subcommands/models-cache-probe.js +23 -20
  144. package/dist/cli/subcommands/models-discover.d.ts +3 -0
  145. package/dist/cli/subcommands/models-discover.js +44 -21
  146. package/dist/cli/subcommands/models.d.ts +1 -1
  147. package/dist/cli/subcommands/models.js +29 -22
  148. package/dist/cli/subcommands/probe-runner.js +8 -7
  149. package/dist/cli/subcommands/providers-list.js +32 -21
  150. package/dist/cli/subcommands/providers-plan.js +24 -25
  151. package/dist/cli/subcommands/providers-probe.js +5 -6
  152. package/dist/cli/subcommands/providers.d.ts +1 -1
  153. package/dist/cli/subcommands/providers.js +45 -50
  154. package/dist/cli/subcommands/sessions-export.d.ts +1 -1
  155. package/dist/cli/subcommands/sessions-export.js +10 -9
  156. package/dist/cli/subcommands/sessions-search.d.ts +1 -1
  157. package/dist/cli/subcommands/sessions-search.js +11 -10
  158. package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
  159. package/dist/cli/subcommands/sessions-trace.js +156 -0
  160. package/dist/cli/subcommands/sessions.d.ts +4 -3
  161. package/dist/cli/subcommands/sessions.js +40 -37
  162. package/dist/cli/subcommands/stats.d.ts +1 -1
  163. package/dist/cli/subcommands/stats.js +49 -30
  164. package/dist/cli/system-prompt-arg.js +3 -2
  165. package/dist/codemode/capability.js +3 -2
  166. package/dist/compaction/post-compact.d.ts +1 -0
  167. package/dist/compaction/post-compact.js +15 -1
  168. package/dist/compaction/prune-tier.d.ts +1 -1
  169. package/dist/compaction/prune-tier.js +3 -3
  170. package/dist/compaction/serialize.js +2 -1
  171. package/dist/config/auth-file.d.ts +12 -2
  172. package/dist/config/auth-file.js +32 -10
  173. package/dist/config/checker.js +12 -11
  174. package/dist/config/context-files.js +3 -2
  175. package/dist/config/edit.d.ts +106 -0
  176. package/dist/config/edit.js +350 -0
  177. package/dist/config/init.d.ts +4 -3
  178. package/dist/config/init.js +10 -18
  179. package/dist/config/json-schema.d.ts +2 -1
  180. package/dist/config/json-schema.js +101 -68
  181. package/dist/config/key-docs.d.ts +18 -7
  182. package/dist/config/key-docs.js +43 -128
  183. package/dist/config/load.js +7 -6
  184. package/dist/config/merge.d.ts +4 -1
  185. package/dist/config/merge.js +42 -22
  186. package/dist/config/paths.js +6 -5
  187. package/dist/config/profile.d.ts +5 -1
  188. package/dist/config/profile.js +7 -2
  189. package/dist/config/schema-w5.js +3 -2
  190. package/dist/config/schema-w6.d.ts +19 -0
  191. package/dist/config/schema-w6.js +115 -0
  192. package/dist/config/schema.js +34 -20
  193. package/dist/config/settings-registry.d.ts +78 -0
  194. package/dist/config/settings-registry.js +184 -0
  195. package/dist/config/types-w6.d.ts +109 -0
  196. package/dist/config/types-w6.js +19 -0
  197. package/dist/config/types.d.ts +11 -8
  198. package/dist/config/types.js +1 -0
  199. package/dist/drivers/acp/client.js +1 -1
  200. package/dist/drivers/acp/driver.js +13 -8
  201. package/dist/drivers/agents.js +4 -3
  202. package/dist/drivers/base.js +3 -2
  203. package/dist/drivers/host-runners.js +2 -1
  204. package/dist/drivers/native/claude-stream.js +12 -11
  205. package/dist/drivers/native/codex-app-server.js +17 -12
  206. package/dist/drivers/native/oneshot.js +8 -7
  207. package/dist/drivers/pool.js +1 -1
  208. package/dist/drivers/runner.d.ts +3 -1
  209. package/dist/drivers/runner.js +68 -20
  210. package/dist/drivers/turn.js +1 -1
  211. package/dist/hooks/config.js +3 -2
  212. package/dist/hooks/protocol.js +18 -12
  213. package/dist/host/api-impl.js +11 -10
  214. package/dist/host/loader.js +9 -8
  215. package/dist/host/types.d.ts +3 -0
  216. package/dist/i18n/catalog.d.ts +2169 -0
  217. package/dist/i18n/catalog.js +72 -0
  218. package/dist/i18n/format.d.ts +21 -0
  219. package/dist/i18n/format.js +58 -0
  220. package/dist/i18n/index.d.ts +58 -0
  221. package/dist/i18n/index.js +72 -0
  222. package/dist/i18n/messages/agents.d.ts +84 -0
  223. package/dist/i18n/messages/agents.js +85 -0
  224. package/dist/i18n/messages/approval.d.ts +99 -0
  225. package/dist/i18n/messages/approval.js +100 -0
  226. package/dist/i18n/messages/auth.d.ts +187 -0
  227. package/dist/i18n/messages/auth.js +189 -0
  228. package/dist/i18n/messages/cli-args.d.ts +46 -0
  229. package/dist/i18n/messages/cli-args.js +46 -0
  230. package/dist/i18n/messages/cli-help.d.ts +12 -0
  231. package/dist/i18n/messages/cli-help.js +244 -0
  232. package/dist/i18n/messages/cli.d.ts +336 -0
  233. package/dist/i18n/messages/cli.js +311 -0
  234. package/dist/i18n/messages/config-keys.d.ts +289 -0
  235. package/dist/i18n/messages/config-keys.js +292 -0
  236. package/dist/i18n/messages/config.d.ts +502 -0
  237. package/dist/i18n/messages/config.js +239 -0
  238. package/dist/i18n/messages/drivers.d.ts +123 -0
  239. package/dist/i18n/messages/drivers.js +124 -0
  240. package/dist/i18n/messages/errors.d.ts +83 -0
  241. package/dist/i18n/messages/errors.js +171 -0
  242. package/dist/i18n/messages/interactive-line.d.ts +61 -0
  243. package/dist/i18n/messages/interactive-line.js +69 -0
  244. package/dist/i18n/messages/interactive-startup.d.ts +103 -0
  245. package/dist/i18n/messages/interactive-startup.js +104 -0
  246. package/dist/i18n/messages/interactive-view.d.ts +140 -0
  247. package/dist/i18n/messages/interactive-view.js +141 -0
  248. package/dist/i18n/messages/interactive.d.ts +493 -0
  249. package/dist/i18n/messages/interactive.js +248 -0
  250. package/dist/i18n/messages/memory.d.ts +123 -0
  251. package/dist/i18n/messages/memory.js +128 -0
  252. package/dist/i18n/messages/panels.d.ts +190 -0
  253. package/dist/i18n/messages/panels.js +189 -0
  254. package/dist/i18n/messages/permissions.d.ts +126 -0
  255. package/dist/i18n/messages/permissions.js +151 -0
  256. package/dist/i18n/messages/plan.d.ts +123 -0
  257. package/dist/i18n/messages/plan.js +124 -0
  258. package/dist/i18n/messages/print.d.ts +86 -0
  259. package/dist/i18n/messages/print.js +91 -0
  260. package/dist/i18n/messages/report.d.ts +391 -0
  261. package/dist/i18n/messages/report.js +490 -0
  262. package/dist/i18n/messages/rewind.d.ts +198 -0
  263. package/dist/i18n/messages/rewind.js +217 -0
  264. package/dist/i18n/messages/session.d.ts +230 -0
  265. package/dist/i18n/messages/session.js +258 -0
  266. package/dist/i18n/messages/settings.d.ts +348 -0
  267. package/dist/i18n/messages/settings.js +336 -0
  268. package/dist/i18n/messages/subcommands-config.d.ts +111 -0
  269. package/dist/i18n/messages/subcommands-config.js +127 -0
  270. package/dist/i18n/messages/subcommands.d.ts +548 -0
  271. package/dist/i18n/messages/subcommands.js +474 -0
  272. package/dist/i18n/messages/trace.d.ts +243 -0
  273. package/dist/i18n/messages/trace.js +238 -0
  274. package/dist/i18n/types.d.ts +15 -0
  275. package/dist/i18n/types.js +7 -0
  276. package/dist/index.d.ts +6 -0
  277. package/dist/index.js +2 -0
  278. package/dist/memory/edit.d.ts +24 -0
  279. package/dist/memory/edit.js +63 -0
  280. package/dist/memory/frontmatter.d.ts +37 -0
  281. package/dist/memory/frontmatter.js +79 -0
  282. package/dist/memory/index.d.ts +28 -0
  283. package/dist/memory/index.js +126 -0
  284. package/dist/memory/lock.d.ts +17 -0
  285. package/dist/memory/lock.js +62 -0
  286. package/dist/memory/paths.d.ts +57 -0
  287. package/dist/memory/paths.js +175 -0
  288. package/dist/memory/report.d.ts +36 -0
  289. package/dist/memory/report.js +86 -0
  290. package/dist/memory/runtime.d.ts +42 -0
  291. package/dist/memory/runtime.js +36 -0
  292. package/dist/memory/secrets.d.ts +8 -0
  293. package/dist/memory/secrets.js +27 -0
  294. package/dist/memory/section.d.ts +28 -0
  295. package/dist/memory/section.js +59 -0
  296. package/dist/memory/store.d.ts +70 -0
  297. package/dist/memory/store.js +284 -0
  298. package/dist/memory/tool.d.ts +31 -0
  299. package/dist/memory/tool.js +94 -0
  300. package/dist/modes/acp/acp-events.js +2 -1
  301. package/dist/modes/acp/acp-server.js +13 -12
  302. package/dist/modes/commands-core.d.ts +11 -0
  303. package/dist/modes/commands-core.js +93 -62
  304. package/dist/modes/image-input.js +20 -6
  305. package/dist/modes/interactive/agent-bar.d.ts +95 -0
  306. package/dist/modes/interactive/agent-bar.js +248 -0
  307. package/dist/modes/interactive/agent-panels.js +27 -26
  308. package/dist/modes/interactive/agent-transcript.d.ts +47 -0
  309. package/dist/modes/interactive/agent-transcript.js +191 -0
  310. package/dist/modes/interactive/agent-ui.d.ts +36 -1
  311. package/dist/modes/interactive/agent-ui.js +180 -14
  312. package/dist/modes/interactive/agent-view.d.ts +72 -0
  313. package/dist/modes/interactive/agent-view.js +281 -0
  314. package/dist/modes/interactive/approval-dialog.js +46 -34
  315. package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
  316. package/dist/modes/interactive/clipboard-paste.js +9 -4
  317. package/dist/modes/interactive/commands.d.ts +19 -1
  318. package/dist/modes/interactive/commands.js +84 -40
  319. package/dist/modes/interactive/completion.js +2 -1
  320. package/dist/modes/interactive/config-panel.d.ts +70 -0
  321. package/dist/modes/interactive/config-panel.js +319 -0
  322. package/dist/modes/interactive/config-ui.d.ts +96 -0
  323. package/dist/modes/interactive/config-ui.js +397 -0
  324. package/dist/modes/interactive/confirm-dialog.js +6 -7
  325. package/dist/modes/interactive/event-notices.js +11 -9
  326. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  327. package/dist/modes/interactive/interactive-mode.js +19 -22
  328. package/dist/modes/interactive/key-dispatch.d.ts +12 -0
  329. package/dist/modes/interactive/key-dispatch.js +24 -9
  330. package/dist/modes/interactive/line/line-editor.js +2 -1
  331. package/dist/modes/interactive/line/line-mode.js +18 -7
  332. package/dist/modes/interactive/line/line-render.js +25 -24
  333. package/dist/modes/interactive/memory-panel.d.ts +64 -0
  334. package/dist/modes/interactive/memory-panel.js +221 -0
  335. package/dist/modes/interactive/message-view.d.ts +4 -2
  336. package/dist/modes/interactive/message-view.js +42 -33
  337. package/dist/modes/interactive/panels.js +39 -31
  338. package/dist/modes/interactive/pickers.d.ts +2 -1
  339. package/dist/modes/interactive/pickers.js +10 -6
  340. package/dist/modes/interactive/plan-command.d.ts +1 -1
  341. package/dist/modes/interactive/plan-command.js +24 -27
  342. package/dist/modes/interactive/plan-dialog.js +18 -17
  343. package/dist/modes/interactive/plan-flow.js +6 -5
  344. package/dist/modes/interactive/rewind-command.d.ts +1 -1
  345. package/dist/modes/interactive/rewind-command.js +18 -16
  346. package/dist/modes/interactive/rewind-flow.d.ts +0 -1
  347. package/dist/modes/interactive/rewind-flow.js +13 -14
  348. package/dist/modes/interactive/rewind-list.js +7 -6
  349. package/dist/modes/interactive/rewind-panel.js +40 -40
  350. package/dist/modes/interactive/rewind-text.d.ts +5 -3
  351. package/dist/modes/interactive/rewind-text.js +48 -38
  352. package/dist/modes/interactive/run-indicator.js +15 -12
  353. package/dist/modes/interactive/session-events.js +3 -2
  354. package/dist/modes/interactive/startup-header.js +22 -23
  355. package/dist/modes/interactive/startup-ui.js +38 -30
  356. package/dist/modes/interactive/status-area.d.ts +2 -0
  357. package/dist/modes/interactive/status-area.js +8 -2
  358. package/dist/modes/interactive/status-bar.js +4 -3
  359. package/dist/modes/interactive/subagent-view.js +9 -7
  360. package/dist/modes/interactive/tasks-report.d.ts +6 -0
  361. package/dist/modes/interactive/tasks-report.js +28 -31
  362. package/dist/modes/interactive/terminal-setup.d.ts +9 -0
  363. package/dist/modes/interactive/terminal-setup.js +23 -0
  364. package/dist/modes/interactive/tool-summary.js +19 -17
  365. package/dist/modes/interactive/tool-view.js +7 -4
  366. package/dist/modes/interactive/trace-view.d.ts +89 -0
  367. package/dist/modes/interactive/trace-view.js +332 -0
  368. package/dist/modes/print/print-mode.js +14 -15
  369. package/dist/modes/rpc/commands.js +7 -3
  370. package/dist/modes/rpc/rpc-mode.js +9 -3
  371. package/dist/modes/session-report.d.ts +2 -0
  372. package/dist/modes/session-report.js +101 -105
  373. package/dist/modes/startup-ui-text.js +11 -6
  374. package/dist/permissions/bypass.d.ts +8 -10
  375. package/dist/permissions/bypass.js +19 -10
  376. package/dist/permissions/memory-class.d.ts +23 -0
  377. package/dist/permissions/memory-class.js +54 -0
  378. package/dist/permissions/modes.d.ts +3 -3
  379. package/dist/permissions/modes.js +21 -16
  380. package/dist/permissions/pipeline.d.ts +1 -1
  381. package/dist/permissions/pipeline.js +9 -2
  382. package/dist/permissions/preview.js +49 -42
  383. package/dist/permissions/rules.js +5 -2
  384. package/dist/permissions/types.d.ts +4 -0
  385. package/dist/plan/store.js +2 -1
  386. package/dist/rpc.d.ts +39 -1
  387. package/dist/rpc.js +3 -0
  388. package/dist/sandbox/bash.js +11 -8
  389. package/dist/sandbox/detect.js +14 -11
  390. package/dist/sdk.d.ts +17 -1
  391. package/dist/sdk.js +29 -7
  392. package/dist/session/export.js +31 -30
  393. package/dist/session/manager.d.ts +1 -1
  394. package/dist/session/manager.js +5 -3
  395. package/dist/session/reuse.js +5 -4
  396. package/dist/session/scan.js +3 -2
  397. package/dist/session/stats-aggregate.d.ts +3 -1
  398. package/dist/session/stats-aggregate.js +5 -1
  399. package/dist/session/stats-index.js +2 -1
  400. package/dist/session/stats-scan.d.ts +4 -1
  401. package/dist/session/stats-scan.js +6 -2
  402. package/dist/session/store.d.ts +11 -0
  403. package/dist/session/store.js +48 -1
  404. package/dist/session/types.d.ts +2 -0
  405. package/dist/skills/builtin.js +2 -1
  406. package/dist/tools/image-file.d.ts +26 -1
  407. package/dist/tools/image-file.js +55 -13
  408. package/dist/tools/presets.d.ts +14 -1
  409. package/dist/tools/presets.js +3 -3
  410. package/dist/tools/registry.js +1 -1
  411. package/dist/tools/truncate.d.ts +1 -1
  412. package/dist/tools/truncate.js +2 -2
  413. package/dist/tools/types.d.ts +17 -1
  414. package/dist/trace/build-index.d.ts +91 -0
  415. package/dist/trace/build-index.js +127 -0
  416. package/dist/trace/build-nodes.d.ts +24 -0
  417. package/dist/trace/build-nodes.js +279 -0
  418. package/dist/trace/build-util.d.ts +43 -0
  419. package/dist/trace/build-util.js +120 -0
  420. package/dist/trace/build.d.ts +82 -0
  421. package/dist/trace/build.js +382 -0
  422. package/dist/trace/detail.d.ts +35 -0
  423. package/dist/trace/detail.js +205 -0
  424. package/dist/trace/flatten.d.ts +69 -0
  425. package/dist/trace/flatten.js +173 -0
  426. package/dist/trace/format.d.ts +47 -0
  427. package/dist/trace/format.js +329 -0
  428. package/dist/trace/html-template.d.ts +19 -0
  429. package/dist/trace/html-template.js +150 -0
  430. package/dist/trace/html.d.ts +104 -0
  431. package/dist/trace/html.js +292 -0
  432. package/dist/trace/preview.d.ts +29 -0
  433. package/dist/trace/preview.js +59 -0
  434. package/dist/trace/query-session.d.ts +14 -0
  435. package/dist/trace/query-session.js +38 -0
  436. package/dist/trace/query.d.ts +55 -0
  437. package/dist/trace/query.js +188 -0
  438. package/dist/trace/session.d.ts +40 -0
  439. package/dist/trace/session.js +168 -0
  440. package/dist/trace/types.d.ts +243 -0
  441. package/dist/trace/types.js +13 -0
  442. package/dist/tui/components/editor-paste.d.ts +2 -0
  443. package/dist/tui/components/editor-paste.js +6 -3
  444. package/dist/tui/components/editor.js +2 -2
  445. package/dist/tui/components/loader.d.ts +3 -0
  446. package/dist/tui/components/loader.js +14 -0
  447. package/dist/tui/components/settings-list.d.ts +61 -0
  448. package/dist/tui/components/settings-list.js +135 -0
  449. package/dist/tui/keybindings.d.ts +5 -0
  450. package/dist/tui/keybindings.js +17 -5
  451. package/dist/tui.d.ts +1 -0
  452. package/dist/tui.js +2 -0
  453. package/docs/en/host-api.md +167 -0
  454. package/docs/en/permissions.md +214 -0
  455. package/docs/en/providers.md +625 -0
  456. package/docs/en/rpc.md +361 -0
  457. package/docs/en/sessions.md +219 -0
  458. package/docs/en/tui.md +527 -0
  459. package/docs/host-api.md +18 -17
  460. package/docs/memory.md +172 -0
  461. package/docs/permissions.md +2 -2
  462. package/docs/providers.md +67 -1
  463. package/docs/rpc.md +31 -3
  464. package/docs/session-format.md +8 -2
  465. package/docs/sessions.md +29 -1
  466. package/docs/tui.md +132 -3
  467. package/package.json +8 -3
@@ -14,8 +14,11 @@
14
14
  * `createRuntimeDeps()`(cli/compose.ts,动态 import)。
15
15
  * - 签名 `main(argv): Promise<number>` 与「直接执行才自动运行」判定保持不变:
16
16
  * src/bundle.ts 显式调用 `main()`。
17
+ * - [W6-C0] 界面语言在解析参数后、任何输出前定一次:`AMA_LANG` > `--lang` > 用户级 `ui.language` >
18
+ * `LC_ALL` / `LC_MESSAGES` / `LANG`(docs/i18n.md);profile / 项目级的 `ui.language` 由 bootstrap 合并后补定。
17
19
  */
18
20
  import type { CliIo, RuntimeDeps, StdinKind } from "./deps.js";
21
+ import { type LanguageSetting } from "../i18n/index.js";
19
22
  /** 集成批次注入运行时实现(B1 / B2 / B3 / B6 / B7)。 */
20
23
  export declare function registerRuntimeDeps(deps: RuntimeDeps | undefined): void;
21
24
  export interface MainOptions {
@@ -31,4 +34,6 @@ export declare function stdinKindDefault(): StdinKind;
31
34
  /** 等 stdin 首字节至多 `timeoutMs`;超时则停止读取并返回 undefined,否则读到 EOF。 */
32
35
  export declare function readStdinFirstByteDefault(timeoutMs: number): Promise<string | undefined>;
33
36
  export declare function defaultIo(): CliIo;
37
+ /** 用户级 config.json 的 `ui.language`(只读、不校验、读不到当未设;完整校验在 bootstrap)。 */
38
+ export declare function peekUserLanguage(env: NodeJS.ProcessEnv): LanguageSetting | undefined;
34
39
  export declare function main(argv: readonly string[], options?: MainOptions): Promise<number>;
package/dist/cli/main.js CHANGED
@@ -14,8 +14,11 @@
14
14
  * `createRuntimeDeps()`(cli/compose.ts,动态 import)。
15
15
  * - 签名 `main(argv): Promise<number>` 与「直接执行才自动运行」判定保持不变:
16
16
  * src/bundle.ts 显式调用 `main()`。
17
+ * - [W6-C0] 界面语言在解析参数后、任何输出前定一次:`AMA_LANG` > `--lang` > 用户级 `ui.language` >
18
+ * `LC_ALL` / `LC_MESSAGES` / `LANG`(docs/i18n.md);profile / 项目级的 `ui.language` 由 bootstrap 合并后补定。
17
19
  */
18
- import { fstatSync, realpathSync } from "node:fs";
20
+ import { fstatSync, readFileSync, realpathSync } from "node:fs";
21
+ import { join } from "node:path";
19
22
  import { fileURLToPath } from "node:url";
20
23
  import { AMA_VERSION } from "../version.js";
21
24
  import { parseArgs } from "./args.js";
@@ -32,6 +35,7 @@ import { resolveConfigDir } from "../config/paths.js";
32
35
  import { runSessions } from "./subcommands/sessions.js";
33
36
  import { runStats } from "./subcommands/stats.js";
34
37
  import { enableEnvProxy, proxyHint } from "./proxy.js";
38
+ import { msg, resolveLocale, setLocale } from "../i18n/index.js";
35
39
  let registeredDeps;
36
40
  /** 集成批次注入运行时实现(B1 / B2 / B3 / B6 / B7)。 */
37
41
  export function registerRuntimeDeps(deps) {
@@ -145,6 +149,17 @@ export function defaultIo() {
145
149
  stdinKind: stdinKindDefault,
146
150
  };
147
151
  }
152
+ /** 用户级 config.json 的 `ui.language`(只读、不校验、读不到当未设;完整校验在 bootstrap)。 */
153
+ export function peekUserLanguage(env) {
154
+ try {
155
+ const raw = readFileSync(join(resolveConfigDir({ env }), "config.json"), "utf8");
156
+ const value = JSON.parse(raw).ui?.language;
157
+ return value === "auto" || value === "zh" || value === "en" ? value : undefined;
158
+ }
159
+ catch {
160
+ return undefined;
161
+ }
162
+ }
148
163
  let hooksInstalled = false;
149
164
  function installProcessHooks(io) {
150
165
  if (hooksInstalled)
@@ -152,7 +167,7 @@ function installProcessHooks(io) {
152
167
  hooksInstalled = true;
153
168
  const fatal = (error) => {
154
169
  const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
155
- io.stderr(`ama: 未捕获的异常:${message.split("\n")[0] ?? ""}\n`);
170
+ io.stderr(msg().cli.main.uncaught(message.split("\n")[0] ?? ""));
156
171
  process.exit(ExitCode.RuntimeError);
157
172
  };
158
173
  process.on("uncaughtException", fatal);
@@ -181,6 +196,8 @@ export async function main(argv, options = {}) {
181
196
  });
182
197
  try {
183
198
  const parsed = parseArgs(argv);
199
+ const cliLang = parsed.kind === "run" ? parsed.args.lang : parsed.lang;
200
+ setLocale(resolveLocale(io.env, { language: peekUserLanguage(io.env) }, cliLang));
184
201
  if (parsed.kind !== "subcommand")
185
202
  noTui = parsed.args.noTui;
186
203
  const informational = parsed.kind === "run" ? parsed.args.help || parsed.args.version : parsed.name === "init";
@@ -214,6 +231,8 @@ export async function main(argv, options = {}) {
214
231
  return runInit(parsed.argv, io);
215
232
  case "stats":
216
233
  return await runStats(parsed.argv, io);
234
+ case "memory":
235
+ return await (await import("./subcommands/memory.js")).runMemory(parsed.argv, io);
217
236
  }
218
237
  }
219
238
  if (parsed.args.version) {
package/dist/cli/proxy.js CHANGED
@@ -10,6 +10,7 @@
10
10
  * `ama doctor` 用 `describeProxy()` 显示同一份状态;代理 URL 里的账号密码打码。
11
11
  */
12
12
  import * as http from "node:http";
13
+ import { msg } from "../i18n/index.js";
13
14
  function pick(env, name) {
14
15
  const value = env[name.toLowerCase()] ?? env[name.toUpperCase()];
15
16
  return value !== undefined && value.trim() !== "" ? value.trim() : undefined;
@@ -58,7 +59,11 @@ export function inspectProxy(env, runtime = defaultProxyRuntime()) {
58
59
  return { env: proxy, state: "unsupported" };
59
60
  for (const value of [proxy.httpsProxy, proxy.httpProxy]) {
60
61
  if (value !== undefined && !URL.canParse(value))
61
- return { env: proxy, state: "invalid", error: `无法解析 ${redactProxyUrl(value)}` };
62
+ return {
63
+ env: proxy,
64
+ state: "invalid",
65
+ error: msg().cli.proxy.unparsable(redactProxyUrl(value)),
66
+ };
62
67
  }
63
68
  return { env: proxy, state: "enabled" };
64
69
  }
@@ -104,12 +109,11 @@ export function proxyHint(status, nodeVersion = process.versions.node) {
104
109
  return undefined;
105
110
  if (status.state === "unsupported") {
106
111
  hinted = true;
107
- return (`ama: 检测到 HTTPS_PROXY / HTTP_PROXY,但 Node ${nodeVersion} 的 fetch 不读代理变量,请求将直连;` +
108
- "升级到 Node 24+,或在 Node 22.21+ 上设 NODE_USE_ENV_PROXY=1\n");
112
+ return msg().cli.proxy.unsupportedHint(nodeVersion);
109
113
  }
110
114
  if (status.state === "invalid") {
111
115
  hinted = true;
112
- return `ama: 代理变量无法解析,请求将直连:${status.error ?? ""}\n`;
116
+ return msg().cli.proxy.invalidHint(status.error ?? "");
113
117
  }
114
118
  return undefined;
115
119
  }
@@ -123,12 +127,13 @@ export function describeProxy(status) {
123
127
  lines.push(`HTTP_PROXY=${redactProxyUrl(env.httpProxy)}`);
124
128
  if (env.noProxy !== undefined)
125
129
  lines.push(`NO_PROXY=${env.noProxy}`);
130
+ const m = msg().cli.proxy.state;
126
131
  const state = {
127
- none: "未设置代理变量:直连",
128
- runtime: "已启用(Node 按 NODE_USE_ENV_PROXY / --use-env-proxy 接管)",
129
- enabled: "已启用(ama 启动时调用 Node 内置的 setGlobalProxyFromEnv)",
130
- unsupported: `✗ 当前 Node ${process.versions.node} 不支持内置代理,请求直连;升级到 Node 24+`,
131
- invalid: `✗ 代理变量无法解析:${status.error ?? ""}`,
132
+ none: m.none,
133
+ runtime: m.runtime,
134
+ enabled: m.enabled,
135
+ unsupported: m.unsupported(process.versions.node),
136
+ invalid: m.invalid(status.error ?? ""),
132
137
  };
133
138
  lines.push(state[status.state]);
134
139
  return lines;
@@ -83,6 +83,11 @@ export interface Runtime {
83
83
  readonly tools: ToolRegistryApi;
84
84
  readonly approvals: RuntimeApprovals;
85
85
  readonly notifier: RuntimeNotifier;
86
+ /**
87
+ * [W6-S] 换上重新合并的配置(`/config` 改完立即写盘后调用):`config` 与之后 `/new` / `/resume` 组装的
88
+ * 会话读新值;已在运行的会话不受影响(「即时」档由界面另行热应用)。SDK 组装的运行时可以没有。
89
+ */
90
+ replaceConfig?(config: AmaConfig): void;
86
91
  /** 启动期收集的 warning(被忽略的放宽项、文件读错等)。 */
87
92
  readonly warnings: readonly string[];
88
93
  /** 发 session_shutdown、SessionEnd Hook、适配器 dispose;幂等。 */
@@ -14,25 +14,19 @@ import { isBuiltinSkill } from "../skills/builtin.js";
14
14
  import { basename } from "node:path";
15
15
  import { formatModelRef } from "../ai/providers/channels.js";
16
16
  import { effectiveCodemodeMode } from "../tools/presets.js";
17
+ import { msg } from "../i18n/index.js";
17
18
  import { AMA_VERSION } from "../version.js";
18
19
  export function startupScreenLevel(runtime) {
19
20
  return runtime.config.ui?.quietStartup ?? "normal";
20
21
  }
21
22
  export function headerLine() {
22
- return `ama ${AMA_VERSION} · Enter 发送 · Esc 中断 · Ctrl+C 两次退出 · /help 命令`;
23
+ return msg().cli.startupScreen.header(AMA_VERSION);
23
24
  }
24
25
  function trustText(runtime) {
25
26
  const { trusted, source, matchedPath } = runtime.trust;
26
- const from = source === "flag"
27
- ? "命令行"
28
- : source === "trust-file"
29
- ? `trust.json${matchedPath === undefined ? "" : ` ${matchedPath}`}`
30
- : source === "prompt"
31
- ? "本次确认"
32
- : source === "profile"
33
- ? "profile"
34
- : "缺省";
35
- return `${trusted ? "已信任" : "未信任"}(${from})`;
27
+ const label = trustSourceLabel(source);
28
+ const from = source === "trust-file" && matchedPath !== undefined ? `${label} ${matchedPath}` : label;
29
+ return msg().cli.startupScreen.trust(trusted, from);
36
30
  }
37
31
  export function buildStartupScreen(runtime, level = startupScreenLevel(runtime)) {
38
32
  if (level === "silent")
@@ -41,34 +35,33 @@ export function buildStartupScreen(runtime, level = startupScreenLevel(runtime))
41
35
  if (level === "header")
42
36
  return lines;
43
37
  const { resources } = runtime;
44
- lines.push(`模型:${runtime.model.provider}/${runtime.model.id} · 思考 ${runtime.thinkingLevel}`);
45
- lines.push(`目录:${runtime.paths.cwd} · ${trustText(runtime)}`);
38
+ const m = msg().cli.startupScreen;
39
+ lines.push(m.model(`${runtime.model.provider}/${runtime.model.id}`, runtime.thinkingLevel));
40
+ lines.push(m.cwd(runtime.paths.cwd, trustText(runtime)));
46
41
  if (resources.contextFiles.length > 0) {
47
- lines.push(`上下文:${resources.contextFiles.map((f) => f.path).join(", ")}`);
42
+ lines.push(m.context(resources.contextFiles.map((f) => f.path)));
48
43
  }
49
44
  const skills = resources.skills.filter((s) => !isBuiltinSkill(s));
50
45
  if (skills.length > 0) {
51
- lines.push(`Skill:${skills.map((s) => s.name).join(", ")}`);
46
+ lines.push(m.skills(skills.map((s) => s.name)));
52
47
  }
53
48
  if (resources.prompts.length > 0) {
54
- lines.push(`提示模板:${resources.prompts.map((p) => `/${p.name}`).join(" ")}`);
49
+ lines.push(m.prompts(resources.prompts.map((p) => `/${p.name}`)));
55
50
  }
56
51
  const hooks = runtime.hooks.list();
57
52
  if (hooks.length > 0)
58
- lines.push(`Hook:${hooks.length} 条`);
53
+ lines.push(m.hooks(hooks.length));
59
54
  if (runtime.host !== undefined)
60
- lines.push(`宿主:${runtime.host.adapter.id}`);
55
+ lines.push(m.host(runtime.host.adapter.id));
61
56
  if (runtime.warnings.length > 0)
62
- lines.push(`警告:${runtime.warnings.length} 条(ama doctor 查看)`);
57
+ lines.push(m.warnings(runtime.warnings.length));
63
58
  return lines;
64
59
  }
65
- const TRUST_SOURCE = {
66
- flag: "命令行",
67
- "trust-file": "trust.json",
68
- prompt: "本次确认",
69
- profile: "profile",
70
- default: "缺省",
71
- };
60
+ /** 信任来源的短名(按界面语言)。 */
61
+ function trustSourceLabel(source) {
62
+ const labels = msg().cli.startupScreen.trustSource;
63
+ return source === "trust-file" ? labels.trustFile : labels[source];
64
+ }
72
65
  /** 家目录前缀缩写为 `~`(`/` 与 `\` 两种分隔都认,余下部分原样保留)。 */
73
66
  export function tildePath(path, home) {
74
67
  if (home === undefined || home === "")
@@ -89,7 +82,7 @@ export function startupInfo(runtime, home) {
89
82
  thinking: runtime.thinkingLevel,
90
83
  cwd: tildePath(runtime.paths.cwd, home),
91
84
  trusted: runtime.trust.trusted,
92
- trustSource: TRUST_SOURCE[runtime.trust.source],
85
+ trustSource: trustSourceLabel(runtime.trust.source),
93
86
  permissionMode: runtime.session.state.permissionMode,
94
87
  preset: runtime.config.tools?.preset ?? "default",
95
88
  codemode: effectiveCodemodeMode(runtime.config),
@@ -11,6 +11,7 @@ import { UsageError } from "./args.js";
11
11
  import { noModelGuidance, pickDefaultModel } from "./default-model.js";
12
12
  import { hideFakeProvider } from "./fake-visibility.js";
13
13
  import { ExitCode } from "./exit-codes.js";
14
+ import { msg } from "../i18n/index.js";
14
15
  /** 把非 StartupError 包成指定退出码;StartupError / UsageError 原样透传。 */
15
16
  export async function step(exitCode, label, fn) {
16
17
  try {
@@ -41,7 +42,7 @@ export function toStartupError(error, exitCode, label) {
41
42
  return new StartupError(error.code, error.message, mapped, { cause: error });
42
43
  }
43
44
  const message = error instanceof Error ? error.message : String(error);
44
- return new StartupError("startup_failed", `${label}:${message}`, exitCode, { cause: error });
45
+ return new StartupError("startup_failed", msg().cli.startupSteps.stepFailed(label, message), exitCode, { cause: error });
45
46
  }
46
47
  /** 第 4 步。 */
47
48
  export function decideMode(args, io) {
@@ -106,7 +107,7 @@ export function lastEntry(manager, predicate) {
106
107
  /** 第 11 步:解析模型与 key。 */
107
108
  export async function resolveModel(args, registry, manager, defaultModel, deps, interactive, env = {}) {
108
109
  if (args.provider !== undefined && args.model === undefined) {
109
- throw new UsageError(`--provider ${args.provider} 需要同时给出 --model(不回退到该供应商的缺省模型)`);
110
+ throw new UsageError(msg().cli.startupSteps.providerNeedsModel(args.provider));
110
111
  }
111
112
  const lookup = (ref, label) => {
112
113
  const found = registry.findModel(ref);
@@ -156,10 +157,7 @@ export async function resolveModel(args, registry, manager, defaultModel, deps,
156
157
  if (choice.provider.requiresApiKey) {
157
158
  const key = await registry.resolveApiKey(choice.provider.id);
158
159
  if (key.apiKey === undefined) {
159
- const envs = choice.provider.envKeys.length > 0
160
- ? `,或设置环境变量 ${choice.provider.envKeys.join(" / ")}`
161
- : "";
162
- return pick(`供应商 ${choice.provider.id} 没有 API key:运行 \`ama auth set ${choice.provider.id}\`${envs}`);
160
+ return pick(msg().cli.startupSteps.noApiKey(choice.provider.id, choice.provider.envKeys));
163
161
  }
164
162
  }
165
163
  return choice;
@@ -176,7 +174,7 @@ export function thinkingOf(args, manager, fallback) {
176
174
  export function applyToolFilters(args, runtimeTools) {
177
175
  const unknown = [...(args.tools ?? []), ...(args.excludeTools ?? [])].filter((n) => runtimeTools.get(n) === undefined);
178
176
  if (unknown.length > 0) {
179
- throw new UsageError(`未知工具:${unknown.join(", ")}(可用:${runtimeTools.list().join(", ")})`);
177
+ throw new UsageError(msg().cli.startupSteps.unknownTools(unknown, runtimeTools.list()));
180
178
  }
181
179
  if (args.tools !== undefined)
182
180
  runtimeTools.setActive(args.tools);
@@ -194,7 +192,7 @@ export function instructionSources(paths, cwd) {
194
192
  ok = false;
195
193
  }
196
194
  if (!ok)
197
- throw new StartupError("config_invalid", `--instructions 文件不存在:${abs}`, ExitCode.Config);
195
+ throw new StartupError("config_invalid", msg().cli.startupSteps.instructionsMissing(abs), ExitCode.Config);
198
196
  return { kind: "file", path: abs };
199
197
  });
200
198
  }
@@ -1,12 +1,15 @@
1
1
  /**
2
2
  * `ama auth set|list|remove <provider>`(设计 §3.5、§16.2 B5 验收)。[B5]
3
+ * `ama auth login|logout|status chatgpt`(docs/wave6-plan.md §4.2)。[W6-O] 实现在 auth/chatgpt/cli.ts。
3
4
  *
4
5
  * - set:key 从 stdin 读取(TTY 下不回显),不经命令行参数,避免进 shell 历史;写 auth.json 0600。
5
- * - list:只列供应商与 key 形态(字面量 / `!command` / `$ENV` 引用),从不输出 key。
6
+ * - list:只列供应商与 key 形态(字面量 / `!command` / `$ENV` 引用 / oauth 的 flavor 与计划),从不输出 key 或 token。
6
7
  * - `--auth-file <path>` 改变目标文件(缺省 `<configDir>/auth.json`)。
7
8
  */
9
+ import { type AuthCliDeps } from "../../auth/chatgpt/cli.js";
8
10
  import type { CliIo } from "../deps.js";
9
- export declare const AUTH_USAGE = "\u7528\u6CD5\uFF1Aama auth set <provider> [--auth-file <\u6587\u4EF6>] \u4ECE stdin \u8BFB\u53D6 key\n ama auth list [--auth-file <\u6587\u4EF6>]\n ama auth remove <provider> [--auth-file <\u6587\u4EF6>]\n";
11
+ /** 用法文本(按当前语言)。 */
12
+ export declare function authUsage(): string;
10
13
  /** 取第一行并去掉首尾空白;stdin 为空返回 ""。 */
11
14
  export declare function extractKey(raw: string): string;
12
- export declare function runAuth(argv: readonly string[], io: CliIo): Promise<number>;
15
+ export declare function runAuth(argv: readonly string[], io: CliIo, deps?: AuthCliDeps): Promise<number>;
@@ -1,28 +1,46 @@
1
1
  /**
2
2
  * `ama auth set|list|remove <provider>`(设计 §3.5、§16.2 B5 验收)。[B5]
3
+ * `ama auth login|logout|status chatgpt`(docs/wave6-plan.md §4.2)。[W6-O] 实现在 auth/chatgpt/cli.ts。
3
4
  *
4
5
  * - set:key 从 stdin 读取(TTY 下不回显),不经命令行参数,避免进 shell 历史;写 auth.json 0600。
5
- * - list:只列供应商与 key 形态(字面量 / `!command` / `$ENV` 引用),从不输出 key。
6
+ * - list:只列供应商与 key 形态(字面量 / `!command` / `$ENV` 引用 / oauth 的 flavor 与计划),从不输出 key 或 token。
6
7
  * - `--auth-file <path>` 改变目标文件(缺省 `<configDir>/auth.json`)。
7
8
  */
8
9
  import { resolve } from "node:path";
10
+ import { runLogin, runLogout, runStatus } from "../../auth/chatgpt/cli.js";
9
11
  import { PROVIDER_ID_PATTERN, defaultAuthFilePath, describeAuthFile, readAuthFile, removeAuthKey, setAuthKey, } from "../../config/auth-file.js";
10
12
  import { resolveConfigDir } from "../../config/paths.js";
13
+ import { msg } from "../../i18n/index.js";
11
14
  import { parseSubArgs, UsageError } from "../args.js";
12
15
  import { ExitCode } from "../exit-codes.js";
13
- export const AUTH_USAGE = `用法:ama auth set <provider> [--auth-file <文件>] 从 stdin 读取 key
14
- ama auth list [--auth-file <文件>]
15
- ama auth remove <provider> [--auth-file <文件>]
16
- `;
17
- const KIND_TEXT = { literal: "key", command: "!命令", "env-ref": "环境变量引用" };
16
+ /** 用法文本(按当前语言)。 */
17
+ export function authUsage() {
18
+ return msg().auth.usage;
19
+ }
20
+ function kindText(entry) {
21
+ const kind = msg().auth.kind;
22
+ switch (entry.kind) {
23
+ case "literal":
24
+ return kind.literal;
25
+ case "command":
26
+ return kind.command;
27
+ case "env-ref":
28
+ return kind.envRef;
29
+ case "oauth":
30
+ return entry.flavor === undefined
31
+ ? kind.oauth
32
+ : `${kind.oauth} · ${msg().auth.oauthSummary(entry.flavor, entry.plan, entry.needsLogin === true)}`;
33
+ }
34
+ }
18
35
  function providerArg(positionals, action) {
36
+ const m = msg().auth;
19
37
  const provider = positionals[1];
20
38
  if (provider === undefined)
21
- throw new UsageError(`ama auth ${action} 需要 <provider>`);
39
+ throw new UsageError(m.needProvider(action));
22
40
  if (positionals.length > 2)
23
- throw new UsageError(`多余的参数:${positionals.slice(2).join(" ")}`);
41
+ throw new UsageError(m.extraArgs(positionals.slice(2).join(" ")));
24
42
  if (!PROVIDER_ID_PATTERN.test(provider))
25
- throw new UsageError(`供应商 id 不合法:${provider}`);
43
+ throw new UsageError(m.badProvider(provider));
26
44
  return provider;
27
45
  }
28
46
  /** 取第一行并去掉首尾空白;stdin 为空返回 ""。 */
@@ -30,40 +48,52 @@ export function extractKey(raw) {
30
48
  const line = raw.split(/\r?\n/).find((l) => l.trim() !== "") ?? "";
31
49
  return line.trim();
32
50
  }
33
- export async function runAuth(argv, io) {
34
- const { positionals, values, flags } = parseSubArgs(argv, ["auth-file"]);
51
+ export async function runAuth(argv, io, deps = {}) {
52
+ const m = msg().auth;
53
+ const { positionals, values, flags } = parseSubArgs(argv, ["auth-file", "flavor", "port"], ["paste", "device", "no-browser", "yes"]);
35
54
  const action = positionals[0];
36
55
  if (flags.has("help") || action === undefined) {
37
- io.stdout(AUTH_USAGE);
56
+ io.stdout(authUsage());
38
57
  return flags.has("help") ? ExitCode.Ok : ExitCode.Usage;
39
58
  }
40
59
  const explicit = values.get("auth-file");
41
60
  const path = explicit !== undefined
42
61
  ? resolve(io.cwd, explicit)
43
62
  : defaultAuthFilePath(resolveConfigDir({ env: io.env }));
63
+ const loginOnly = ["flavor", "port"].filter((name) => values.has(name));
64
+ const loginFlags = ["paste", "device", "no-browser", "yes"].filter((name) => flags.has(name));
65
+ if (action !== "login" && [...loginOnly, ...loginFlags].length > 0)
66
+ throw new UsageError(m.extraArgs([...loginOnly, ...loginFlags].map((n) => `--${n}`).join(" ")));
67
+ const cli = { positionals, values, flags, path };
44
68
  switch (action) {
69
+ case "login":
70
+ return runLogin(cli, io, deps);
71
+ case "logout":
72
+ return runLogout(cli, io, deps);
73
+ case "status":
74
+ return runStatus(cli, io, deps);
45
75
  case "set": {
46
76
  const provider = providerArg(positionals, "set");
47
77
  if (io.stdinIsTTY)
48
- io.stderr(`输入 ${provider} 的 API key(不回显),回车结束:`);
78
+ io.stderr(m.setPrompt(provider));
49
79
  const key = extractKey(await io.readStdin());
50
80
  if (io.stdinIsTTY)
51
81
  io.stderr("\n");
52
82
  if (key === "")
53
- throw new UsageError("没有从 stdin 读到 key");
83
+ throw new UsageError(m.noKeyFromStdin);
54
84
  setAuthKey(path, provider, key);
55
- io.stdout(`已保存 ${provider} 的 key → ${path}(0600)\n`);
85
+ io.stdout(`${m.saved(provider, path)}\n`);
56
86
  return ExitCode.Ok;
57
87
  }
58
88
  case "list": {
59
89
  if (positionals.length > 1)
60
- throw new UsageError(`多余的参数:${positionals.slice(1).join(" ")}`);
90
+ throw new UsageError(m.extraArgs(positionals.slice(1).join(" ")));
61
91
  const result = readAuthFile(path);
62
92
  for (const warning of result.warnings)
63
- io.stderr(`ama: 警告:${warning}\n`);
93
+ io.stderr(`${m.warning(warning)}\n`);
64
94
  const entries = describeAuthFile(result.file);
65
95
  if (entries.length === 0) {
66
- io.stdout(`${path}:没有保存的 key\n`);
96
+ io.stdout(`${m.listEmpty(path)}\n`);
67
97
  return ExitCode.Ok;
68
98
  }
69
99
  io.stdout(`${path}\n`);
@@ -72,20 +102,20 @@ export async function runAuth(argv, io) {
72
102
  entry.hasBaseUrl ? "baseUrl" : undefined,
73
103
  entry.envNames.length > 0 ? `env ${entry.envNames.join(",")}` : undefined,
74
104
  ].filter((x) => x !== undefined);
75
- io.stdout(` ${entry.provider.padEnd(20)} ${KIND_TEXT[entry.kind]}${extra.length > 0 ? ` · ${extra.join(" · ")}` : ""}\n`);
105
+ io.stdout(` ${entry.provider.padEnd(20)} ${kindText(entry)}${extra.length > 0 ? ` · ${extra.join(" · ")}` : ""}\n`);
76
106
  }
77
107
  return ExitCode.Ok;
78
108
  }
79
109
  case "remove": {
80
110
  const provider = providerArg(positionals, "remove");
81
111
  if (removeAuthKey(path, provider)) {
82
- io.stdout(`已删除 ${provider} 的 key(${path})\n`);
112
+ io.stdout(`${m.removed(provider, path)}\n`);
83
113
  return ExitCode.Ok;
84
114
  }
85
- io.stderr(`ama: ${path} 中没有 ${provider}\n`);
115
+ io.stderr(`${m.notFound(path, provider)}\n`);
86
116
  return ExitCode.RuntimeError;
87
117
  }
88
118
  default:
89
- throw new UsageError(`未知的 auth 子命令:${action}`);
119
+ throw new UsageError(m.unknownAction(action));
90
120
  }
91
121
  }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `ama config get | set | unset | list` (docs/wave6-plan.md §6.4, D24-D26). [W6-S]
3
+ *
4
+ * Thin layer over config/edit.ts (the `/config` panel uses the same core):
5
+ * - `get <key> [--json]`: effective value, source layer and apply tier;
6
+ * - `set <key> <value> [--project] [--json-value] [--yes]`: write one key to the user file (or the
7
+ * project file, tighten only); lists and objects need `--json-value`; `permission.mode full-auto`
8
+ * asks once on a TTY and needs `--yes` otherwise;
9
+ * - `unset <key> [--project]`;
10
+ * - `list [prefix] [--json] [--all]`: panel settings (or every settable key with `--all`).
11
+ * Unknown keys, invalid values and refused project writes exit 3 (`ExitCode.Config`). `get` / `list`
12
+ * never create the config directory. `--profile <file>` adds the host profile layer to the view.
13
+ */
14
+ import type { CliIo } from "../deps.js";
15
+ export declare const CONFIG_EDIT_ACTIONS: readonly ["get", "set", "unset", "list"];
16
+ export type ConfigEditAction = (typeof CONFIG_EDIT_ACTIONS)[number];
17
+ export interface ConfigSetDeps {
18
+ /** Ask before persisting Bypass (TTY only); default: the CLI y/N prompt. */
19
+ confirm?(question: string): Promise<boolean>;
20
+ }
21
+ export declare function runConfigEdit(action: ConfigEditAction, argv: readonly string[], io: CliIo, deps?: ConfigSetDeps): Promise<number>;
@@ -0,0 +1,137 @@
1
+ /**
2
+ * `ama config get | set | unset | list` (docs/wave6-plan.md §6.4, D24-D26). [W6-S]
3
+ *
4
+ * Thin layer over config/edit.ts (the `/config` panel uses the same core):
5
+ * - `get <key> [--json]`: effective value, source layer and apply tier;
6
+ * - `set <key> <value> [--project] [--json-value] [--yes]`: write one key to the user file (or the
7
+ * project file, tighten only); lists and objects need `--json-value`; `permission.mode full-auto`
8
+ * asks once on a TTY and needs `--yes` otherwise;
9
+ * - `unset <key> [--project]`;
10
+ * - `list [prefix] [--json] [--all]`: panel settings (or every settable key with `--all`).
11
+ * Unknown keys, invalid values and refused project writes exit 3 (`ExitCode.Config`). `get` / `list`
12
+ * never create the config directory. `--profile <file>` adds the host profile layer to the view.
13
+ */
14
+ import { msg } from "../../i18n/index.js";
15
+ import { assertSettable, formatSettingValue, getConfigValue, parseValue, readSnapshot, setConfigValue, } from "../../config/edit.js";
16
+ import { existsSync } from "node:fs";
17
+ import { join } from "node:path";
18
+ import { initConfigDir } from "../../config/init.js";
19
+ import { CONFIG_FILE, resolveConfigDir } from "../../config/paths.js";
20
+ import { loadProfile } from "../../config/profile.js";
21
+ import { settableKeys, settingSpec, settingsRegistry } from "../../config/settings-registry.js";
22
+ import { confirmContinue } from "../choice-prompt.js";
23
+ import { parseSubArgs, UsageError } from "../args.js";
24
+ import { ExitCode } from "../exit-codes.js";
25
+ export const CONFIG_EDIT_ACTIONS = ["get", "set", "unset", "list"];
26
+ function layerInput(io, profilePath) {
27
+ const input = {
28
+ configDir: resolveConfigDir({ env: io.env }),
29
+ cwd: io.cwd,
30
+ env: io.env,
31
+ };
32
+ if (profilePath !== undefined) {
33
+ const profile = loadProfile(profilePath, io.cwd);
34
+ input.profile = { config: profile.config };
35
+ input.hasProfile = true;
36
+ }
37
+ return input;
38
+ }
39
+ function applyText(key) {
40
+ const spec = settingSpec(key);
41
+ const s = msg().settings;
42
+ if (spec === undefined)
43
+ return s.cli.applyNone;
44
+ return spec.prefix === true ? `${s.apply[spec.apply]} · ${s.prefixTag}` : s.apply[spec.apply];
45
+ }
46
+ function jsonRow(value) {
47
+ const spec = settingSpec(value.key);
48
+ return {
49
+ key: value.key,
50
+ value: value.value ?? null,
51
+ source: value.source,
52
+ ...(value.envName !== undefined ? { env: value.envName } : {}),
53
+ apply: spec?.apply ?? null,
54
+ prefix: spec?.prefix === true,
55
+ project: spec?.project ?? null,
56
+ };
57
+ }
58
+ function textRow(value) {
59
+ const source = value.envName !== undefined ? `env ${value.envName}` : value.source;
60
+ return msg().settings.cli.getLine(value.key, formatSettingValue(value.value), source, applyText(value.key));
61
+ }
62
+ function scopeLabel(scope) {
63
+ return msg().settings.scope[scope];
64
+ }
65
+ function report(io, result, unset) {
66
+ const s = msg().settings;
67
+ const value = formatSettingValue(result.after.value);
68
+ io.stdout(`${unset
69
+ ? s.unsetDone(result.key, value, scopeLabel(result.scope))
70
+ : s.setDone(result.key, value, scopeLabel(result.scope))}\n`);
71
+ if (result.overriddenBy !== undefined) {
72
+ const by = result.after.envName ?? result.overriddenBy;
73
+ io.stdout(`${s.stillOverridden(result.key, by)}\n`);
74
+ }
75
+ }
76
+ /** Confirm persisting `permission.mode full-auto`: TTY asks, otherwise `--yes` is required. */
77
+ async function confirmBypass(io, yes, deps) {
78
+ const s = msg().settings.cli;
79
+ if (yes)
80
+ return true;
81
+ if (!io.stdinIsTTY) {
82
+ io.stderr(`ama: ${s.needYes}\n`);
83
+ return false;
84
+ }
85
+ const ask = deps.confirm ?? ((question) => confirmContinue({ question, env: io.env }));
86
+ if (await ask(s.confirmBypass))
87
+ return true;
88
+ io.stderr(`${s.cancelled}\n`);
89
+ return false;
90
+ }
91
+ export async function runConfigEdit(action, argv, io, deps = {}) {
92
+ const { positionals, values, flags } = parseSubArgs(argv, ["profile"], ["json", "project", "json-value", "yes", "all"]);
93
+ const s = msg().settings;
94
+ if (flags.has("help")) {
95
+ io.stdout(s.cli.usage);
96
+ return ExitCode.Ok;
97
+ }
98
+ const input = layerInput(io, values.get("profile"));
99
+ const scope = flags.has("project") ? "project" : "user";
100
+ if (action === "list") {
101
+ const snapshot = readSnapshot(input);
102
+ const prefix = positionals[0] ?? "";
103
+ const keys = (flags.has("all") ? settableKeys() : settingsRegistry().map((spec) => spec.key)).filter((key) => key.startsWith(prefix));
104
+ const rows = keys.map((key) => getConfigValue(snapshot, key));
105
+ if (flags.has("json"))
106
+ io.stdout(`${JSON.stringify(rows.map(jsonRow), null, 2)}\n`);
107
+ else
108
+ io.stdout(`${[s.cli.listHeader, ...rows.map((r) => ` ${textRow(r)}`)].join("\n")}\n`);
109
+ return ExitCode.Ok;
110
+ }
111
+ const key = positionals[0];
112
+ if (key === undefined)
113
+ throw new UsageError(s.cli.missingKey);
114
+ if (action === "get") {
115
+ assertSettable(key);
116
+ const value = getConfigValue(readSnapshot(input), key);
117
+ io.stdout(flags.has("json") ? `${JSON.stringify(jsonRow(value), null, 2)}\n` : `${textRow(value)}\n`);
118
+ return ExitCode.Ok;
119
+ }
120
+ if (action === "unset") {
121
+ report(io, setConfigValue({ ...input, scope, key, value: undefined }), true);
122
+ return ExitCode.Ok;
123
+ }
124
+ const raw = positionals.slice(1).join(" ");
125
+ if (positionals.length < 2)
126
+ throw new UsageError(s.cli.missingValue);
127
+ const value = parseValue(key, raw, flags.has("json-value"));
128
+ if (key === "permission.mode" && value === "full-auto" && scope === "user") {
129
+ if (!(await confirmBypass(io, flags.has("yes"), deps)))
130
+ return ExitCode.Config;
131
+ }
132
+ // first write to a fresh config dir: lay out config.json + config.schema.json like `ama init`
133
+ if (scope === "user" && !existsSync(join(input.configDir, CONFIG_FILE)))
134
+ initConfigDir(input.configDir);
135
+ report(io, setConfigValue({ ...input, scope, key, value }), value === undefined);
136
+ return ExitCode.Ok;
137
+ }
@@ -14,7 +14,8 @@
14
14
  import { type AmaConfig, type CodemodeMode } from "../../config/types.js";
15
15
  import type { Api, ProviderRegistryApi } from "../../ai/types.js";
16
16
  import type { CliIo, RuntimeDeps } from "../deps.js";
17
- export declare const CONFIG_USAGE = "\u7528\u6CD5\uFF1Aama config show [--json] [--profile <\u6587\u4EF6>] [--auth-file <\u6587\u4EF6>]\n [--tools-preset <\u540D>] [--codemode off|on|only]\n ama config path \u914D\u7F6E\u76EE\u5F55\u3001\u6570\u636E\u76EE\u5F55\u4E0E\u5404\u6587\u4EF6\u8DEF\u5F84\n ama config edit \u7528 $VISUAL / $EDITOR \u6253\u5F00 config.json\uFF08\u6CA1\u6709\u7F16\u8F91\u5668\u65F6\u6253\u5370\u8DEF\u5F84\uFF09\n";
17
+ /** `ama config --help` 的前半(get / set 等编辑子命令的用法接在后面)。 */
18
+ export declare const configUsage: () => string;
18
19
  type Layer = {
19
20
  name: "default" | "user" | "profile" | "project" | "cli";
20
21
  label: string;