@armadra/agent 0.5.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/CHANGELOG.md +203 -304
  2. package/CHANGELOG.zh-CN.md +462 -0
  3. package/README.md +408 -364
  4. package/README.zh-CN.md +705 -0
  5. package/dist/agent/session-plan.js +2 -2
  6. package/dist/agent/session-state.d.ts +3 -0
  7. package/dist/agent/session-state.js +20 -0
  8. package/dist/agent/session-subagent.d.ts +15 -1
  9. package/dist/agent/session-subagent.js +26 -3
  10. package/dist/agent/session-telemetry.d.ts +16 -2
  11. package/dist/agent/session-telemetry.js +29 -7
  12. package/dist/agent/session-tools.js +5 -2
  13. package/dist/agent/session-trace-writer.d.ts +27 -0
  14. package/dist/agent/session-trace-writer.js +253 -0
  15. package/dist/agent/session.d.ts +2 -0
  16. package/dist/agent/session.js +12 -0
  17. package/dist/agent/subagent-direct.d.ts +20 -0
  18. package/dist/agent/subagent-direct.js +76 -0
  19. package/dist/agent/subagent-registry.d.ts +8 -1
  20. package/dist/agent/subagent-registry.js +28 -1
  21. package/dist/agent/system-prompt.d.ts +3 -1
  22. package/dist/agent/system-prompt.js +3 -0
  23. package/dist/agent/tool-runner.d.ts +2 -1
  24. package/dist/agent/tool-runner.js +5 -4
  25. package/dist/agent/types-w6.d.ts +39 -0
  26. package/dist/agent/types-w6.js +4 -0
  27. package/dist/agent/types.d.ts +5 -2
  28. package/dist/agents/external.js +1 -1
  29. package/dist/agents/task-record.d.ts +74 -1
  30. package/dist/agents/task-record.js +100 -0
  31. package/dist/ai/apis/cache-params.js +2 -1
  32. package/dist/ai/apis/chatgpt-backend.d.ts +52 -0
  33. package/dist/ai/apis/chatgpt-backend.js +224 -0
  34. package/dist/ai/apis/chatgpt-rate-limits.d.ts +26 -0
  35. package/dist/ai/apis/chatgpt-rate-limits.js +91 -0
  36. package/dist/ai/apis/openai-responses-request.d.ts +2 -1
  37. package/dist/ai/apis/openai-responses-request.js +8 -2
  38. package/dist/ai/apis/openai-responses.d.ts +2 -0
  39. package/dist/ai/apis/openai-responses.js +51 -16
  40. package/dist/ai/overflow.d.ts +1 -1
  41. package/dist/ai/overflow.js +10 -7
  42. package/dist/ai/providers/auth.d.ts +15 -2
  43. package/dist/ai/providers/auth.js +69 -2
  44. package/dist/ai/providers/builtin.js +27 -0
  45. package/dist/ai/providers/catalog-data.js +1 -0
  46. package/dist/ai/providers/discovered-cache.d.ts +48 -0
  47. package/dist/ai/providers/discovered-cache.js +102 -0
  48. package/dist/ai/providers/enrich.js +2 -7
  49. package/dist/ai/providers/model-visibility.d.ts +33 -0
  50. package/dist/ai/providers/model-visibility.js +70 -0
  51. package/dist/ai/providers/models-dev-cache.js +15 -19
  52. package/dist/ai/providers/models-dev-snapshot.js +8 -7
  53. package/dist/ai/providers/models-dev.js +5 -15
  54. package/dist/ai/providers/registry.d.ts +2 -0
  55. package/dist/ai/providers/registry.js +6 -1
  56. package/dist/ai/providers/suggest.js +2 -16
  57. package/dist/ai/types.d.ts +27 -1
  58. package/dist/auth/chatgpt/backend-client.d.ts +26 -0
  59. package/dist/auth/chatgpt/backend-client.js +74 -0
  60. package/dist/auth/chatgpt/claims.d.ts +17 -0
  61. package/dist/auth/chatgpt/claims.js +46 -0
  62. package/dist/auth/chatgpt/cli.d.ts +35 -0
  63. package/dist/auth/chatgpt/cli.js +279 -0
  64. package/dist/auth/chatgpt/doctor.d.ts +17 -0
  65. package/dist/auth/chatgpt/doctor.js +36 -0
  66. package/dist/auth/chatgpt/host-id.d.ts +7 -0
  67. package/dist/auth/chatgpt/host-id.js +26 -0
  68. package/dist/auth/chatgpt/login.d.ts +30 -0
  69. package/dist/auth/chatgpt/login.js +130 -0
  70. package/dist/auth/chatgpt/presets.d.ts +66 -0
  71. package/dist/auth/chatgpt/presets.js +120 -0
  72. package/dist/auth/chatgpt/quota-text.d.ts +13 -0
  73. package/dist/auth/chatgpt/quota-text.js +36 -0
  74. package/dist/auth/oauth/browser.d.ts +12 -0
  75. package/dist/auth/oauth/browser.js +27 -0
  76. package/dist/auth/oauth/callback-server.d.ts +47 -0
  77. package/dist/auth/oauth/callback-server.js +147 -0
  78. package/dist/auth/oauth/flows.d.ts +62 -0
  79. package/dist/auth/oauth/flows.js +113 -0
  80. package/dist/auth/oauth/jwt.d.ts +24 -0
  81. package/dist/auth/oauth/jwt.js +81 -0
  82. package/dist/auth/oauth/live.d.ts +21 -0
  83. package/dist/auth/oauth/live.js +25 -0
  84. package/dist/auth/oauth/oidc.d.ts +26 -0
  85. package/dist/auth/oauth/oidc.js +72 -0
  86. package/dist/auth/oauth/pkce.d.ts +15 -0
  87. package/dist/auth/oauth/pkce.js +20 -0
  88. package/dist/auth/oauth/refresh.d.ts +35 -0
  89. package/dist/auth/oauth/refresh.js +129 -0
  90. package/dist/auth/oauth/token-client.d.ts +33 -0
  91. package/dist/auth/oauth/token-client.js +121 -0
  92. package/dist/auth/oauth/token-store.d.ts +23 -0
  93. package/dist/auth/oauth/token-store.js +125 -0
  94. package/dist/auth/testing/fake-oauth.d.ts +73 -0
  95. package/dist/auth/testing/fake-oauth.js +271 -0
  96. package/dist/auth/testing/refresh-child.d.ts +5 -0
  97. package/dist/auth/testing/refresh-child.js +16 -0
  98. package/dist/bundle/ama.cjs +26532 -11045
  99. package/dist/checkpoints/backend.js +6 -5
  100. package/dist/checkpoints/restore.js +3 -2
  101. package/dist/checkpoints/settings.js +2 -1
  102. package/dist/checkpoints/shadow-git.js +7 -6
  103. package/dist/checkpoints/shadow-restore.js +3 -2
  104. package/dist/checkpoints/tracker.js +4 -3
  105. package/dist/cli/args.d.ts +9 -2
  106. package/dist/cli/args.js +74 -27
  107. package/dist/cli/bootstrap.js +53 -31
  108. package/dist/cli/choice-prompt.js +8 -6
  109. package/dist/cli/codemode-notice.js +2 -2
  110. package/dist/cli/compose-agents.js +2 -1
  111. package/dist/cli/compose-extensions.js +2 -0
  112. package/dist/cli/compose-memory.d.ts +53 -0
  113. package/dist/cli/compose-memory.js +127 -0
  114. package/dist/cli/compose-providers.d.ts +6 -0
  115. package/dist/cli/compose-providers.js +38 -2
  116. package/dist/cli/compose-session.d.ts +5 -0
  117. package/dist/cli/compose-session.js +27 -13
  118. package/dist/cli/compose-store.d.ts +2 -0
  119. package/dist/cli/compose-store.js +9 -5
  120. package/dist/cli/compose.d.ts +2 -0
  121. package/dist/cli/compose.js +13 -5
  122. package/dist/cli/default-model.d.ts +0 -2
  123. package/dist/cli/default-model.js +5 -8
  124. package/dist/cli/deps.d.ts +5 -1
  125. package/dist/cli/exit-codes.d.ts +1 -1
  126. package/dist/cli/exit-codes.js +7 -16
  127. package/dist/cli/from-prompt.js +3 -2
  128. package/dist/cli/help-text.d.ts +2 -1
  129. package/dist/cli/help-text.js +5 -99
  130. package/dist/cli/main.d.ts +5 -0
  131. package/dist/cli/main.js +21 -2
  132. package/dist/cli/proxy.js +14 -9
  133. package/dist/cli/runtime.d.ts +5 -0
  134. package/dist/cli/startup-screen.js +20 -27
  135. package/dist/cli/startup-steps.js +6 -8
  136. package/dist/cli/subcommands/auth.d.ts +6 -3
  137. package/dist/cli/subcommands/auth.js +52 -22
  138. package/dist/cli/subcommands/config-set.d.ts +21 -0
  139. package/dist/cli/subcommands/config-set.js +145 -0
  140. package/dist/cli/subcommands/config.d.ts +2 -1
  141. package/dist/cli/subcommands/config.js +51 -37
  142. package/dist/cli/subcommands/doctor.d.ts +2 -1
  143. package/dist/cli/subcommands/doctor.js +97 -58
  144. package/dist/cli/subcommands/init.d.ts +1 -1
  145. package/dist/cli/subcommands/init.js +8 -7
  146. package/dist/cli/subcommands/memory.d.ts +18 -0
  147. package/dist/cli/subcommands/memory.js +189 -0
  148. package/dist/cli/subcommands/model-meta.js +11 -9
  149. package/dist/cli/subcommands/models-cache-probe.js +23 -20
  150. package/dist/cli/subcommands/models-discover.d.ts +4 -0
  151. package/dist/cli/subcommands/models-discover.js +60 -21
  152. package/dist/cli/subcommands/models-enable.d.ts +13 -0
  153. package/dist/cli/subcommands/models-enable.js +145 -0
  154. package/dist/cli/subcommands/models.d.ts +3 -1
  155. package/dist/cli/subcommands/models.js +39 -24
  156. package/dist/cli/subcommands/probe-runner.js +8 -7
  157. package/dist/cli/subcommands/providers-list.js +32 -21
  158. package/dist/cli/subcommands/providers-plan.js +24 -25
  159. package/dist/cli/subcommands/providers-probe.js +5 -6
  160. package/dist/cli/subcommands/providers.d.ts +1 -1
  161. package/dist/cli/subcommands/providers.js +45 -50
  162. package/dist/cli/subcommands/sessions-export.d.ts +1 -1
  163. package/dist/cli/subcommands/sessions-export.js +10 -9
  164. package/dist/cli/subcommands/sessions-search.d.ts +1 -1
  165. package/dist/cli/subcommands/sessions-search.js +11 -10
  166. package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
  167. package/dist/cli/subcommands/sessions-trace.js +156 -0
  168. package/dist/cli/subcommands/sessions.d.ts +4 -3
  169. package/dist/cli/subcommands/sessions.js +40 -37
  170. package/dist/cli/subcommands/stats.d.ts +1 -1
  171. package/dist/cli/subcommands/stats.js +49 -30
  172. package/dist/cli/system-prompt-arg.js +3 -2
  173. package/dist/codemode/capability.js +3 -2
  174. package/dist/compaction/post-compact.d.ts +1 -0
  175. package/dist/compaction/post-compact.js +15 -1
  176. package/dist/compaction/prune-tier.d.ts +1 -1
  177. package/dist/compaction/prune-tier.js +3 -3
  178. package/dist/compaction/serialize.js +2 -1
  179. package/dist/config/auth-file.d.ts +12 -2
  180. package/dist/config/auth-file.js +32 -10
  181. package/dist/config/checker.js +12 -11
  182. package/dist/config/context-files.js +3 -2
  183. package/dist/config/edit.d.ts +106 -0
  184. package/dist/config/edit.js +350 -0
  185. package/dist/config/init.d.ts +4 -3
  186. package/dist/config/init.js +10 -18
  187. package/dist/config/json-schema.d.ts +2 -1
  188. package/dist/config/json-schema.js +102 -69
  189. package/dist/config/key-docs.d.ts +18 -7
  190. package/dist/config/key-docs.js +43 -128
  191. package/dist/config/load.js +7 -6
  192. package/dist/config/merge.d.ts +4 -1
  193. package/dist/config/merge.js +42 -22
  194. package/dist/config/paths.js +6 -5
  195. package/dist/config/profile.d.ts +5 -1
  196. package/dist/config/profile.js +7 -2
  197. package/dist/config/schema-w5.js +12 -4
  198. package/dist/config/schema-w6.d.ts +19 -0
  199. package/dist/config/schema-w6.js +115 -0
  200. package/dist/config/schema.js +34 -20
  201. package/dist/config/settings-registry.d.ts +81 -0
  202. package/dist/config/settings-registry.js +185 -0
  203. package/dist/config/types-w5.d.ts +7 -0
  204. package/dist/config/types-w5.js +2 -0
  205. package/dist/config/types-w6.d.ts +109 -0
  206. package/dist/config/types-w6.js +19 -0
  207. package/dist/config/types.d.ts +11 -8
  208. package/dist/config/types.js +1 -0
  209. package/dist/drivers/acp/client.js +1 -1
  210. package/dist/drivers/acp/driver.js +13 -8
  211. package/dist/drivers/agents.js +4 -3
  212. package/dist/drivers/base.js +3 -2
  213. package/dist/drivers/host-runners.js +2 -1
  214. package/dist/drivers/native/claude-stream.js +12 -11
  215. package/dist/drivers/native/codex-app-server.js +17 -12
  216. package/dist/drivers/native/oneshot.js +8 -7
  217. package/dist/drivers/pool.js +1 -1
  218. package/dist/drivers/runner.d.ts +3 -1
  219. package/dist/drivers/runner.js +68 -20
  220. package/dist/drivers/turn.js +1 -1
  221. package/dist/hooks/config.js +3 -2
  222. package/dist/hooks/protocol.js +18 -12
  223. package/dist/host/api-impl.js +11 -10
  224. package/dist/host/loader.js +9 -8
  225. package/dist/host/types.d.ts +3 -0
  226. package/dist/i18n/catalog.d.ts +2209 -0
  227. package/dist/i18n/catalog.js +72 -0
  228. package/dist/i18n/format.d.ts +21 -0
  229. package/dist/i18n/format.js +58 -0
  230. package/dist/i18n/index.d.ts +58 -0
  231. package/dist/i18n/index.js +72 -0
  232. package/dist/i18n/messages/agents.d.ts +84 -0
  233. package/dist/i18n/messages/agents.js +85 -0
  234. package/dist/i18n/messages/approval.d.ts +99 -0
  235. package/dist/i18n/messages/approval.js +100 -0
  236. package/dist/i18n/messages/auth.d.ts +189 -0
  237. package/dist/i18n/messages/auth.js +201 -0
  238. package/dist/i18n/messages/cli-args.d.ts +46 -0
  239. package/dist/i18n/messages/cli-args.js +46 -0
  240. package/dist/i18n/messages/cli-help.d.ts +12 -0
  241. package/dist/i18n/messages/cli-help.js +248 -0
  242. package/dist/i18n/messages/cli.d.ts +336 -0
  243. package/dist/i18n/messages/cli.js +311 -0
  244. package/dist/i18n/messages/config-keys.d.ts +293 -0
  245. package/dist/i18n/messages/config-keys.js +296 -0
  246. package/dist/i18n/messages/config.d.ts +508 -0
  247. package/dist/i18n/messages/config.js +241 -0
  248. package/dist/i18n/messages/drivers.d.ts +123 -0
  249. package/dist/i18n/messages/drivers.js +124 -0
  250. package/dist/i18n/messages/errors.d.ts +83 -0
  251. package/dist/i18n/messages/errors.js +171 -0
  252. package/dist/i18n/messages/interactive-line.d.ts +61 -0
  253. package/dist/i18n/messages/interactive-line.js +69 -0
  254. package/dist/i18n/messages/interactive-startup.d.ts +99 -0
  255. package/dist/i18n/messages/interactive-startup.js +100 -0
  256. package/dist/i18n/messages/interactive-view.d.ts +140 -0
  257. package/dist/i18n/messages/interactive-view.js +141 -0
  258. package/dist/i18n/messages/interactive.d.ts +489 -0
  259. package/dist/i18n/messages/interactive.js +248 -0
  260. package/dist/i18n/messages/memory.d.ts +123 -0
  261. package/dist/i18n/messages/memory.js +128 -0
  262. package/dist/i18n/messages/panels.d.ts +233 -0
  263. package/dist/i18n/messages/panels.js +232 -0
  264. package/dist/i18n/messages/permissions.d.ts +126 -0
  265. package/dist/i18n/messages/permissions.js +151 -0
  266. package/dist/i18n/messages/plan.d.ts +123 -0
  267. package/dist/i18n/messages/plan.js +124 -0
  268. package/dist/i18n/messages/print.d.ts +86 -0
  269. package/dist/i18n/messages/print.js +91 -0
  270. package/dist/i18n/messages/report.d.ts +391 -0
  271. package/dist/i18n/messages/report.js +490 -0
  272. package/dist/i18n/messages/rewind.d.ts +198 -0
  273. package/dist/i18n/messages/rewind.js +217 -0
  274. package/dist/i18n/messages/session.d.ts +230 -0
  275. package/dist/i18n/messages/session.js +258 -0
  276. package/dist/i18n/messages/settings.d.ts +355 -0
  277. package/dist/i18n/messages/settings.js +343 -0
  278. package/dist/i18n/messages/subcommands-config.d.ts +113 -0
  279. package/dist/i18n/messages/subcommands-config.js +129 -0
  280. package/dist/i18n/messages/subcommands-models.d.ts +34 -0
  281. package/dist/i18n/messages/subcommands-models.js +34 -0
  282. package/dist/i18n/messages/subcommands.d.ts +576 -0
  283. package/dist/i18n/messages/subcommands.js +477 -0
  284. package/dist/i18n/messages/trace.d.ts +243 -0
  285. package/dist/i18n/messages/trace.js +238 -0
  286. package/dist/i18n/types.d.ts +15 -0
  287. package/dist/i18n/types.js +7 -0
  288. package/dist/index.d.ts +6 -0
  289. package/dist/index.js +2 -0
  290. package/dist/memory/edit.d.ts +24 -0
  291. package/dist/memory/edit.js +63 -0
  292. package/dist/memory/frontmatter.d.ts +37 -0
  293. package/dist/memory/frontmatter.js +79 -0
  294. package/dist/memory/index.d.ts +28 -0
  295. package/dist/memory/index.js +126 -0
  296. package/dist/memory/lock.d.ts +17 -0
  297. package/dist/memory/lock.js +62 -0
  298. package/dist/memory/paths.d.ts +57 -0
  299. package/dist/memory/paths.js +175 -0
  300. package/dist/memory/report.d.ts +36 -0
  301. package/dist/memory/report.js +86 -0
  302. package/dist/memory/runtime.d.ts +42 -0
  303. package/dist/memory/runtime.js +36 -0
  304. package/dist/memory/secrets.d.ts +8 -0
  305. package/dist/memory/secrets.js +27 -0
  306. package/dist/memory/section.d.ts +28 -0
  307. package/dist/memory/section.js +59 -0
  308. package/dist/memory/store.d.ts +70 -0
  309. package/dist/memory/store.js +284 -0
  310. package/dist/memory/tool.d.ts +31 -0
  311. package/dist/memory/tool.js +94 -0
  312. package/dist/modes/acp/acp-events.js +2 -1
  313. package/dist/modes/acp/acp-server.js +13 -12
  314. package/dist/modes/commands-core.d.ts +11 -0
  315. package/dist/modes/commands-core.js +93 -62
  316. package/dist/modes/image-input.js +20 -6
  317. package/dist/modes/interactive/agent-bar.d.ts +95 -0
  318. package/dist/modes/interactive/agent-bar.js +248 -0
  319. package/dist/modes/interactive/agent-panels.js +27 -26
  320. package/dist/modes/interactive/agent-transcript.d.ts +47 -0
  321. package/dist/modes/interactive/agent-transcript.js +191 -0
  322. package/dist/modes/interactive/agent-ui.d.ts +36 -1
  323. package/dist/modes/interactive/agent-ui.js +180 -14
  324. package/dist/modes/interactive/agent-view.d.ts +72 -0
  325. package/dist/modes/interactive/agent-view.js +281 -0
  326. package/dist/modes/interactive/approval-dialog.js +46 -34
  327. package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
  328. package/dist/modes/interactive/clipboard-paste.js +9 -4
  329. package/dist/modes/interactive/commands.d.ts +22 -1
  330. package/dist/modes/interactive/commands.js +100 -49
  331. package/dist/modes/interactive/completion.js +2 -1
  332. package/dist/modes/interactive/config-panel.d.ts +70 -0
  333. package/dist/modes/interactive/config-panel.js +319 -0
  334. package/dist/modes/interactive/config-ui.d.ts +96 -0
  335. package/dist/modes/interactive/config-ui.js +397 -0
  336. package/dist/modes/interactive/confirm-dialog.js +6 -7
  337. package/dist/modes/interactive/event-notices.js +11 -9
  338. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  339. package/dist/modes/interactive/interactive-mode.js +21 -22
  340. package/dist/modes/interactive/key-dispatch.d.ts +12 -0
  341. package/dist/modes/interactive/key-dispatch.js +24 -9
  342. package/dist/modes/interactive/line/line-editor.js +2 -1
  343. package/dist/modes/interactive/line/line-mode.js +18 -7
  344. package/dist/modes/interactive/line/line-render.js +25 -24
  345. package/dist/modes/interactive/memory-panel.d.ts +64 -0
  346. package/dist/modes/interactive/memory-panel.js +221 -0
  347. package/dist/modes/interactive/message-view.d.ts +4 -2
  348. package/dist/modes/interactive/message-view.js +42 -33
  349. package/dist/modes/interactive/model-items.d.ts +45 -0
  350. package/dist/modes/interactive/model-items.js +134 -0
  351. package/dist/modes/interactive/model-picker.d.ts +57 -0
  352. package/dist/modes/interactive/model-picker.js +191 -0
  353. package/dist/modes/interactive/panels.js +39 -31
  354. package/dist/modes/interactive/pickers.d.ts +2 -1
  355. package/dist/modes/interactive/pickers.js +10 -6
  356. package/dist/modes/interactive/plan-command.d.ts +1 -1
  357. package/dist/modes/interactive/plan-command.js +24 -27
  358. package/dist/modes/interactive/plan-dialog.js +18 -17
  359. package/dist/modes/interactive/plan-flow.js +6 -5
  360. package/dist/modes/interactive/rewind-command.d.ts +1 -1
  361. package/dist/modes/interactive/rewind-command.js +18 -16
  362. package/dist/modes/interactive/rewind-flow.d.ts +0 -1
  363. package/dist/modes/interactive/rewind-flow.js +13 -14
  364. package/dist/modes/interactive/rewind-list.js +7 -6
  365. package/dist/modes/interactive/rewind-panel.js +40 -40
  366. package/dist/modes/interactive/rewind-text.d.ts +5 -3
  367. package/dist/modes/interactive/rewind-text.js +48 -38
  368. package/dist/modes/interactive/run-indicator.js +15 -12
  369. package/dist/modes/interactive/session-events.js +3 -2
  370. package/dist/modes/interactive/startup-header.js +22 -23
  371. package/dist/modes/interactive/startup-ui.d.ts +3 -9
  372. package/dist/modes/interactive/startup-ui.js +44 -88
  373. package/dist/modes/interactive/status-area.d.ts +2 -0
  374. package/dist/modes/interactive/status-area.js +8 -2
  375. package/dist/modes/interactive/status-bar.js +4 -3
  376. package/dist/modes/interactive/subagent-view.js +9 -7
  377. package/dist/modes/interactive/tasks-report.d.ts +6 -0
  378. package/dist/modes/interactive/tasks-report.js +28 -31
  379. package/dist/modes/interactive/terminal-setup.d.ts +9 -0
  380. package/dist/modes/interactive/terminal-setup.js +23 -0
  381. package/dist/modes/interactive/tool-summary.js +19 -17
  382. package/dist/modes/interactive/tool-view.js +7 -4
  383. package/dist/modes/interactive/trace-view.d.ts +89 -0
  384. package/dist/modes/interactive/trace-view.js +332 -0
  385. package/dist/modes/print/print-mode.js +14 -15
  386. package/dist/modes/rpc/commands.js +7 -3
  387. package/dist/modes/rpc/rpc-mode.js +9 -3
  388. package/dist/modes/session-report.d.ts +2 -0
  389. package/dist/modes/session-report.js +101 -105
  390. package/dist/modes/startup-ui-text.js +11 -6
  391. package/dist/permissions/bypass.d.ts +8 -10
  392. package/dist/permissions/bypass.js +19 -10
  393. package/dist/permissions/memory-class.d.ts +23 -0
  394. package/dist/permissions/memory-class.js +54 -0
  395. package/dist/permissions/modes.d.ts +3 -3
  396. package/dist/permissions/modes.js +21 -16
  397. package/dist/permissions/pipeline.d.ts +1 -1
  398. package/dist/permissions/pipeline.js +9 -2
  399. package/dist/permissions/preview.js +49 -42
  400. package/dist/permissions/rules.js +5 -2
  401. package/dist/permissions/types.d.ts +4 -0
  402. package/dist/plan/store.js +2 -1
  403. package/dist/rpc.d.ts +39 -1
  404. package/dist/rpc.js +3 -0
  405. package/dist/sandbox/bash.js +11 -8
  406. package/dist/sandbox/detect.js +14 -11
  407. package/dist/sdk.d.ts +17 -1
  408. package/dist/sdk.js +29 -7
  409. package/dist/session/export.js +31 -30
  410. package/dist/session/manager.d.ts +1 -1
  411. package/dist/session/manager.js +5 -3
  412. package/dist/session/reuse.js +5 -4
  413. package/dist/session/scan.js +3 -2
  414. package/dist/session/stats-aggregate.d.ts +3 -1
  415. package/dist/session/stats-aggregate.js +5 -1
  416. package/dist/session/stats-index.js +2 -1
  417. package/dist/session/stats-scan.d.ts +4 -1
  418. package/dist/session/stats-scan.js +6 -2
  419. package/dist/session/store.d.ts +11 -0
  420. package/dist/session/store.js +48 -1
  421. package/dist/session/types.d.ts +2 -0
  422. package/dist/skills/builtin.js +2 -1
  423. package/dist/tools/image-file.d.ts +26 -1
  424. package/dist/tools/image-file.js +55 -13
  425. package/dist/tools/presets.d.ts +14 -1
  426. package/dist/tools/presets.js +3 -3
  427. package/dist/tools/registry.js +1 -1
  428. package/dist/tools/truncate.d.ts +1 -1
  429. package/dist/tools/truncate.js +2 -2
  430. package/dist/tools/types.d.ts +17 -1
  431. package/dist/trace/build-index.d.ts +91 -0
  432. package/dist/trace/build-index.js +127 -0
  433. package/dist/trace/build-nodes.d.ts +24 -0
  434. package/dist/trace/build-nodes.js +279 -0
  435. package/dist/trace/build-util.d.ts +43 -0
  436. package/dist/trace/build-util.js +120 -0
  437. package/dist/trace/build.d.ts +82 -0
  438. package/dist/trace/build.js +382 -0
  439. package/dist/trace/detail.d.ts +35 -0
  440. package/dist/trace/detail.js +205 -0
  441. package/dist/trace/flatten.d.ts +69 -0
  442. package/dist/trace/flatten.js +173 -0
  443. package/dist/trace/format.d.ts +47 -0
  444. package/dist/trace/format.js +329 -0
  445. package/dist/trace/html-template.d.ts +19 -0
  446. package/dist/trace/html-template.js +150 -0
  447. package/dist/trace/html.d.ts +104 -0
  448. package/dist/trace/html.js +292 -0
  449. package/dist/trace/preview.d.ts +29 -0
  450. package/dist/trace/preview.js +59 -0
  451. package/dist/trace/query-session.d.ts +14 -0
  452. package/dist/trace/query-session.js +38 -0
  453. package/dist/trace/query.d.ts +55 -0
  454. package/dist/trace/query.js +188 -0
  455. package/dist/trace/session.d.ts +40 -0
  456. package/dist/trace/session.js +168 -0
  457. package/dist/trace/types.d.ts +243 -0
  458. package/dist/trace/types.js +13 -0
  459. package/dist/tui/components/editor-paste.d.ts +2 -0
  460. package/dist/tui/components/editor-paste.js +6 -3
  461. package/dist/tui/components/editor.js +2 -2
  462. package/dist/tui/components/loader.d.ts +3 -0
  463. package/dist/tui/components/loader.js +14 -0
  464. package/dist/tui/components/select-list.d.ts +2 -0
  465. package/dist/tui/components/select-list.js +7 -0
  466. package/dist/tui/components/settings-list.d.ts +61 -0
  467. package/dist/tui/components/settings-list.js +135 -0
  468. package/dist/tui/keybindings.d.ts +5 -0
  469. package/dist/tui/keybindings.js +17 -5
  470. package/dist/tui.d.ts +1 -0
  471. package/dist/tui.js +2 -0
  472. package/docs/en/host-api.md +167 -0
  473. package/docs/en/permissions.md +214 -0
  474. package/docs/en/providers.md +627 -0
  475. package/docs/en/rpc.md +361 -0
  476. package/docs/en/sessions.md +219 -0
  477. package/docs/en/tui.md +534 -0
  478. package/docs/host-api.md +18 -17
  479. package/docs/memory.md +172 -0
  480. package/docs/permissions.md +2 -2
  481. package/docs/providers.md +73 -1
  482. package/docs/rpc.md +31 -3
  483. package/docs/session-format.md +8 -2
  484. package/docs/sessions.md +29 -1
  485. package/docs/tui.md +140 -4
  486. package/package.json +8 -3
