@armadra/agent 0.5.0 → 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 (471) hide show
  1. package/CHANGELOG.md +177 -294
  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 +28307 -13241
  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.d.ts +58 -0
  103. package/dist/cli/choice-prompt.js +142 -0
  104. package/dist/cli/codemode-notice.js +2 -2
  105. package/dist/cli/compose-agents.js +2 -1
  106. package/dist/cli/compose-extensions.js +2 -0
  107. package/dist/cli/compose-memory.d.ts +53 -0
  108. package/dist/cli/compose-memory.js +127 -0
  109. package/dist/cli/compose-providers.d.ts +5 -0
  110. package/dist/cli/compose-providers.js +32 -2
  111. package/dist/cli/compose-session.d.ts +5 -0
  112. package/dist/cli/compose-session.js +27 -13
  113. package/dist/cli/compose-store.d.ts +2 -0
  114. package/dist/cli/compose-store.js +9 -5
  115. package/dist/cli/compose.d.ts +2 -0
  116. package/dist/cli/compose.js +13 -5
  117. package/dist/cli/default-model.d.ts +0 -2
  118. package/dist/cli/default-model.js +5 -8
  119. package/dist/cli/deps.d.ts +5 -1
  120. package/dist/cli/exit-codes.d.ts +1 -1
  121. package/dist/cli/exit-codes.js +7 -16
  122. package/dist/cli/from-prompt.js +3 -2
  123. package/dist/cli/help-text.d.ts +2 -1
  124. package/dist/cli/help-text.js +5 -99
  125. package/dist/cli/main.d.ts +5 -0
  126. package/dist/cli/main.js +21 -2
  127. package/dist/cli/proxy.js +14 -9
  128. package/dist/cli/runtime.d.ts +5 -0
  129. package/dist/cli/startup-screen.js +20 -27
  130. package/dist/cli/startup-steps.js +6 -8
  131. package/dist/cli/subcommands/auth.d.ts +6 -3
  132. package/dist/cli/subcommands/auth.js +52 -22
  133. package/dist/cli/subcommands/config-set.d.ts +21 -0
  134. package/dist/cli/subcommands/config-set.js +137 -0
  135. package/dist/cli/subcommands/config.d.ts +2 -1
  136. package/dist/cli/subcommands/config.js +51 -37
  137. package/dist/cli/subcommands/doctor.d.ts +2 -1
  138. package/dist/cli/subcommands/doctor.js +97 -58
  139. package/dist/cli/subcommands/init.d.ts +1 -1
  140. package/dist/cli/subcommands/init.js +8 -7
  141. package/dist/cli/subcommands/memory.d.ts +18 -0
  142. package/dist/cli/subcommands/memory.js +189 -0
  143. package/dist/cli/subcommands/model-meta.js +11 -9
  144. package/dist/cli/subcommands/models-cache-probe.d.ts +1 -1
  145. package/dist/cli/subcommands/models-cache-probe.js +26 -32
  146. package/dist/cli/subcommands/models-discover.d.ts +3 -0
  147. package/dist/cli/subcommands/models-discover.js +44 -21
  148. package/dist/cli/subcommands/models.d.ts +1 -1
  149. package/dist/cli/subcommands/models.js +29 -22
  150. package/dist/cli/subcommands/probe-runner.js +8 -7
  151. package/dist/cli/subcommands/providers-list.js +32 -21
  152. package/dist/cli/subcommands/providers-plan.js +24 -25
  153. package/dist/cli/subcommands/providers-probe.js +5 -6
  154. package/dist/cli/subcommands/providers.d.ts +2 -2
  155. package/dist/cli/subcommands/providers.js +48 -59
  156. package/dist/cli/subcommands/sessions-export.d.ts +1 -1
  157. package/dist/cli/subcommands/sessions-export.js +10 -9
  158. package/dist/cli/subcommands/sessions-search.d.ts +1 -1
  159. package/dist/cli/subcommands/sessions-search.js +11 -10
  160. package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
  161. package/dist/cli/subcommands/sessions-trace.js +156 -0
  162. package/dist/cli/subcommands/sessions.d.ts +4 -3
  163. package/dist/cli/subcommands/sessions.js +40 -37
  164. package/dist/cli/subcommands/stats.d.ts +1 -1
  165. package/dist/cli/subcommands/stats.js +49 -30
  166. package/dist/cli/system-prompt-arg.js +3 -2
  167. package/dist/codemode/capability.js +3 -2
  168. package/dist/compaction/post-compact.d.ts +1 -0
  169. package/dist/compaction/post-compact.js +15 -1
  170. package/dist/compaction/prune-tier.d.ts +1 -1
  171. package/dist/compaction/prune-tier.js +3 -3
  172. package/dist/compaction/serialize.js +2 -1
  173. package/dist/config/auth-file.d.ts +12 -2
  174. package/dist/config/auth-file.js +32 -10
  175. package/dist/config/checker.js +12 -11
  176. package/dist/config/context-files.js +3 -2
  177. package/dist/config/edit.d.ts +106 -0
  178. package/dist/config/edit.js +350 -0
  179. package/dist/config/init.d.ts +4 -3
  180. package/dist/config/init.js +10 -18
  181. package/dist/config/json-schema.d.ts +2 -1
  182. package/dist/config/json-schema.js +101 -68
  183. package/dist/config/key-docs.d.ts +18 -7
  184. package/dist/config/key-docs.js +43 -128
  185. package/dist/config/load.js +7 -6
  186. package/dist/config/merge.d.ts +4 -1
  187. package/dist/config/merge.js +42 -22
  188. package/dist/config/paths.js +6 -5
  189. package/dist/config/profile.d.ts +5 -1
  190. package/dist/config/profile.js +7 -2
  191. package/dist/config/schema-w5.js +3 -2
  192. package/dist/config/schema-w6.d.ts +19 -0
  193. package/dist/config/schema-w6.js +115 -0
  194. package/dist/config/schema.js +34 -20
  195. package/dist/config/settings-registry.d.ts +78 -0
  196. package/dist/config/settings-registry.js +184 -0
  197. package/dist/config/types-w6.d.ts +109 -0
  198. package/dist/config/types-w6.js +19 -0
  199. package/dist/config/types.d.ts +11 -8
  200. package/dist/config/types.js +1 -0
  201. package/dist/drivers/acp/client.js +1 -1
  202. package/dist/drivers/acp/driver.js +13 -8
  203. package/dist/drivers/agents.js +4 -3
  204. package/dist/drivers/base.js +3 -2
  205. package/dist/drivers/host-runners.js +2 -1
  206. package/dist/drivers/native/claude-stream.js +12 -11
  207. package/dist/drivers/native/codex-app-server.js +17 -12
  208. package/dist/drivers/native/oneshot.js +8 -7
  209. package/dist/drivers/pool.js +1 -1
  210. package/dist/drivers/runner.d.ts +3 -1
  211. package/dist/drivers/runner.js +68 -20
  212. package/dist/drivers/turn.js +1 -1
  213. package/dist/hooks/config.js +3 -2
  214. package/dist/hooks/protocol.js +18 -12
  215. package/dist/host/api-impl.js +11 -10
  216. package/dist/host/loader.js +9 -8
  217. package/dist/host/types.d.ts +3 -0
  218. package/dist/i18n/catalog.d.ts +2169 -0
  219. package/dist/i18n/catalog.js +72 -0
  220. package/dist/i18n/format.d.ts +21 -0
  221. package/dist/i18n/format.js +58 -0
  222. package/dist/i18n/index.d.ts +58 -0
  223. package/dist/i18n/index.js +72 -0
  224. package/dist/i18n/messages/agents.d.ts +84 -0
  225. package/dist/i18n/messages/agents.js +85 -0
  226. package/dist/i18n/messages/approval.d.ts +99 -0
  227. package/dist/i18n/messages/approval.js +100 -0
  228. package/dist/i18n/messages/auth.d.ts +187 -0
  229. package/dist/i18n/messages/auth.js +189 -0
  230. package/dist/i18n/messages/cli-args.d.ts +46 -0
  231. package/dist/i18n/messages/cli-args.js +46 -0
  232. package/dist/i18n/messages/cli-help.d.ts +12 -0
  233. package/dist/i18n/messages/cli-help.js +244 -0
  234. package/dist/i18n/messages/cli.d.ts +336 -0
  235. package/dist/i18n/messages/cli.js +311 -0
  236. package/dist/i18n/messages/config-keys.d.ts +289 -0
  237. package/dist/i18n/messages/config-keys.js +292 -0
  238. package/dist/i18n/messages/config.d.ts +502 -0
  239. package/dist/i18n/messages/config.js +239 -0
  240. package/dist/i18n/messages/drivers.d.ts +123 -0
  241. package/dist/i18n/messages/drivers.js +124 -0
  242. package/dist/i18n/messages/errors.d.ts +83 -0
  243. package/dist/i18n/messages/errors.js +171 -0
  244. package/dist/i18n/messages/interactive-line.d.ts +61 -0
  245. package/dist/i18n/messages/interactive-line.js +69 -0
  246. package/dist/i18n/messages/interactive-startup.d.ts +103 -0
  247. package/dist/i18n/messages/interactive-startup.js +104 -0
  248. package/dist/i18n/messages/interactive-view.d.ts +140 -0
  249. package/dist/i18n/messages/interactive-view.js +141 -0
  250. package/dist/i18n/messages/interactive.d.ts +493 -0
  251. package/dist/i18n/messages/interactive.js +248 -0
  252. package/dist/i18n/messages/memory.d.ts +123 -0
  253. package/dist/i18n/messages/memory.js +128 -0
  254. package/dist/i18n/messages/panels.d.ts +190 -0
  255. package/dist/i18n/messages/panels.js +189 -0
  256. package/dist/i18n/messages/permissions.d.ts +126 -0
  257. package/dist/i18n/messages/permissions.js +151 -0
  258. package/dist/i18n/messages/plan.d.ts +123 -0
  259. package/dist/i18n/messages/plan.js +124 -0
  260. package/dist/i18n/messages/print.d.ts +86 -0
  261. package/dist/i18n/messages/print.js +91 -0
  262. package/dist/i18n/messages/report.d.ts +391 -0
  263. package/dist/i18n/messages/report.js +490 -0
  264. package/dist/i18n/messages/rewind.d.ts +198 -0
  265. package/dist/i18n/messages/rewind.js +217 -0
  266. package/dist/i18n/messages/session.d.ts +230 -0
  267. package/dist/i18n/messages/session.js +258 -0
  268. package/dist/i18n/messages/settings.d.ts +348 -0
  269. package/dist/i18n/messages/settings.js +336 -0
  270. package/dist/i18n/messages/subcommands-config.d.ts +111 -0
  271. package/dist/i18n/messages/subcommands-config.js +127 -0
  272. package/dist/i18n/messages/subcommands.d.ts +548 -0
  273. package/dist/i18n/messages/subcommands.js +474 -0
  274. package/dist/i18n/messages/trace.d.ts +243 -0
  275. package/dist/i18n/messages/trace.js +238 -0
  276. package/dist/i18n/types.d.ts +15 -0
  277. package/dist/i18n/types.js +7 -0
  278. package/dist/index.d.ts +6 -0
  279. package/dist/index.js +2 -0
  280. package/dist/memory/edit.d.ts +24 -0
  281. package/dist/memory/edit.js +63 -0
  282. package/dist/memory/frontmatter.d.ts +37 -0
  283. package/dist/memory/frontmatter.js +79 -0
  284. package/dist/memory/index.d.ts +28 -0
  285. package/dist/memory/index.js +126 -0
  286. package/dist/memory/lock.d.ts +17 -0
  287. package/dist/memory/lock.js +62 -0
  288. package/dist/memory/paths.d.ts +57 -0
  289. package/dist/memory/paths.js +175 -0
  290. package/dist/memory/report.d.ts +36 -0
  291. package/dist/memory/report.js +86 -0
  292. package/dist/memory/runtime.d.ts +42 -0
  293. package/dist/memory/runtime.js +36 -0
  294. package/dist/memory/secrets.d.ts +8 -0
  295. package/dist/memory/secrets.js +27 -0
  296. package/dist/memory/section.d.ts +28 -0
  297. package/dist/memory/section.js +59 -0
  298. package/dist/memory/store.d.ts +70 -0
  299. package/dist/memory/store.js +284 -0
  300. package/dist/memory/tool.d.ts +31 -0
  301. package/dist/memory/tool.js +94 -0
  302. package/dist/modes/acp/acp-events.js +2 -1
  303. package/dist/modes/acp/acp-server.js +13 -12
  304. package/dist/modes/commands-core.d.ts +17 -0
  305. package/dist/modes/commands-core.js +101 -61
  306. package/dist/modes/image-input.js +20 -6
  307. package/dist/modes/interactive/agent-bar.d.ts +95 -0
  308. package/dist/modes/interactive/agent-bar.js +248 -0
  309. package/dist/modes/interactive/agent-panels.js +27 -26
  310. package/dist/modes/interactive/agent-transcript.d.ts +47 -0
  311. package/dist/modes/interactive/agent-transcript.js +191 -0
  312. package/dist/modes/interactive/agent-ui.d.ts +36 -1
  313. package/dist/modes/interactive/agent-ui.js +180 -14
  314. package/dist/modes/interactive/agent-view.d.ts +72 -0
  315. package/dist/modes/interactive/agent-view.js +281 -0
  316. package/dist/modes/interactive/approval-dialog.js +46 -34
  317. package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
  318. package/dist/modes/interactive/clipboard-paste.js +9 -4
  319. package/dist/modes/interactive/commands.d.ts +22 -1
  320. package/dist/modes/interactive/commands.js +93 -38
  321. package/dist/modes/interactive/completion.js +2 -1
  322. package/dist/modes/interactive/config-panel.d.ts +70 -0
  323. package/dist/modes/interactive/config-panel.js +319 -0
  324. package/dist/modes/interactive/config-ui.d.ts +96 -0
  325. package/dist/modes/interactive/config-ui.js +397 -0
  326. package/dist/modes/interactive/confirm-dialog.d.ts +49 -0
  327. package/dist/modes/interactive/confirm-dialog.js +120 -0
  328. package/dist/modes/interactive/event-notices.js +11 -9
  329. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  330. package/dist/modes/interactive/interactive-mode.js +25 -22
  331. package/dist/modes/interactive/key-dispatch.d.ts +18 -0
  332. package/dist/modes/interactive/key-dispatch.js +39 -13
  333. package/dist/modes/interactive/line/line-editor.js +2 -1
  334. package/dist/modes/interactive/line/line-mode.d.ts +2 -0
  335. package/dist/modes/interactive/line/line-mode.js +24 -4
  336. package/dist/modes/interactive/line/line-render.js +25 -24
  337. package/dist/modes/interactive/memory-panel.d.ts +64 -0
  338. package/dist/modes/interactive/memory-panel.js +221 -0
  339. package/dist/modes/interactive/message-view.d.ts +4 -2
  340. package/dist/modes/interactive/message-view.js +42 -33
  341. package/dist/modes/interactive/panels.js +39 -31
  342. package/dist/modes/interactive/pickers.d.ts +2 -1
  343. package/dist/modes/interactive/pickers.js +10 -6
  344. package/dist/modes/interactive/plan-command.d.ts +1 -1
  345. package/dist/modes/interactive/plan-command.js +24 -27
  346. package/dist/modes/interactive/plan-dialog.js +18 -17
  347. package/dist/modes/interactive/plan-flow.js +6 -5
  348. package/dist/modes/interactive/rewind-command.d.ts +1 -1
  349. package/dist/modes/interactive/rewind-command.js +18 -16
  350. package/dist/modes/interactive/rewind-flow.d.ts +0 -1
  351. package/dist/modes/interactive/rewind-flow.js +13 -14
  352. package/dist/modes/interactive/rewind-list.js +7 -6
  353. package/dist/modes/interactive/rewind-panel.js +40 -40
  354. package/dist/modes/interactive/rewind-text.d.ts +5 -3
  355. package/dist/modes/interactive/rewind-text.js +48 -38
  356. package/dist/modes/interactive/run-indicator.js +15 -12
  357. package/dist/modes/interactive/session-events.js +3 -2
  358. package/dist/modes/interactive/startup-header.js +22 -23
  359. package/dist/modes/interactive/startup-ui.js +41 -29
  360. package/dist/modes/interactive/status-area.d.ts +2 -0
  361. package/dist/modes/interactive/status-area.js +8 -2
  362. package/dist/modes/interactive/status-bar.js +4 -3
  363. package/dist/modes/interactive/subagent-view.js +9 -7
  364. package/dist/modes/interactive/tasks-report.d.ts +6 -0
  365. package/dist/modes/interactive/tasks-report.js +28 -31
  366. package/dist/modes/interactive/terminal-setup.d.ts +9 -0
  367. package/dist/modes/interactive/terminal-setup.js +23 -0
  368. package/dist/modes/interactive/tool-summary.js +19 -17
  369. package/dist/modes/interactive/tool-view.js +7 -4
  370. package/dist/modes/interactive/trace-view.d.ts +89 -0
  371. package/dist/modes/interactive/trace-view.js +332 -0
  372. package/dist/modes/print/print-mode.js +14 -15
  373. package/dist/modes/rpc/commands.js +7 -3
  374. package/dist/modes/rpc/rpc-mode.js +9 -3
  375. package/dist/modes/session-report.d.ts +2 -0
  376. package/dist/modes/session-report.js +101 -105
  377. package/dist/modes/startup-ui-text.js +11 -6
  378. package/dist/permissions/bypass.d.ts +30 -0
  379. package/dist/permissions/bypass.js +45 -0
  380. package/dist/permissions/memory-class.d.ts +23 -0
  381. package/dist/permissions/memory-class.js +54 -0
  382. package/dist/permissions/modes.d.ts +3 -3
  383. package/dist/permissions/modes.js +21 -16
  384. package/dist/permissions/pipeline.d.ts +1 -1
  385. package/dist/permissions/pipeline.js +9 -2
  386. package/dist/permissions/preview.js +49 -42
  387. package/dist/permissions/rules.js +5 -2
  388. package/dist/permissions/types.d.ts +4 -0
  389. package/dist/plan/store.js +2 -1
  390. package/dist/rpc.d.ts +39 -1
  391. package/dist/rpc.js +3 -0
  392. package/dist/sandbox/bash.js +11 -8
  393. package/dist/sandbox/detect.js +14 -11
  394. package/dist/sdk.d.ts +17 -1
  395. package/dist/sdk.js +29 -7
  396. package/dist/session/export.js +31 -30
  397. package/dist/session/manager.d.ts +1 -1
  398. package/dist/session/manager.js +5 -3
  399. package/dist/session/reuse.js +5 -4
  400. package/dist/session/scan.js +3 -2
  401. package/dist/session/stats-aggregate.d.ts +3 -1
  402. package/dist/session/stats-aggregate.js +5 -1
  403. package/dist/session/stats-index.js +2 -1
  404. package/dist/session/stats-scan.d.ts +4 -1
  405. package/dist/session/stats-scan.js +6 -2
  406. package/dist/session/store.d.ts +11 -0
  407. package/dist/session/store.js +48 -1
  408. package/dist/session/types.d.ts +2 -0
  409. package/dist/skills/builtin.js +2 -1
  410. package/dist/tools/image-file.d.ts +26 -1
  411. package/dist/tools/image-file.js +55 -13
  412. package/dist/tools/presets.d.ts +14 -1
  413. package/dist/tools/presets.js +3 -3
  414. package/dist/tools/registry.js +1 -1
  415. package/dist/tools/truncate.d.ts +1 -1
  416. package/dist/tools/truncate.js +2 -2
  417. package/dist/tools/types.d.ts +17 -1
  418. package/dist/trace/build-index.d.ts +91 -0
  419. package/dist/trace/build-index.js +127 -0
  420. package/dist/trace/build-nodes.d.ts +24 -0
  421. package/dist/trace/build-nodes.js +279 -0
  422. package/dist/trace/build-util.d.ts +43 -0
  423. package/dist/trace/build-util.js +120 -0
  424. package/dist/trace/build.d.ts +82 -0
  425. package/dist/trace/build.js +382 -0
  426. package/dist/trace/detail.d.ts +35 -0
  427. package/dist/trace/detail.js +205 -0
  428. package/dist/trace/flatten.d.ts +69 -0
  429. package/dist/trace/flatten.js +173 -0
  430. package/dist/trace/format.d.ts +47 -0
  431. package/dist/trace/format.js +329 -0
  432. package/dist/trace/html-template.d.ts +19 -0
  433. package/dist/trace/html-template.js +150 -0
  434. package/dist/trace/html.d.ts +104 -0
  435. package/dist/trace/html.js +292 -0
  436. package/dist/trace/preview.d.ts +29 -0
  437. package/dist/trace/preview.js +59 -0
  438. package/dist/trace/query-session.d.ts +14 -0
  439. package/dist/trace/query-session.js +38 -0
  440. package/dist/trace/query.d.ts +55 -0
  441. package/dist/trace/query.js +188 -0
  442. package/dist/trace/session.d.ts +40 -0
  443. package/dist/trace/session.js +168 -0
  444. package/dist/trace/types.d.ts +243 -0
  445. package/dist/trace/types.js +13 -0
  446. package/dist/tui/components/editor-paste.d.ts +2 -0
  447. package/dist/tui/components/editor-paste.js +6 -3
  448. package/dist/tui/components/editor.js +2 -2
  449. package/dist/tui/components/loader.d.ts +3 -0
  450. package/dist/tui/components/loader.js +14 -0
  451. package/dist/tui/components/settings-list.d.ts +61 -0
  452. package/dist/tui/components/settings-list.js +135 -0
  453. package/dist/tui/keybindings.d.ts +6 -1
  454. package/dist/tui/keybindings.js +18 -6
  455. package/dist/tui.d.ts +1 -0
  456. package/dist/tui.js +2 -0
  457. package/docs/en/host-api.md +167 -0
  458. package/docs/en/permissions.md +214 -0
  459. package/docs/en/providers.md +625 -0
  460. package/docs/en/rpc.md +361 -0
  461. package/docs/en/sessions.md +219 -0
  462. package/docs/en/tui.md +527 -0
  463. package/docs/host-api.md +18 -17
  464. package/docs/memory.md +172 -0
  465. package/docs/permissions.md +3 -2
  466. package/docs/providers.md +67 -1
  467. package/docs/rpc.md +31 -3
  468. package/docs/session-format.md +8 -2
  469. package/docs/sessions.md +29 -1
  470. package/docs/tui.md +189 -21
  471. package/package.json +8 -3
