@armadra/agent 0.3.0 → 0.5.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 (527) hide show
  1. package/CHANGELOG.md +257 -0
  2. package/README.md +263 -95
  3. package/THIRD_PARTY_NOTICES.md +34 -0
  4. package/dist/acp.d.ts +18 -0
  5. package/dist/acp.js +19 -0
  6. package/dist/agent/limits.d.ts +38 -0
  7. package/dist/agent/limits.js +127 -0
  8. package/dist/agent/loop-guard.d.ts +38 -0
  9. package/dist/agent/loop-guard.js +95 -0
  10. package/dist/agent/loop.d.ts +4 -0
  11. package/dist/agent/loop.js +7 -0
  12. package/dist/agent/prompt-rules.d.ts +12 -0
  13. package/dist/agent/prompt-rules.js +18 -0
  14. package/dist/agent/reminders.d.ts +59 -0
  15. package/dist/agent/reminders.js +327 -0
  16. package/dist/agent/retry.d.ts +1 -1
  17. package/dist/agent/retry.js +2 -1
  18. package/dist/agent/session-cache.d.ts +5 -0
  19. package/dist/agent/session-cache.js +18 -2
  20. package/dist/agent/session-classifier.d.ts +18 -0
  21. package/dist/agent/session-classifier.js +105 -0
  22. package/dist/agent/session-compaction.d.ts +35 -6
  23. package/dist/agent/session-compaction.js +157 -31
  24. package/dist/agent/session-core.d.ts +40 -1
  25. package/dist/agent/session-extensions.d.ts +61 -0
  26. package/dist/agent/session-extensions.js +129 -0
  27. package/dist/agent/session-images.d.ts +23 -0
  28. package/dist/agent/session-images.js +97 -0
  29. package/dist/agent/session-plan.d.ts +21 -0
  30. package/dist/agent/session-plan.js +524 -0
  31. package/dist/agent/session-rewind.d.ts +81 -0
  32. package/dist/agent/session-rewind.js +354 -0
  33. package/dist/agent/session-run.d.ts +28 -1
  34. package/dist/agent/session-run.js +157 -6
  35. package/dist/agent/session-settings.d.ts +49 -0
  36. package/dist/agent/session-settings.js +95 -0
  37. package/dist/agent/session-subagent.d.ts +36 -24
  38. package/dist/agent/session-subagent.js +259 -129
  39. package/dist/agent/session-sync.d.ts +10 -3
  40. package/dist/agent/session-sync.js +37 -8
  41. package/dist/agent/session-telemetry.d.ts +39 -0
  42. package/dist/agent/session-telemetry.js +231 -0
  43. package/dist/agent/session-tools.js +63 -3
  44. package/dist/agent/session.d.ts +33 -29
  45. package/dist/agent/session.js +91 -126
  46. package/dist/agent/subagent-registry.d.ts +91 -0
  47. package/dist/agent/subagent-registry.js +494 -0
  48. package/dist/agent/system-prompt.d.ts +6 -3
  49. package/dist/agent/system-prompt.js +7 -2
  50. package/dist/agent/tool-runner.d.ts +8 -1
  51. package/dist/agent/tool-runner.js +72 -6
  52. package/dist/agent/types-w5.d.ts +192 -0
  53. package/dist/agent/types-w5.js +10 -0
  54. package/dist/agent/types.d.ts +55 -4
  55. package/dist/agent/types.js +2 -0
  56. package/dist/agent/worktree.d.ts +36 -0
  57. package/dist/agent/worktree.js +86 -0
  58. package/dist/agents/builtin.d.ts +14 -0
  59. package/dist/agents/builtin.js +39 -0
  60. package/dist/agents/catalog.d.ts +43 -0
  61. package/dist/agents/catalog.js +82 -0
  62. package/dist/agents/discover.d.ts +35 -0
  63. package/dist/agents/discover.js +83 -0
  64. package/dist/agents/external.d.ts +82 -0
  65. package/dist/agents/external.js +326 -0
  66. package/dist/agents/parse.d.ts +18 -0
  67. package/dist/agents/parse.js +116 -0
  68. package/dist/agents/result.d.ts +32 -0
  69. package/dist/agents/result.js +67 -0
  70. package/dist/agents/task-control.d.ts +17 -0
  71. package/dist/agents/task-control.js +17 -0
  72. package/dist/agents/task-record.d.ts +78 -0
  73. package/dist/agents/task-record.js +141 -0
  74. package/dist/agents/types.d.ts +46 -0
  75. package/dist/agents/types.js +8 -0
  76. package/dist/ai/apis/anthropic-compat.d.ts +36 -0
  77. package/dist/ai/apis/anthropic-compat.js +92 -0
  78. package/dist/ai/apis/anthropic-messages.js +3 -2
  79. package/dist/ai/apis/anthropic-request.d.ts +7 -6
  80. package/dist/ai/apis/anthropic-request.js +10 -28
  81. package/dist/ai/apis/cache-params.d.ts +11 -2
  82. package/dist/ai/apis/cache-params.js +25 -6
  83. package/dist/ai/apis/google-generative-ai.js +3 -2
  84. package/dist/ai/apis/openai-compat.d.ts +4 -1
  85. package/dist/ai/apis/openai-compat.js +8 -1
  86. package/dist/ai/apis/openai-completions.js +3 -2
  87. package/dist/ai/apis/openai-responses.js +3 -2
  88. package/dist/ai/http.d.ts +28 -6
  89. package/dist/ai/http.js +41 -8
  90. package/dist/ai/image-limits.d.ts +45 -0
  91. package/dist/ai/image-limits.js +68 -0
  92. package/dist/ai/providers/builtin.d.ts +18 -6
  93. package/dist/ai/providers/builtin.js +135 -6
  94. package/dist/ai/providers/catalog-data.js +17 -13
  95. package/dist/ai/providers/catalog.d.ts +60 -7
  96. package/dist/ai/providers/catalog.js +197 -38
  97. package/dist/ai/providers/channels.d.ts +33 -3
  98. package/dist/ai/providers/channels.js +108 -7
  99. package/dist/ai/providers/enrich.d.ts +6 -3
  100. package/dist/ai/providers/enrich.js +19 -4
  101. package/dist/ai/providers/models-dev-cache.d.ts +28 -24
  102. package/dist/ai/providers/models-dev-cache.js +92 -78
  103. package/dist/ai/providers/models-dev-data.d.ts +7 -0
  104. package/dist/ai/providers/models-dev-data.js +32 -0
  105. package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
  106. package/dist/ai/providers/models-dev-snapshot.js +137 -0
  107. package/dist/ai/providers/models-dev.d.ts +51 -10
  108. package/dist/ai/providers/models-dev.js +132 -39
  109. package/dist/ai/providers/registry.d.ts +28 -11
  110. package/dist/ai/providers/registry.js +112 -65
  111. package/dist/ai/providers/suggest.d.ts +18 -0
  112. package/dist/ai/providers/suggest.js +72 -0
  113. package/dist/ai/sse.d.ts +6 -2
  114. package/dist/ai/sse.js +22 -2
  115. package/dist/ai/types.d.ts +37 -4
  116. package/dist/ai/types.js +5 -0
  117. package/dist/bundle/ama.cjs +41979 -21147
  118. package/dist/checkpoints/backend.d.ts +61 -0
  119. package/dist/checkpoints/backend.js +135 -0
  120. package/dist/checkpoints/blobs.d.ts +60 -0
  121. package/dist/checkpoints/blobs.js +203 -0
  122. package/dist/checkpoints/gc.d.ts +47 -0
  123. package/dist/checkpoints/gc.js +144 -0
  124. package/dist/checkpoints/git-head.d.ts +15 -0
  125. package/dist/checkpoints/git-head.js +89 -0
  126. package/dist/checkpoints/index.d.ts +17 -0
  127. package/dist/checkpoints/index.js +17 -0
  128. package/dist/checkpoints/replay.d.ts +48 -0
  129. package/dist/checkpoints/replay.js +154 -0
  130. package/dist/checkpoints/restore.d.ts +86 -0
  131. package/dist/checkpoints/restore.js +263 -0
  132. package/dist/checkpoints/settings.d.ts +14 -0
  133. package/dist/checkpoints/settings.js +23 -0
  134. package/dist/checkpoints/shadow-git.d.ts +108 -0
  135. package/dist/checkpoints/shadow-git.js +491 -0
  136. package/dist/checkpoints/shadow-restore.d.ts +25 -0
  137. package/dist/checkpoints/shadow-restore.js +128 -0
  138. package/dist/checkpoints/tracker.d.ts +64 -0
  139. package/dist/checkpoints/tracker.js +192 -0
  140. package/dist/checkpoints/types.d.ts +99 -0
  141. package/dist/checkpoints/types.js +12 -0
  142. package/dist/cli/args.d.ts +26 -7
  143. package/dist/cli/args.js +75 -82
  144. package/dist/cli/bootstrap.js +40 -4
  145. package/dist/cli/codemode-notice.d.ts +21 -0
  146. package/dist/cli/codemode-notice.js +56 -0
  147. package/dist/cli/compose-agents.d.ts +27 -0
  148. package/dist/cli/compose-agents.js +111 -0
  149. package/dist/cli/compose-extensions.d.ts +29 -0
  150. package/dist/cli/compose-extensions.js +44 -0
  151. package/dist/cli/compose-session.d.ts +8 -0
  152. package/dist/cli/compose-session.js +76 -2
  153. package/dist/cli/compose-store.d.ts +1 -1
  154. package/dist/cli/compose-store.js +3 -1
  155. package/dist/cli/compose.d.ts +17 -4
  156. package/dist/cli/compose.js +60 -14
  157. package/dist/cli/default-model.d.ts +38 -1
  158. package/dist/cli/default-model.js +96 -9
  159. package/dist/cli/deps.d.ts +42 -0
  160. package/dist/cli/exit-codes.d.ts +12 -0
  161. package/dist/cli/exit-codes.js +15 -0
  162. package/dist/cli/fake-visibility.d.ts +13 -0
  163. package/dist/cli/fake-visibility.js +26 -0
  164. package/dist/cli/from-prompt.d.ts +18 -0
  165. package/dist/cli/from-prompt.js +49 -0
  166. package/dist/cli/help-text.d.ts +4 -0
  167. package/dist/cli/help-text.js +102 -0
  168. package/dist/cli/main.d.ts +9 -2
  169. package/dist/cli/main.js +77 -3
  170. package/dist/cli/proxy.d.ts +51 -0
  171. package/dist/cli/proxy.js +135 -0
  172. package/dist/cli/startup-screen.d.ts +29 -0
  173. package/dist/cli/startup-screen.js +51 -2
  174. package/dist/cli/startup-steps.d.ts +1 -1
  175. package/dist/cli/startup-steps.js +21 -13
  176. package/dist/cli/subcommands/config.d.ts +22 -3
  177. package/dist/cli/subcommands/config.js +119 -21
  178. package/dist/cli/subcommands/context.js +4 -1
  179. package/dist/cli/subcommands/doctor.js +33 -1
  180. package/dist/cli/subcommands/init.js +2 -1
  181. package/dist/cli/subcommands/models-discover.d.ts +15 -9
  182. package/dist/cli/subcommands/models-discover.js +58 -52
  183. package/dist/cli/subcommands/models.d.ts +2 -0
  184. package/dist/cli/subcommands/models.js +33 -14
  185. package/dist/cli/subcommands/probe-runner.d.ts +96 -0
  186. package/dist/cli/subcommands/probe-runner.js +264 -0
  187. package/dist/cli/subcommands/providers-probe.d.ts +34 -0
  188. package/dist/cli/subcommands/providers-probe.js +87 -0
  189. package/dist/cli/subcommands/providers.d.ts +3 -2
  190. package/dist/cli/subcommands/providers.js +53 -51
  191. package/dist/cli/subcommands/sessions-export.d.ts +10 -0
  192. package/dist/cli/subcommands/sessions-export.js +59 -0
  193. package/dist/cli/subcommands/sessions-search.d.ts +13 -0
  194. package/dist/cli/subcommands/sessions-search.js +103 -0
  195. package/dist/cli/subcommands/sessions.d.ts +6 -3
  196. package/dist/cli/subcommands/sessions.js +58 -3
  197. package/dist/cli/subcommands/stats.d.ts +17 -0
  198. package/dist/cli/subcommands/stats.js +198 -0
  199. package/dist/cli/system-prompt-arg.d.ts +11 -0
  200. package/dist/cli/system-prompt-arg.js +34 -0
  201. package/dist/codemode/capability.d.ts +24 -7
  202. package/dist/codemode/capability.js +38 -10
  203. package/dist/codemode/host-side.d.ts +14 -0
  204. package/dist/codemode/host-side.js +24 -1
  205. package/dist/codemode/modes.d.ts +4 -11
  206. package/dist/codemode/modes.js +5 -27
  207. package/dist/codemode/tool.d.ts +18 -14
  208. package/dist/codemode/tool.js +76 -31
  209. package/dist/compaction/breaker.d.ts +25 -9
  210. package/dist/compaction/breaker.js +47 -17
  211. package/dist/compaction/estimate.d.ts +11 -3
  212. package/dist/compaction/estimate.js +64 -22
  213. package/dist/compaction/image-budget.d.ts +45 -0
  214. package/dist/compaction/image-budget.js +115 -0
  215. package/dist/compaction/post-compact.d.ts +38 -0
  216. package/dist/compaction/post-compact.js +152 -0
  217. package/dist/compaction/protect.d.ts +27 -0
  218. package/dist/compaction/protect.js +56 -0
  219. package/dist/compaction/prune-tier.d.ts +58 -12
  220. package/dist/compaction/prune-tier.js +120 -54
  221. package/dist/compaction/summarize-tier.d.ts +23 -4
  222. package/dist/compaction/summarize-tier.js +100 -29
  223. package/dist/config/checker.d.ts +28 -0
  224. package/dist/config/checker.js +97 -0
  225. package/dist/config/init.d.ts +6 -2
  226. package/dist/config/init.js +12 -5
  227. package/dist/config/json-schema.d.ts +1 -0
  228. package/dist/config/json-schema.js +98 -4
  229. package/dist/config/key-docs.d.ts +22 -0
  230. package/dist/config/key-docs.js +174 -0
  231. package/dist/config/merge.d.ts +12 -9
  232. package/dist/config/merge.js +102 -13
  233. package/dist/config/profile.d.ts +2 -0
  234. package/dist/config/profile.js +2 -0
  235. package/dist/config/schema-w5.d.ts +18 -0
  236. package/dist/config/schema-w5.js +109 -0
  237. package/dist/config/schema.d.ts +5 -9
  238. package/dist/config/schema.js +91 -118
  239. package/dist/config/types-w5.d.ts +118 -0
  240. package/dist/config/types-w5.js +20 -0
  241. package/dist/config/types.d.ts +84 -7
  242. package/dist/config/types.js +29 -1
  243. package/dist/drivers/acp/client.d.ts +57 -0
  244. package/dist/drivers/acp/client.js +160 -0
  245. package/dist/drivers/acp/driver.d.ts +31 -0
  246. package/dist/drivers/acp/driver.js +274 -0
  247. package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
  248. package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
  249. package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
  250. package/dist/drivers/acp/testing/fake-agent.js +211 -0
  251. package/dist/drivers/acp/types.d.ts +285 -0
  252. package/dist/drivers/acp/types.js +36 -0
  253. package/dist/drivers/agents.d.ts +58 -0
  254. package/dist/drivers/agents.js +142 -0
  255. package/dist/drivers/base.d.ts +35 -0
  256. package/dist/drivers/base.js +59 -0
  257. package/dist/drivers/catalog.d.ts +46 -0
  258. package/dist/drivers/catalog.js +167 -0
  259. package/dist/drivers/env.d.ts +20 -0
  260. package/dist/drivers/env.js +46 -0
  261. package/dist/drivers/host-runners.d.ts +18 -0
  262. package/dist/drivers/host-runners.js +45 -0
  263. package/dist/drivers/jsonrpc.d.ts +58 -0
  264. package/dist/drivers/jsonrpc.js +180 -0
  265. package/dist/drivers/native/claude-normalize.d.ts +46 -0
  266. package/dist/drivers/native/claude-normalize.js +106 -0
  267. package/dist/drivers/native/claude-stream.d.ts +29 -0
  268. package/dist/drivers/native/claude-stream.js +456 -0
  269. package/dist/drivers/native/codex-app-server.d.ts +26 -0
  270. package/dist/drivers/native/codex-app-server.js +407 -0
  271. package/dist/drivers/native/codex-normalize.d.ts +38 -0
  272. package/dist/drivers/native/codex-normalize.js +124 -0
  273. package/dist/drivers/native/oneshot.d.ts +28 -0
  274. package/dist/drivers/native/oneshot.js +312 -0
  275. package/dist/drivers/permissions.d.ts +40 -0
  276. package/dist/drivers/permissions.js +92 -0
  277. package/dist/drivers/pids.d.ts +32 -0
  278. package/dist/drivers/pids.js +93 -0
  279. package/dist/drivers/pool.d.ts +28 -0
  280. package/dist/drivers/pool.js +96 -0
  281. package/dist/drivers/probe.d.ts +47 -0
  282. package/dist/drivers/probe.js +172 -0
  283. package/dist/drivers/process.d.ts +48 -0
  284. package/dist/drivers/process.js +100 -0
  285. package/dist/drivers/runner.d.ts +61 -0
  286. package/dist/drivers/runner.js +388 -0
  287. package/dist/drivers/store.d.ts +49 -0
  288. package/dist/drivers/store.js +91 -0
  289. package/dist/drivers/turn.d.ts +41 -0
  290. package/dist/drivers/turn.js +99 -0
  291. package/dist/drivers/types.d.ts +122 -0
  292. package/dist/drivers/types.js +11 -0
  293. package/dist/git/info.d.ts +75 -0
  294. package/dist/git/info.js +191 -0
  295. package/dist/hooks/protocol.js +6 -1
  296. package/dist/hooks/types.d.ts +10 -1
  297. package/dist/hooks/types.js +2 -0
  298. package/dist/host/api-impl.d.ts +7 -0
  299. package/dist/host/api-impl.js +15 -0
  300. package/dist/host/types.d.ts +24 -2
  301. package/dist/host/types.js +4 -0
  302. package/dist/index.d.ts +3 -0
  303. package/dist/index.js +1 -0
  304. package/dist/modes/acp/acp-events.d.ts +46 -0
  305. package/dist/modes/acp/acp-events.js +233 -0
  306. package/dist/modes/acp/acp-mode.d.ts +17 -0
  307. package/dist/modes/acp/acp-mode.js +47 -0
  308. package/dist/modes/acp/acp-server.d.ts +79 -0
  309. package/dist/modes/acp/acp-server.js +315 -0
  310. package/dist/modes/commands-core.d.ts +7 -1
  311. package/dist/modes/commands-core.js +61 -5
  312. package/dist/modes/image-input.d.ts +12 -4
  313. package/dist/modes/image-input.js +22 -5
  314. package/dist/modes/interactive/agent-panels.d.ts +14 -0
  315. package/dist/modes/interactive/agent-panels.js +103 -0
  316. package/dist/modes/interactive/agent-ui.d.ts +73 -0
  317. package/dist/modes/interactive/agent-ui.js +234 -0
  318. package/dist/modes/interactive/approval-dialog.d.ts +40 -7
  319. package/dist/modes/interactive/approval-dialog.js +192 -35
  320. package/dist/modes/interactive/approval-merge.d.ts +41 -0
  321. package/dist/modes/interactive/approval-merge.js +89 -0
  322. package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
  323. package/dist/modes/interactive/clipboard-paste.js +28 -0
  324. package/dist/modes/interactive/commands.d.ts +20 -3
  325. package/dist/modes/interactive/commands.js +75 -16
  326. package/dist/modes/interactive/double-esc.d.ts +20 -0
  327. package/dist/modes/interactive/double-esc.js +34 -0
  328. package/dist/modes/interactive/event-notices.d.ts +32 -0
  329. package/dist/modes/interactive/event-notices.js +79 -0
  330. package/dist/modes/interactive/external-editor.d.ts +16 -0
  331. package/dist/modes/interactive/external-editor.js +39 -0
  332. package/dist/modes/interactive/interactive-mode.d.ts +16 -2
  333. package/dist/modes/interactive/interactive-mode.js +184 -202
  334. package/dist/modes/interactive/key-dispatch.d.ts +18 -2
  335. package/dist/modes/interactive/key-dispatch.js +53 -6
  336. package/dist/modes/interactive/line/line-mode.d.ts +3 -1
  337. package/dist/modes/interactive/line/line-mode.js +28 -9
  338. package/dist/modes/interactive/line/line-render.d.ts +6 -1
  339. package/dist/modes/interactive/line/line-render.js +66 -8
  340. package/dist/modes/interactive/message-view.d.ts +49 -10
  341. package/dist/modes/interactive/message-view.js +262 -46
  342. package/dist/modes/interactive/panels.d.ts +35 -0
  343. package/dist/modes/interactive/panels.js +157 -0
  344. package/dist/modes/interactive/pickers.d.ts +23 -2
  345. package/dist/modes/interactive/pickers.js +48 -15
  346. package/dist/modes/interactive/plan-command.d.ts +40 -0
  347. package/dist/modes/interactive/plan-command.js +129 -0
  348. package/dist/modes/interactive/plan-dialog.d.ts +98 -0
  349. package/dist/modes/interactive/plan-dialog.js +290 -0
  350. package/dist/modes/interactive/plan-flow.d.ts +34 -0
  351. package/dist/modes/interactive/plan-flow.js +98 -0
  352. package/dist/modes/interactive/rewind-command.d.ts +31 -0
  353. package/dist/modes/interactive/rewind-command.js +106 -0
  354. package/dist/modes/interactive/rewind-flow.d.ts +37 -0
  355. package/dist/modes/interactive/rewind-flow.js +151 -0
  356. package/dist/modes/interactive/rewind-list.d.ts +36 -0
  357. package/dist/modes/interactive/rewind-list.js +123 -0
  358. package/dist/modes/interactive/rewind-panel.d.ts +77 -0
  359. package/dist/modes/interactive/rewind-panel.js +309 -0
  360. package/dist/modes/interactive/rewind-text.d.ts +40 -0
  361. package/dist/modes/interactive/rewind-text.js +139 -0
  362. package/dist/modes/interactive/run-indicator.d.ts +51 -0
  363. package/dist/modes/interactive/run-indicator.js +189 -0
  364. package/dist/modes/interactive/session-events.d.ts +24 -0
  365. package/dist/modes/interactive/session-events.js +96 -0
  366. package/dist/modes/interactive/startup-header.d.ts +40 -0
  367. package/dist/modes/interactive/startup-header.js +169 -0
  368. package/dist/modes/interactive/status-area.d.ts +73 -0
  369. package/dist/modes/interactive/status-area.js +190 -0
  370. package/dist/modes/interactive/status-bar.d.ts +107 -16
  371. package/dist/modes/interactive/status-bar.js +306 -81
  372. package/dist/modes/interactive/status-line.d.ts +33 -0
  373. package/dist/modes/interactive/status-line.js +113 -0
  374. package/dist/modes/interactive/subagent-view.d.ts +56 -0
  375. package/dist/modes/interactive/subagent-view.js +154 -0
  376. package/dist/modes/interactive/tasks-report.d.ts +27 -0
  377. package/dist/modes/interactive/tasks-report.js +114 -0
  378. package/dist/modes/interactive/tool-summary.d.ts +46 -0
  379. package/dist/modes/interactive/tool-summary.js +218 -0
  380. package/dist/modes/interactive/tool-view.d.ts +58 -15
  381. package/dist/modes/interactive/tool-view.js +233 -145
  382. package/dist/modes/print/print-mode.d.ts +40 -4
  383. package/dist/modes/print/print-mode.js +161 -8
  384. package/dist/modes/rpc/commands.d.ts +9 -0
  385. package/dist/modes/rpc/commands.js +49 -0
  386. package/dist/modes/rpc/rpc-mode.js +7 -1
  387. package/dist/modes/session-report.d.ts +11 -0
  388. package/dist/modes/session-report.js +48 -1
  389. package/dist/permissions/auto-safe.d.ts +65 -0
  390. package/dist/permissions/auto-safe.js +547 -0
  391. package/dist/permissions/classifier.d.ts +68 -0
  392. package/dist/permissions/classifier.js +186 -0
  393. package/dist/permissions/dangerous.d.ts +5 -0
  394. package/dist/permissions/dangerous.js +1 -1
  395. package/dist/permissions/modes.d.ts +30 -0
  396. package/dist/permissions/modes.js +78 -0
  397. package/dist/permissions/pipeline.d.ts +72 -6
  398. package/dist/permissions/pipeline.js +306 -11
  399. package/dist/permissions/protected.d.ts +19 -0
  400. package/dist/permissions/protected.js +74 -0
  401. package/dist/permissions/readonly-bash.d.ts +30 -0
  402. package/dist/permissions/readonly-bash.js +118 -0
  403. package/dist/permissions/rules.js +3 -0
  404. package/dist/permissions/types.d.ts +92 -3
  405. package/dist/permissions/types.js +3 -0
  406. package/dist/plan/compose.d.ts +9 -0
  407. package/dist/plan/compose.js +19 -0
  408. package/dist/plan/controller.d.ts +71 -0
  409. package/dist/plan/controller.js +27 -0
  410. package/dist/plan/done-markers.d.ts +17 -0
  411. package/dist/plan/done-markers.js +51 -0
  412. package/dist/plan/extract.d.ts +29 -0
  413. package/dist/plan/extract.js +160 -0
  414. package/dist/plan/prompts.d.ts +36 -0
  415. package/dist/plan/prompts.js +89 -0
  416. package/dist/plan/store.d.ts +37 -0
  417. package/dist/plan/store.js +90 -0
  418. package/dist/rpc.d.ts +58 -2
  419. package/dist/rpc.js +7 -0
  420. package/dist/sandbox/bash.d.ts +74 -0
  421. package/dist/sandbox/bash.js +126 -0
  422. package/dist/sandbox/detect.d.ts +48 -0
  423. package/dist/sandbox/detect.js +149 -0
  424. package/dist/sandbox/index.d.ts +5 -0
  425. package/dist/sandbox/index.js +5 -0
  426. package/dist/sandbox/profile.d.ts +33 -0
  427. package/dist/sandbox/profile.js +76 -0
  428. package/dist/sandbox/wrap.d.ts +29 -0
  429. package/dist/sandbox/wrap.js +117 -0
  430. package/dist/sdk.d.ts +42 -5
  431. package/dist/sdk.js +34 -4
  432. package/dist/session/export.d.ts +32 -0
  433. package/dist/session/export.js +187 -0
  434. package/dist/session/redact.d.ts +15 -0
  435. package/dist/session/redact.js +55 -0
  436. package/dist/session/reuse.d.ts +33 -0
  437. package/dist/session/reuse.js +86 -0
  438. package/dist/session/scan.d.ts +34 -0
  439. package/dist/session/scan.js +140 -0
  440. package/dist/session/search.d.ts +52 -0
  441. package/dist/session/search.js +211 -0
  442. package/dist/session/stats-aggregate.d.ts +63 -0
  443. package/dist/session/stats-aggregate.js +163 -0
  444. package/dist/session/stats-index.d.ts +26 -0
  445. package/dist/session/stats-index.js +91 -0
  446. package/dist/session/stats-scan.d.ts +54 -0
  447. package/dist/session/stats-scan.js +236 -0
  448. package/dist/session/types.d.ts +3 -1
  449. package/dist/session/types.js +1 -0
  450. package/dist/skills/builtin.d.ts +31 -0
  451. package/dist/skills/builtin.js +109 -0
  452. package/dist/skills/discover.d.ts +2 -1
  453. package/dist/skills/index-prompt.js +5 -8
  454. package/dist/tools/background-jobs.d.ts +71 -0
  455. package/dist/tools/background-jobs.js +198 -0
  456. package/dist/tools/bash.d.ts +53 -1
  457. package/dist/tools/bash.js +158 -7
  458. package/dist/tools/clipboard-image.d.ts +44 -0
  459. package/dist/tools/clipboard-image.js +148 -0
  460. package/dist/tools/edit.d.ts +2 -0
  461. package/dist/tools/edit.js +18 -3
  462. package/dist/tools/image-file.d.ts +38 -3
  463. package/dist/tools/image-file.js +81 -10
  464. package/dist/tools/image-resize.d.ts +58 -0
  465. package/dist/tools/image-resize.js +97 -0
  466. package/dist/tools/presets.d.ts +40 -8
  467. package/dist/tools/presets.js +65 -19
  468. package/dist/tools/read.d.ts +5 -2
  469. package/dist/tools/read.js +13 -10
  470. package/dist/tools/registry.d.ts +7 -1
  471. package/dist/tools/registry.js +27 -4
  472. package/dist/tools/task-ctl.d.ts +22 -0
  473. package/dist/tools/task-ctl.js +116 -0
  474. package/dist/tools/task.d.ts +22 -10
  475. package/dist/tools/task.js +66 -26
  476. package/dist/tools/todo.d.ts +22 -2
  477. package/dist/tools/todo.js +58 -14
  478. package/dist/tools/truncate.d.ts +15 -0
  479. package/dist/tools/truncate.js +25 -0
  480. package/dist/tools/types.d.ts +113 -0
  481. package/dist/tools/types.js +5 -0
  482. package/dist/tools/write.js +3 -0
  483. package/dist/tui/component.d.ts +8 -2
  484. package/dist/tui/component.js +3 -1
  485. package/dist/tui/components/box.d.ts +6 -1
  486. package/dist/tui/components/box.js +16 -6
  487. package/dist/tui/components/card.d.ts +23 -0
  488. package/dist/tui/components/card.js +37 -0
  489. package/dist/tui/components/editor-history.d.ts +6 -0
  490. package/dist/tui/components/editor-history.js +45 -0
  491. package/dist/tui/components/editor-paste.d.ts +1 -1
  492. package/dist/tui/components/editor-paste.js +4 -4
  493. package/dist/tui/components/editor.d.ts +11 -5
  494. package/dist/tui/components/editor.js +52 -58
  495. package/dist/tui/components/key-value.d.ts +3 -0
  496. package/dist/tui/components/key-value.js +16 -6
  497. package/dist/tui/components/loader.d.ts +37 -7
  498. package/dist/tui/components/loader.js +84 -21
  499. package/dist/tui/components/markdown.d.ts +5 -1
  500. package/dist/tui/components/markdown.js +45 -21
  501. package/dist/tui/components/meter.d.ts +3 -3
  502. package/dist/tui/components/meter.js +13 -11
  503. package/dist/tui/components/select-list.d.ts +23 -1
  504. package/dist/tui/components/select-list.js +76 -13
  505. package/dist/tui/glyphs.d.ts +72 -0
  506. package/dist/tui/glyphs.js +118 -0
  507. package/dist/tui/keybindings.d.ts +5 -0
  508. package/dist/tui/keybindings.js +5 -0
  509. package/dist/tui/theme.d.ts +30 -6
  510. package/dist/tui/theme.js +103 -17
  511. package/dist/tui.d.ts +4 -2
  512. package/dist/tui.js +3 -1
  513. package/docs/acp.md +78 -0
  514. package/docs/agents.md +250 -0
  515. package/docs/codemode.md +28 -10
  516. package/docs/hooks.md +36 -32
  517. package/docs/permissions.md +212 -0
  518. package/docs/plan.md +107 -0
  519. package/docs/providers.md +261 -62
  520. package/docs/rewind-plan.md +181 -0
  521. package/docs/rpc.md +127 -40
  522. package/docs/sandbox.md +215 -0
  523. package/docs/session-format.md +43 -22
  524. package/docs/sessions.md +174 -0
  525. package/docs/tui-design.md +751 -0
  526. package/docs/tui.md +260 -64
  527. package/package.json +15 -2