package/dist/rpc.js CHANGED
@@ -16,5 +16,8 @@
16
16
  * get_tasks / get_agents`(返回形状见 `RpcW5Results`),客户端能力 `plans`(声明后计划审批交客户端);
17
17
  * 新事件由 `SessionEvent` 派生自动包含。命令实现归 W5-F(C0 时返回 `not_implemented`),
18
18
  * `RPC_PROTOCOL_VERSION` 不变。
19
+ * - [W6-C0] 第六波(docs/wave6-plan.md §2.6、§4.4):命令 `get_trace`(参数 `RpcGetTraceParams`、返回
20
+ * `RpcW6Results`,W6-T2 实现,之前回 `not_implemented`);事件 `quota_update`;`permission_request.context`
21
+ * 可带 `toolCallId`;`keySource` 可为 `oauth`。`RPC_PROTOCOL_VERSION` 不变。
19
22
  */
20
23
  export const RPC_PROTOCOL_VERSION = 1;
@@ -13,6 +13,7 @@
13
13
  import { homedir, tmpdir } from "node:os";
14
14
  import { isAbsolute, join, resolve } from "node:path";
15
15
  import { wrapCommand } from "./wrap.js";
16
+ import { msg } from "../i18n/index.js";
16
17
  export const DEFAULT_BASH_SANDBOX_MODE = "off";
17
18
  export const DEFAULT_SANDBOX_NETWORK = "deny";
18
19
  export const NO_BASH_SANDBOX = Object.freeze({
@@ -21,12 +22,16 @@ export const NO_BASH_SANDBOX = Object.freeze({
21
22
  kind: "none",
22
23
  isolatesNetwork: false,
23
24
  restrictsWrites: false,
24
- detail: "未配置",
25
+ get detail() {
26
+ return msg().session.sandbox.notConfigured;
27
+ },
25
28
  }),
26
29
  network: DEFAULT_SANDBOX_NETWORK,
27
30
  writable: [],
28
31
  hidden: [],
29
- detail: "未配置",
32
+ get detail() {
33
+ return msg().session.sandbox.notConfigured;
34
+ },
30
35
  });
31
36
  /** 用户主目录下的凭据路径(与 permissions/protected.ts 的机密路径同一批)。 */
32
37
  export const HIDDEN_HOME_PATHS = [
@@ -66,16 +71,14 @@ export function resolveBashSandbox(config, deps) {
66
71
  const active = mode === "auto" && usable && status.restrictsWrites;
67
72
  let detail;
68
73
  if (mode === "off")
69
- detail = "关闭(sandbox.bash: off)";
74
+ detail = msg().session.sandbox.bashOff;
70
75
  else if (!active)
71
76
  detail =
72
77
  status.kind === "unshare"
73
- ? "不可用:unshare 只隔离网络、不能限制写入"
74
- : `不可用:${status.detail}`;
78
+ ? msg().session.sandbox.bashUnshareOnly
79
+ : msg().session.sandbox.bashUnavailable(status.detail);
75
80
  else
76
- detail =
77
- `${status.kind},网络 ${network},可写:工作区、临时目录、输出目录` +
78
- (writable.length > 0 ? `、${writable.join("、")}` : "");
81
+ detail = msg().session.sandbox.bashActive(status.kind, network, writable);
79
82
  return { active, status, network, writable, hidden, detail };
80
83
  }
81
84
  /** 一次 bash 调用的沙箱策略(路径未 realpath,wrapCommand 再解析)。 */
@@ -13,11 +13,14 @@ import { spawnSync } from "node:child_process";
13
13
  import { accessSync, constants } from "node:fs";
14
14
  import { posix, win32 } from "node:path";
15
15
  import { buildBwrapArgs, buildSbplProfile, buildUnshareArgs, } from "./profile.js";
16
+ import { msg } from "../i18n/index.js";
16
17
  export const NO_OS_SANDBOX = Object.freeze({
17
18
  kind: "none",
18
19
  isolatesNetwork: false,
19
20
  restrictsWrites: false,
20
- detail: "没有可用的操作系统沙箱",
21
+ get detail() {
22
+ return msg().session.sandbox.noOsSandbox;
23
+ },
21
24
  });
22
25
  export const SANDBOX_EXEC_PATH = "/usr/bin/sandbox-exec";
23
26
  export const PROBE_TIMEOUT_MS = 5000;
@@ -67,10 +70,10 @@ export function resolveSandboxEnabled(configured, env = process.env) {
67
70
  /** 不缓存的探测(测试注入 deps)。 */
68
71
  export function probeOsSandbox(enabled, deps = REAL_PROBE_DEPS) {
69
72
  if (enabled === "off")
70
- return { ...NO_OS_SANDBOX, detail: "已关闭(sandbox.enabled: off 或 AMA_SANDBOX=off)" };
73
+ return { ...NO_OS_SANDBOX, detail: msg().session.sandbox.disabled };
71
74
  if (deps.platform === "darwin") {
72
75
  if (!deps.isExecutable(SANDBOX_EXEC_PATH))
73
- return { ...NO_OS_SANDBOX, detail: `没有 ${SANDBOX_EXEC_PATH}` };
76
+ return { ...NO_OS_SANDBOX, detail: msg().session.sandbox.missing(SANDBOX_EXEC_PATH) };
74
77
  const code = deps.run(SANDBOX_EXEC_PATH, [
75
78
  "-p",
76
79
  buildSbplProfile(PROBE_POLICY),
@@ -86,7 +89,7 @@ export function probeOsSandbox(enabled, deps = REAL_PROBE_DEPS) {
86
89
  };
87
90
  return {
88
91
  ...NO_OS_SANDBOX,
89
- detail: `sandbox-exec 探针失败(${code === null ? "无法启动" : `退出码 ${code}`};可能已在别的沙箱里)`,
92
+ detail: msg().session.sandbox.sandboxExecFailed(code),
90
93
  };
91
94
  }
92
95
  if (deps.platform === "linux") {
@@ -102,10 +105,10 @@ export function probeOsSandbox(enabled, deps = REAL_PROBE_DEPS) {
102
105
  restrictsWrites: true,
103
106
  detail: "Linux bubblewrap",
104
107
  };
105
- failures.push(`bwrap 探针失败(${code === null ? "无法启动" : `退出码 ${code}`})`);
108
+ failures.push(msg().session.sandbox.bwrapFailed(code));
106
109
  }
107
110
  else
108
- failures.push("没有 bwrap");
111
+ failures.push(msg().session.sandbox.noBwrap);
109
112
  const unshare = findExecutable("unshare", deps.env, deps.isExecutable, deps.platform);
110
113
  if (unshare !== undefined) {
111
114
  const code = deps.run(unshare, [...buildUnshareArgs(), "true"]);
@@ -115,15 +118,15 @@ export function probeOsSandbox(enabled, deps = REAL_PROBE_DEPS) {
115
118
  path: unshare,
116
119
  isolatesNetwork: true,
117
120
  restrictsWrites: false,
118
- detail: `Linux unshare -r -n(只隔离网络;${failures.join(",")})`,
121
+ detail: msg().session.sandbox.unshareOnly(failures),
119
122
  };
120
- failures.push(`unshare 探针失败(${code === null ? "无法启动" : `退出码 ${code}`};可能不允许非特权用户命名空间)`);
123
+ failures.push(msg().session.sandbox.unshareFailed(code));
121
124
  }
122
125
  else
123
- failures.push("没有 unshare");
124
- return { ...NO_OS_SANDBOX, detail: failures.join(",") };
126
+ failures.push(msg().session.sandbox.noUnshare);
127
+ return { ...NO_OS_SANDBOX, detail: msg().session.sandbox.failures(failures) };
125
128
  }
126
- return { ...NO_OS_SANDBOX, detail: `${deps.platform} 上没有操作系统沙箱实现` };
129
+ return { ...NO_OS_SANDBOX, detail: msg().session.sandbox.unsupportedPlatform(deps.platform) };
127
130
  }
128
131
  const cache = new Map();
129
132
  let configured;
package/dist/sdk.d.ts CHANGED
@@ -13,6 +13,7 @@
13
13
  * - [W5-F] 计划(docs/plan.md):`CreateSessionOptions.plan`(plan.* 配置 + `onProposed` 审批回调);
14
14
  * 返回的会话带 `plan.current() / respond() / todos()`。没有 `onProposed` 时按 `plan.unattended`
15
15
  * (缺省 stop:计划落盘后停下,不替人批准)。
16
+ * - [W6-C0] `language`(两个入口都有):界面语言,跟随宿主界面(docs/i18n.md);进程级,`AMA_LANG` 仍优先。
16
17
  */
17
18
  import type { ApiRegistry } from "./ai/apis/api.js";
18
19
  import type { ModelThinkingLevel, ProviderData } from "./ai/types.js";
@@ -23,7 +24,9 @@ import type { PlanConfig } from "./config/types-w5.js";
23
24
  import { type LogFn } from "./cli/compose-session.js";
24
25
  import { type ComposeOptions } from "./cli/compose.js";
25
26
  import type { Runtime } from "./cli/runtime.js";
26
- import { type AmaConfig, type ToolsPresetInput } from "./config/types.js";
27
+ import { type AmaConfig, type ProfileMemoryOptions, type ToolsPresetInput } from "./config/types.js";
28
+ import type { Trace, TraceOptions } from "./trace/types.js";
29
+ import { type Locale } from "./i18n/index.js";
27
30
  import type { HookConfig } from "./hooks/types.js";
28
31
  import type { InstructionSource } from "./host/types.js";
29
32
  import type { ApprovalDecision, ApprovalRequest, PermissionMode } from "./permissions/types.js";
@@ -53,6 +56,10 @@ export interface RuntimeOptions {
53
56
  stderr?: (text: string) => void;
54
57
  /** 组装根选项:追加供应商 / 协议 / 工具 / 工具工厂。 */
55
58
  compose?: ComposeOptions;
59
+ /** [W6-C0] 界面语言(等价 `--lang`);进程级。 */
60
+ language?: Locale;
61
+ /** [W6-C0] 记忆开关(等价 `--memory` / `--no-memory`;W6-M 实现)。 */
62
+ memory?: boolean;
56
63
  }
57
64
  export declare function createRuntime(options?: RuntimeOptions): Promise<Runtime>;
58
65
  /** [W5-F] 计划:类型与 RPC 同形(`plan_proposed` / `plan_response`)。 */
@@ -74,6 +81,8 @@ export interface SessionPlanApi {
74
81
  }
75
82
  export type SdkAgentSession = AgentSessionImpl & {
76
83
  readonly plan: SessionPlanApi;
84
+ /** [W6-C0] 本会话的轨迹([W6-T2] 实现,见 trace/query-session.ts)。 */
85
+ trace?(options?: TraceOptions): Trace;
77
86
  };
78
87
  export type SessionAuth = {
79
88
  kind: "file";
@@ -131,5 +140,12 @@ export interface CreateSessionOptions {
131
140
  unattended?: boolean;
132
141
  onWarning?: (message: string) => void;
133
142
  log?: LogFn;
143
+ /** [W6-C0] 界面语言(跟随宿主界面);进程级,`AMA_LANG` 仍优先。不影响发给模型的文本。 */
144
+ language?: Locale;
145
+ /**
146
+ * [W6-C0] 记忆(W6-M 实现,D11):缺省禁用;`enabled: true` 时 `dir` 必填(按工作空间隔离的绝对路径),
147
+ * 作用域只有 workspace,不读用户级记忆。
148
+ */
149
+ memory?: ProfileMemoryOptions;
134
150
  }
135
151
  export declare function createAgentSession(options?: CreateSessionOptions): Promise<SdkAgentSession>;
package/dist/sdk.js CHANGED
@@ -13,12 +13,14 @@
13
13
  * - [W5-F] 计划(docs/plan.md):`CreateSessionOptions.plan`(plan.* 配置 + `onProposed` 审批回调);
14
14
  * 返回的会话带 `plan.current() / respond() / todos()`。没有 `onProposed` 时按 `plan.unattended`
15
15
  * (缺省 stop:计划落盘后停下,不替人批准)。
16
+ * - [W6-C0] `language`(两个入口都有):界面语言,跟随宿主界面(docs/i18n.md);进程级,`AMA_LANG` 仍优先。
16
17
  */
17
18
  import { resolve } from "node:path";
18
19
  import { ProviderRegistry } from "./ai/providers/registry.js";
19
20
  import { planController, } from "./agent/session-plan.js";
20
21
  import { parseArgs } from "./cli/args.js";
21
22
  import { bootstrap } from "./cli/bootstrap.js";
23
+ import { resolveMemory } from "./cli/compose-memory.js";
22
24
  import { withExtraProviders } from "./cli/compose-providers.js";
23
25
  import { composeSession, emptyComposeState } from "./cli/compose-session.js";
24
26
  import { buildRules, createRuntimeDeps, createTools } from "./cli/compose.js";
@@ -26,8 +28,10 @@ import { pickDefaultModel } from "./cli/default-model.js";
26
28
  import { findContextFiles } from "./config/context-files.js";
27
29
  import { DEFAULT_CONFIG, mergeConfig } from "./config/merge.js";
28
30
  import { resolveConfigDir, resolveDataDir } from "./config/paths.js";
29
- import { canonicalPreset } from "./config/types.js";
31
+ import { canonicalPreset, } from "./config/types.js";
32
+ import { sdkSessionTrace } from "./trace/query-session.js";
30
33
  import { AmaError } from "./errors.js";
34
+ import { msg, resolveLocale, setLocale } from "./i18n/index.js";
31
35
  import { hooksFromConfig } from "./hooks/config.js";
32
36
  import { HookDispatcher } from "./hooks/dispatcher.js";
33
37
  import { AgentEventBus } from "./host/api-impl.js";
@@ -38,7 +42,7 @@ import { PresetToolRegistry } from "./tools/presets.js";
38
42
  export async function createRuntime(options = {}) {
39
43
  const parsed = parseArgs(options.argv ?? []);
40
44
  if (parsed.kind !== "run")
41
- throw new AmaError("invalid_arguments", "createRuntime 不接受子命令");
45
+ throw new AmaError("invalid_arguments", msg().errors.sdk.noSubcommand);
42
46
  const args = parsed.args;
43
47
  if (options.model !== undefined)
44
48
  args.model = options.model;
@@ -56,7 +60,13 @@ export async function createRuntime(options = {}) {
56
60
  args.profile = options.profile;
57
61
  if (options.unattended === true)
58
62
  args.print = true;
63
+ if (options.language !== undefined)
64
+ args.lang = options.language;
65
+ if (options.memory !== undefined)
66
+ args.memory = options.memory;
59
67
  const env = options.env ?? process.env;
68
+ if (args.lang !== undefined)
69
+ setLocale(resolveLocale(env, undefined, args.lang));
60
70
  const io = {
61
71
  stdout: () => undefined,
62
72
  stderr: options.stderr ?? ((text) => void process.stderr.write(text)),
@@ -85,6 +95,8 @@ function keyOptions(auth) {
85
95
  export async function createAgentSession(options = {}) {
86
96
  const cwd = resolve(options.cwd ?? process.cwd());
87
97
  const warn = options.onWarning ?? (() => undefined);
98
+ if (options.language !== undefined)
99
+ setLocale(resolveLocale(process.env, undefined, options.language));
88
100
  let config = mergeConfig(DEFAULT_CONFIG, options.config);
89
101
  const { onProposed, ...planConfig } = options.plan ?? {};
90
102
  if (options.plan !== undefined)
@@ -105,18 +117,28 @@ export async function createAgentSession(options = {}) {
105
117
  if (ref !== undefined) {
106
118
  const found = providers.findModel(ref);
107
119
  if (!found.ok)
108
- throw new AmaError("model_not_found", `模型不存在:${ref}`, { detail: found.candidates });
120
+ throw new AmaError("model_not_found", msg().errors.sdk.modelNotFound(ref), {
121
+ detail: found.candidates,
122
+ });
109
123
  choice = found;
110
124
  }
111
125
  else {
112
126
  choice = await pickDefaultModel(providers);
113
127
  if (choice === undefined)
114
- throw new AmaError("no_api_key", "没有可用模型:传 model,或配置任一供应商的 key");
128
+ throw new AmaError("no_api_key", msg().errors.sdk.noModel);
115
129
  }
116
130
  const state = emptyComposeState();
117
131
  let tools;
118
132
  if (options.tools === undefined || options.tools === "default") {
119
- tools = createTools({ config, cwd, mode: "line" }, { extraTools: options.extraTools ?? [] }, state);
133
+ // [W6-M] SDK 同嵌入宿主:只有 `options.memory = { enabled, dir }` 开启(workspace 作用域)
134
+ const memory = resolveMemory({
135
+ config,
136
+ cwd,
137
+ dataDir: resolveDataDir(),
138
+ trusted: true,
139
+ embedded: { memory: options.memory },
140
+ });
141
+ tools = createTools({ config, cwd, mode: "line", memory }, { extraTools: options.extraTools ?? [] }, state);
120
142
  }
121
143
  else {
122
144
  tools = new PresetToolRegistry();
@@ -214,12 +236,12 @@ function withPlanApi(session, onProposed) {
214
236
  const controller = planController(session);
215
237
  controller?.setAttendance(onProposed === undefined ? "unattended" : "callback", onProposed);
216
238
  const missing = () => {
217
- throw new AmaError("not_implemented", "该会话没有装配 plan 扩展");
239
+ throw new AmaError("not_implemented", msg().errors.sdk.noPlan);
218
240
  };
219
241
  const plan = {
220
242
  current: () => controller?.current() ?? null,
221
243
  respond: (response) => (controller ?? missing()).respond(response),
222
244
  todos: () => controller?.todos() ?? [],
223
245
  };
224
- return Object.assign(session, { plan });
246
+ return Object.assign(session, { plan, trace: (o) => sdkSessionTrace(session, o) }); // [W6-T2]
225
247
  }
@@ -10,6 +10,7 @@
10
10
  import { contentImages, contentText, numberUserMessages } from "./reuse.js";
11
11
  import { redactSecrets, redactValue } from "./redact.js";
12
12
  import { indexEntries, pathToRoot } from "./tree.js";
13
+ import { msg } from "../i18n/index.js";
13
14
  export function selectEntries(input, branch) {
14
15
  return branch === "all"
15
16
  ? [...input.entries]
@@ -52,7 +53,9 @@ function sessionName(entries) {
52
53
  return name;
53
54
  }
54
55
  function truncate(text, max) {
55
- return text.length > max ? `${text.slice(0, max)}\n…(截断,原长 ${text.length} 字符)` : text;
56
+ return text.length > max
57
+ ? `${text.slice(0, max)}\n${msg().session.export.truncated(text.length)}`
58
+ : text;
56
59
  }
57
60
  function fence(text, lang = "") {
58
61
  let ticks = "```";