@@ -5,11 +5,12 @@
5
5
  * 合并成一条「已省略 N 张早期图片以符合请求上限」,N 按占位文本数;
6
6
  * - W5-H1:`compaction_end.error` 的「compaction did not shrink」换成中文说明(其余错误原样)。
7
7
  */
8
+ import { msg } from "../../i18n/index.js";
8
9
  import { IMAGE_OMITTED_FOR_BUDGET, IMAGE_OMITTED_TOO_LARGE, } from "../../compaction/image-budget.js";
9
10
  /** `compaction_end.error` 的显示文本。 */
10
11
  export function compactionErrorText(error) {
11
12
  if (/compaction did not shrink/i.test(error)) {
12
- return "压缩后上下文没有变小,已保留原对话(不写摘要)";
13
+ return msg().interactive.events.compactionNoShrink;
13
14
  }
14
15
  return error;
15
16
  }
@@ -43,7 +44,7 @@ export class ImageBudgetNotices {
43
44
  const n = this.pending;
44
45
  this.pending = 0;
45
46
  this.scheduled = false;
46
- this.notify(`已省略 ${n} 张早期图片以符合请求上限`);
47
+ this.notify(msg().interactive.events.imagesOmitted(n));
47
48
  });
48
49
  }
49
50
  }
@@ -54,26 +55,27 @@ export class ImageBudgetNotices {
54
55
  export const LIMIT_WARNING = "limit_reached";
55
56
  /** `limit_reached`:回合 / 费用到限(每次运行每类一次)。 */
56
57
  export function limitReachedText(event) {
58
+ const m = msg().interactive.events;
57
59
  if (event.kind === "turns")
58
- return `已到回合上限(${event.limit} 回合),本次运行停止;发新消息继续(--max-turns / limits.maxTurns)`;
59
- const spent = `$${event.value.toFixed(2)}`;
60
- return `已到费用上限 $${event.limit.toFixed(2)}(本次运行已用 ${spent}),本次运行停止;发新消息继续(--max-cost / limits.maxCostUsd)`;
60
+ return m.limitTurns(event.limit);
61
+ return m.limitCost(`$${event.limit.toFixed(2)}`, `$${event.value.toFixed(2)}`);
61
62
  }
62
63
  /** `model_fallback`:主模型失败后改用回退模型重试一次。 */
63
64
  export function modelFallbackText(event) {
64
65
  const ref = (m) => `${m.provider}/${m.id}`;
65
- return `${ref(event.from)} 不可用(${event.reason}),本次请求改用 ${ref(event.to)},回复后切回`;
66
+ return msg().interactive.events.modelFallback(ref(event.from), event.reason, ref(event.to));
66
67
  }
67
68
  /** `background_job`:后台命令启动 / 退出 / 停止。 */
68
69
  export function backgroundJobText(event) {
69
70
  const command = event.command.replace(/\s+/g, " ").trim();
70
71
  const short = command.length > 60 ? `${command.slice(0, 59)}…` : command;
72
+ const m = msg().interactive.events;
71
73
  switch (event.phase) {
72
74
  case "started":
73
- return `后台命令 ${event.jobId} 已启动:${short}`;
75
+ return m.backgroundStarted(event.jobId, short);
74
76
  case "exited":
75
- return `后台命令 ${event.jobId} 已退出(码 ${event.exitCode ?? "?"}):${short}`;
77
+ return m.backgroundExited(event.jobId, String(event.exitCode ?? "?"), short);
76
78
  case "stopped":
77
- return `后台命令 ${event.jobId} 已停止:${short}`;
79
+ return m.backgroundStopped(event.jobId, short);
78
80
  }
79
81
  }
@@ -24,7 +24,7 @@ import type { ModeContext } from "../../cli/deps.js";
24
24
  import type { Runtime } from "../../cli/runtime.js";
25
25
  import type { StatusLineMode } from "../../config/types.js";
26
26
  import type { ClipboardDeps } from "../../tools/clipboard-image.js";
27
- import { Editor, Keybindings, TUI, type Terminal, type Theme } from "../../tui.js";
27
+ import { Editor, TUI, type Keybindings, type Terminal, type Theme } from "../../tui.js";
28
28
  import { MessageView } from "./message-view.js";
29
29
  import { StatusArea } from "./status-area.js";
30
30
  import type { StatusBar } from "./status-bar.js";
@@ -25,40 +25,32 @@ import { AgentSessionImpl } from "../../agent/session.js";
25
25
  import { taskRegistryView } from "../../agent/subagent-registry.js";
26
26
  import { currentSession, switchSession } from "../../cli/compose-session.js";
27
27
  import { startupInfo, startupScreenLevel, tildePath } from "../../cli/startup-screen.js";
28
- import { KEYBINDINGS_FILE } from "../../config/paths.js";
29
28
  import { AmaError, isAmaError } from "../../errors.js";
30
- import { Container, Editor, Keybindings, Loader, ProcessTerminal, Spacer, TUI, Text, createTheme, detectCapabilities, resolveAscii, resolveThemeName, loadKeybindingsFile, } from "../../tui.js";
29
+ import { msg } from "../../i18n/index.js";
30
+ import { Container, Editor, Loader, Spacer, TUI, Text, createTheme, detectCapabilities, resolveAscii, resolveThemeName, } from "../../tui.js";
31
+ import { BYPASS_MODE, createBypassGate } from "../../permissions/bypass.js";
31
32
  import { onTerminationSignals } from "../shared.js";
32
- import { AgentUi } from "./agent-ui.js";
33
+ import { AgentUi, agentCommandHooks } from "./agent-ui.js";
33
34
  import { ApprovalDialogBroker, approvalOutcomeText } from "./approval-dialog.js";
34
35
  import { mergingBroker } from "./approval-merge.js";
35
36
  import { ALL_COMMANDS, runInteractiveCommand } from "./commands.js";
37
+ import { memoryPanelFor } from "./memory-panel.js";
36
38
  import { InteractiveCompletion } from "./completion.js";
39
+ import { confirmBypass } from "./confirm-dialog.js";
40
+ import { configUiFor } from "./config-ui.js";
37
41
  import { createKeyDispatch } from "./key-dispatch.js";
38
42
  import { MessageView, exitSummaryLines } from "./message-view.js";
39
43
  import { openPicker } from "./pickers.js";
40
44
  import { createRewindFlow } from "./rewind-flow.js";
45
+ import { openTraceView } from "./trace-view.js";
41
46
  import { StartupHeader } from "./startup-header.js";
42
47
  import { QueueView, RunIndicator } from "./run-indicator.js";
43
48
  import { StatusArea, statusLineSlash } from "./status-area.js";
44
49
  import { createSessionEventHandler } from "./session-events.js";
45
50
  import { SubagentTracker } from "./subagent-view.js";
51
+ import { loadKeys, processTerminal } from "./terminal-setup.js";
46
52
  import { ToolTracker } from "./tool-view.js";
47
53
  const HINT_MS = 2500;
48
- const EDITOR_PLACEHOLDER = "输入消息,/ 命令,@ 文件,Shift+Enter 换行";
49
- function processTerminal() {
50
- const stdin = process.stdin;
51
- if (stdin.isTTY !== true || typeof stdin.setRawMode !== "function" || !process.stdout.isTTY) {
52
- throw new AmaError("terminal_init_failed", "stdin / stdout 不是终端");
53
- }
54
- return new ProcessTerminal();
55
- }
56
- function loadKeys(runtime, warn) {
57
- const parsed = loadKeybindingsFile(join(runtime.paths.configDir, KEYBINDINGS_FILE));
58
- for (const w of parsed.warnings)
59
- warn(`keybindings.json:${w}`);
60
- return new Keybindings(parsed.overrides);
61
- }
62
54
  export function runInteractiveMode(runtime, context, options = {}) {
63
55
  const terminal = options.terminal ?? processTerminal();
64
56
  const ui = runtime.config.ui ?? {};
@@ -93,7 +85,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
93
85
  const loaderSlot = new Container();
94
86
  const loader = new Loader(() => tui.requestRender(), {
95
87
  theme,
96
- message: "思考中",
88
+ message: msg().interactive.view.run.thinking,
97
89
  now,
98
90
  ...(ui.animation === false ? { animation: false } : {}),
99
91
  ...(options.spinnerIntervalMs !== undefined ? { intervalMs: options.spinnerIntervalMs } : {}),
@@ -124,7 +116,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
124
116
  theme,
125
117
  keybindings: keys,
126
118
  maxVisibleLines: 8,
127
- placeholder: EDITOR_PLACEHOLDER,
119
+ placeholder: msg().interactive.app.placeholder,
128
120
  autocomplete: completion,
129
121
  requestRender: () => tui.requestRender(),
130
122
  ...(historyFile !== undefined ? { historyFile } : {}),
@@ -194,7 +186,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
194
186
  const replay = () => {
195
187
  view.replay(session.messages, {
196
188
  tool: (call, result) => tools.completed(call.id, call.name, call.arguments, result === undefined
197
- ? { content: "(没有结果)", isError: true }
189
+ ? { content: msg().interactive.app.noResult, isError: true }
198
190
  : {
199
191
  content: result.content,
200
192
  isError: result.isError,
@@ -270,6 +262,8 @@ export function runInteractiveMode(runtime, context, options = {}) {
270
262
  columns: () => terminal.columns,
271
263
  rows: () => terminal.rows,
272
264
  };
265
+ // 进入 Bypass 前确认一次;启动时已是 Bypass(命令行 / 配置指定)视为已确认
266
+ const confirmMode = createBypassGate(() => confirmBypass(pickerHost), session.state.permissionMode === BYPASS_MODE);
273
267
  const rewind = createRewindFlow({
274
268
  ...pickerHost,
275
269
  session: () => session,
@@ -281,6 +275,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
281
275
  setDraft,
282
276
  editorEmpty: () => editor.isEmpty(),
283
277
  });
278
+ const configUi = configUiFor(pickerHost, { runtime, context, view, loader, area, tui, notice });
284
279
  const commandUi = {
285
280
  runtime,
286
281
  session: () => session,
@@ -290,6 +285,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
290
285
  return next;
291
286
  },
292
287
  pick: (spec) => openPicker(pickerHost, spec),
288
+ confirmMode,
293
289
  rewind: () => rewind.open(),
294
290
  setDraft,
295
291
  notice,
@@ -309,6 +305,10 @@ export function runInteractiveMode(runtime, context, options = {}) {
309
305
  exit: (code) => exit(code),
310
306
  now,
311
307
  extra: (name, args) => agentUi.command(name, args),
308
+ ...agentCommandHooks(() => agentUi),
309
+ configPanel: (args) => configUi.open(args),
310
+ traceView: (id) => openTraceView({ ...pickerHost, session: () => session, now, notice, render }, id),
311
+ memoryPanel: memoryPanelFor(() => commandUi, pickerHost, tui, env), // [W6-M]
312
312
  };
313
313
  const runCommand = (line) => (statusLineSlash(area, line, notice)
314
314
  ? Promise.resolve(true)
@@ -350,10 +350,12 @@ export function runInteractiveMode(runtime, context, options = {}) {
350
350
  onExpandToggle: (expanded) => view.setThinkingExpanded(expanded),
351
351
  onStatusLineToggle: () => area.toggle(),
352
352
  onPasteImage: () => void agentUi.paste(),
353
+ confirmMode,
353
354
  submit: (text, via) => submit(text, via),
354
355
  runCommand: (line) => void runCommand(line),
355
356
  exit: (code) => exit(code),
356
357
  onInterrupted: (empty) => void rewind.afterInterrupt(empty),
358
+ agents: () => agentUi.keys,
357
359
  }));
358
360
  // ---- 晚绑定 ---------------------------------------------------------------
359
361
  const overlayHooks = {
@@ -389,6 +391,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
389
391
  dialog: { theme, keybindings: keys, ...overlayHooks },
390
392
  displayPath: (path) => tildePath(path, home),
391
393
  ...(options.clipboard !== undefined ? { clipboard: options.clipboard } : {}),
394
+ area,
392
395
  });
393
396
  const taskAgent = (taskId) => taskRegistryView(session.state.sessionId)?.get(taskId)?.agent;
394
397
  const broker = mergingBroker(new ApprovalDialogBroker({
@@ -405,7 +408,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
405
408
  notice(outcome === "deny" ? "info" : "warn", text);
406
409
  }
407
410
  },
408
- }), agentUi.merge, (request) => notice("info", `${approvalOutcomeText(request, "allow", taskAgent)}(随上一次确认)`));
411
+ }), agentUi.merge, (request) => notice("info", msg().interactive.app.followed(approvalOutcomeText(request, "allow", taskAgent))));
409
412
  // ---- 启动与退出 -----------------------------------------------------------
410
413
  let offSignals = () => undefined;
411
414
  function exit(code) {
@@ -447,7 +450,7 @@ export function runInteractiveMode(runtime, context, options = {}) {
447
450
  }
448
451
  catch (error) {
449
452
  unsubscribe();
450
- reject(new AmaError("terminal_init_failed", `终端初始化失败:${error instanceof Error ? error.message : String(error)}`, { cause: error }));
453
+ reject(new AmaError("terminal_init_failed", msg().interactive.app.terminalInitFailed(error instanceof Error ? error.message : String(error)), { cause: error }));
451
454
  return;
452
455
  }
453
456
  runtime.approvals.setUiBroker(broker);
@@ -9,11 +9,22 @@
9
9
  *
10
10
  * [RW-C] 空闲时双击 Esc(`app.rewind`,double-esc.ts):输入框为空打开回滚列表,有字则清空并存进
11
11
  * 输入历史;运行中 Esc 仍为中断,中断后交给 `onInterrupted`(中断即撤回)。
12
+ *
13
+ * [W6-A] Agent 栏(agent-ui.ts):栏聚焦时它先收键(Esc 是「返回」,不中断、不回滚);输入为空、补全没开时
14
+ * `app.agents.focus`(缺省 `Ctrl+B` / `↓`)先问它要不要进栏,不要就照常交给编辑器(光标左移、历史下一条)。
12
15
  */
13
16
  import type { AgentSession } from "../../agent/types.js";
17
+ import type { PermissionMode } from "../../permissions/types.js";
14
18
  import type { Editor, Keybindings } from "../../tui.js";
15
19
  import type { StatusBar } from "./status-bar.js";
16
20
  import type { ToolTracker } from "./tool-view.js";
21
+ /** [W6-A] Agent 栏的按键入口。 */
22
+ export interface AgentKeys {
23
+ /** 栏聚焦时先消费按键;返回 true 已处理。 */
24
+ handleKey(data: string): boolean;
25
+ /** `app.agents.focus`(输入为空):进栏返回 true,否则交给编辑器。 */
26
+ focus(data: string): boolean;
27
+ }
17
28
  export interface KeyDispatchDeps {
18
29
  keys: Keybindings;
19
30
  editor: Editor;
@@ -31,6 +42,11 @@ export interface KeyDispatchDeps {
31
42
  onExpandToggle?(expanded: boolean): void;
32
43
  /** Ctrl+G:切换底部信息行,返回切换后的布局。 */
33
44
  onStatusLineToggle?(): "full" | "compact";
45
+ /**
46
+ * 循环到某模式前的确认(进入 Bypass 前弹确认框,permissions/bypass.ts);返回 false 时跳过该模式,
47
+ * 落到循环里的下一个。没有时直接切换。
48
+ */
49
+ confirmMode?(mode: PermissionMode): boolean | Promise<boolean>;
34
50
  /** Ctrl+V:粘贴剪贴板图片(W5-U)。 */
35
51
  onPasteImage?(): void;
36
52
  submit(text: string, via: "followUp"): void;
@@ -40,6 +56,8 @@ export interface KeyDispatchDeps {
40
56
  onInterrupted?(editorWasEmpty: boolean): void;
41
57
  /** 双击 Esc 的间隔(测试注入)。 */
42
58
  doubleEscMs?: number;
59
+ /** [W6-A] Agent 栏(晚绑定)。 */
60
+ agents?(): AgentKeys | undefined;
43
61
  }
44
62
  /** 返回输入监听器:已处理返回 true,交给编辑器返回 false。 */
45
63
  export declare function createKeyDispatch(deps: KeyDispatchDeps): (data: string) => boolean;
@@ -9,7 +9,11 @@
9
9
  *
10
10
  * [RW-C] 空闲时双击 Esc(`app.rewind`,double-esc.ts):输入框为空打开回滚列表,有字则清空并存进
11
11
  * 输入历史;运行中 Esc 仍为中断,中断后交给 `onInterrupted`(中断即撤回)。
12
+ *
13
+ * [W6-A] Agent 栏(agent-ui.ts):栏聚焦时它先收键(Esc 是「返回」,不中断、不回滚);输入为空、补全没开时
14
+ * `app.agents.focus`(缺省 `Ctrl+B` / `↓`)先问它要不要进栏,不要就照常交给编辑器(光标左移、历史下一条)。
12
15
  */
16
+ import { msg } from "../../i18n/index.js";
13
17
  import { ExitCode } from "../../cli/exit-codes.js";
14
18
  import { nextCycleMode, permissionModeLabel } from "../../permissions/modes.js";
15
19
  import { DOUBLE_ESC_HINT_MS, DoubleEscape } from "./double-esc.js";
@@ -23,10 +27,10 @@ export function createKeyDispatch(deps) {
23
27
  const doubleEscape = () => {
24
28
  switch (esc.press(deps.now(), editor.isEmpty())) {
25
29
  case "arm-rewind":
26
- deps.showHint("再按 Esc 回滚", DOUBLE_ESC_HINT_MS);
30
+ deps.showHint(msg().interactive.keys.escRewind, DOUBLE_ESC_HINT_MS);
27
31
  return;
28
32
  case "arm-clear":
29
- deps.showHint("再按 Esc 清空", DOUBLE_ESC_HINT_MS);
33
+ deps.showHint(msg().interactive.keys.escClear, DOUBLE_ESC_HINT_MS);
30
34
  return;
31
35
  case "rewind":
32
36
  deps.showHint("");
@@ -38,7 +42,7 @@ export function createKeyDispatch(deps) {
38
42
  if (text.trim() !== "")
39
43
  editor.addToHistory(text);
40
44
  editor.clear();
41
- deps.showHint("已清空输入 · ↑ 取回");
45
+ deps.showHint(msg().interactive.keys.cleared);
42
46
  return;
43
47
  }
44
48
  }
@@ -68,12 +72,21 @@ export function createKeyDispatch(deps) {
68
72
  const current = editor.getText();
69
73
  editor.setText(current.trim() === "" ? last : `${last}\n${current}`);
70
74
  };
71
- const cyclePermission = () => {
72
- const session = deps.session();
73
- const next = nextCycleMode(session.state.permissionMode);
74
- session.setPermissionMode(next);
75
+ const applyMode = (mode, skipped) => {
76
+ deps.session().setPermissionMode(mode);
75
77
  status.refresh();
76
- deps.showHint(`权限模式:${permissionModeLabel(next)}`);
78
+ const label = msg().interactive.commands.modeSet(permissionModeLabel(mode));
79
+ deps.showHint(skipped ? msg().interactive.keys.bypassSkipped(label) : label);
80
+ };
81
+ const cyclePermission = () => {
82
+ const next = nextCycleMode(deps.session().state.permissionMode);
83
+ // 取消进入 Bypass:跳过它继续循环(回到起点 Manual),而不是停在原模式——否则不进 Bypass 就绕不回去
84
+ const settle = (ok) => ok ? applyMode(next, false) : applyMode(nextCycleMode(next), true);
85
+ const answer = deps.confirmMode?.(next) ?? true;
86
+ if (typeof answer === "boolean")
87
+ settle(answer);
88
+ else
89
+ void answer.then(settle);
77
90
  };
78
91
  return (data) => {
79
92
  if (deps.inactive())
@@ -81,18 +94,29 @@ export function createKeyDispatch(deps) {
81
94
  const is = (action) => keys.matches(data, action);
82
95
  if (!is("app.rewind"))
83
96
  esc.reset();
97
+ const agents = deps.agents?.();
98
+ if (agents?.handleKey(data) === true) {
99
+ esc.reset();
100
+ return true;
101
+ }
102
+ if (agents !== undefined &&
103
+ is("app.agents.focus") &&
104
+ editor.isEmpty() &&
105
+ !editor.isCompletionOpen &&
106
+ agents.focus(data))
107
+ return true;
84
108
  if (is("app.clear")) {
85
109
  if (!editor.isEmpty()) {
86
110
  editor.clear();
87
111
  ctrlCArmedAt = deps.now();
88
- deps.showHint("已清空输入 · 再按 Ctrl+C 退出");
112
+ deps.showHint(msg().interactive.keys.clearedCtrlC);
89
113
  }
90
114
  else if (deps.now() - ctrlCArmedAt < DOUBLE_CTRL_C_MS) {
91
115
  deps.exit(ExitCode.Sigint);
92
116
  }
93
117
  else {
94
118
  ctrlCArmedAt = deps.now();
95
- deps.showHint("再按一次 Ctrl+C 退出");
119
+ deps.showHint(msg().interactive.keys.ctrlCAgain);
96
120
  }
97
121
  return true;
98
122
  }
@@ -100,7 +124,7 @@ export function createKeyDispatch(deps) {
100
124
  if (is("app.interrupt") && !editor.isCompletionOpen && deps.busy()) {
101
125
  esc.reset();
102
126
  interrupt();
103
- deps.showHint("已中断");
127
+ deps.showHint(msg().interactive.keys.interrupted);
104
128
  deps.onInterrupted?.(editor.isEmpty());
105
129
  return true;
106
130
  }
@@ -122,14 +146,16 @@ export function createKeyDispatch(deps) {
122
146
  dequeue();
123
147
  return true;
124
148
  }
125
- if (is("app.permission.cycle")) {
149
+ // 与补全共用的键(缺省 Tab)只在输入为空、补全未打开时切换模式;有输入时照常交给编辑器补全
150
+ if (is("app.permission.cycle") &&
151
+ (!is("tui.editor.complete") || (editor.isEmpty() && !editor.isCompletionOpen))) {
126
152
  cyclePermission();
127
153
  return true;
128
154
  }
129
155
  if (is("app.tools.expand")) {
130
156
  const expanded = tools.toggleExpanded();
131
157
  deps.onExpandToggle?.(expanded);
132
- deps.showHint(expanded ? "工具输出:展开" : "工具输出:折叠");
158
+ deps.showHint(expanded ? msg().interactive.keys.toolsExpanded : msg().interactive.keys.toolsCollapsed);
133
159
  return true;
134
160
  }
135
161
  if (is("app.model.select")) {
@@ -6,6 +6,7 @@
6
6
  * 空行 Ctrl+D 结束。括号粘贴:单行原样插入,多行折叠成 `[粘贴 #n +k 行]` 标记,提交时展开。
7
7
  * `ask()`:审批等单键问答,下一个可见字符(或 Enter = 缺省答案)作答。
8
8
  */
9
+ import { msg } from "../../../i18n/index.js";
9
10
  import { visibleWidth } from "../../../tui/ansi.js";
10
11
  import { PasteState } from "./paste-state.js";
11
12
  const KEYS = {
@@ -205,7 +206,7 @@ export class LineEditor {
205
206
  this.insert(text);
206
207
  }
207
208
  else {
208
- const marker = `[粘贴 #${this.pastes.size + 1} +${lines} 行]`;
209
+ const marker = msg().interactive.line.pasteMarker(this.pastes.size + 1, lines);
209
210
  this.pastes.set(marker, text);
210
211
  this.insert(marker);
211
212
  }
@@ -6,6 +6,8 @@
6
6
  * 问句之前逐行打印执行前预览(`request.preview`,W3-B9a-2)。
7
7
  * - 否则(管道):逐行读 stdin,每行依次执行(等上一条运行结束);没有审批 UI,ask → deny。
8
8
  * 模型错误在运行结束时只打印一次(重试中只显示 ↻);有运行最终失败时退出码 1。
9
+ * - raw 终端里 `/permission full-auto` 进入 Bypass 前文本确认(`确认进入 Bypass?[y/N]`,本次运行确认过
10
+ * 一次后不再问;启动时已是 Bypass 视为已确认)。
9
11
  * - 斜杠命令走 commands-core(与 B7 同一语义),`pick` 退化为列出候选;`/rewind` 列编号、
10
12
  * `/rewind <n> …` 执行,回到的单行原消息放回编辑行。
11
13
  */
@@ -6,18 +6,25 @@
6
6
  * 问句之前逐行打印执行前预览(`request.preview`,W3-B9a-2)。
7
7
  * - 否则(管道):逐行读 stdin,每行依次执行(等上一条运行结束);没有审批 UI,ask → deny。
8
8
  * 模型错误在运行结束时只打印一次(重试中只显示 ↻);有运行最终失败时退出码 1。
9
+ * - raw 终端里 `/permission full-auto` 进入 Bypass 前文本确认(`确认进入 Bypass?[y/N]`,本次运行确认过
10
+ * 一次后不再问;启动时已是 Bypass 视为已确认)。
9
11
  * - 斜杠命令走 commands-core(与 B7 同一语义),`pick` 退化为列出候选;`/rewind` 列编号、
10
12
  * `/rewind <n> …` 执行,回到的单行原消息放回编辑行。
11
13
  */
14
+ import { msg } from "../../../i18n/index.js";
12
15
  import { promptImages, sessionModel } from "../../image-input.js";
13
16
  import { taskRegistryView } from "../../../agent/subagent-registry.js";
14
17
  import { currentSession, switchSession } from "../../../cli/compose-session.js";
15
18
  import { ExitCode } from "../../../cli/exit-codes.js";
19
+ import { BYPASS_MODE, bypassLineQuestion, bypassRiskLines, createBypassGate, } from "../../../permissions/bypass.js";
16
20
  import { previewDisplayLines } from "../../../permissions/preview.js";
17
21
  import { AMA_VERSION } from "../../../version.js";
18
22
  import { runSlashCommand } from "../../commands-core.js";
23
+ import { configCommand } from "../config-ui.js";
24
+ import { lineTraceCommand } from "../../../trace/session.js";
19
25
  import { createLineReader } from "../../rpc/jsonl.js";
20
26
  import { errorText, onTerminationSignals } from "../../shared.js";
27
+ import { memoryLineCommand } from "../memory-panel.js";
21
28
  import { LineEditor } from "./line-editor.js";
22
29
  import { cacheNoticesEnabled } from "../../session-report.js";
23
30
  import { EventPrinter, approvalQuestion, logsInfo, pickHint } from "./line-render.js";
@@ -43,6 +50,11 @@ export async function runLineMode(runtime, context, options = {}) {
43
50
  let unsubscribe = session.subscribe((event) => printer.handle(event));
44
51
  const commands = {
45
52
  runtime,
53
+ extra: {
54
+ config: configCommand(runtime, context),
55
+ trace: lineTraceCommand,
56
+ memory: memoryLineCommand, // [W6-M]
57
+ },
46
58
  session: () => session,
47
59
  async switchSession(request) {
48
60
  const next = await switchSession(runtime, request);
@@ -103,8 +115,16 @@ export async function runLineMode(runtime, context, options = {}) {
103
115
  const ed = editor;
104
116
  if (runtime.config.ui?.quietStartup !== "silent") {
105
117
  const model = session.state.model;
106
- io.stdout(`ama ${AMA_VERSION} · ${model?.provider}/${model?.id} · /help 查看命令,Ctrl+D 退出\n`);
118
+ io.stdout(`${msg().interactive.line.banner(AMA_VERSION, `${model?.provider}/${model?.id}`)}\n`);
107
119
  }
120
+ // /permission full-auto:进入 Bypass 前文本确认一次(管道里没有这一步,命令本身就是显式选择)
121
+ commands.confirmPermissionMode = createBypassGate(() => {
122
+ ed.hide();
123
+ io.stdout(`\n${bypassRiskLines()
124
+ .map((l) => ` ${l}\n`)
125
+ .join("")}`);
126
+ return ed.ask(bypassLineQuestion(), "n").then((answer) => answer === "y");
127
+ }, session.state.permissionMode === BYPASS_MODE);
108
128
  runtime.approvals.setUiBroker({
109
129
  ask: (request, signal) => new Promise((resolve) => {
110
130
  if (signal.aborted)
@@ -161,14 +181,14 @@ export async function runLineMode(runtime, context, options = {}) {
161
181
  if (action.kind === "interrupt") {
162
182
  if (busy) {
163
183
  void session.abort();
164
- err("^C 已中断\n");
184
+ err(`${msg().interactive.line.interrupted}\n`);
165
185
  }
166
186
  else if (Date.now() - lastInterrupt < DOUBLE_INTERRUPT_MS) {
167
187
  return finish(ExitCode.Sigint);
168
188
  }
169
189
  else {
170
190
  lastInterrupt = Date.now();
171
- io.stdout("\n(再按一次 Ctrl+C 退出)\n");
191
+ io.stdout(`\n${msg().interactive.line.ctrlCAgain}\n`);
172
192
  ed.render();
173
193
  }
174
194
  continue;
@@ -176,7 +196,7 @@ export async function runLineMode(runtime, context, options = {}) {
176
196
  if (busy) {
177
197
  if (action.text.trim() !== "") {
178
198
  void session.steer(action.text).catch(() => undefined);
179
- out(`↳ steer:${action.text}\n`);
199
+ out(`${msg().interactive.line.steer(action.text)}\n`);
180
200
  }
181
201
  continue;
182
202
  }
@@ -2,9 +2,10 @@
2
2
  * 行式界面的输出:会话事件 → 纯文本(助手文本流式写 stdout,工具 / 重试 / 压缩一行提示)。[B6]
3
3
  * 选择器在行式界面里退化为列出候选、提示带参数重发。
4
4
  */
5
+ import { msg } from "../../../i18n/index.js";
5
6
  import { THINKING_LEVELS } from "../../../ai/thinking.js";
6
7
  import { listSessions } from "../../../cli/compose-store.js";
7
- import { AUTO_LAYER_TEXT, permissionModeLines } from "../../../permissions/modes.js";
8
+ import { autoLayerText, permissionModeLines } from "../../../permissions/modes.js";
8
9
  import { cacheEventNotice, warmSentNotice } from "../../session-report.js";
9
10
  import { isFirstRunRequest, sourceLabel } from "../approval-dialog.js";
10
11
  import { LIMIT_WARNING, backgroundJobText, limitReachedText, modelFallbackText, } from "../event-notices.js";
@@ -25,27 +26,27 @@ export function argsSummary(args) {
25
26
  return "";
26
27
  }
27
28
  export function approvalQuestion(request, taskAgent) {
29
+ const m = msg().interactive.line;
28
30
  const label = sourceLabel(request, taskAgent);
29
31
  const task = label === undefined ? "" : `${label} `;
30
32
  const origin = request.context?.origin;
31
33
  if (origin !== undefined) {
32
- const where = origin.toolCall.locations?.[0];
33
- return `${task}允许 ${origin.toolCall.title}${where !== undefined ? ` ${where}` : ""}?[y 允许 / a 本会话都允许 / N 拒绝] `;
34
+ return m.approvalOrigin(task, origin.toolCall.title, origin.toolCall.locations?.[0]);
34
35
  }
35
36
  if (isFirstRunRequest(request)) {
36
37
  const input = request.input;
37
- return `${task}${String(input["note"])} 允许?[y 允许 / N 拒绝] `;
38
+ return m.approvalFirstRun(task, String(input["note"]));
38
39
  }
39
40
  const summary = argsSummary(request.input);
40
41
  const auto = request.autoDecision;
41
42
  const why = request.reason === "dangerous"
42
- ? "(危险命令)"
43
+ ? { kind: "dangerous" }
43
44
  : request.hookReason !== undefined
44
- ? `(${request.hookReason})`
45
+ ? { kind: "hook", reason: request.hookReason }
45
46
  : auto !== undefined
46
- ? `(Auto ${AUTO_LAYER_TEXT[auto.layer]}:${auto.reason})`
47
- : "";
48
- return `${task}允许 ${request.toolName}${summary !== "" ? ` ${summary}` : ""}${why}?[y 允许 / a 本会话都允许 / N 拒绝] `;
47
+ ? { kind: "auto", layer: autoLayerText(auto.layer), reason: auto.reason }
48
+ : undefined;
49
+ return m.approvalTool(task, request.toolName, summary, why);
49
50
  }
50
51
  /** `AMA_LOG=info|debug`。 */
51
52
  export function logsInfo(env) {
@@ -92,7 +93,8 @@ export class EventPrinter {
92
93
  if (event.message.role === "assistant") {
93
94
  this.endLine();
94
95
  if (event.message.stopReason === "error")
95
- this.pendingError = event.message.errorMessage ?? "模型调用失败";
96
+ this.pendingError =
97
+ event.message.errorMessage ?? msg().interactive.view.message.modelError;
96
98
  }
97
99
  return;
98
100
  case "agent_end":
@@ -114,14 +116,14 @@ export class EventPrinter {
114
116
  }
115
117
  return;
116
118
  case "auto_retry_start":
117
- this.line(`↻ 重试 ${event.attempt}/${event.maxAttempts}(${Math.round(event.delayMs / 1000)}s):${event.errorMessage}`, true);
119
+ this.line(msg().interactive.line.retry(event.attempt, event.maxAttempts, Math.round(event.delayMs / 1000), event.errorMessage), true);
118
120
  return;
119
121
  case "compaction_start":
120
- this.line("… 压缩上下文", true);
122
+ this.line(msg().interactive.line.compacting, true);
121
123
  return;
122
124
  case "compaction_end":
123
125
  if (event.error !== undefined)
124
- this.line(`压缩失败:${event.error}`, true);
126
+ this.line(msg().interactive.events.compactionFailed(event.error), true);
125
127
  return;
126
128
  case "cache_miss":
127
129
  case "context_pressure": {
@@ -142,7 +144,7 @@ export class EventPrinter {
142
144
  this.pendingError = undefined;
143
145
  if (error !== undefined) {
144
146
  this.failures++;
145
- this.line(`ama: 错误:${error}`, true);
147
+ this.line(msg().interactive.line.error(error), true);
146
148
  }
147
149
  // 失败时 warning 就是同一条错误文本,不再重复打印;预算到限已由 limit_reached 说明
148
150
  if (event.warning !== undefined &&
@@ -153,12 +155,11 @@ export class EventPrinter {
153
155
  }
154
156
  // [W5-U] 第五波事件
155
157
  case "plan_proposed": {
156
- const file = event.filePath !== undefined ? `(${event.filePath})` : "";
157
- this.line(`◇ 计划 v${event.version} 待审批${file}:/plan approve [模式|fresh] 批准 · /plan reject 放弃 · 直接输入修改意见`);
158
+ this.line(msg().interactive.line.planProposed(event.version, event.filePath));
158
159
  return;
159
160
  }
160
161
  case "subagent_start":
161
- this.line(` ↳ ${event.taskId} ${event.agent}${event.background ? "(后台)" : ""} 开始`);
162
+ this.line(msg().interactive.line.subagentStart(event.taskId, event.agent, event.background === true));
162
163
  return;
163
164
  case "subagent_end":
164
165
  this.line(` ↳ ${event.taskId} ${taskStatusText(event.status)}`);
@@ -189,14 +190,14 @@ export async function pickHint(what, runtime, session) {
189
190
  for (const model of provider.models)
190
191
  refs.push(` ${provider.id}/${model.id}`);
191
192
  }
192
- return ["可用模型(/model <provider/id>):", ...refs.slice(0, 40)].join("\n");
193
+ return [msg().interactive.line.modelsHeading, ...refs.slice(0, 40)].join("\n");
193
194
  }
194
195
  case "session": {
195
196
  const items = listSessions({ sessionDir: runtime.paths.sessionDir, cwd: session.state.cwd });
196
197
  if (items.length === 0)
197
- return "本目录没有会话";
198
+ return msg().interactive.line.noSessions;
198
199
  return [
199
- "最近的会话(/resume <id>):",
200
+ msg().interactive.line.sessionsHeading,
200
201
  ...items
201
202
  .slice(0, 15)
202
203
  .map((i) => ` ${i.id.slice(0, 8)} ${i.modifiedAt.slice(0, 16).replace("T", " ")} ${(i.name ?? i.firstPrompt ?? "").replace(/\s+/g, " ").slice(0, 50)}`),
@@ -205,9 +206,9 @@ export async function pickHint(what, runtime, session) {
205
206
  case "tree": {
206
207
  const users = session.entries.filter((e) => e.type === "message" && e.message.role === "user");
207
208
  if (users.length === 0)
208
- return "还没有可分叉的消息";
209
+ return msg().interactive.line.noForkable;
209
210
  return [
210
- "可分叉的位置(/fork <条目 id>):",
211
+ msg().interactive.line.forkHeading,
211
212
  ...users.slice(-15).map((e) => {
212
213
  const message = e.type === "message" ? e.message : undefined;
213
214
  const content = message?.role === "user" ? message.content : "";
@@ -220,10 +221,10 @@ export async function pickHint(what, runtime, session) {
220
221
  }
221
222
  case "permission":
222
223
  return [
223
- "Mode(/permission <模式>):",
224
+ msg().interactive.line.modeHeading,
224
225
  ...permissionModeLines(session.state.permissionMode, runtime.config.permission?.mode ?? "default").map((line) => ` ${line}`),
225
226
  ].join("\n");
226
227
  case "thinking":
227
- return `思考级别(/thinking <级别>):${THINKING_LEVELS.join(" | ")};当前 ${session.state.thinkingLevel}`;
228
+ return msg().interactive.line.thinking(THINKING_LEVELS.join(" | "), session.state.thinkingLevel);
228
229
  }
229
230
  }