@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
@@ -12,6 +12,8 @@
12
12
  import { AgentSessionImpl } from "../agent/session.js";
13
13
  import { MISS_NOTICE_TOKENS, MISS_NOTICE_USD } from "../ai/cache/miss.js";
14
14
  import { KeyValue } from "../tui/components/key-value.js";
15
+ import { quotaParts } from "../auth/chatgpt/quota-text.js";
16
+ import { msg } from "../i18n/index.js";
15
17
  const REPORT_WIDTH = 240;
16
18
  /** `950`、`38.2k`、`150k`、`1.05M`(比状态栏多一位精度,面板与提示用)。 */
17
19
  export function formatTokenCount(count) {
@@ -44,33 +46,28 @@ export function formatDuration(ms) {
44
46
  return rest === 0 ? `${minutes}m` : `${minutes}m ${rest}s`;
45
47
  }
46
48
  export function reportingLabel(reporting) {
47
- return reporting === "reported" ? "reported" : reporting === "silent" ? "未报告" : "未知";
49
+ const m = msg().report.cache;
50
+ return reporting === "reported" ? "reported" : reporting === "silent" ? m.unreported : m.unknown;
48
51
  }
49
- const REASON_LABELS = {
50
- prefix_changed: "前缀变化",
51
- model_changed: "切换模型",
52
- idle: "空闲超时",
53
- subtask: "子任务",
54
- evicted: "服务端淘汰",
55
- };
56
52
  /** 未命中原因的短语(提示行括号里那段)。 */
57
53
  export function missReasonText(miss) {
58
54
  const minutes = Math.max(1, Math.round(miss.idleMs / 60_000));
55
+ const m = msg().report.cache;
59
56
  switch (miss.reason) {
60
57
  case "idle":
61
- return `空闲 ${minutes} 分钟后`;
58
+ return m.missIdle(minutes);
62
59
  case "subtask":
63
- return `子任务运行 ${minutes} 分钟后`;
60
+ return m.missSubtask(minutes);
64
61
  case "model_changed":
65
- return "切换模型后";
62
+ return m.missModel;
66
63
  case "prefix_changed":
67
64
  return miss.detail === "tools"
68
- ? "工具表变化"
65
+ ? m.missTools
69
66
  : miss.detail === "system"
70
- ? "系统提示变化"
71
- : "前缀变化";
67
+ ? m.missSystem
68
+ : m.missPrefix;
72
69
  case "evicted":
73
- return "服务端已淘汰";
70
+ return m.missEvicted;
74
71
  }
75
72
  }
76
73
  export function shouldNotifyMiss(miss) {
@@ -79,17 +76,17 @@ export function shouldNotifyMiss(miss) {
79
76
  }
80
77
  /** `缓存未命中(空闲 7 分钟后):重计费 38.2k token(约 $0.11)`。 */
81
78
  export function cacheMissNotice(miss) {
82
- const cost = miss.missedCost === undefined ? "" : `(约 ${formatUsd(miss.missedCost)})`;
83
- return `缓存未命中(${missReasonText(miss)}):重计费 ${formatTokenCount(miss.missedTokens)} token${cost}`;
79
+ return msg().report.cache.missNotice(missReasonText(miss), formatTokenCount(miss.missedTokens), miss.missedCost === undefined ? undefined : formatUsd(miss.missedCost));
84
80
  }
85
81
  /** `上下文已用 72%,约剩 9 回合(按最近 5 回合均值)`;估不出回合时给余量 token。 */
86
82
  export function contextPressureNotice(event) {
87
- const head = `上下文已用 ${Math.round(event.percent)}%`;
83
+ const m = msg().report.cache;
84
+ const percent = Math.round(event.percent);
88
85
  if (event.estimatedTurnsLeft !== undefined)
89
- return `${head},约剩 ${event.estimatedTurnsLeft} 回合(按最近 5 回合均值)`;
86
+ return m.pressureTurns(percent, event.estimatedTurnsLeft);
90
87
  if (event.remainingTokens !== undefined)
91
- return `${head},余量 ${formatTokenCount(event.remainingTokens)} token`;
92
- return head;
88
+ return m.pressureTokens(percent, formatTokenCount(event.remainingTokens));
89
+ return m.pressure(percent);
93
90
  }
94
91
  /**
95
92
  * 缓存事件 → 消息区 / stderr 的一行提示;不提示时 undefined。`enabled` = `cache.missNotices`。
@@ -111,67 +108,50 @@ export function cacheEventNotice(event, enabled) {
111
108
  export function warmSentNotice(event) {
112
109
  if (event.phase !== "sent")
113
110
  return undefined;
114
- const read = event.usage === undefined ? "" : `读 ${formatTokenCount(event.usage.cacheRead)} token`;
115
- const cost = event.cost === undefined ? "" : `${read !== "" ? "," : ""}${formatUsd(event.cost)}`;
116
- return `缓存保温已刷新${read + cost !== "" ? `(${read}${cost})` : ""}`;
111
+ return msg().report.cache.warmSent(event.usage === undefined ? undefined : formatTokenCount(event.usage.cacheRead), event.cost === undefined ? undefined : formatUsd(event.cost));
117
112
  }
118
113
  /** 消息区 / stderr 是否提示未命中与上下文余量(`cache.missNotices`,缺省 true)。 */
119
114
  export function cacheNoticesEnabled(session) {
120
115
  return session instanceof AgentSessionImpl ? session.cache.cacheSettings.missNotices : true;
121
116
  }
122
- const STOP_REASONS = {
123
- retention_none: "缓存保留为 none",
124
- payload_replaced: "请求体被 onPayload 替换",
125
- thinking_budget: "思考预算随 max_tokens,不可重放",
126
- reporting_unknown: "端点还没报过缓存",
127
- reporting_silent: "端点不报缓存",
128
- no_ttl: "模型目录没有缓存 TTL",
129
- ttl_too_short: "缓存 TTL 太短",
130
- max_duration: "已达保温时长上限",
131
- late: "计时器迟到",
132
- off: "已关闭",
133
- stale: "上下文已变",
134
- declined: "宿主否决",
135
- error: "保温请求失败",
136
- no_cache_hits: "连续保温零命中",
137
- no_price: "缺价格,经济性不可算",
138
- below_min_savings: "期望节省低于门槛",
139
- };
140
117
  export function warmStopText(reason) {
118
+ const m = msg().report.cache;
141
119
  if (reason === undefined)
142
- return "已停止";
143
- return `已停止:${STOP_REASONS[reason] ?? reason}`;
120
+ return m.stopped;
121
+ return m.stoppedWith(m.stopReason(reason));
144
122
  }
145
123
  /** `streaming · 下次 2m 10s · 期望节省 $0.18 ≥ $0.05 · 已发 2 次 $0.01`。 */
146
124
  export function warmingText(status, now, minSavingsUsd) {
147
125
  if (status.mode === "off")
148
126
  return "off";
127
+ const m = msg().report.cache;
149
128
  const parts = [status.mode];
150
129
  if (status.state === "scheduled") {
151
130
  if (status.nextWarmAt !== undefined)
152
- parts.push(`下次 ${formatDuration(status.nextWarmAt - now)}`);
131
+ parts.push(m.next(formatDuration(status.nextWarmAt - now)));
153
132
  if (status.expectedSavingsUsd !== undefined) {
154
- const floor = minSavingsUsd === undefined ? "" : ` ≥ ${formatUsd(minSavingsUsd)}`;
155
- parts.push(`期望节省 ${formatUsd(status.expectedSavingsUsd)}${floor}`);
133
+ const floor = minSavingsUsd === undefined ? undefined : formatUsd(minSavingsUsd);
134
+ parts.push(m.savings(formatUsd(status.expectedSavingsUsd), floor));
156
135
  }
157
136
  }
158
137
  else if (status.state === "stopped")
159
138
  parts.push(warmStopText(status.reason));
160
139
  else
161
- parts.push("待下一次请求");
140
+ parts.push(m.pending);
162
141
  if (status.sent !== undefined && status.sent > 0)
163
- parts.push(`已发 ${status.sent} 次 ${formatUsd(status.costUsd)}`);
142
+ parts.push(m.sent(status.sent, formatUsd(status.costUsd)));
164
143
  return parts.join(" · ");
165
144
  }
166
145
  function missesText(cache) {
146
+ const m = msg().report.cache;
167
147
  if (cache.misses.count === 0)
168
- return "0 次";
148
+ return m.missesNone;
169
149
  const by = Object.entries(cache.misses.byReason)
170
150
  .filter(([, n]) => n !== undefined && n > 0)
171
- .map(([reason, n]) => `${REASON_LABELS[reason] ?? reason} ${n}`)
151
+ .map(([reason, n]) => `${m.reason(reason) ?? reason} ${n}`)
172
152
  .join(" · ");
173
153
  const cost = cache.reBilledUsd === undefined ? "$?" : formatUsd(cache.reBilledUsd);
174
- return `${cache.misses.count} 次,重计费 ${formatTokenCount(cache.reBilledTokens)} token ≈ ${cost}${by !== "" ? `(${by})` : ""}`;
154
+ return m.misses(cache.misses.count, formatTokenCount(cache.reBilledTokens), cost, by);
175
155
  }
176
156
  /** 缓存段的键值行(`/session` 与 `/cache` 共用)。 */
177
157
  export function cacheRows(session, now = Date.now()) {
@@ -179,57 +159,57 @@ export function cacheRows(session, now = Date.now()) {
179
159
  const t = stats.tokens;
180
160
  const prompt = t.input + t.cacheRead + t.cacheWrite;
181
161
  const uncached = t.input + t.cacheWrite;
182
- const readShare = prompt > 0 ? `(${formatPercent(t.cacheRead / prompt)})` : " ";
183
- const write = t.cacheWrite > 0 ? `(其中写入 ${formatTokenCount(t.cacheWrite)})` : "";
162
+ const m = msg().report.cache;
184
163
  const rows = [
185
164
  {
186
- key: "输入",
187
- value: `${formatTokenCount(prompt)} = 缓存读 ${formatTokenCount(t.cacheRead)}${readShare}+ 未缓存 ${formatTokenCount(uncached)}${write}`,
165
+ key: m.keyInput,
166
+ value: m.input(formatTokenCount(prompt), formatTokenCount(t.cacheRead), prompt > 0 ? formatPercent(t.cacheRead / prompt) : undefined, formatTokenCount(uncached), t.cacheWrite > 0 ? formatTokenCount(t.cacheWrite) : undefined),
188
167
  },
189
168
  ];
190
169
  const cache = stats.cache;
191
170
  if (cache === undefined) {
192
- rows.push({ key: "命中率", value: `会话 ${formatPercent(stats.cacheHitRate)}` });
171
+ rows.push({ key: m.keyHitRate, value: m.sessionRate(formatPercent(stats.cacheHitRate)) });
193
172
  return rows;
194
173
  }
195
- rows.push({ key: "报告状态", value: reportingLabel(cache.reporting) });
174
+ rows.push({ key: m.keyReporting, value: reportingLabel(cache.reporting) });
196
175
  if (cache.reporting === "reported") {
197
176
  rows.push({
198
- key: "命中率",
199
- value: `最近 ${formatPercent(cache.lastHitRate)} · 会话 ${formatPercent(cache.hitRate)}`,
177
+ key: m.keyHitRate,
178
+ value: m.rates(formatPercent(cache.lastHitRate), formatPercent(cache.hitRate)),
200
179
  });
201
180
  }
202
- rows.push({ key: "未命中", value: missesText(cache) });
181
+ rows.push({ key: m.keyMisses, value: missesText(cache) });
203
182
  const minSavings = session instanceof AgentSessionImpl ? session.cache.cacheSettings.minSavingsUsd : undefined;
204
- rows.push({ key: "保温", value: warmingText(cache.warming, now, minSavings) });
183
+ rows.push({ key: m.keyWarming, value: warmingText(cache.warming, now, minSavings) });
205
184
  if (stats.contextPercent !== undefined) {
206
- const remaining = cache.contextRemainingTokens === undefined
207
- ? ""
208
- : `,余量 ≈ ${formatTokenCount(cache.contextRemainingTokens)} token`;
209
- const turns = cache.estimatedTurnsLeft === undefined ? "" : ` ≈ ${cache.estimatedTurnsLeft} 回合`;
210
- rows.push({ key: "上下文", value: `${Math.round(stats.contextPercent)}%${remaining}${turns}` });
185
+ rows.push({
186
+ key: m.keyContext,
187
+ value: m.context(Math.round(stats.contextPercent), cache.contextRemainingTokens === undefined
188
+ ? undefined
189
+ : formatTokenCount(cache.contextRemainingTokens), cache.estimatedTurnsLeft),
190
+ });
211
191
  }
212
192
  if (cache.subagents !== undefined) {
213
193
  const sub = cache.subagents;
214
- const rebill = sub.reBilledTokens > 0 ? `,重计费 ${formatTokenCount(sub.reBilledTokens)} token` : "";
215
194
  rows.push({
216
- key: "子任务",
217
- value: `${sub.count} 个会话,命中率 ${formatPercent(sub.hitRate)}${rebill}`,
195
+ key: m.keySubtasks,
196
+ value: m.subtasks(sub.count, formatPercent(sub.hitRate), sub.reBilledTokens > 0 ? formatTokenCount(sub.reBilledTokens) : undefined),
218
197
  });
219
198
  }
220
199
  return rows;
221
200
  }
222
201
  /** [W5-U] 外部 Agent 用量一项:美元 / token / 请求数按各自单位,不换算。 */
223
202
  export function externalUsageText(usage) {
203
+ const m = msg().report.session;
224
204
  const amount = usage.unit === "usd"
225
205
  ? formatUsd(usage.amount)
226
206
  : usage.unit === "tokens"
227
- ? `${formatTokenCount(usage.amount)} token`
228
- : `${usage.amount} 次请求`;
207
+ ? m.externalTokens(formatTokenCount(usage.amount))
208
+ : m.externalRequests(usage.amount);
229
209
  const tokens = usage.unit !== "tokens" && usage.tokens !== undefined && usage.tokens > 0
230
- ? ` · ${formatTokenCount(usage.tokens)} token`
231
- : "";
232
- return `${usage.runs} 次运行 · ${amount}${tokens}`;
210
+ ? formatTokenCount(usage.tokens)
211
+ : undefined;
212
+ return m.external(usage.runs, amount, tokens);
233
213
  }
234
214
  /** [W5-U] 「外部 Agent」段(`getStats().external.byAgent`);没有外部运行时为空。 */
235
215
  export function externalRows(session) {
@@ -243,20 +223,34 @@ export function taskStatsText(session) {
243
223
  const tasks = session.getStats().tasks;
244
224
  if (tasks === undefined || tasks.total === 0)
245
225
  return undefined;
246
- const parts = [`${tasks.total} 个任务`];
226
+ const m = msg().report.session;
227
+ const parts = [m.tasks(tasks.total)];
247
228
  if (tasks.running > 0)
248
- parts.push(`运行中 ${tasks.running}`);
249
- const labels = {
250
- completed: "完成",
251
- failed: "失败",
252
- aborted: "已停止",
253
- max_turns: "轮数耗尽",
254
- interrupted: "已中断",
255
- };
229
+ parts.push(m.running(tasks.running));
256
230
  for (const [status, count] of Object.entries(tasks.byStatus))
257
231
  if (count !== undefined && count > 0)
258
- parts.push(`${labels[status] ?? status} ${count}`);
259
- return `${parts.join(" · ")}(/tasks)`;
232
+ parts.push(m.status(status, count));
233
+ return m.tasksLine(parts);
234
+ }
235
+ /** [W6-O] 「订阅用量」段(`getStats().subscription`):按供应商列请求与 token、缓存只给命中率;附最近配额。 */
236
+ export function subscriptionRows(session, now = Date.now()) {
237
+ const sub = session.getStats().subscription;
238
+ if (sub === undefined)
239
+ return [];
240
+ const m = msg().auth.report;
241
+ const rows = Object.entries(sub.byProvider)
242
+ .sort(([a], [b]) => a.localeCompare(b))
243
+ .map(([provider, u]) => {
244
+ const prompt = u.input + u.cacheRead;
245
+ return {
246
+ key: provider,
247
+ value: m.row(u.requests, formatTokenCount(u.input), formatTokenCount(u.output), formatTokenCount(u.cacheRead), formatPercent(prompt > 0 ? u.cacheRead / prompt : undefined)),
248
+ };
249
+ });
250
+ const quota = sub.quota === undefined ? undefined : quotaParts(sub.quota, now);
251
+ if (quota !== undefined)
252
+ rows.push({ key: m.quotaKey, value: quota });
253
+ return rows;
260
254
  }
261
255
  /** 键值行 → 纯文本(键列对齐、去行尾空白)。 */
262
256
  export function renderRows(rows, indent = "") {
@@ -265,7 +259,7 @@ export function renderRows(rows, indent = "") {
265
259
  .map((line) => (line === "" ? "" : `${indent}${line}`.replace(/\s+$/, "")));
266
260
  }
267
261
  export function describeCache(session, now = Date.now()) {
268
- return ["缓存", ...renderRows(cacheRows(session, now), " ")].join("\n");
262
+ return [msg().report.cache.title, ...renderRows(cacheRows(session, now), " ")].join("\n");
269
263
  }
270
264
  export function describeSession(session, now = Date.now()) {
271
265
  const state = session.state;
@@ -273,49 +267,51 @@ export function describeSession(session, now = Date.now()) {
273
267
  const model = state.model === undefined ? "?" : `${state.model.provider}/${state.model.id}`;
274
268
  const t = stats.tokens;
275
269
  const percent = stats.contextPercent === undefined ? "?" : `${Math.round(stats.contextPercent)}`;
270
+ const m = msg().report.session;
276
271
  const rows = [
272
+ { key: m.keySession, value: m.session(state.sessionId, state.sessionFile) },
277
273
  {
278
- key: "会话",
279
- value: `${state.sessionId}${state.sessionFile !== undefined ? `(${state.sessionFile})` : "(未落盘)"}`,
280
- },
281
- {
282
- key: "模型",
283
- value: `${model} · 思考 ${state.thinkingLevel} · 权限 ${state.permissionMode}`,
274
+ key: m.keyModel,
275
+ value: m.model(model, state.thinkingLevel, state.permissionMode),
284
276
  },
285
277
  {
286
- key: "消息",
287
- value: `用户 ${stats.userMessages} · 助手 ${stats.assistantMessages} · 工具调用 ${stats.toolCalls}`,
278
+ key: m.keyMessages,
279
+ value: m.messages(stats.userMessages, stats.assistantMessages, stats.toolCalls),
288
280
  },
289
281
  {
290
- key: "用量",
291
- value: `输入 ${t.input} · 输出 ${t.output} · 缓存读 ${t.cacheRead} · 缓存写 ${t.cacheWrite}` +
292
- (stats.cost !== undefined ? ` · $${stats.cost.toFixed(4)}` : " · $?"),
282
+ key: m.keyUsage,
283
+ value: m.usage(t.input, t.output, t.cacheRead, t.cacheWrite, stats.cost !== undefined ? `$${stats.cost.toFixed(4)}` : "$?"),
293
284
  },
294
285
  {
295
- key: "上下文",
296
- value: `${stats.contextTokens ?? "?"} / ${stats.contextWindow ?? "?"}(${percent}%)`,
286
+ key: m.keyContext,
287
+ value: m.context(String(stats.contextTokens ?? "?"), String(stats.contextWindow ?? "?"), percent),
297
288
  },
298
289
  ];
299
290
  const tasks = taskStatsText(session);
300
291
  if (tasks !== undefined)
301
- rows.push({ key: "子 Agent", value: tasks });
292
+ rows.push({ key: m.keyAgents, value: tasks });
302
293
  const external = externalRows(session);
294
+ const subscription = subscriptionRows(session, now);
303
295
  return [
304
296
  ...renderRows(rows),
305
297
  describeCache(session, now),
306
- ...(external.length > 0 ? ["外部 Agent", ...renderRows(external, " ")] : []),
298
+ ...(subscription.length > 0
299
+ ? [msg().auth.report.section, ...renderRows(subscription, " ")]
300
+ : []),
301
+ ...(external.length > 0 ? [m.externalTitle, ...renderRows(external, " ")] : []),
307
302
  ].join("\n");
308
303
  }
309
304
  /** `/cache fingerprint`:最近一次真实请求的前缀指纹(system / tools 哈希与模型)。 */
310
305
  export function describeFingerprint(session) {
306
+ const m = msg().report.session;
311
307
  if (!(session instanceof AgentSessionImpl))
312
- return "当前会话不提供前缀指纹";
308
+ return m.noFingerprint;
313
309
  const record = session.cache.lastTurn;
314
310
  if (record === undefined)
315
- return "还没有真实请求(指纹在第一次请求后记录)";
311
+ return m.noRequestYet;
316
312
  const f = record.fingerprint;
317
313
  return [
318
- "前缀指纹(最近一次请求)",
314
+ m.fingerprintTitle,
319
315
  ...renderRows([
320
316
  { key: "system", value: f.system },
321
317
  { key: "tools", value: f.tools },
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import { existsSync, statSync } from "node:fs";
8
8
  import { resolve } from "node:path";
9
+ import { msg } from "../i18n/index.js";
9
10
  /** 读一行(不含行尾);EOF 且无内容返回 undefined。 */
10
11
  export function readOneLine(stdin) {
11
12
  if (stdin.readableEnded === true)
@@ -61,10 +62,11 @@ export function createTextStartupUi(io) {
61
62
  const list = (values, labels) => values.map((_, i) => ` ${i + 1}. ${labels[i]}`);
62
63
  return {
63
64
  async promptTrust(cwd, resources) {
65
+ const m = msg().report.startup;
64
66
  const shown = resources.slice(0, 6).map((p) => ` ${p}`);
65
67
  if (resources.length > shown.length)
66
- shown.push(` …另有 ${resources.length - shown.length} 项`);
67
- const answer = await ask([`信任这个目录的项目资源?${cwd}`, ...shown], "[y 仅本次 / a 信任并记住 / N 不信任] ");
68
+ shown.push(m.more(resources.length - shown.length));
69
+ const answer = await ask([m.trustQuestion(cwd), ...shown], m.trustChoices);
68
70
  const key = answer?.trim().toLowerCase();
69
71
  if (key === "a")
70
72
  return { trusted: true, remember: true };
@@ -76,7 +78,8 @@ export function createTextStartupUi(io) {
76
78
  const sorted = [...items].sort((a, b) => b.modifiedAt.localeCompare(a.modifiedAt));
77
79
  const ids = sorted.map((item) => item.id);
78
80
  const labels = sorted.map((item) => `${item.id.slice(0, 8)} ${(item.name ?? item.firstPrompt ?? "").replace(/\s+/g, " ").slice(0, 60)}`);
79
- return choose(await ask(["恢复哪个会话?", ...list(ids, labels)], "编号或 id:"), ids);
81
+ const m = msg().report.startup;
82
+ return choose(await ask([m.resumeQuestion, ...list(ids, labels)], m.resumeAnswer), ids);
80
83
  },
81
84
  async pickModel(providers, reason) {
82
85
  const refs = [];
@@ -85,16 +88,18 @@ export function createTextStartupUi(io) {
85
88
  refs.push(`${provider.id}/${model.id}`);
86
89
  if (refs.length === 0)
87
90
  return undefined;
88
- const answer = await ask([reason, "选择模型:", ...list(refs, refs)], "编号或 provider/id:");
91
+ const m = msg().report.startup;
92
+ const answer = await ask([reason, m.pickModel, ...list(refs, refs)], m.pickModelAnswer);
89
93
  return choose(answer, refs);
90
94
  },
91
95
  async askCwd(missing) {
92
- const answer = (await ask([`会话的工作目录不存在:${missing}`], "替代目录(空行取消):"))?.trim();
96
+ const m = msg().report.startup;
97
+ const answer = (await ask([m.cwdMissing(missing)], m.cwdAnswer))?.trim();
93
98
  if (answer === undefined || answer === "")
94
99
  return undefined;
95
100
  const abs = resolve(answer);
96
101
  if (!existsSync(abs) || !isDirectory(abs)) {
97
- io.write(`不是目录:${abs}\n`);
102
+ io.write(m.notDirectory(abs));
98
103
  return undefined;
99
104
  }
100
105
  return abs;
@@ -9,20 +9,18 @@
9
9
  */
10
10
  import type { PermissionMode } from "./types.js";
11
11
  export declare const BYPASS_MODE: PermissionMode;
12
- export declare const BYPASS_CONFIRM_TITLE = "\u8FDB\u5165 Bypass permissions\uFF1F";
12
+ /** 确认框标题(随界面语言)。 */
13
+ export declare function bypassConfirmTitle(): string;
13
14
  /** 确认框正文:Bypass 意味着什么(一两条关键风险)。 */
14
- export declare const BYPASS_RISK_LINES: readonly string[];
15
+ export declare function bypassRiskLines(): string[];
15
16
  /** 选项:缺省选中「取消」。 */
16
- export declare const BYPASS_CHOICES: readonly [{
17
- readonly label: "进入 Bypass";
18
- readonly keys: "y";
19
- }, {
20
- readonly label: "取消";
21
- readonly keys: "n Esc";
22
- }];
17
+ export declare function bypassChoices(): {
18
+ label: string;
19
+ keys: string;
20
+ }[];
23
21
  export declare const BYPASS_DEFAULT_CHOICE = 1;
24
22
  /** 行式界面的问句(单键 y/N,缺省 N)。 */
25
- export declare const BYPASS_LINE_QUESTION = "\u786E\u8BA4\u8FDB\u5165 Bypass\uFF1F[y/N] ";
23
+ export declare function bypassLineQuestion(): string;
26
24
  /** 不用问时同步返回 true(切换立即生效);要问时返回等用户回答的 Promise。 */
27
25
  export type BypassGate = (mode: PermissionMode) => boolean | Promise<boolean>;
28
26
  /**
@@ -7,21 +7,30 @@
7
7
  * - 离开 Bypass、切到其它模式都不问。
8
8
  * - 只管「要不要问」与记住确认;怎么问(对话框 / 行式 y/N)由各界面提供 `ask`。
9
9
  */
10
+ import { msg } from "../i18n/index.js";
10
11
  export const BYPASS_MODE = "full-auto";
11
- export const BYPASS_CONFIRM_TITLE = "进入 Bypass permissions?";
12
+ /** 确认框标题(随界面语言)。 */
13
+ export function bypassConfirmTitle() {
14
+ return msg().permissions.bypass.title;
15
+ }
12
16
  /** 确认框正文:Bypass 意味着什么(一两条关键风险)。 */
13
- export const BYPASS_RISK_LINES = [
14
- "所有工具调用都不再询问:写文件、执行命令、联网直接放行",
15
- "只有危险命令仍会询问,deny 规则照常生效;只建议在一次性沙箱、容器里用",
16
- ];
17
+ export function bypassRiskLines() {
18
+ const m = msg().permissions.bypass;
19
+ return [m.riskAllowAll, m.riskDangerous];
20
+ }
17
21
  /** 选项:缺省选中「取消」。 */
18
- export const BYPASS_CHOICES = [
19
- { label: "进入 Bypass", keys: "y" },
20
- { label: "取消", keys: "n Esc" },
21
- ];
22
+ export function bypassChoices() {
23
+ const m = msg().permissions.bypass;
24
+ return [
25
+ { label: m.choiceEnter, keys: "y" },
26
+ { label: m.choiceCancel, keys: "n Esc" },
27
+ ];
28
+ }
22
29
  export const BYPASS_DEFAULT_CHOICE = 1;
23
30
  /** 行式界面的问句(单键 y/N,缺省 N)。 */
24
- export const BYPASS_LINE_QUESTION = "确认进入 Bypass?[y/N] ";
31
+ export function bypassLineQuestion() {
32
+ return msg().permissions.bypass.lineQuestion;
33
+ }
25
34
  /**
26
35
  * 返回「切到 `mode` 前要不要放行」的闸门:不是 Bypass 直接放行;Bypass 首次调用 `ask`,
27
36
  * 确认后本闸门内不再问。`confirmed` 为 true 表示启动时已在 Bypass(视为已确认)。
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 权限类 `memory`(docs/wave6-plan.md §3.3、D10)。[W6-C0] 管线判定;`memory` 工具本身由 W6-M 实现。
3
+ *
4
+ * 管线按命令把它折成已有的类再走通常的真值表:
5
+ * - `view` → `read`:所有模式放行;
6
+ * - 写命令(`create` / `str_replace` / `delete`,以及无法识别的命令)→ `execute`:default / auto-edit 询问
7
+ * (审批可选「本会话允许」)、plan 拒绝、full-auto 放行、allowlist 只放行 allow 规则命中的
8
+ * (`memory` 不带括号即全部放行)、auto 交给分类器。
9
+ * 写入前的脱敏拒写、子会话写命令拒绝在工具执行层(W6-M),不在这里。
10
+ */
11
+ import type { ToolPermission } from "../tools/types.js";
12
+ export declare const MEMORY_COMMANDS: readonly ["view", "create", "str_replace", "delete"];
13
+ export type MemoryCommand = (typeof MEMORY_COMMANDS)[number];
14
+ /** 调用的 `command`(不是字符串返回 undefined)。 */
15
+ export declare function memoryCommand(input: unknown): string | undefined;
16
+ /** `memory` 类在真值表里按哪一类判定。 */
17
+ export declare function memoryEffectivePermission(input: unknown): Exclude<ToolPermission, "memory">;
18
+ /**
19
+ * [W6-M] `memory(pattern)` 规则:pattern 是命令名(`view` / `create` / `str_replace` / `delete`)时比对命令;
20
+ * 否则按 glob 比对逻辑路径(`/memories/user/**`,`*` 不跨 `/`,`**` 跨);单独的 `*` / `**` 命中全部。
21
+ * 记忆路径是逻辑路径,不按文件系统解析(`rules.ts` 对 memory 不走 bash 命令与真实路径的匹配)。
22
+ */
23
+ export declare function memoryRuleMatches(pattern: string, input: unknown): boolean;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * 权限类 `memory`(docs/wave6-plan.md §3.3、D10)。[W6-C0] 管线判定;`memory` 工具本身由 W6-M 实现。
3
+ *
4
+ * 管线按命令把它折成已有的类再走通常的真值表:
5
+ * - `view` → `read`:所有模式放行;
6
+ * - 写命令(`create` / `str_replace` / `delete`,以及无法识别的命令)→ `execute`:default / auto-edit 询问
7
+ * (审批可选「本会话允许」)、plan 拒绝、full-auto 放行、allowlist 只放行 allow 规则命中的
8
+ * (`memory` 不带括号即全部放行)、auto 交给分类器。
9
+ * 写入前的脱敏拒写、子会话写命令拒绝在工具执行层(W6-M),不在这里。
10
+ */
11
+ export const MEMORY_COMMANDS = ["view", "create", "str_replace", "delete"];
12
+ /** 调用的 `command`(不是字符串返回 undefined)。 */
13
+ export function memoryCommand(input) {
14
+ const raw = typeof input === "object" && input !== null
15
+ ? input["command"]
16
+ : undefined;
17
+ return typeof raw === "string" ? raw : undefined;
18
+ }
19
+ /** `memory` 类在真值表里按哪一类判定。 */
20
+ export function memoryEffectivePermission(input) {
21
+ return memoryCommand(input) === "view" ? "read" : "execute";
22
+ }
23
+ /**
24
+ * [W6-M] `memory(pattern)` 规则:pattern 是命令名(`view` / `create` / `str_replace` / `delete`)时比对命令;
25
+ * 否则按 glob 比对逻辑路径(`/memories/user/**`,`*` 不跨 `/`,`**` 跨);单独的 `*` / `**` 命中全部。
26
+ * 记忆路径是逻辑路径,不按文件系统解析(`rules.ts` 对 memory 不走 bash 命令与真实路径的匹配)。
27
+ */
28
+ export function memoryRuleMatches(pattern, input) {
29
+ const p = pattern.trim();
30
+ if (p === "*" || p === "**")
31
+ return true;
32
+ if (MEMORY_COMMANDS.includes(p))
33
+ return memoryCommand(input) === p;
34
+ const raw = typeof input === "object" && input !== null
35
+ ? input["path"]
36
+ : undefined;
37
+ if (typeof raw !== "string")
38
+ return false;
39
+ let body = "";
40
+ for (let i = 0; i < p.length; i++) {
41
+ const ch = p[i];
42
+ if (ch === "*" && p[i + 1] === "*") {
43
+ body += ".*";
44
+ i++;
45
+ }
46
+ else if (ch === "*")
47
+ body += "[^/]*";
48
+ else if (ch === "?")
49
+ body += "[^/]";
50
+ else
51
+ body += ch.replace(/[.+^${}()|[\]\\]/g, "\\$&");
52
+ }
53
+ return new RegExp(`^${body}$`).test(raw.replace(/\/+$/, ""));
54
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 六种权限模式的显示名、一行说明、界面顺序与 Shift+Tab 循环(§7.4)。
3
3
  *
4
- * 显示名用英文(与常见编码 Agent 的叫法一致),说明用界面语言(中文)。界面顺序就是选择器里
4
+ * 显示名用英文(与常见编码 Agent 的叫法一致),说明随界面语言(`msg().permissions`)。界面顺序就是选择器里
5
5
  * 数字快捷键 1–6 的顺序;`allowlist` 不在 Shift+Tab 循环里,只能显式选。
6
6
  */
7
7
  import { type PermissionMode } from "./types.js";
@@ -22,8 +22,8 @@ export declare function isPermissionMode(value: unknown): value is PermissionMod
22
22
  export declare function nextCycleMode(mode: PermissionMode): PermissionMode;
23
23
  /** line 模式 `/permission` 与 `/permissions` 用的纯文本列表(与选择器同一顺序与标注)。 */
24
24
  export declare function permissionModeLines(current: PermissionMode, configDefault: PermissionMode): string[];
25
- /** 审批对话框与提示里 auto 判定层的中文名。 */
26
- export declare const AUTO_LAYER_TEXT: Readonly<Record<"rule" | "static" | "classifier", string>>;
25
+ /** 审批对话框与提示里 auto 判定层的名字(随界面语言)。 */
26
+ export declare function autoLayerText(layer: "rule" | "static" | "classifier"): string;
27
27
  /**
28
28
  * 命令参数里的模式:接受值(`auto-edit`)或显示名(`Accept edits`、`accept-edits`,大小写不敏感)。
29
29
  */
@@ -1,20 +1,27 @@
1
1
  /**
2
2
  * 六种权限模式的显示名、一行说明、界面顺序与 Shift+Tab 循环(§7.4)。
3
3
  *
4
- * 显示名用英文(与常见编码 Agent 的叫法一致),说明用界面语言(中文)。界面顺序就是选择器里
4
+ * 显示名用英文(与常见编码 Agent 的叫法一致),说明随界面语言(`msg().permissions`)。界面顺序就是选择器里
5
5
  * 数字快捷键 1–6 的顺序;`allowlist` 不在 Shift+Tab 循环里,只能显式选。
6
6
  */
7
+ import { msg } from "../i18n/index.js";
7
8
  import { PERMISSION_MODES_STRICT_FIRST } from "./types.js";
9
+ /** 说明随界面语言(取用时求值,不在 import 时定死)。 */
10
+ function info(label, key) {
11
+ return {
12
+ label,
13
+ get description() {
14
+ return msg().permissions.modeDescription[key];
15
+ },
16
+ };
17
+ }
8
18
  export const PERMISSION_MODE_INFO = {
9
- default: { label: "Manual", description: "写文件、执行命令前询问" },
10
- "auto-edit": { label: "Accept edits", description: "自动接受文件编辑,执行命令仍询问" },
11
- plan: { label: "Plan", description: "只读调研,只跑只读命令,出计划后审批执行" },
12
- auto: { label: "Auto", description: "由 ama 判断每一步:安全的自动放行,有风险的才问" },
13
- "full-auto": { label: "Bypass permissions", description: "全部放行(危险命令仍询问)" },
14
- allowlist: {
15
- label: "Allowlist only",
16
- description: "只放行 allow 规则命中的,其余拒绝,从不询问",
17
- },
19
+ default: info("Manual", "default"),
20
+ "auto-edit": info("Accept edits", "autoEdit"),
21
+ plan: info("Plan", "plan"),
22
+ auto: info("Auto", "auto"),
23
+ "full-auto": info("Bypass permissions", "fullAuto"),
24
+ allowlist: info("Allowlist only", "allowlist"),
18
25
  };
19
26
  /** 选择器顺序(数字快捷键 1–6)。 */
20
27
  export const PERMISSION_MODE_ORDER = [
@@ -60,12 +67,10 @@ export function permissionModeLines(current, configDefault) {
60
67
  return `${mark} ${i + 1}. ${info.label} (${mode}) — ${info.description}${tail}`;
61
68
  });
62
69
  }
63
- /** 审批对话框与提示里 auto 判定层的中文名。 */
64
- export const AUTO_LAYER_TEXT = {
65
- rule: "规则层",
66
- static: "静态判定",
67
- classifier: "分类器",
68
- };
70
+ /** 审批对话框与提示里 auto 判定层的名字(随界面语言)。 */
71
+ export function autoLayerText(layer) {
72
+ return msg().permissions.autoLayer[layer];
73
+ }
69
74
  /**
70
75
  * 命令参数里的模式:接受值(`auto-edit`)或显示名(`Accept edits`、`accept-edits`,大小写不敏感)。
71
76
  */