@@ -65,66 +68,64 @@ function time(iso) {
65
68
  }
66
69
  function imagesNote(content) {
67
70
  return contentImages(content)
68
- .map((image) => `[图片 ${image.mimeType}]`)
71
+ .map((image) => msg().session.export.image(image.mimeType))
69
72
  .join(" ");
70
73
  }
71
74
  export function renderMarkdown(input, branch) {
72
75
  const entries = selectEntries(input, branch);
73
76
  const numbers = new Map(numberUserMessages(input.entries).map((u) => [u.entryId, u.n]));
74
77
  const name = sessionName(input.entries);
78
+ const m = msg().session.export;
75
79
  const out = [
76
- `# ${name ?? `会话 ${input.header.id.slice(0, 8)}`}`,
80
+ `# ${name ?? m.title(input.header.id.slice(0, 8))}`,
77
81
  "",
78
- `- id:${input.header.id}`,
79
- `- 目录:${input.header.cwd}`,
80
- `- 创建:${time(input.header.timestamp)}`,
81
- `- 范围:${branch === "all" ? "全部条目" : "当前分支"}(${entries.length} 条条目)`,
82
- ...(input.header.parentSession !== undefined
83
- ? [`- 来源会话:${input.header.parentSession}`]
84
- : []),
82
+ m.id(input.header.id),
83
+ m.cwd(input.header.cwd),
84
+ m.created(time(input.header.timestamp)),
85
+ m.scope(branch === "all", entries.length),
86
+ ...(input.header.parentSession !== undefined ? [m.parent(input.header.parentSession)] : []),
85
87
  "",
86
88
  ];
87
89
  for (const entry of entries) {
88
90
  switch (entry.type) {
89
91
  case "message": {
90
- const m = entry.message;
91
- if (m.role === "user") {
92
+ const message = entry.message;
93
+ if (message.role === "user") {
92
94
  const n = numbers.get(entry.id);
93
- const origin = m.origin;
94
- out.push(`## 用户${n !== undefined ? ` #${n}` : ""}${origin !== undefined ? `(${origin})` : ""} · ${time(entry.timestamp)}`, "");
95
- const text = contentText(m.content);
95
+ const origin = message.origin;
96
+ out.push(m.user(n, origin, time(entry.timestamp)), "");
97
+ const text = contentText(message.content);
96
98
  if (text !== "")
97
99
  out.push(text, "");
98
- const images = imagesNote(m.content);
100
+ const images = imagesNote(message.content);
99
101
  if (images !== "")
100
102
  out.push(images, "");
101
103
  }
102
- else if (m.role === "assistant") {
103
- out.push(`## 助手 · ${m.provider}/${m.model} · ${time(entry.timestamp)}`, "");
104
- for (const block of m.content) {
104
+ else if (message.role === "assistant") {
105
+ out.push(m.assistant(`${message.provider}/${message.model}`, time(entry.timestamp)), "");
106
+ for (const block of message.content) {
105
107
  if (block.type === "text" && block.text.trim() !== "")
106
108
  out.push(block.text, "");
107
109
  if (block.type === "toolCall") {
108
- out.push(`**工具调用** \`${block.name}\``, "", fence(truncate(JSON.stringify(block.arguments, null, 2), 500), "json"), "");
110
+ out.push(m.toolCall(block.name), "", fence(truncate(JSON.stringify(block.arguments, null, 2), 500), "json"), "");
109
111
  }
110
112
  }
111
- if (m.stopReason === "error" || m.stopReason === "aborted") {
112
- out.push(`> 停止:${m.stopReason}${m.errorMessage !== undefined ? ` · ${m.errorMessage}` : ""}`, "");
113
- }
113
+ if (message.stopReason === "error" || message.stopReason === "aborted")
114
+ out.push(m.stopped(message.stopReason, message.errorMessage), "");
114
115
  }
115
- else if (m.role === "toolResult") {
116
- out.push(`**结果** \`${m.toolName}\`${m.isError ? "(出错)" : ""}`, "", fence(truncate(contentText(m.content), 2000)), "");
117
- const images = imagesNote(m.content);
116
+ else if (message.role === "toolResult") {
117
+ out.push(m.toolResult(message.toolName, message.isError), "", fence(truncate(contentText(message.content), 2000)), "");
118
+ const images = imagesNote(message.content);
118
119
  if (images !== "")
119
120
  out.push(images, "");
120
121
  }
121
122
  break;
122
123
  }
123
124
  case "compaction":
124
- out.push(`## 压缩摘要 · ${time(entry.timestamp)}`, "", entry.summary, "");
125
+ out.push(m.compaction(time(entry.timestamp)), "", entry.summary, "");
125
126
  break;
126
127
  case "branch_summary":
127
- out.push(`## 分支摘要 · ${time(entry.timestamp)}`, "", entry.summary, "");
128
+ out.push(m.branchSummary(time(entry.timestamp)), "", entry.summary, "");
128
129
  break;
129
130
  case "custom_message":
130
131
  if (entry.display) {
@@ -133,14 +134,14 @@ export function renderMarkdown(input, branch) {
133
134
  }
134
135
  break;
135
136
  case "model_change":
136
- out.push(`_切换模型:${entry.provider}/${entry.modelId}${entry.channel !== undefined ? `@${entry.channel}` : ""}_`, "");
137
+ out.push(m.modelChange(`${entry.provider}/${entry.modelId}${entry.channel !== undefined ? `@${entry.channel}` : ""}`), "");
137
138
  break;
138
139
  default:
139
140
  break;
140
141
  }
141
142
  }
142
143
  const usage = usageTotals(entries);
143
- out.push("## 用量", "", "| 请求 | 输入 | 输出 | 缓存读 | 缓存写 | 费用 |", "| ---: | ---: | ---: | ---: | ---: | ---: |", `| ${usage.requests} | ${usage.input} | ${usage.output} | ${usage.cacheRead} | ${usage.cacheWrite} | ${usage.cost !== undefined ? `$${usage.cost.toFixed(4)}` : "—"} |`, "");
144
+ out.push(m.usage, "", m.usageHeader, "| ---: | ---: | ---: | ---: | ---: | ---: |", `| ${usage.requests} | ${usage.input} | ${usage.output} | ${usage.cacheRead} | ${usage.cacheWrite} | ${usage.cost !== undefined ? `$${usage.cost.toFixed(4)}` : "—"} |`, "");
144
145
  return redactSecrets(out.join("\n"));
145
146
  }
146
147
  export function renderJson(input, branch) {
@@ -39,7 +39,7 @@ export declare class SessionManager implements SessionManagerApi {
39
39
  static open(file: string, options?: {
40
40
  now?: () => Date;
41
41
  }): SessionManager;
42
- /** `--continue`:本目录最近一条;没有则新建(延迟落盘)。 */
42
+ /** `--continue`:本目录最近一条(跳过子 Agent 会话,只读文件头两行);没有则新建(延迟落盘)。 */
43
43
  static continueRecent(dir: string, cwd: string): SessionManager;
44
44
  /** 只读列出目录下的会话(最新在前);损坏的文件跳过。 */
45
45
  static list(dir: string): SessionListItem[];
@@ -17,7 +17,7 @@ import { dirname, join } from "node:path";
17
17
  import { AmaError } from "../errors.js";
18
18
  import { AMA_VERSION } from "../version.js";
19
19
  import { migrateSessionLines } from "./migrate.js";
20
- import { acquireLock, appendLines, listSessionFiles, readSessionLines, sessionDirForCwd, sessionFileName, writeNewSessionFile, } from "./store.js";
20
+ import { acquireLock, appendLines, isSubagentSession, isSubagentSessionFile, listSessionFiles, readSessionLines, sessionDirForCwd, sessionFileName, writeNewSessionFile, } from "./store.js";
21
21
  import { buildTree, indexEntries, pathToRoot } from "./tree.js";
22
22
  import { SESSION_FORMAT_VERSION } from "./types.js";
23
23
  function newEntryId(taken) {
@@ -86,9 +86,9 @@ export class SessionManager {
86
86
  throw error;
87
87
  }
88
88
  }
89
- /** `--continue`:本目录最近一条;没有则新建(延迟落盘)。 */
89
+ /** `--continue`:本目录最近一条(跳过子 Agent 会话,只读文件头两行);没有则新建(延迟落盘)。 */
90
90
  static continueRecent(dir, cwd) {
91
- const [latest] = listSessionFiles(dir);
91
+ const latest = listSessionFiles(dir).find((file) => !isSubagentSessionFile(file));
92
92
  return latest === undefined ? this.create(dir, cwd) : this.open(latest);
93
93
  }
94
94
  /** 只读列出目录下的会话(最新在前);损坏的文件跳过。 */
@@ -124,6 +124,8 @@ export class SessionManager {
124
124
  };
125
125
  if (name !== undefined)
126
126
  item.name = name;
127
+ if (isSubagentSession(header, entries[0]))
128
+ item.subagent = true;
127
129
  if (firstPrompt !== undefined)
128
130
  item.firstPrompt = firstPrompt.slice(0, 200);
129
131
  items.push(item);
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { AmaError } from "../errors.js";
10
10
  import { findSessionFileReadOnly, readSessionReadOnly } from "./scan.js";
11
+ import { msg } from "../i18n/index.js";
11
12
  /** 内容 → 纯文本(文本块用空行连接;不含图片)。 */
12
13
  export function contentText(content) {
13
14
  if (typeof content === "string")
@@ -54,14 +55,14 @@ export function parseFromSpec(spec) {
54
55
  const at = spec.lastIndexOf("#");
55
56
  if (at < 0) {
56
57
  if (spec.trim() === "")
57
- throw new AmaError("invalid_arguments", "--from 需要会话 id", { exitCode: 2 });
58
+ throw new AmaError("invalid_arguments", msg().session.lookup.fromNeedsId, { exitCode: 2 });
58
59
  return { id: spec };
59
60
  }
60
61
  const id = spec.slice(0, at);
61
62
  const raw = spec.slice(at + 1);
62
63
  const n = Number(raw);
63
64
  if (id === "" || !/^\d+$/.test(raw) || n < 1) {
64
- throw new AmaError("invalid_arguments", `--from 应为 <会话 id> 或 <会话 id>#<编号>(收到 ${spec})`, {
65
+ throw new AmaError("invalid_arguments", msg().session.lookup.fromInvalid(spec), {
65
66
  exitCode: 2,
66
67
  });
67
68
  }
@@ -74,13 +75,13 @@ export function resolveFromMessage(root, spec, cwd) {
74
75
  const session = readSessionReadOnly(file);
75
76
  const messages = numberUserMessages(session.entries);
76
77
  if (messages.length === 0) {
77
- throw new AmaError("invalid_arguments", `会话 ${session.header.id} 没有用户消息`, {
78
+ throw new AmaError("invalid_arguments", msg().session.lookup.noUserMessages(session.header.id), {
78
79
  exitCode: 2,
79
80
  });
80
81
  }
81
82
  const picked = n === undefined ? messages.at(-1) : messages[n - 1];
82
83
  if (picked === undefined) {
83
- throw new AmaError("invalid_arguments", `会话 ${session.header.id} 只有 ${messages.length} 条用户消息(收到 #${n})`, { exitCode: 2 });
84
+ throw new AmaError("invalid_arguments", msg().session.lookup.tooFewMessages(session.header.id, messages.length, n), { exitCode: 2 });
84
85
  }
85
86
  return { ...picked, sessionId: session.header.id, file };
86
87
  }
@@ -13,6 +13,7 @@ import { basename, join } from "node:path";
13
13
  import { AmaError } from "../errors.js";
14
14
  import { migrateSessionLines } from "./migrate.js";
15
15
  import { SESSION_FILE_SUFFIX, TRASH_DIR_NAME, listSessionFiles, sessionDirForCwd, sessionIdFromFileName, } from "./store.js";
16
+ import { msg } from "../i18n/index.js";
16
17
  /** 根目录下全部 cwd 子目录(不含 trash)。 */
17
18
  export function sessionSubdirs(root) {
18
19
  if (!existsSync(root))
@@ -56,13 +57,13 @@ export function findSessionFileReadOnly(root, id, cwd) {
56
57
  }
57
58
  if (prefix.length > 1) {
58
59
  const ids = prefix.map((f) => sessionIdFromFileName(f) ?? f).slice(0, 10);
59
- throw new AmaError("invalid_arguments", `会话 id 前缀 ${id} 不唯一,候选:${ids.join(", ")}`, {
60
+ throw new AmaError("invalid_arguments", msg().session.lookup.ambiguousPrefix(id, ids.join(", ")), {
60
61
  exitCode: 5,
61
62
  });
62
63
  }
63
64
  const [file] = prefix;
64
65
  if (file === undefined)
65
- throw new AmaError("session_not_found", `会话不存在:${id}`, { exitCode: 5 });
66
+ throw new AmaError("session_not_found", msg().session.lookup.notFound(id), { exitCode: 5 });
66
67
  return file;
67
68
  }
68
69
  /**
@@ -19,8 +19,10 @@ export interface StatsTotals {
19
19
  cacheWrite: number;
20
20
  /** 有价请求的费用;没有任何有价请求时缺省。 */
21
21
  cost?: number;
22
- /** 无价请求数。 */
22
+ /** 无价请求数(不含订阅计费的)。 */
23
23
  unpriced: number;
24
+ /** [W6-I5] 订阅计费的请求数(ChatGPT 登录;不折算美元);没有时缺省。 */
25
+ subscription?: number;
24
26
  /** 0–1;报告缓存的端点没有输入时缺省。 */
25
27
  hitRate?: number;
26
28
  errors: number;
@@ -25,6 +25,7 @@ const newAcc = () => ({
25
25
  cacheWrite: 0,
26
26
  cost: 0,
27
27
  costed: 0,
28
+ subscription: 0,
28
29
  hitRead: 0,
29
30
  hitPrompt: 0,
30
31
  errors: 0,
@@ -45,6 +46,7 @@ function add(acc, b, reported, session) {
45
46
  acc.cacheWrite += b.cacheWrite;
46
47
  acc.cost += b.cost;
47
48
  acc.costed += b.costed;
49
+ acc.subscription += b.subscription;
48
50
  if (reported) {
49
51
  acc.hitRead += b.cacheRead;
50
52
  acc.hitPrompt += b.input + b.cacheRead + b.cacheWrite;
@@ -63,12 +65,14 @@ function totals(acc) {
63
65
  output: acc.output,
64
66
  cacheRead: acc.cacheRead,
65
67
  cacheWrite: acc.cacheWrite,
66
- unpriced: acc.requests - acc.costed,
68
+ unpriced: acc.requests - acc.costed - acc.subscription,
67
69
  errors: acc.errors,
68
70
  retries: acc.retries,
69
71
  };
70
72
  if (acc.costed > 0)
71
73
  out.cost = acc.cost;
74
+ if (acc.subscription > 0)
75
+ out.subscription = acc.subscription;
72
76
  if (acc.hitPrompt > 0)
73
77
  out.hitRate = acc.hitRead / acc.hitPrompt;
74
78
  if (acc.timedTurns > 0)
@@ -10,7 +10,8 @@ import { mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from "no
10
10
  import { dirname } from "node:path";
11
11
  import { summarizeSessionFile } from "./stats-scan.js";
12
12
  export const STATS_INDEX_FILE = "stats-index.json";
13
- const INDEX_VERSION = 1;
13
+ // 2:桶加 subscription([W6-I5]),旧索引里订阅请求被算成 $0 有价,整体重扫
14
+ const INDEX_VERSION = 2;
14
15
  export function timeZoneKey(now = new Date()) {
15
16
  let zone = "";
16
17
  try {
@@ -5,7 +5,8 @@
5
5
  * - 请求来源:assistant 消息 = `turn`;`usage` 条目用自己的 `kind`(cache_warm、permission_classify…);
6
6
  * `compaction` / `branch_summary` 带的 usage 记为同名 kind(模型取最近一条 assistant 的)。
7
7
  * - token:input(不含缓存)/ output / cacheRead / cacheWrite;费用只累加有 `usage.cost` 的请求,
8
- * `costed` 记有价请求数,展示层据此区分「有价」「部分无价」「全无价」。
8
+ * `costed` 记有价请求数,展示层据此区分「有价」「部分无价」「全无价」。订阅计费
9
+ * (`usage.billing: "subscription"`,ChatGPT 登录)单列 `subscription`,不进费用也不算无价。
9
10
  * - 缓存三态:桶记下是否出现过 cacheRead > 0 或 cacheWrite > 0(`cacheSeen`);汇总时同一端点
10
11
  * (provider/model@channel)任一桶出现过即算报告缓存,其余端点不进命中率分母(同会话层三态)。
11
12
  * - 回合:非 `steer` 的用户消息开始一个回合,到下一个回合开始为止;回合计入首条 assistant 的桶,
@@ -31,6 +32,8 @@ export interface StatsBucket {
31
32
  cost: number;
32
33
  /** 有价请求数。 */
33
34
  costed: number;
35
+ /** [W6-I5] 订阅计费的请求数(不折算美元)。 */
36
+ subscription: number;
34
37
  /** 出现过 cacheRead > 0 或 cacheWrite > 0。 */
35
38
  cacheSeen: boolean;
36
39
  errors: number;
@@ -5,7 +5,8 @@
5
5
  * - 请求来源:assistant 消息 = `turn`;`usage` 条目用自己的 `kind`(cache_warm、permission_classify…);
6
6
  * `compaction` / `branch_summary` 带的 usage 记为同名 kind(模型取最近一条 assistant 的)。
7
7
  * - token:input(不含缓存)/ output / cacheRead / cacheWrite;费用只累加有 `usage.cost` 的请求,
8
- * `costed` 记有价请求数,展示层据此区分「有价」「部分无价」「全无价」。
8
+ * `costed` 记有价请求数,展示层据此区分「有价」「部分无价」「全无价」。订阅计费
9
+ * (`usage.billing: "subscription"`,ChatGPT 登录)单列 `subscription`,不进费用也不算无价。
9
10
  * - 缓存三态:桶记下是否出现过 cacheRead > 0 或 cacheWrite > 0(`cacheSeen`);汇总时同一端点
10
11
  * (provider/model@channel)任一桶出现过即算报告缓存,其余端点不进命中率分母(同会话层三态)。
11
12
  * - 回合:非 `steer` 的用户消息开始一个回合,到下一个回合开始为止;回合计入首条 assistant 的桶,
@@ -64,6 +65,7 @@ export function summarizeSessionFile(file) {
64
65
  cacheWrite: 0,
65
66
  cost: 0,
66
67
  costed: 0,
68
+ subscription: 0,
67
69
  cacheSeen: false,
68
70
  errors: 0,
69
71
  retries: 0,
@@ -88,7 +90,9 @@ export function summarizeSessionFile(file) {
88
90
  bucket.cacheWrite += num(u.cacheWrite);
89
91
  if (num(u.cacheRead) > 0 || num(u.cacheWrite) > 0)
90
92
  bucket.cacheSeen = true;
91
- if (isRec(u.cost) && typeof u.cost["total"] === "number") {
93
+ if (u.billing === "subscription")
94
+ bucket.subscription++;
95
+ else if (isRec(u.cost) && typeof u.cost["total"] === "number") {
92
96
  bucket.cost += num(u.cost["total"]);
93
97
  bucket.costed++;
94
98
  }