@@ -16,6 +16,18 @@ export declare const ExitCode: {
16
16
  readonly Session: 5;
17
17
  /** 宿主 / Hook 加载或启动失败。 */
18
18
  readonly HostOrHook: 6;
19
+ /** `-p` 运行中有工具调用被拒(无人审批、deny 规则、plan 等),要求的动作没有完成。 */
20
+ readonly ToolDenied: 7;
21
+ /**
22
+ * [W5-C0] `-p` 到达 `--max-turns` / `--max-cost` / `limits.*` 上限(`limit_reached`,W5-H2)。
23
+ * 设计稿写的是 7,但 7 已发布为 ToolDenied,这里用 8。
24
+ */
25
+ readonly LimitReached: 8;
26
+ /**
27
+ * [W5-H2] `-p` 在 plan 模式产出计划、已落盘但没有人审批(`plan.unattended: stop`,缺省):
28
+ * 计划还没执行。不复用 7(7 已发布为「工具调用被拒」)。
29
+ */
30
+ readonly PlanPending: 9;
19
31
  /** HOST_API_VERSION 不匹配。 */
20
32
  readonly HostVersion: 78;
21
33
  /** SIGINT 退出(两次 Ctrl+C)。 */
@@ -16,6 +16,18 @@ export const ExitCode = {
16
16
  Session: 5,
17
17
  /** 宿主 / Hook 加载或启动失败。 */
18
18
  HostOrHook: 6,
19
+ /** `-p` 运行中有工具调用被拒(无人审批、deny 规则、plan 等),要求的动作没有完成。 */
20
+ ToolDenied: 7,
21
+ /**
22
+ * [W5-C0] `-p` 到达 `--max-turns` / `--max-cost` / `limits.*` 上限(`limit_reached`,W5-H2)。
23
+ * 设计稿写的是 7,但 7 已发布为 ToolDenied,这里用 8。
24
+ */
25
+ LimitReached: 8,
26
+ /**
27
+ * [W5-H2] `-p` 在 plan 模式产出计划、已落盘但没有人审批(`plan.unattended: stop`,缺省):
28
+ * 计划还没执行。不复用 7(7 已发布为「工具调用被拒」)。
29
+ */
30
+ PlanPending: 9,
19
31
  /** HOST_API_VERSION 不匹配。 */
20
32
  HostVersion: 78,
21
33
  /** SIGINT 退出(两次 Ctrl+C)。 */
@@ -31,6 +43,9 @@ export const EXIT_CODE_DESCRIPTIONS = {
31
43
  4: "无可用模型或密钥",
32
44
  5: "会话不存在 / 损坏 / cwd 不匹配",
33
45
  6: "宿主 / Hook 加载或启动失败",
46
+ 7: "-p 运行中有工具调用被拒(没有人审批)",
47
+ 8: "-p 到达预算上限(--max-turns / --max-cost / limits)",
48
+ 9: "-p 产出的计划已落盘、待审批(未执行)",
34
49
  78: "HOST_API_VERSION 不匹配",
35
50
  130: "SIGINT 退出(两次 Ctrl+C)",
36
51
  143: "SIGTERM",
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 测试供应商 `fake` 的可见性:零配置的模型选择器、`ama doctor`、`ama models list`、`ama providers list`、
3
+ * `ama config show` 缺省不列出它(实测零配置 TUI 的首项是 `fake › echo`,直接回车就用上了测试供应商)。
4
+ *
5
+ * - `AMA_SHOW_FAKE=1` 或设置了 `AMA_FAKE_SCRIPT` 时照常列出;
6
+ * - 只藏 `list()`:`--model fake/…`、`findModel`、`resolveApiKey` 等显式引用不受影响。
7
+ */
8
+ import type { ProviderRegistryApi } from "../ai/types.js";
9
+ export declare const SHOW_FAKE_ENV = "AMA_SHOW_FAKE";
10
+ export declare const FAKE_PROVIDER_ID = "fake";
11
+ export declare function fakeVisible(env: Readonly<Record<string, string | undefined>>): boolean;
12
+ /** 列表里藏起 fake 的注册表视图(其余方法原样转给原注册表);可见时原样返回。 */
13
+ export declare function hideFakeProvider<T extends ProviderRegistryApi>(registry: T, env: Readonly<Record<string, string | undefined>>): T;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * 测试供应商 `fake` 的可见性:零配置的模型选择器、`ama doctor`、`ama models list`、`ama providers list`、
3
+ * `ama config show` 缺省不列出它(实测零配置 TUI 的首项是 `fake › echo`,直接回车就用上了测试供应商)。
4
+ *
5
+ * - `AMA_SHOW_FAKE=1` 或设置了 `AMA_FAKE_SCRIPT` 时照常列出;
6
+ * - 只藏 `list()`:`--model fake/…`、`findModel`、`resolveApiKey` 等显式引用不受影响。
7
+ */
8
+ import { FAKE_SCRIPT_ENV } from "../ai/fake/fake-provider.js";
9
+ export const SHOW_FAKE_ENV = "AMA_SHOW_FAKE";
10
+ export const FAKE_PROVIDER_ID = "fake";
11
+ export function fakeVisible(env) {
12
+ return env[SHOW_FAKE_ENV] === "1" || (env[FAKE_SCRIPT_ENV] ?? "") !== "";
13
+ }
14
+ /** 列表里藏起 fake 的注册表视图(其余方法原样转给原注册表);可见时原样返回。 */
15
+ export function hideFakeProvider(registry, env) {
16
+ if (fakeVisible(env))
17
+ return registry;
18
+ return new Proxy(registry, {
19
+ get(target, prop) {
20
+ if (prop === "list")
21
+ return () => target.list().filter((provider) => provider.id !== FAKE_PROVIDER_ID);
22
+ const value = Reflect.get(target, prop, target);
23
+ return typeof value === "function" ? value.bind(target) : value;
24
+ },
25
+ });
26
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `--from <会话 id>[#编号]`:用旧会话里的一条用户消息作为新提示(docs/sessions.md「复用」)。[W4-D]
3
+ *
4
+ * - 文本:那条消息的文本;命令行另有位置参数时接在后面(空一行);
5
+ * - 图片:`-p` 时把图片块写进临时目录、追加到 `--image`(沿用 print 模式的图片校验:模型不收图片 →
6
+ * 用法错误),运行结束删掉;交互 / 行式界面只带文本,有图片时在 stderr 提示一行;
7
+ * - 交互模式经现有的「初始提示」参数传入(启动后直接提交,与 `ama "提示"` 相同);
8
+ * - `--mode rpc` 不支持(rpc 的提示来自宿主)。
9
+ * 会话目录用 bootstrap 解析后的 `paths.sessionDir`(含 `--session-dir` 与 profile),本目录优先找 id。
10
+ */
11
+ import { type ParsedArgs } from "./args.js";
12
+ import type { CliIo, ModeContext } from "./deps.js";
13
+ import type { Runtime } from "./runtime.js";
14
+ export interface FromContext {
15
+ context: ModeContext;
16
+ cleanup(): void;
17
+ }
18
+ export declare function applyFromOption(args: ParsedArgs, runtime: Pick<Runtime, "mode" | "paths">, io: CliIo): FromContext;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * `--from <会话 id>[#编号]`:用旧会话里的一条用户消息作为新提示(docs/sessions.md「复用」)。[W4-D]
3
+ *
4
+ * - 文本:那条消息的文本;命令行另有位置参数时接在后面(空一行);
5
+ * - 图片:`-p` 时把图片块写进临时目录、追加到 `--image`(沿用 print 模式的图片校验:模型不收图片 →
6
+ * 用法错误),运行结束删掉;交互 / 行式界面只带文本,有图片时在 stderr 提示一行;
7
+ * - 交互模式经现有的「初始提示」参数传入(启动后直接提交,与 `ama "提示"` 相同);
8
+ * - `--mode rpc` 不支持(rpc 的提示来自宿主)。
9
+ * 会话目录用 bootstrap 解析后的 `paths.sessionDir`(含 `--session-dir` 与 profile),本目录优先找 id。
10
+ */
11
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
12
+ import { tmpdir } from "node:os";
13
+ import { join } from "node:path";
14
+ import { resolveFromMessage } from "../session/reuse.js";
15
+ import { UsageError } from "./args.js";
16
+ const EXT = {
17
+ "image/png": "png",
18
+ "image/jpeg": "jpg",
19
+ "image/gif": "gif",
20
+ "image/webp": "webp",
21
+ };
22
+ export function applyFromOption(args, runtime, io) {
23
+ const spec = args.from;
24
+ const plain = { context: { args, prompt: args.prompt, io }, cleanup: () => { } };
25
+ if (spec === undefined)
26
+ return plain;
27
+ if (runtime.mode === "rpc")
28
+ throw new UsageError("--from 不用于 --mode rpc");
29
+ const picked = resolveFromMessage(runtime.paths.sessionDir, spec, runtime.paths.cwd);
30
+ const parts = [picked.text, args.prompt ?? ""].filter((p) => p.trim() !== "");
31
+ const prompt = parts.length > 0 ? parts.join("\n\n") : undefined;
32
+ if (picked.images.length === 0) {
33
+ return { context: { args, prompt, io }, cleanup: () => { } };
34
+ }
35
+ if (runtime.mode !== "print") {
36
+ io.stderr(`ama: --from 的消息带 ${picked.images.length} 张图片,交互界面只带文本(-p 会一并发送)\n`);
37
+ return { context: { args, prompt, io }, cleanup: () => { } };
38
+ }
39
+ const dir = mkdtempSync(join(tmpdir(), "ama-from-"));
40
+ const files = picked.images.map((image, i) => {
41
+ const file = join(dir, `${picked.n}-${i + 1}.${EXT[image.mimeType] ?? "png"}`);
42
+ writeFileSync(file, Buffer.from(image.data, "base64"), { mode: 0o600 });
43
+ return file;
44
+ });
45
+ return {
46
+ context: { args: { ...args, images: [...args.images, ...files] }, prompt, io },
47
+ cleanup: () => rmSync(dir, { recursive: true, force: true }),
48
+ };
49
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * `ama --help` 的文本(从 args.ts 搬出,args.ts 再导出)。[W5-C0]
3
+ */
4
+ export declare const HELP_TEXT = "\u7528\u6CD5\uFF1Aama [\u9009\u9879] [\u63D0\u793A]\n ama <\u5B50\u547D\u4EE4> \u2026\n\n\u6A21\u5F0F\n \uFF08\u7F3A\u7701\uFF09 \u7EC8\u7AEF\u754C\u9762\uFF1Bstdin / stdout \u975E TTY \u6216 TERM=dumb \u65F6\u81EA\u52A8\u964D\u7EA7\u4E3A\u884C\u5F0F\n --no-tui \u884C\u5F0F\u754C\u9762\uFF08readline + \u62EC\u53F7\u7C98\u8D34\uFF09\n -p, --print \u975E\u4EA4\u4E92\uFF1A\u6267\u884C\u63D0\u793A\u540E\u9000\u51FA\u3002\u63D0\u793A = \u53C2\u6570 + stdin \u7BA1\u9053\u5185\u5BB9\uFF1B\u6709\u63D0\u793A\u53C2\u6570\u65F6\n \u53EA\u7B49\u7BA1\u9053\u9996\u5B57\u8282 2 s\uFF08AMA_STDIN_WAIT_MS\uFF09\uFF0C\u6CA1\u6536\u5230\u5C31\u5FFD\u7565\u5E76\u63D0\u793A\uFF1B\n \u672B\u5C3E\u52A0 - \u5219\u4E00\u76F4\u7B49\u5230 EOF\uFF08\u5982 npm test | ama -p \u627E\u539F\u56E0 -\uFF09\n --no-stdin -p \u4E0D\u8BFB stdin\uFF08\u7236\u8FDB\u7A0B\u7559\u7740\u7BA1\u9053\u3001\u53C8\u4E0D\u60F3\u7B49 2 s \u65F6\uFF09\n --output-format <\u683C\u5F0F> -p \u7684\u8F93\u51FA\uFF1Atext\uFF08\u7F3A\u7701\uFF09| json | stream-json\n --max-turns <N> -p \u6700\u591A\u8DD1 N \u8F6E\uFF08\u4E00\u6B21\u6A21\u578B\u8BF7\u6C42\u52A0\u5176\u5DE5\u5177\u6267\u884C\u7B97\u4E00\u8F6E\uFF09\uFF1B\u5230\u8FBE\u4E0A\u9650\u4ECD\u6709\n \u672A\u5B8C\u6210\u7684\u5DE5\u5177\u8C03\u7528\u65F6\u63D0\u524D\u7ED3\u675F\uFF0C\u9000\u51FA\u7801 8\n --image <\u6587\u4EF6> -p \u968F\u63D0\u793A\u53D1\u9001\u56FE\u7247\uFF08\u53EF\u91CD\u590D\uFF1Bpng / jpg / gif / webp\uFF0C\u5355\u5F20 \u2264 5 MB\uFF09\uFF1B\n \u4EA4\u4E92\u754C\u9762\u91CC\u5199 @\u56FE\u7247\u8DEF\u5F84 \u6216\u7C98\u8D34\u56FE\u7247\u8DEF\u5F84\n --mode rpc stdio JSONL \u534F\u8BAE\uFF08\u4F9B\u5D4C\u5165\uFF09\n --mode acp ACP \u670D\u52A1\u7AEF\uFF08\u4F9B Zed / JetBrains / Armadra \u9A71\u52A8\uFF09\n --max-cost <USD> \u4E00\u6B21\u8FD0\u884C\u7684\u7F8E\u5143\u4E0A\u9650\uFF08\u6309\u76EE\u5F55\u4EF7\u4F30\u7B97\uFF09\uFF1B\u5230\u9650\u7ED3\u675F\u8FD0\u884C\uFF0C-p \u9000\u51FA\u7801 8\n --tui-mode <\u6A21\u5F0F> \u663E\u793A\u6A21\u5F0F\uFF0C\u7B2C\u4E00\u671F\u53EA\u6709 regular\uFF08\u4E3B\u5C4F\uFF09\n --quiet-startup <\u6863> \u542F\u52A8\u753B\u9762\uFF1Anormal | header | silent\n\n\u6A21\u578B\n --model <provider/id> \u6A21\u578B\uFF08\u53EF\u914D\u5408 --provider \u53EA\u5199 id\uFF1B@\u6E20\u9053 \u6307\u5B9A\u6E20\u9053\uFF0C\u5982 packy/kimi-k2.5@messages\uFF09\n --provider <id> \u4F9B\u5E94\u5546\uFF08\u5FC5\u987B\u540C\u65F6\u7ED9 --model\uFF09\n --api-key <key> \u53EA\u7528\u4E8E\u672C\u6B21\u542F\u52A8\u7684 key\uFF08\u9700\u8981 --model\uFF1B\u4F18\u5148\u7528 ama auth set\uFF09\n --thinking <\u7EA7\u522B> off | minimal | low | medium | high | xhigh\n\n\u4F1A\u8BDD\n -c, --continue \u7EE7\u7EED\u672C\u76EE\u5F55\u6700\u8FD1\u7684\u4F1A\u8BDD\n -r, --resume [id] \u6062\u590D\u4F1A\u8BDD\uFF08\u4EA4\u4E92\u6A21\u5F0F\u65E0 id \u65F6\u5F39\u9009\u62E9\u5668\uFF09\n --session-id <id> \u4F7F\u7528\u6307\u5B9A id \u7684\u4F1A\u8BDD\uFF08\u4E0D\u5B58\u5728\u5219\u65B0\u5EFA\uFF09\n --fork <id> \u4ECE\u6307\u5B9A\u4F1A\u8BDD\u5206\u53C9\u51FA\u65B0\u4F1A\u8BDD\n --session-dir <\u76EE\u5F55> \u4F1A\u8BDD\u76EE\u5F55\uFF08\u7F3A\u7701 ~/.local/share/ama/sessions\uFF09\n --no-session \u4F1A\u8BDD\u53EA\u5728\u5185\u5B58\u91CC\uFF0C\u4E0D\u5199\u4F1A\u8BDD\u6587\u4EF6\uFF08\u4E4B\u540E\u65E0\u6CD5 --resume\uFF09\n --from <id>[#\u7F16\u53F7] \u7528\u65E7\u4F1A\u8BDD\u7684\u4E00\u6761\u7528\u6237\u6D88\u606F\u4F5C\u63D0\u793A\uFF08\u7F3A\u7701\u6700\u540E\u4E00\u6761\uFF1B-p \u65F6\u8FDE\u56FE\u7247\u4E00\u8D77\uFF1B\n \u7F16\u53F7\u89C1 ama sessions show\uFF09\n\n\u6743\u9650\u4E0E\u4FE1\u4EFB\n --permission-mode <\u6A21\u5F0F> default | auto-edit | plan | auto | full-auto | allowlist\n \uFF08auto \u7531 ama \u5224\u65AD\u6BCF\u4E00\u6B65\uFF1Ballowlist \u53EA\u653E\u884C allow \u89C4\u5219\u547D\u4E2D\u7684\uFF0C\u9002\u5408 CI\uFF09\n --allow <\u89C4\u5219> \u8FFD\u52A0\u5141\u8BB8\u89C4\u5219\uFF0C\u53EF\u91CD\u590D\uFF08\u5982 \"bash(git status*)\"\uFF09\n --deny <\u89C4\u5219> \u8FFD\u52A0\u62D2\u7EDD\u89C4\u5219\uFF0C\u53EF\u91CD\u590D\uFF08\u5982 \"write(**/.env*)\"\uFF09\n --trust / --no-trust \u4FE1\u4EFB / \u4E0D\u4FE1\u4EFB\u5F53\u524D\u9879\u76EE\uFF08\u9879\u76EE\u7EA7 Hook\u3001Skill\u3001\u63D0\u793A\u6A21\u677F\uFF09\n\n\u8D44\u6E90\n --system-prompt <\u6587\u672C|@\u6587\u4EF6> \u8FFD\u52A0\u7CFB\u7EDF\u63D0\u793A\uFF1A\u7F3A\u7701\u4F5C\u4E3A\u6700\u540E\u4E00\u6761\u89C4\u5219\u8FFD\u52A0\uFF08\u5DE5\u5177\u8868\u7B49\u524D\u7F00\u4E0D\u53D8\uFF0C\u5229\u4E8E\u7F13\u5B58\uFF09\n --system-prompt-mode <\u65B9\u5F0F> append\uFF08\u7F3A\u7701\uFF09| replace\uFF08\u66FF\u6362\u5F00\u5934\u7684\u89D2\u8272\u8BF4\u660E\uFF0C\u5DE5\u5177\u4E0E\u9879\u76EE\u4E0A\u4E0B\u6587\u4FDD\u7559\uFF09\n --profile <\u6587\u4EF6> \u5BBF\u4E3B profile.json\uFF08\u5B57\u6BB5\u7B49\u4EF7\u4E8E\u5BF9\u5E94\u53C2\u6570\uFF0C\u547D\u4EE4\u884C\u4F18\u5148\uFF09\n --host <\u6A21\u5757> \u5BBF\u4E3B\u9002\u914D\u5668\u6A21\u5757\uFF08CJS / ESM\uFF09\n --instructions <\u6587\u4EF6> \u8FFD\u52A0\u6307\u4EE4\u6587\u4EF6\uFF0C\u53EF\u91CD\u590D\n --skill-dir <\u76EE\u5F55> \u8FFD\u52A0 Skill \u76EE\u5F55\uFF0C\u53EF\u91CD\u590D\n --agent-dir <\u76EE\u5F55> \u8FFD\u52A0\u5B50 Agent \u5B9A\u4E49\u76EE\u5F55\uFF0C\u53EF\u91CD\u590D\n --auth-file <\u6587\u4EF6> auth.json \u4F4D\u7F6E\uFF08\u7F3A\u7701 ~/.config/ama/auth.json\uFF09\n --tools <a,b,\u2026> \u53EA\u542F\u7528\u8FD9\u4E9B\u5DE5\u5177\n --exclude-tools <a,b,\u2026> \u7981\u7528\u8FD9\u4E9B\u5DE5\u5177\n --tools-preset <\u540D> \u5DE5\u5177\u9884\u8BBE\uFF1Adefault\uFF08\u7F3A\u7701\uFF09| minimal | codemode-only | coordinator\n \uFF08codemode \u662F codemode-only \u7684\u65E7\u540D\uFF0C\u4ECD\u53EF\u7528\uFF09\n --codemode <\u6A21\u5F0F> codemode \u8C03\u7528\u65B9\u5F0F\uFF1Aoff | on | only\uFF08\u7F3A\u7701\u968F\u9884\u8BBE\uFF09\n\n\u5B50\u547D\u4EE4\n ama auth set <provider> \u4ECE stdin \u8BFB\u53D6 key \u5199\u5165 auth.json\uFF080600\uFF09\n ama auth list \u5217\u51FA\u5DF2\u4FDD\u5B58 key \u7684\u4F9B\u5E94\u5546\uFF08\u4E0D\u663E\u793A key\uFF09\n ama auth remove <provider> \u5220\u9664\u5DF2\u4FDD\u5B58\u7684 key\n ama sessions list|show|prune \u4F1A\u8BDD\u7BA1\u7406\n ama sessions search <\u5173\u952E\u8BCD|/\u6B63\u5219/> [--all] [--role user|assistant|tool] [--since 7d] [--limit N]\n \u8DE8\u4F1A\u8BDD\u5168\u6587\u68C0\u7D22\n ama sessions export <id> [--format md|json|jsonl] [--output <\u6587\u4EF6>] [--branch leaf|all]\n \u5BFC\u51FA\u4F1A\u8BDD\uFF08\u5DF2\u8131\u654F\uFF09\n ama models list [--provider <id>] \u5217\u51FA\u6A21\u578B\uFF08\u542B\u6765\u6E90\u4E0E key \u72B6\u6001\uFF09\n ama models check <provider/id> \u53D1\u4E00\u6B21\u6700\u5C0F\u8BF7\u6C42\u68C0\u67E5\u53EF\u7528\u6027\n ama models discover <provider> [--probe] [--write] [--limit N]\n \u4ECE\u4E2D\u8F6C /v1/models \u5217\u51FA\u6A21\u578B\uFF0C\u63A2\u6D4B\u534F\u8BAE\u5E76\u5199\u5165\u914D\u7F6E\n ama models refresh [--provider <id>] \u8054\u7F51\u5237\u65B0 models.dev \u5143\u6570\u636E\u5230\u6570\u636E\u76EE\u5F55\uFF08\u542F\u52A8\u4E0D\u8054\u7F51\uFF1B\n \u65E7\u540D refresh-catalog\uFF09\n ama providers add <id> --base-url <url> [--key-env VAR] [--probe] [--channel n=api@url] [--yes]\n \u4E00\u952E\u63A5\u5165\uFF1A\u5217\u6A21\u578B\u3001\u8865 models.dev \u5143\u6570\u636E\u3001\u63A2\u6D4B\u6E20\u9053\u3001\u5199\u5165\u914D\u7F6E\n ama providers list|channels <id>|remove <id>|refresh <id>\n \u4F9B\u5E94\u5546 \u2192 \u6E20\u9053 \u2192 \u6A21\u578B\uFF1B\u5220\u9664\uFF1B\u91CD\u62C9\u6A21\u578B\u5217\u8868\n ama models cache-probe <provider/id> [--tokens N] [--gap-ms MS] [--yes] [--json]\n \u5224\u65AD\u7AEF\u70B9\u662F\u5426\u62A5\u544A\u7F13\u5B58\u547D\u4E2D\n ama doctor \u914D\u7F6E\u5C42\u7EA7\u3001\u4FE1\u4EFB\u3001key \u6765\u6E90\u3001Hook\u3001\u7EC8\u7AEF\u80FD\u529B\n ama config show [--json] \u751F\u6548\u914D\u7F6E\u4E0E\u6BCF\u9879\u6765\u6E90\u3001\u5C06\u4F7F\u7528\u7684\u6A21\u578B\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\n ama init [--force] \u5EFA\u914D\u7F6E\u76EE\u5F55\uFF080700\uFF09\u4E0E config.json\u3001config.schema.json\uFF1B\u5DF2\u6709\u7684\u4E0D\u8986\u76D6\n ama stats [--since 7d] [--by day|week|month|provider|channel|model|project] [--all] [--json]\n \u8DE8\u4F1A\u8BDD\u7EDF\u8BA1\uFF1A\u8BF7\u6C42\u3001token\u3001\u7F13\u5B58\u547D\u4E2D\u7387\u3001\u8D39\u7528\u3001\u5DE5\u5177\u8C03\u7528\n\n\u5176\u5B83\n -h, --help \u8F93\u51FA\u672C\u5E2E\u52A9\n -v, --version \u8F93\u51FA\u7248\u672C\n\n\u9000\u51FA\u7801\uFF1A0 \u6B63\u5E38 \u00B7 1 \u8FD0\u884C\u671F\u9519\u8BEF \u00B7 2 \u7528\u6CD5\u9519\u8BEF \u00B7 3 \u914D\u7F6E\u9519\u8BEF \u00B7 4 \u65E0\u53EF\u7528\u6A21\u578B\u6216 key \u00B7\n 5 \u4F1A\u8BDD\u9519\u8BEF \u00B7 6 \u5BBF\u4E3B / Hook \u542F\u52A8\u5931\u8D25 \u00B7 7 -p \u6709\u5DE5\u5177\u8C03\u7528\u88AB\u62D2\uFF08\u65E0\u4EBA\u5BA1\u6279\uFF1B\u7528\n --permission-mode auto-edit|auto \u6216 --allow \u653E\u884C\uFF09\u00B7 8 -p \u5230\u8FBE\u9884\u7B97\u4E0A\u9650 \u00B7\n 9 -p \u7684\u8BA1\u5212\u5DF2\u843D\u76D8\u5F85\u5BA1\u6279\uFF08plan.unattended: approve \u5219\u81EA\u52A8\u6279\u51C6\u6267\u884C\uFF09\u00B7\n 78 \u5BBF\u4E3B API \u7248\u672C\u4E0D\u5339\u914D \u00B7\n 130 SIGINT \u00B7 143 SIGTERM\n";
@@ -0,0 +1,102 @@
1
+ /**
2
+ * `ama --help` 的文本(从 args.ts 搬出,args.ts 再导出)。[W5-C0]
3
+ */
4
+ export const HELP_TEXT = `用法:ama [选项] [提示]
5
+ ama <子命令> …
6
+
7
+ 模式
8
+ (缺省) 终端界面;stdin / stdout 非 TTY 或 TERM=dumb 时自动降级为行式
9
+ --no-tui 行式界面(readline + 括号粘贴)
10
+ -p, --print 非交互:执行提示后退出。提示 = 参数 + stdin 管道内容;有提示参数时
11
+ 只等管道首字节 2 s(AMA_STDIN_WAIT_MS),没收到就忽略并提示;
12
+ 末尾加 - 则一直等到 EOF(如 npm test | ama -p 找原因 -)
13
+ --no-stdin -p 不读 stdin(父进程留着管道、又不想等 2 s 时)
14
+ --output-format <格式> -p 的输出:text(缺省)| json | stream-json
15
+ --max-turns <N> -p 最多跑 N 轮(一次模型请求加其工具执行算一轮);到达上限仍有
16
+ 未完成的工具调用时提前结束,退出码 8
17
+ --image <文件> -p 随提示发送图片(可重复;png / jpg / gif / webp,单张 ≤ 5 MB);
18
+ 交互界面里写 @图片路径 或粘贴图片路径
19
+ --mode rpc stdio JSONL 协议(供嵌入)
20
+ --mode acp ACP 服务端(供 Zed / JetBrains / Armadra 驱动)
21
+ --max-cost <USD> 一次运行的美元上限(按目录价估算);到限结束运行,-p 退出码 8
22
+ --tui-mode <模式> 显示模式,第一期只有 regular(主屏)
23
+ --quiet-startup <档> 启动画面:normal | header | silent
24
+
25
+ 模型
26
+ --model <provider/id> 模型(可配合 --provider 只写 id;@渠道 指定渠道,如 packy/kimi-k2.5@messages)
27
+ --provider <id> 供应商(必须同时给 --model)
28
+ --api-key <key> 只用于本次启动的 key(需要 --model;优先用 ama auth set)
29
+ --thinking <级别> off | minimal | low | medium | high | xhigh
30
+
31
+ 会话
32
+ -c, --continue 继续本目录最近的会话
33
+ -r, --resume [id] 恢复会话(交互模式无 id 时弹选择器)
34
+ --session-id <id> 使用指定 id 的会话(不存在则新建)
35
+ --fork <id> 从指定会话分叉出新会话
36
+ --session-dir <目录> 会话目录(缺省 ~/.local/share/ama/sessions)
37
+ --no-session 会话只在内存里,不写会话文件(之后无法 --resume)
38
+ --from <id>[#编号] 用旧会话的一条用户消息作提示(缺省最后一条;-p 时连图片一起;
39
+ 编号见 ama sessions show)
40
+
41
+ 权限与信任
42
+ --permission-mode <模式> default | auto-edit | plan | auto | full-auto | allowlist
43
+ (auto 由 ama 判断每一步;allowlist 只放行 allow 规则命中的,适合 CI)
44
+ --allow <规则> 追加允许规则,可重复(如 "bash(git status*)")
45
+ --deny <规则> 追加拒绝规则,可重复(如 "write(**/.env*)")
46
+ --trust / --no-trust 信任 / 不信任当前项目(项目级 Hook、Skill、提示模板)
47
+
48
+ 资源
49
+ --system-prompt <文本|@文件> 追加系统提示:缺省作为最后一条规则追加(工具表等前缀不变,利于缓存)
50
+ --system-prompt-mode <方式> append(缺省)| replace(替换开头的角色说明,工具与项目上下文保留)
51
+ --profile <文件> 宿主 profile.json(字段等价于对应参数,命令行优先)
52
+ --host <模块> 宿主适配器模块(CJS / ESM)
53
+ --instructions <文件> 追加指令文件,可重复
54
+ --skill-dir <目录> 追加 Skill 目录,可重复
55
+ --agent-dir <目录> 追加子 Agent 定义目录,可重复
56
+ --auth-file <文件> auth.json 位置(缺省 ~/.config/ama/auth.json)
57
+ --tools <a,b,…> 只启用这些工具
58
+ --exclude-tools <a,b,…> 禁用这些工具
59
+ --tools-preset <名> 工具预设:default(缺省)| minimal | codemode-only | coordinator
60
+ (codemode 是 codemode-only 的旧名,仍可用)
61
+ --codemode <模式> codemode 调用方式:off | on | only(缺省随预设)
62
+
63
+ 子命令
64
+ ama auth set <provider> 从 stdin 读取 key 写入 auth.json(0600)
65
+ ama auth list 列出已保存 key 的供应商(不显示 key)
66
+ ama auth remove <provider> 删除已保存的 key
67
+ ama sessions list|show|prune 会话管理
68
+ ama sessions search <关键词|/正则/> [--all] [--role user|assistant|tool] [--since 7d] [--limit N]
69
+ 跨会话全文检索
70
+ ama sessions export <id> [--format md|json|jsonl] [--output <文件>] [--branch leaf|all]
71
+ 导出会话(已脱敏)
72
+ ama models list [--provider <id>] 列出模型(含来源与 key 状态)
73
+ ama models check <provider/id> 发一次最小请求检查可用性
74
+ ama models discover <provider> [--probe] [--write] [--limit N]
75
+ 从中转 /v1/models 列出模型,探测协议并写入配置
76
+ ama models refresh [--provider <id>] 联网刷新 models.dev 元数据到数据目录(启动不联网;
77
+ 旧名 refresh-catalog)
78
+ ama providers add <id> --base-url <url> [--key-env VAR] [--probe] [--channel n=api@url] [--yes]
79
+ 一键接入:列模型、补 models.dev 元数据、探测渠道、写入配置
80
+ ama providers list|channels <id>|remove <id>|refresh <id>
81
+ 供应商 → 渠道 → 模型;删除;重拉模型列表
82
+ ama models cache-probe <provider/id> [--tokens N] [--gap-ms MS] [--yes] [--json]
83
+ 判断端点是否报告缓存命中
84
+ ama doctor 配置层级、信任、key 来源、Hook、终端能力
85
+ ama config show [--json] 生效配置与每项来源、将使用的模型
86
+ ama config path 配置目录、数据目录与各文件路径
87
+ ama config edit 用 $VISUAL / $EDITOR 打开 config.json
88
+ ama init [--force] 建配置目录(0700)与 config.json、config.schema.json;已有的不覆盖
89
+ ama stats [--since 7d] [--by day|week|month|provider|channel|model|project] [--all] [--json]
90
+ 跨会话统计:请求、token、缓存命中率、费用、工具调用
91
+
92
+ 其它
93
+ -h, --help 输出本帮助
94
+ -v, --version 输出版本
95
+
96
+ 退出码:0 正常 · 1 运行期错误 · 2 用法错误 · 3 配置错误 · 4 无可用模型或 key ·
97
+ 5 会话错误 · 6 宿主 / Hook 启动失败 · 7 -p 有工具调用被拒(无人审批;用
98
+ --permission-mode auto-edit|auto 或 --allow 放行)· 8 -p 到达预算上限 ·
99
+ 9 -p 的计划已落盘待审批(plan.unattended: approve 则自动批准执行)·
100
+ 78 宿主 API 版本不匹配 ·
101
+ 130 SIGINT · 143 SIGTERM
102
+ `;
@@ -5,14 +5,17 @@
5
5
  * - 设 `AMA=1`、`AI_AGENT=ama`;直接执行时装 `uncaughtException` / `unhandledRejection` →
6
6
  * stderr 一行 + 退出码 1;SIGINT / SIGTERM 交给当前模式。
7
7
  * - `--version` / `--help` 短路;子命令 `auth / sessions / models / providers / doctor / config /
8
- * init` 分派后返回;其余命令启动前若配置目录不存在则静默初始化(`AMA_NO_INIT=1` 关闭);
8
+ * init` 分派后返回;进入对话的命令(与 `providers add`)启动前若配置目录不存在则静默初始化
9
+ * (`AMA_NO_INIT=1` 关闭),只读子命令(`config show`、`doctor`、`models list` 等)不写配置目录;
9
10
  * 其余交给 `runCli()`(bootstrap → 模式)。
11
+ * - 设了 HTTPS_PROXY / HTTP_PROXY 时启用 Node 内置的环境变量代理(cli/proxy.ts);不支持的 Node
12
+ * 版本在会联网的命令里提示一次。
10
13
  * - 运行时实现(RuntimeDeps):`MainOptions.deps` > `registerRuntimeDeps()` > 组装根
11
14
  * `createRuntimeDeps()`(cli/compose.ts,动态 import)。
12
15
  * - 签名 `main(argv): Promise<number>` 与「直接执行才自动运行」判定保持不变:
13
16
  * src/bundle.ts 显式调用 `main()`。
14
17
  */
15
- import type { CliIo, RuntimeDeps } from "./deps.js";
18
+ import type { CliIo, RuntimeDeps, StdinKind } from "./deps.js";
16
19
  /** 集成批次注入运行时实现(B1 / B2 / B3 / B6 / B7)。 */
17
20
  export declare function registerRuntimeDeps(deps: RuntimeDeps | undefined): void;
18
21
  export interface MainOptions {
@@ -23,5 +26,9 @@ export interface MainOptions {
23
26
  }
24
27
  /** 读 stdin 全部内容;TTY 下只读一行且不回显(auth set)。 */
25
28
  export declare function readStdinDefault(): Promise<string>;
29
+ /** fd 0 的类型;fstat 失败(已关闭)按 `null` 处理。 */
30
+ export declare function stdinKindDefault(): StdinKind;
31
+ /** 等 stdin 首字节至多 `timeoutMs`;超时则停止读取并返回 undefined,否则读到 EOF。 */
32
+ export declare function readStdinFirstByteDefault(timeoutMs: number): Promise<string | undefined>;
26
33
  export declare function defaultIo(): CliIo;
27
34
  export declare function main(argv: readonly string[], options?: MainOptions): Promise<number>;
package/dist/cli/main.js CHANGED
@@ -5,14 +5,17 @@
5
5
  * - 设 `AMA=1`、`AI_AGENT=ama`;直接执行时装 `uncaughtException` / `unhandledRejection` →
6
6
  * stderr 一行 + 退出码 1;SIGINT / SIGTERM 交给当前模式。
7
7
  * - `--version` / `--help` 短路;子命令 `auth / sessions / models / providers / doctor / config /
8
- * init` 分派后返回;其余命令启动前若配置目录不存在则静默初始化(`AMA_NO_INIT=1` 关闭);
8
+ * init` 分派后返回;进入对话的命令(与 `providers add`)启动前若配置目录不存在则静默初始化
9
+ * (`AMA_NO_INIT=1` 关闭),只读子命令(`config show`、`doctor`、`models list` 等)不写配置目录;
9
10
  * 其余交给 `runCli()`(bootstrap → 模式)。
11
+ * - 设了 HTTPS_PROXY / HTTP_PROXY 时启用 Node 内置的环境变量代理(cli/proxy.ts);不支持的 Node
12
+ * 版本在会联网的命令里提示一次。
10
13
  * - 运行时实现(RuntimeDeps):`MainOptions.deps` > `registerRuntimeDeps()` > 组装根
11
14
  * `createRuntimeDeps()`(cli/compose.ts,动态 import)。
12
15
  * - 签名 `main(argv): Promise<number>` 与「直接执行才自动运行」判定保持不变:
13
16
  * src/bundle.ts 显式调用 `main()`。
14
17
  */
15
- import { realpathSync } from "node:fs";
18
+ import { fstatSync, realpathSync } from "node:fs";
16
19
  import { fileURLToPath } from "node:url";
17
20
  import { AMA_VERSION } from "../version.js";
18
21
  import { parseArgs } from "./args.js";
@@ -27,6 +30,8 @@ import { runInit } from "./subcommands/init.js";
27
30
  import { autoInitConfigDir } from "../config/init.js";
28
31
  import { resolveConfigDir } from "../config/paths.js";
29
32
  import { runSessions } from "./subcommands/sessions.js";
33
+ import { runStats } from "./subcommands/stats.js";
34
+ import { enableEnvProxy, proxyHint } from "./proxy.js";
30
35
  let registeredDeps;
31
36
  /** 集成批次注入运行时实现(B1 / B2 / B3 / B6 / B7)。 */
32
37
  export function registerRuntimeDeps(deps) {
@@ -72,6 +77,61 @@ export function readStdinDefault() {
72
77
  stdin.on("data", onData);
73
78
  });
74
79
  }
80
+ /** fd 0 的类型;fstat 失败(已关闭)按 `null` 处理。 */
81
+ export function stdinKindDefault() {
82
+ try {
83
+ const stat = fstatSync(0);
84
+ if (stat.isFile())
85
+ return "file";
86
+ if (stat.isFIFO())
87
+ return "fifo";
88
+ if (stat.isSocket())
89
+ return "socket";
90
+ if (stat.isCharacterDevice())
91
+ return process.stdin.isTTY === true ? "tty" : "null";
92
+ return "other";
93
+ }
94
+ catch {
95
+ return "null";
96
+ }
97
+ }
98
+ /** 等 stdin 首字节至多 `timeoutMs`;超时则停止读取并返回 undefined,否则读到 EOF。 */
99
+ export function readStdinFirstByteDefault(timeoutMs) {
100
+ const stdin = process.stdin;
101
+ return new Promise((resolve, reject) => {
102
+ const chunks = [];
103
+ let timer;
104
+ const cleanup = () => {
105
+ clearTimeout(timer);
106
+ stdin.off("data", onData);
107
+ stdin.off("end", onEnd);
108
+ stdin.off("error", onError);
109
+ };
110
+ const onData = (chunk) => {
111
+ clearTimeout(timer);
112
+ timer = undefined;
113
+ chunks.push(chunk);
114
+ };
115
+ const onEnd = () => {
116
+ cleanup();
117
+ resolve(Buffer.concat(chunks).toString("utf8"));
118
+ };
119
+ const onError = (error) => {
120
+ cleanup();
121
+ reject(error);
122
+ };
123
+ timer = setTimeout(() => {
124
+ cleanup();
125
+ // 不再读:释放句柄,父进程留着不关的管道不会让进程挂住
126
+ stdin.pause();
127
+ stdin.destroy();
128
+ resolve(undefined);
129
+ }, timeoutMs);
130
+ stdin.on("data", onData);
131
+ stdin.once("end", onEnd);
132
+ stdin.once("error", onError);
133
+ });
134
+ }
75
135
  export function defaultIo() {
76
136
  return {
77
137
  stdout: (text) => void process.stdout.write(text),
@@ -81,6 +141,8 @@ export function defaultIo() {
81
141
  env: process.env,
82
142
  cwd: process.cwd(),
83
143
  readStdin: readStdinDefault,
144
+ readStdinFirstByte: readStdinFirstByteDefault,
145
+ stdinKind: stdinKindDefault,
84
146
  };
85
147
  }
86
148
  let hooksInstalled = false;
@@ -122,8 +184,18 @@ export async function main(argv, options = {}) {
122
184
  if (parsed.kind !== "subcommand")
123
185
  noTui = parsed.args.noTui;
124
186
  const informational = parsed.kind === "run" ? parsed.args.help || parsed.args.version : parsed.name === "init";
125
- if (!informational)
187
+ // 首次自动初始化只在会进入对话的命令(和接入供应商)里做;只读子命令不写配置目录
188
+ const startsWork = parsed.kind === "run" || (parsed.name === "providers" && parsed.argv[0] === "add");
189
+ if (!informational && startsWork)
126
190
  autoInitConfigDir(resolveConfigDir({ env: io.env }), io.env);
191
+ // 进程级副作用(全局 dispatcher):只在真正的进程入口做,测试里调 main() 不碰
192
+ if (!informational && options.processHooks !== false) {
193
+ const proxy = enableEnvProxy(io.env);
194
+ const online = parsed.kind === "run" || parsed.name === "models" || parsed.name === "providers";
195
+ const hint = online ? proxyHint(proxy) : undefined;
196
+ if (hint !== undefined)
197
+ io.stderr(hint);
198
+ }
127
199
  if (parsed.kind === "subcommand") {
128
200
  switch (parsed.name) {
129
201
  case "auth":
@@ -140,6 +212,8 @@ export async function main(argv, options = {}) {
140
212
  return await runConfig(parsed.argv, io, await resolveDeps());
141
213
  case "init":
142
214
  return runInit(parsed.argv, io);
215
+ case "stats":
216
+ return await runStats(parsed.argv, io);
143
217
  }
144
218
  }
145
219
  if (parsed.args.version) {
@@ -0,0 +1,51 @@
1
+ /**
2
+ * 环境变量代理(W4-C):Node 的全局 fetch 缺省不读 `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY`。
3
+ *
4
+ * - 没设代理变量 → 什么都不做。
5
+ * - 运行时已接管(`NODE_USE_ENV_PROXY=1` 或 `--use-env-proxy`,且 Node 支持)→ 不重复设置。
6
+ * - Node 有 `http.setGlobalProxyFromEnv()`(24.x / 26.x 等)→ 进程启动时调用一次,等价于
7
+ * `NODE_USE_ENV_PROXY=1`(fetch 与 http/https 全局 agent 都走代理,`NO_PROXY` 生效)。零依赖。
8
+ * - 不支持的 Node 版本 → 只在会联网的命令里于 stderr 提示一次(不中断)。
9
+ *
10
+ * `ama doctor` 用 `describeProxy()` 显示同一份状态;代理 URL 里的账号密码打码。
11
+ */
12
+ export interface ProxyEnv {
13
+ httpsProxy?: string;
14
+ httpProxy?: string;
15
+ noProxy?: string;
16
+ }
17
+ export type ProxyState = "none"
18
+ /** 运行时已按环境变量接管(NODE_USE_ENV_PROXY / --use-env-proxy)。 */
19
+ | "runtime"
20
+ /** ama 启动时调用 http.setGlobalProxyFromEnv() 启用。 */
21
+ | "enabled"
22
+ /** 设了代理变量,但当前 Node 不支持内置代理。 */
23
+ | "unsupported"
24
+ /** 代理 URL 无法解析。 */
25
+ | "invalid";
26
+ export interface ProxyStatus {
27
+ env: ProxyEnv;
28
+ state: ProxyState;
29
+ error?: string;
30
+ }
31
+ type SetGlobalProxy = (env?: NodeJS.ProcessEnv) => () => void;
32
+ export interface ProxyRuntime {
33
+ setGlobalProxyFromEnv?: SetGlobalProxy | undefined;
34
+ execArgv: readonly string[];
35
+ version: string;
36
+ }
37
+ export declare function readProxyEnv(env: Readonly<Record<string, string | undefined>>): ProxyEnv;
38
+ export declare function defaultProxyRuntime(): ProxyRuntime;
39
+ /** 只判断不启用:没设代理 / 运行时已接管 / 能启用 / 不支持 / URL 无法解析。 */
40
+ export declare function inspectProxy(env: Readonly<Record<string, string | undefined>>, runtime?: ProxyRuntime): ProxyStatus;
41
+ /** 按上面的规则启用代理(进程级副作用);同一进程只做一次,之后返回同一份状态。 */
42
+ export declare function enableEnvProxy(env: Readonly<Record<string, string | undefined>>, runtime?: ProxyRuntime): ProxyStatus;
43
+ /** 测试用:清掉进程内记住的状态。 */
44
+ export declare function resetProxyForTest(): void;
45
+ /** 代理 URL 里的账号密码打码。 */
46
+ export declare function redactProxyUrl(value: string): string;
47
+ /** 不能启用时给一次 stderr 提示(每个进程至多一次);能用或没设代理返回 undefined。 */
48
+ export declare function proxyHint(status: ProxyStatus, nodeVersion?: string): string | undefined;
49
+ /** `ama doctor` 的代理段落。 */
50
+ export declare function describeProxy(status: ProxyStatus): string[];
51
+ export {};
@@ -0,0 +1,135 @@
1
+ /**
2
+ * 环境变量代理(W4-C):Node 的全局 fetch 缺省不读 `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY`。
3
+ *
4
+ * - 没设代理变量 → 什么都不做。
5
+ * - 运行时已接管(`NODE_USE_ENV_PROXY=1` 或 `--use-env-proxy`,且 Node 支持)→ 不重复设置。
6
+ * - Node 有 `http.setGlobalProxyFromEnv()`(24.x / 26.x 等)→ 进程启动时调用一次,等价于
7
+ * `NODE_USE_ENV_PROXY=1`(fetch 与 http/https 全局 agent 都走代理,`NO_PROXY` 生效)。零依赖。
8
+ * - 不支持的 Node 版本 → 只在会联网的命令里于 stderr 提示一次(不中断)。
9
+ *
10
+ * `ama doctor` 用 `describeProxy()` 显示同一份状态;代理 URL 里的账号密码打码。
11
+ */
12
+ import * as http from "node:http";
13
+ function pick(env, name) {
14
+ const value = env[name.toLowerCase()] ?? env[name.toUpperCase()];
15
+ return value !== undefined && value.trim() !== "" ? value.trim() : undefined;
16
+ }
17
+ export function readProxyEnv(env) {
18
+ const out = {};
19
+ const https = pick(env, "https_proxy");
20
+ const plain = pick(env, "http_proxy");
21
+ const no = pick(env, "no_proxy");
22
+ if (https !== undefined)
23
+ out.httpsProxy = https;
24
+ if (plain !== undefined)
25
+ out.httpProxy = plain;
26
+ if (no !== undefined)
27
+ out.noProxy = no;
28
+ return out;
29
+ }
30
+ export function defaultProxyRuntime() {
31
+ const fn = http.setGlobalProxyFromEnv;
32
+ return {
33
+ setGlobalProxyFromEnv: typeof fn === "function" ? fn.bind(http) : undefined,
34
+ execArgv: process.execArgv,
35
+ version: process.versions.node,
36
+ };
37
+ }
38
+ /** Node ≥ 24,或 22.21+:认 NODE_USE_ENV_PROXY / --use-env-proxy。 */
39
+ function runtimeReadsEnvProxy(version) {
40
+ const [major = 0, minor = 0] = version.split(".").map(Number);
41
+ return major >= 24 || (major === 22 && minor >= 21);
42
+ }
43
+ let current;
44
+ let hinted = false;
45
+ /** 只判断不启用:没设代理 / 运行时已接管 / 能启用 / 不支持 / URL 无法解析。 */
46
+ export function inspectProxy(env, runtime = defaultProxyRuntime()) {
47
+ if (current !== undefined)
48
+ return current;
49
+ const proxy = readProxyEnv(env);
50
+ if (proxy.httpsProxy === undefined && proxy.httpProxy === undefined)
51
+ return { env: proxy, state: "none" };
52
+ const flagged = env["NODE_USE_ENV_PROXY"] === "1" ||
53
+ runtime.execArgv.includes("--use-env-proxy") ||
54
+ (env["NODE_OPTIONS"] ?? "").includes("--use-env-proxy");
55
+ if (flagged && runtimeReadsEnvProxy(runtime.version))
56
+ return { env: proxy, state: "runtime" };
57
+ if (runtime.setGlobalProxyFromEnv === undefined)
58
+ return { env: proxy, state: "unsupported" };
59
+ for (const value of [proxy.httpsProxy, proxy.httpProxy]) {
60
+ if (value !== undefined && !URL.canParse(value))
61
+ return { env: proxy, state: "invalid", error: `无法解析 ${redactProxyUrl(value)}` };
62
+ }
63
+ return { env: proxy, state: "enabled" };
64
+ }
65
+ /** 按上面的规则启用代理(进程级副作用);同一进程只做一次,之后返回同一份状态。 */
66
+ export function enableEnvProxy(env, runtime = defaultProxyRuntime()) {
67
+ if (current !== undefined)
68
+ return current;
69
+ const status = inspectProxy(env, runtime);
70
+ if (status.state === "enabled") {
71
+ try {
72
+ runtime.setGlobalProxyFromEnv?.({ ...env });
73
+ }
74
+ catch (error) {
75
+ current = { env: status.env, state: "invalid", error: error.message };
76
+ return current;
77
+ }
78
+ }
79
+ current = status;
80
+ return current;
81
+ }
82
+ /** 测试用:清掉进程内记住的状态。 */
83
+ export function resetProxyForTest() {
84
+ current = undefined;
85
+ hinted = false;
86
+ }
87
+ /** 代理 URL 里的账号密码打码。 */
88
+ export function redactProxyUrl(value) {
89
+ try {
90
+ const url = new URL(value);
91
+ if (url.username === "" && url.password === "")
92
+ return value;
93
+ url.username = url.username === "" ? "" : "***";
94
+ url.password = url.password === "" ? "" : "***";
95
+ return url.toString();
96
+ }
97
+ catch {
98
+ return value.replace(/\/\/[^@/]*@/, "//***@");
99
+ }
100
+ }
101
+ /** 不能启用时给一次 stderr 提示(每个进程至多一次);能用或没设代理返回 undefined。 */
102
+ export function proxyHint(status, nodeVersion = process.versions.node) {
103
+ if (hinted)
104
+ return undefined;
105
+ if (status.state === "unsupported") {
106
+ hinted = true;
107
+ return (`ama: 检测到 HTTPS_PROXY / HTTP_PROXY,但 Node ${nodeVersion} 的 fetch 不读代理变量,请求将直连;` +
108
+ "升级到 Node 24+,或在 Node 22.21+ 上设 NODE_USE_ENV_PROXY=1\n");
109
+ }
110
+ if (status.state === "invalid") {
111
+ hinted = true;
112
+ return `ama: 代理变量无法解析,请求将直连:${status.error ?? ""}\n`;
113
+ }
114
+ return undefined;
115
+ }
116
+ /** `ama doctor` 的代理段落。 */
117
+ export function describeProxy(status) {
118
+ const { env } = status;
119
+ const lines = [];
120
+ if (env.httpsProxy !== undefined)
121
+ lines.push(`HTTPS_PROXY=${redactProxyUrl(env.httpsProxy)}`);
122
+ if (env.httpProxy !== undefined)
123
+ lines.push(`HTTP_PROXY=${redactProxyUrl(env.httpProxy)}`);
124
+ if (env.noProxy !== undefined)
125
+ lines.push(`NO_PROXY=${env.noProxy}`);
126
+ 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
+ };
133
+ lines.push(state[status.state]);
134
+ return lines;
135
+ }