@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
@@ -28,19 +28,12 @@ import { DISCOVER_TIMEOUT_MS } from "./models-discover.js";
28
28
  import { describeProbePlan, parseProbeTuning } from "./probe-runner.js";
29
29
  import { probeChannels } from "./providers-probe.js";
30
30
  import { DEFAULT_PREFER, capRequests, defaultChannels, hintedChannels, listingTarget, mergeProvider, orderChannels, parseChannelSpec, parseModelList, probeSelection, renderTable, } from "./providers-plan.js";
31
+ import { msg } from "../../i18n/index.js";
31
32
  export const DEFAULT_MAX_REQUESTS = 60;
32
33
  export const DEFAULT_LIMIT = 30;
33
- export const PROVIDERS_USAGE = `用法:ama providers add <id> --base-url <url> [--channel <名字>=<协议>@<地址> …]
34
- [--api openai-completions|openai-responses|anthropic-messages|auto]
35
- [--key-env <VAR>] [--probe] [--limit N] [--probe-models a,b,…]
36
- [--max-requests N] [--concurrency N] [--probe-timeout ms]
37
- [--prefer chat,responses,messages] [--include-no-tools] [--yes]
38
- ama providers list
39
- ama providers channels <id>
40
- ama providers remove <id>
41
- ama providers refresh <id> [--probe] [--limit N] [--probe-models a,b,…] [--max-requests N]
42
- [--concurrency N] [--probe-timeout ms] [--yes]
43
- `;
34
+ export function providersUsage() {
35
+ return msg().subcommands.providers.usage;
36
+ }
44
37
  const VALUE_OPTIONS = [
45
38
  "base-url",
46
39
  "api",
@@ -62,7 +55,7 @@ function intValue(ctx, name, fallback) {
62
55
  return fallback;
63
56
  const n = Number(raw);
64
57
  if (!Number.isInteger(n) || n < 1)
65
- throw new UsageError(`--${name} 需要正整数:${raw}`);
58
+ throw new UsageError(msg().subcommands.providers.positiveInt(name, raw));
66
59
  return n;
67
60
  }
68
61
  function list(raw) {
@@ -83,7 +76,7 @@ async function approved(ctx, what) {
83
76
  if (ctx.flags.has("yes"))
84
77
  return true;
85
78
  if (!ctx.io.stdinIsTTY) {
86
- ctx.io.stderr(`ama: ${what},非交互环境需加 --yes\n`);
79
+ ctx.io.stderr(msg().subcommands.providers.needsYes(what));
87
80
  return "usage";
88
81
  }
89
82
  return confirm(ctx.io, `${what}\n`);
@@ -138,10 +131,8 @@ async function plan(ctx, input) {
138
131
  const max = intValue(ctx, "max-requests", DEFAULT_MAX_REQUESTS);
139
132
  const capped = capRequests(selected, tryChannels, max);
140
133
  const tuning = parseProbeTuning(ctx.values);
141
- io.stdout(`\n探测:${capped.ids.length} 个模型、${capped.requests} 次最小请求(每模型每渠道 1 次,上限 ${max})` +
142
- `${capped.dropped > 0 ? `;另有 ${capped.dropped} 个超出上限未探测` : ""}\n` +
143
- `${describeProbePlan(capped.requests, tuning.concurrency, tuning.timeoutMs)}\n`);
144
- const ok = await approved(ctx, `将发 ${capped.requests} 次计费请求并写入 ${ctx.level.userConfigPath}`);
134
+ io.stdout(msg().subcommands.providers.probePlan(capped.ids.length, capped.requests, max, capped.dropped) + `${describeProbePlan(capped.requests, tuning.concurrency, tuning.timeoutMs)}\n`);
135
+ const ok = await approved(ctx, msg().subcommands.providers.confirmProbe(capped.requests, ctx.level.userConfigPath));
145
136
  if (ok === "usage")
146
137
  return { plans: [], cancelled: ExitCode.Usage };
147
138
  if (!ok)
@@ -197,10 +188,10 @@ async function obtainKey(ctx, id, registry) {
197
188
  const keyEnv = ctx.values.get("key-env");
198
189
  if (keyEnv !== undefined) {
199
190
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(keyEnv))
200
- throw new UsageError(`--key-env 不是合法的变量名:${keyEnv}`);
191
+ throw new UsageError(msg().subcommands.providers.invalidKeyEnv(keyEnv));
201
192
  const value = ctx.io.env[keyEnv]?.trim();
202
193
  if (!value)
203
- ctx.io.stderr(`ama: 警告:环境变量 ${keyEnv} 未设置,列模型与探测将不带 key\n`);
194
+ ctx.io.stderr(msg().subcommands.providers.keyEnvUnset(keyEnv));
204
195
  return { apiKey: value || undefined, configValue: `$${keyEnv}` };
205
196
  }
206
197
  if (registry.get(id) !== undefined) {
@@ -209,22 +200,23 @@ async function obtainKey(ctx, id, registry) {
209
200
  return { apiKey: existing.apiKey };
210
201
  }
211
202
  if (ctx.io.stdinIsTTY)
212
- ctx.io.stderr(`输入 ${id} 的 API key(不回显),回车结束:`);
203
+ ctx.io.stderr(msg().subcommands.providers.keyPrompt(id));
213
204
  const key = extractKey(await ctx.io.readStdin());
214
205
  if (ctx.io.stdinIsTTY)
215
206
  ctx.io.stderr("\n");
216
207
  if (key === "")
217
- throw new UsageError("没有从 stdin 读到 key(或用 --key-env <VAR>)");
208
+ throw new UsageError(msg().subcommands.providers.noKeyOnStdin);
218
209
  return { apiKey: key, store: key };
219
210
  }
220
211
  async function add(ctx, id, refresh) {
221
212
  const { io, level } = ctx;
213
+ const m = msg().subcommands.providers;
222
214
  if (!PROVIDER_ID_PATTERN.test(id) || id.includes("@"))
223
- throw new UsageError(`供应商 id 不合法:${id}`);
215
+ throw new UsageError(m.invalidId(id));
224
216
  const config = userConfig(level);
225
217
  const existing = config.providers?.[id];
226
218
  if (refresh && existing === undefined) {
227
- io.stderr(`ama: ${level.userConfigPath} 里没有供应商 ${id}(先 ama providers add)\n`);
219
+ io.stderr(m.missingInConfig(level.userConfigPath, id));
228
220
  return ExitCode.Usage;
229
221
  }
230
222
  const registry = await buildRegistry(level, io, ctx.deps);
@@ -236,28 +228,28 @@ async function add(ctx, id, refresh) {
236
228
  else {
237
229
  const baseUrl = ctx.values.get("base-url");
238
230
  if (baseUrl === undefined)
239
- throw new UsageError("ama providers add 需要 --base-url <url> 或 --channel");
231
+ throw new UsageError(m.needsBaseUrl);
240
232
  if (!/^https?:\/\//.test(baseUrl))
241
- throw new UsageError(`--base-url 应为 http(s) URL:${baseUrl}`);
233
+ throw new UsageError(m.baseUrlNotHttp(baseUrl));
242
234
  candidates = defaultChannels(baseUrl, ctx.values.get("api"));
243
235
  }
244
236
  const target = listingTarget(candidates);
245
237
  if (target === undefined)
246
- throw new UsageError(`${id} 没有可用的渠道`);
238
+ throw new UsageError(m.noChannel(id));
247
239
  const key = await obtainKey(ctx, id, registry);
248
240
  let listed;
249
241
  try {
250
242
  listed = await fetchModelList(target, key.apiKey);
251
243
  }
252
244
  catch (error) {
253
- io.stderr(`ama: ${id} 模型列表获取失败:${error.message}\n`);
245
+ io.stderr(m.listFailed(id, error.message));
254
246
  return ExitCode.RuntimeError;
255
247
  }
256
- io.stdout(`${id}:发现 ${listed.length} 个模型(${target.url})\n`);
248
+ io.stdout(m.discovered(id, listed.length, target.url));
257
249
  // models.dev 只读本地(快照 ⊕ `ama models refresh` 的覆盖),不联网。
258
250
  const mdIndex = loadModelsDevIndex(level.dataDir);
259
251
  io.stdout(`${describeModelsDev(level.dataDir)}\n`);
260
- io.stdout(`候选渠道:${candidates.map((c) => `${c.name}(${c.api} ${c.baseUrl})`).join(" · ")}\n`);
252
+ io.stdout(m.candidates(candidates));
261
253
  const existingIds = new Set((existing?.models ?? []).map((m) => m.id));
262
254
  const result = await plan(ctx, {
263
255
  id,
@@ -275,7 +267,7 @@ async function add(ctx, id, refresh) {
275
267
  if (refresh) {
276
268
  const gone = [...existingIds].filter((m) => !listed.some((l) => l.id === m));
277
269
  if (gone.length > 0)
278
- io.stdout(`上游已不再列出(未删除):${gone.join(", ")}\n`);
270
+ io.stdout(m.goneUpstream(gone));
279
271
  }
280
272
  const writable = result.plans.filter((p) => p.status === "ok" || p.status === "unprobed");
281
273
  const legacy = existing !== undefined && existing.channels === undefined;
@@ -290,7 +282,6 @@ async function add(ctx, id, refresh) {
290
282
  models: writable,
291
283
  prefer: list(ctx.values.get("prefer")) ?? [...DEFAULT_PREFER],
292
284
  });
293
- const keyNote = key.store !== undefined ? `;key → ${level.authFile}(0600)` : "";
294
285
  // 还没有缺省模型时按价格规则挑一个写进 defaultModel(default-model.ts 的 pickByPrice);
295
286
  // 探测过时只在探测通过的模型里挑
296
287
  const verified = writable.filter((p) => p.status === "ok");
@@ -302,26 +293,30 @@ async function add(ctx, id, refresh) {
302
293
  toolCall: p.fields.toolCall,
303
294
  })))
304
295
  : undefined;
305
- const defaultNote = defaultPick !== undefined ? `;defaultModel → ${id}/${defaultPick.id}` : "";
306
- const summary = `\n将写入 ${level.userConfigPath}:${id} 新增渠道 ${merged.addedChannels.join(", ") || "无"},` +
307
- `新增模型 ${merged.addedModels.length} 个${keyNote}${defaultNote}`;
308
- io.stdout(`${summary}\n`);
296
+ io.stdout(m.writeSummary({
297
+ path: level.userConfigPath,
298
+ id,
299
+ channels: merged.addedChannels,
300
+ models: merged.addedModels.length,
301
+ authFile: key.store !== undefined ? level.authFile : undefined,
302
+ defaultModel: defaultPick !== undefined ? `${id}/${defaultPick.id}` : undefined,
303
+ }));
309
304
  if (defaultPick !== undefined)
310
- io.stdout(` 选 ${defaultPick.id}:${defaultPick.reason}\n`);
305
+ io.stdout(m.defaultPick(defaultPick.id, defaultPick.reason));
311
306
  else if (level.merged.config.defaultModel === undefined && writable.length > 0)
312
- io.stdout(" 未设置 defaultModel:没有同时支持工具调用、上下文 ≥ 64k 且有价格的模型;用 ama config edit 设置\n");
307
+ io.stdout(m.noDefaultPick);
313
308
  if (merged.addedModels.length === 0 &&
314
309
  merged.addedChannels.length === 0 &&
315
310
  key.store === undefined) {
316
- io.stdout("没有要写入的内容\n");
311
+ io.stdout(m.nothingToWrite);
317
312
  return result.stopped !== undefined ? ExitCode.RuntimeError : ExitCode.Ok;
318
313
  }
319
314
  if (!ctx.flags.has("probe")) {
320
- const ok = await approved(ctx, "确认写入");
315
+ const ok = await approved(ctx, m.confirmWrite);
321
316
  if (ok === "usage")
322
317
  return ExitCode.Usage;
323
318
  if (!ok) {
324
- io.stderr("ama: 已取消\n");
319
+ io.stderr(msg().subcommands.common.cancelled);
325
320
  return ExitCode.Ok;
326
321
  }
327
322
  }
@@ -333,14 +328,14 @@ async function add(ctx, id, refresh) {
333
328
  writeConfigFile(level.userConfigPath, config, { backup: true });
334
329
  if (key.store !== undefined)
335
330
  setAuthKey(level.authFile, id, key.store);
336
- io.stdout(`已写入 ${level.userConfigPath}${backup ? "(原文件备份为 config.json.bak)" : ""}\n`);
331
+ io.stdout(m.written(level.userConfigPath, backup));
337
332
  const sample = defaultPick?.id ??
338
333
  result.plans.find((p) => p.status === "ok" && merged.addedModels.includes(p.id))?.id ??
339
334
  merged.addedModels[0];
340
335
  if (sample !== undefined)
341
- io.stdout(`试试:ama -p "hi" --model ${id}/${sample}\n`);
336
+ io.stdout(m.tryIt(`${id}/${sample}`));
342
337
  if (result.stopped !== undefined) {
343
- io.stderr(`ama: 探测提前停止(${result.stopped})\n`);
338
+ io.stderr(m.probeStopped(result.stopped));
344
339
  return ExitCode.RuntimeError;
345
340
  }
346
341
  return ExitCode.Ok;
@@ -375,7 +370,7 @@ function takeChannels(argv) {
375
370
  if (token === "--channel") {
376
371
  const value = argv[++i];
377
372
  if (value === undefined || value === "")
378
- throw new UsageError("--channel 需要一个值");
373
+ throw new UsageError(msg().subcommands.providers.channelNeedsValue);
379
374
  specs.push(value);
380
375
  }
381
376
  else if (token.startsWith("--channel="))
@@ -390,11 +385,11 @@ export async function runProviders(argv, io, deps) {
390
385
  const { positionals, values, flags } = parseSubArgs(rest, VALUE_OPTIONS, FLAG_OPTIONS);
391
386
  const action = positionals[0];
392
387
  if (flags.has("help") || action === undefined) {
393
- io.stdout(PROVIDERS_USAGE);
388
+ io.stdout(providersUsage());
394
389
  return flags.has("help") ? ExitCode.Ok : ExitCode.Usage;
395
390
  }
396
391
  if (deps === undefined) {
397
- io.stderr("ama: providers 尚未装配(供应商注册表由集成批次注入)\n");
392
+ io.stderr(msg().subcommands.common.notAssembled("providers"));
398
393
  return ExitCode.RuntimeError;
399
394
  }
400
395
  const level = loadUserLevel(io, {
@@ -402,14 +397,14 @@ export async function runProviders(argv, io, deps) {
402
397
  authFile: values.get("auth-file"),
403
398
  });
404
399
  for (const warning of level.warnings)
405
- io.stderr(`ama: 警告:${warning}\n`);
400
+ io.stderr(msg().subcommands.common.warning(warning));
406
401
  const ctx = { io, deps, level, values, flags, channelSpecs: specs };
407
402
  const target = positionals[1];
408
403
  const need = () => {
409
404
  if (target === undefined)
410
- throw new UsageError(`ama providers ${action} 需要 <id>`);
405
+ throw new UsageError(msg().subcommands.common.needsArg(`ama providers ${action}`, "<id>"));
411
406
  if (positionals.length > 2)
412
- throw new UsageError(`多余的参数:${positionals.slice(2).join(" ")}`);
407
+ throw new UsageError(msg().subcommands.common.extraArgs(positionals.slice(2).join(" ")));
413
408
  return target;
414
409
  };
415
410
  switch (action) {
@@ -424,6 +419,6 @@ export async function runProviders(argv, io, deps) {
424
419
  case "remove":
425
420
  return removeProvider(ctx, need());
426
421
  default:
427
- throw new UsageError(`未知的 providers 子命令:${action}`);
422
+ throw new UsageError(msg().subcommands.common.unknownSubcommand("providers", action));
428
423
  }
429
424
  }
@@ -6,5 +6,5 @@
6
6
  * - 导出内容先脱敏(session/redact.ts),格式说明见 docs/sessions.md「导出」。
7
7
  */
8
8
  import type { CliIo } from "../deps.js";
9
- export declare const SESSIONS_EXPORT_USAGE = "\u7528\u6CD5\uFF1Aama sessions export <id> [--format md|json|jsonl] [--output <\u6587\u4EF6>] [--branch leaf|all]\n [--session-dir <\u76EE\u5F55>]\n";
9
+ export declare function sessionsExportUsage(): string;
10
10
  export declare function runSessionsExport(argv: readonly string[], io: CliIo): Promise<number>;
@@ -12,9 +12,10 @@ import { renderExport } from "../../session/export.js";
12
12
  import { findSessionFileReadOnly, readSessionReadOnly } from "../../session/scan.js";
13
13
  import { parseSubArgs, UsageError } from "../args.js";
14
14
  import { ExitCode } from "../exit-codes.js";
15
- export const SESSIONS_EXPORT_USAGE = `用法:ama sessions export <id> [--format md|json|jsonl] [--output <文件>] [--branch leaf|all]
16
- [--session-dir <目录>]
17
- `;
15
+ import { msg } from "../../i18n/index.js";
16
+ export function sessionsExportUsage() {
17
+ return msg().subcommands.sessionsExport.usage;
18
+ }
18
19
  const FORMATS = ["md", "json", "jsonl"];
19
20
  const BRANCHES = ["leaf", "all"];
20
21
  export async function runSessionsExport(argv, io) {
@@ -25,21 +26,21 @@ export async function runSessionsExport(argv, io) {
25
26
  "session-dir",
26
27
  ]);
27
28
  if (flags.has("help")) {
28
- io.stdout(SESSIONS_EXPORT_USAGE);
29
+ io.stdout(sessionsExportUsage());
29
30
  return ExitCode.Ok;
30
31
  }
31
32
  const [id, extra] = positionals;
32
33
  if (id === undefined)
33
- throw new UsageError("ama sessions export 需要 <id>");
34
+ throw new UsageError(msg().subcommands.common.needsArg("ama sessions export", "<id>"));
34
35
  if (extra !== undefined)
35
- throw new UsageError(`多余的参数:${extra}`);
36
+ throw new UsageError(msg().subcommands.common.extraArgs(extra));
36
37
  const format = (values.get("format") ?? "md");
37
38
  if (!FORMATS.includes(format)) {
38
- throw new UsageError(`--format 的取值应为 ${FORMATS.join(" | ")}(收到 ${format})`);
39
+ throw new UsageError(msg().subcommands.common.invalidChoice("--format", FORMATS, format));
39
40
  }
40
41
  const branch = (values.get("branch") ?? "leaf");
41
42
  if (!BRANCHES.includes(branch)) {
42
- throw new UsageError(`--branch 的取值应为 ${BRANCHES.join(" | ")}(收到 ${branch})`);
43
+ throw new UsageError(msg().subcommands.common.invalidChoice("--branch", BRANCHES, branch));
43
44
  }
44
45
  const dirFlag = values.get("session-dir");
45
46
  const root = dirFlag !== undefined
@@ -54,6 +55,6 @@ export async function runSessionsExport(argv, io) {
54
55
  }
55
56
  const target = resolve(io.cwd, expandHome(output, { env: io.env }));
56
57
  writeFileSync(target, text, { mode: 0o600 });
57
- io.stderr(`已导出到 ${target}\n`);
58
+ io.stderr(msg().subcommands.sessionsExport.exported(target));
58
59
  return ExitCode.Ok;
59
60
  }
@@ -8,6 +8,6 @@
8
8
  */
9
9
  import { type SearchHit } from "../../session/search.js";
10
10
  import type { CliIo } from "../deps.js";
11
- export declare const SESSIONS_SEARCH_USAGE = "\u7528\u6CD5\uFF1Aama sessions search <\u5173\u952E\u8BCD|/\u6B63\u5219/\u6807\u5FD7> [--all] [--role user|assistant|tool]\n [--since 7d|today|YYYY-MM-DD] [--limit N] [--json] [--session-dir <\u76EE\u5F55>]\n";
11
+ export declare function sessionsSearchUsage(): string;
12
12
  export declare function renderHit(hit: SearchHit, color: boolean): string;
13
13
  export declare function runSessionsSearch(argv: readonly string[], io: CliIo): Promise<number>;
@@ -13,9 +13,10 @@ import { compileQuery, searchSessions, } from "../../session/search.js";
13
13
  import { parseSubArgs, UsageError } from "../args.js";
14
14
  import { ExitCode } from "../exit-codes.js";
15
15
  import { parseDaySpec } from "./stats.js";
16
- export const SESSIONS_SEARCH_USAGE = `用法:ama sessions search <关键词|/正则/标志> [--all] [--role user|assistant|tool]
17
- [--since 7d|today|YYYY-MM-DD] [--limit N] [--json] [--session-dir <目录>]
18
- `;
16
+ import { msg } from "../../i18n/index.js";
17
+ export function sessionsSearchUsage() {
18
+ return msg().subcommands.sessionsSearch.usage;
19
+ }
19
20
  const ROLES = ["user", "assistant", "tool"];
20
21
  function highlight(text, ranges, color) {
21
22
  if (!color || ranges.length === 0)
@@ -44,18 +45,18 @@ export function renderHit(hit, color) {
44
45
  export async function runSessionsSearch(argv, io) {
45
46
  const { positionals, values, flags } = parseSubArgs(argv, ["role", "since", "limit", "session-dir"], ["all", "json"]);
46
47
  if (flags.has("help")) {
47
- io.stdout(SESSIONS_SEARCH_USAGE);
48
+ io.stdout(sessionsSearchUsage());
48
49
  return ExitCode.Ok;
49
50
  }
50
51
  const pattern = positionals.join(" ");
51
52
  if (pattern.trim() === "")
52
- throw new UsageError("ama sessions search 需要关键词或 /正则/");
53
+ throw new UsageError(msg().subcommands.sessionsSearch.needsPattern);
53
54
  let query;
54
55
  try {
55
56
  query = compileQuery(pattern);
56
57
  }
57
58
  catch (error) {
58
- throw new UsageError(`正则无效:${error.message}`);
59
+ throw new UsageError(msg().subcommands.sessionsSearch.invalidRegex(error.message));
59
60
  }
60
61
  let roles;
61
62
  const roleRaw = values.get("role");
@@ -63,14 +64,14 @@ export async function runSessionsSearch(argv, io) {
63
64
  roles = new Set();
64
65
  for (const role of roleRaw.split(",").map((r) => r.trim())) {
65
66
  if (!ROLES.includes(role)) {
66
- throw new UsageError(`--role 的取值应为 ${ROLES.join(" | ")}(收到 ${role})`);
67
+ throw new UsageError(msg().subcommands.common.invalidChoice("--role", ROLES, role));
67
68
  }
68
69
  roles.add(role);
69
70
  }
70
71
  }
71
72
  const limit = Number(values.get("limit") ?? "20");
72
73
  if (!Number.isInteger(limit) || limit < 1)
73
- throw new UsageError("--limit 应为正整数");
74
+ throw new UsageError(msg().subcommands.sessionsSearch.limitPositive);
74
75
  const sinceRaw = values.get("since");
75
76
  const sinceIso = sinceRaw === undefined
76
77
  ? undefined
@@ -91,13 +92,13 @@ export async function runSessionsSearch(argv, io) {
91
92
  return ExitCode.Ok;
92
93
  }
93
94
  if (hits.length === 0) {
94
- io.stdout(flags.has("all") ? "没有命中\n" : "没有命中(只搜了当前目录的会话,--all 搜全部)\n");
95
+ io.stdout(msg().subcommands.sessionsSearch.noHits(flags.has("all")));
95
96
  return ExitCode.Ok;
96
97
  }
97
98
  const color = io.stdoutIsTTY && (io.env["NO_COLOR"] ?? "") === "";
98
99
  for (const hit of hits)
99
100
  io.stdout(renderHit(hit, color));
100
101
  if (truncated)
101
- io.stdout(`(已到 --limit ${limit},可能还有更多)\n`);
102
+ io.stdout(msg().subcommands.sessionsSearch.truncated(limit));
102
103
  return ExitCode.Ok;
103
104
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * `ama sessions trace <id|文件>`:会话轨迹导出(docs/wave6-plan.md §2.5、D7)。[W6-T2]
3
+ *
4
+ * - 缺省 / `--html [文件]` / `--format html`:自包含 HTML(`trace/html.ts`);`--json` / `--format json`:与 RPC
5
+ * `get_trace` 同形的 JSON(全部回合、已加载子会话、`previews` 只含本会话节点;`--no-content` 时没有)。
6
+ * - 输出:`--html <文件>` 或 `--output <文件>` 写文件(0600),否则 stdout;`--open` 写好后用系统浏览器打开
7
+ * (没给文件时写到临时目录)。
8
+ * - `--branch leaf|all`、`--no-content`(只留结构与数字)、`--children`(HTML 内嵌子会话预览)、
9
+ * `--now <ms>`(生成时间,确定性)。
10
+ * - 只读:不加锁、不改会话文件(推算出的时间不写回);子会话缺失只标 childMissing。
11
+ */
12
+ import { type TraceInput } from "../../trace/build.js";
13
+ import type { CliIo } from "../deps.js";
14
+ export declare function sessionsTraceUsage(): string;
15
+ export interface SessionsTraceDeps {
16
+ /** 打开浏览器(测试替身;缺省 detached spawn)。 */
17
+ open?: (command: OpenCommand) => Promise<void>;
18
+ /** 生成时间(缺省 `Date.now()`;`--now` 优先)。 */
19
+ now?: () => number;
20
+ platform?: NodeJS.Platform;
21
+ /** 读子会话(测试替身)。 */
22
+ readChild?: (file: string) => TraceInput | undefined;
23
+ }
24
+ export interface OpenCommand {
25
+ command: string;
26
+ args: string[];
27
+ }
28
+ /** 各平台「用缺省程序打开文件」的命令。 */
29
+ export declare function openCommand(platform: NodeJS.Platform, file: string): OpenCommand;
30
+ export declare function runSessionsTrace(argv: readonly string[], io: CliIo, deps?: SessionsTraceDeps): Promise<number>;
@@ -0,0 +1,156 @@
1
+ /**
2
+ * `ama sessions trace <id|文件>`:会话轨迹导出(docs/wave6-plan.md §2.5、D7)。[W6-T2]
3
+ *
4
+ * - 缺省 / `--html [文件]` / `--format html`:自包含 HTML(`trace/html.ts`);`--json` / `--format json`:与 RPC
5
+ * `get_trace` 同形的 JSON(全部回合、已加载子会话、`previews` 只含本会话节点;`--no-content` 时没有)。
6
+ * - 输出:`--html <文件>` 或 `--output <文件>` 写文件(0600),否则 stdout;`--open` 写好后用系统浏览器打开
7
+ * (没给文件时写到临时目录)。
8
+ * - `--branch leaf|all`、`--no-content`(只留结构与数字)、`--children`(HTML 内嵌子会话预览)、
9
+ * `--now <ms>`(生成时间,确定性)。
10
+ * - 只读:不加锁、不改会话文件(推算出的时间不写回);子会话缺失只标 childMissing。
11
+ */
12
+ import { spawn } from "node:child_process";
13
+ import { existsSync, writeFileSync } from "node:fs";
14
+ import { tmpdir } from "node:os";
15
+ import { join, resolve } from "node:path";
16
+ import { expandHome, resolveDataDir } from "../../config/paths.js";
17
+ import { msg } from "../../i18n/index.js";
18
+ import { findSessionFileReadOnly, readSessionReadOnly } from "../../session/scan.js";
19
+ import { buildTrace } from "../../trace/build.js";
20
+ import { entryLookup } from "../../trace/detail.js";
21
+ import { renderTraceHtml } from "../../trace/html.js";
22
+ import { queryTrace } from "../../trace/query.js";
23
+ import { childLoader } from "../../trace/session.js";
24
+ import { AMA_VERSION } from "../../version.js";
25
+ import { parseSubArgs, UsageError } from "../args.js";
26
+ import { ExitCode } from "../exit-codes.js";
27
+ export function sessionsTraceUsage() {
28
+ return msg().trace.cli.usage;
29
+ }
30
+ /** 各平台「用缺省程序打开文件」的命令。 */
31
+ export function openCommand(platform, file) {
32
+ if (platform === "darwin")
33
+ return { command: "open", args: [file] };
34
+ if (platform === "win32")
35
+ return { command: "explorer", args: [file] };
36
+ return { command: "xdg-open", args: [file] };
37
+ }
38
+ function spawnOpen({ command, args }) {
39
+ return new Promise((done, fail) => {
40
+ const child = spawn(command, args, { detached: true, stdio: "ignore" });
41
+ child.once("error", fail);
42
+ child.once("spawn", () => {
43
+ child.unref();
44
+ done();
45
+ });
46
+ });
47
+ }
48
+ /** `--html [文件]`:值可省略,只在下一个参数像 HTML 文件名时才当作文件。 */
49
+ function splitHtmlFlag(argv) {
50
+ const rest = [];
51
+ let html = false;
52
+ let file;
53
+ for (let i = 0; i < argv.length; i++) {
54
+ const token = argv[i] ?? "";
55
+ if (token.startsWith("--html=")) {
56
+ html = true;
57
+ file = token.slice("--html=".length) || undefined;
58
+ }
59
+ else if (token === "--html") {
60
+ html = true;
61
+ const next = argv[i + 1];
62
+ if (next !== undefined && !next.startsWith("-") && /\.html?$/i.test(next)) {
63
+ file = next;
64
+ i++;
65
+ }
66
+ }
67
+ else
68
+ rest.push(token);
69
+ }
70
+ return { rest, html, ...(file !== undefined ? { file } : {}) };
71
+ }
72
+ function locate(io, target, dirFlag) {
73
+ const asPath = resolve(io.cwd, expandHome(target, { env: io.env }));
74
+ if (/[\\/]|\.jsonl$/.test(target) && existsSync(asPath))
75
+ return asPath;
76
+ const root = dirFlag !== undefined
77
+ ? resolve(io.cwd, expandHome(dirFlag, { env: io.env }))
78
+ : join(resolveDataDir({ env: io.env }), "sessions");
79
+ return findSessionFileReadOnly(root, target, io.cwd);
80
+ }
81
+ export async function runSessionsTrace(argv, io, deps = {}) {
82
+ const common = msg().subcommands.common;
83
+ const m = msg().trace.cli;
84
+ const split = splitHtmlFlag(argv);
85
+ const { positionals, values, flags } = parseSubArgs(split.rest, ["format", "output", "branch", "session-dir", "now"], ["json", "open", "no-content", "children"]);
86
+ if (flags.has("help")) {
87
+ io.stdout(sessionsTraceUsage());
88
+ return ExitCode.Ok;
89
+ }
90
+ const [target, extra] = positionals;
91
+ if (target === undefined)
92
+ throw new UsageError(common.needsArg("ama sessions trace", "<id|file>"));
93
+ if (extra !== undefined)
94
+ throw new UsageError(common.extraArgs(extra));
95
+ const formatFlag = values.get("format");
96
+ if (formatFlag !== undefined && formatFlag !== "html" && formatFlag !== "json")
97
+ throw new UsageError(common.invalidChoice("--format", ["html", "json"], formatFlag));
98
+ const wantsJson = flags.has("json") || formatFlag === "json";
99
+ if (wantsJson && (split.html || formatFlag === "html"))
100
+ throw new UsageError(m.formatConflict);
101
+ const branch = values.get("branch") ?? "leaf";
102
+ if (branch !== "leaf" && branch !== "all")
103
+ throw new UsageError(common.invalidChoice("--branch", ["leaf", "all"], branch));
104
+ const rawNow = values.get("now");
105
+ const nowFlag = rawNow === undefined ? undefined : Number(rawNow);
106
+ if (nowFlag !== undefined && (!Number.isInteger(nowFlag) || nowFlag < 0))
107
+ throw new UsageError(m.badNow(rawNow ?? ""));
108
+ const content = !flags.has("no-content");
109
+ const file = locate(io, target, values.get("session-dir"));
110
+ const read = readSessionReadOnly(file);
111
+ const input = {
112
+ header: read.header,
113
+ entries: read.entries,
114
+ leaf: read.leaf,
115
+ sessionFile: file,
116
+ };
117
+ const loadChild = childLoader(deps.readChild);
118
+ const base = nowFlag !== undefined ? { now: nowFlag } : {};
119
+ let text;
120
+ if (wantsJson) {
121
+ const result = queryTrace(input, { branch, content: content ? "preview" : "none" }, { loadChild, loadChildren: true, unlimited: true, ...base });
122
+ text = `${JSON.stringify(result, null, 2)}\n`;
123
+ }
124
+ else {
125
+ const trace = buildTrace(input, { branch, loadChild, ...base });
126
+ const children = loadChild.inputs().flatMap((i) => i.entries);
127
+ text = renderTraceHtml(trace, {
128
+ content,
129
+ children: flags.has("children"),
130
+ generatedAt: nowFlag ?? (deps.now ?? Date.now)(),
131
+ version: AMA_VERSION,
132
+ lookup: entryLookup([...input.entries, ...children], read.header.cwd),
133
+ });
134
+ }
135
+ const outFlag = split.file ?? values.get("output");
136
+ const open = flags.has("open");
137
+ let outPath = outFlag === undefined ? undefined : resolve(io.cwd, expandHome(outFlag, { env: io.env }));
138
+ if (outPath === undefined && open)
139
+ outPath = join(tmpdir(), `ama-trace-${read.header.id}.${wantsJson ? "json" : "html"}`);
140
+ if (outPath === undefined) {
141
+ io.stdout(text);
142
+ return ExitCode.Ok;
143
+ }
144
+ writeFileSync(outPath, text, { mode: 0o600 });
145
+ io.stderr(m.wrote(outPath));
146
+ if (open) {
147
+ try {
148
+ await (deps.open ?? spawnOpen)(openCommand(deps.platform ?? process.platform, outPath));
149
+ }
150
+ catch (error) {
151
+ io.stderr(m.openFailed(error instanceof Error ? error.message : String(error)));
152
+ return ExitCode.RuntimeError;
153
+ }
154
+ }
155
+ return ExitCode.Ok;
156
+ }
@@ -2,13 +2,14 @@
2
2
  * `ama sessions list|show|prune`(设计 §1.2、§8)。[B5]
3
3
  *
4
4
  * 会话存储是 B2 的实现,经 RuntimeDeps.sessions 注入;这里只做参数、目录解析与输出格式。
5
- * - list [--all]:缺省只列当前目录的会话;`--all` 列全部。
5
+ * - list [--all]:缺省只列当前目录的会话、不列子 Agent 会话;`--all` 列全部目录并带上子 Agent 会话(标 `↳`)。
6
6
  * - show <id>:头信息 + 条目类型统计 + 首条提示 + 用户消息编号(`--from <id>#<编号>` 复用)。
7
- * - search / export:见 sessions-search.ts、sessions-export.ts(只读扫描,不经会话存储)。
7
+ * - search / export / trace:见 sessions-search.ts、sessions-export.ts、sessions-trace.ts(只读扫描,不经会话存储)。
8
8
  * - prune [--older-than <天>] [--dry-run]:缺省 30 天,移到 trash(不删除);之后清理检查点备份
9
9
  * (未被任何会话引用且超过 1 天的 blob,docs/rewind-plan.md §1.4)与超过 7 天的剪贴板图片
10
10
  * (`<数据目录>/clipboard/`,W5-I),`--dry-run` 时只报告。
11
11
  */
12
12
  import type { CliIo, RuntimeDeps } from "../deps.js";
13
- export declare const SESSIONS_USAGE = "\u7528\u6CD5\uFF1Aama sessions list [--all] [--session-dir <\u76EE\u5F55>]\n ama sessions show <id> [--session-dir <\u76EE\u5F55>]\n ama sessions prune [--older-than <\u5929>] [--dry-run] [--all] [--session-dir <\u76EE\u5F55>]\n ama sessions search <\u5173\u952E\u8BCD|/\u6B63\u5219/> [--all] [--role user|assistant|tool] [--since 7d] [--limit N]\n ama sessions export <id> [--format md|json|jsonl] [--output <\u6587\u4EF6>] [--branch leaf|all]\n";
13
+ /** 用法(随界面语言)。 */
14
+ export declare function sessionsUsage(): string;
14
15
  export declare function runSessions(argv: readonly string[], io: CliIo, deps: Pick<RuntimeDeps, "sessions"> | undefined): Promise<number>;