@armadra/agent 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (527) hide show
  1. package/CHANGELOG.md +257 -0
  2. package/README.md +263 -95
  3. package/THIRD_PARTY_NOTICES.md +34 -0
  4. package/dist/acp.d.ts +18 -0
  5. package/dist/acp.js +19 -0
  6. package/dist/agent/limits.d.ts +38 -0
  7. package/dist/agent/limits.js +127 -0
  8. package/dist/agent/loop-guard.d.ts +38 -0
  9. package/dist/agent/loop-guard.js +95 -0
  10. package/dist/agent/loop.d.ts +4 -0
  11. package/dist/agent/loop.js +7 -0
  12. package/dist/agent/prompt-rules.d.ts +12 -0
  13. package/dist/agent/prompt-rules.js +18 -0
  14. package/dist/agent/reminders.d.ts +59 -0
  15. package/dist/agent/reminders.js +327 -0
  16. package/dist/agent/retry.d.ts +1 -1
  17. package/dist/agent/retry.js +2 -1
  18. package/dist/agent/session-cache.d.ts +5 -0
  19. package/dist/agent/session-cache.js +18 -2
  20. package/dist/agent/session-classifier.d.ts +18 -0
  21. package/dist/agent/session-classifier.js +105 -0
  22. package/dist/agent/session-compaction.d.ts +35 -6
  23. package/dist/agent/session-compaction.js +157 -31
  24. package/dist/agent/session-core.d.ts +40 -1
  25. package/dist/agent/session-extensions.d.ts +61 -0
  26. package/dist/agent/session-extensions.js +129 -0
  27. package/dist/agent/session-images.d.ts +23 -0
  28. package/dist/agent/session-images.js +97 -0
  29. package/dist/agent/session-plan.d.ts +21 -0
  30. package/dist/agent/session-plan.js +524 -0
  31. package/dist/agent/session-rewind.d.ts +81 -0
  32. package/dist/agent/session-rewind.js +354 -0
  33. package/dist/agent/session-run.d.ts +28 -1
  34. package/dist/agent/session-run.js +157 -6
  35. package/dist/agent/session-settings.d.ts +49 -0
  36. package/dist/agent/session-settings.js +95 -0
  37. package/dist/agent/session-subagent.d.ts +36 -24
  38. package/dist/agent/session-subagent.js +259 -129
  39. package/dist/agent/session-sync.d.ts +10 -3
  40. package/dist/agent/session-sync.js +37 -8
  41. package/dist/agent/session-telemetry.d.ts +39 -0
  42. package/dist/agent/session-telemetry.js +231 -0
  43. package/dist/agent/session-tools.js +63 -3
  44. package/dist/agent/session.d.ts +33 -29
  45. package/dist/agent/session.js +91 -126
  46. package/dist/agent/subagent-registry.d.ts +91 -0
  47. package/dist/agent/subagent-registry.js +494 -0
  48. package/dist/agent/system-prompt.d.ts +6 -3
  49. package/dist/agent/system-prompt.js +7 -2
  50. package/dist/agent/tool-runner.d.ts +8 -1
  51. package/dist/agent/tool-runner.js +72 -6
  52. package/dist/agent/types-w5.d.ts +192 -0
  53. package/dist/agent/types-w5.js +10 -0
  54. package/dist/agent/types.d.ts +55 -4
  55. package/dist/agent/types.js +2 -0
  56. package/dist/agent/worktree.d.ts +36 -0
  57. package/dist/agent/worktree.js +86 -0
  58. package/dist/agents/builtin.d.ts +14 -0
  59. package/dist/agents/builtin.js +39 -0
  60. package/dist/agents/catalog.d.ts +43 -0
  61. package/dist/agents/catalog.js +82 -0
  62. package/dist/agents/discover.d.ts +35 -0
  63. package/dist/agents/discover.js +83 -0
  64. package/dist/agents/external.d.ts +82 -0
  65. package/dist/agents/external.js +326 -0
  66. package/dist/agents/parse.d.ts +18 -0
  67. package/dist/agents/parse.js +116 -0
  68. package/dist/agents/result.d.ts +32 -0
  69. package/dist/agents/result.js +67 -0
  70. package/dist/agents/task-control.d.ts +17 -0
  71. package/dist/agents/task-control.js +17 -0
  72. package/dist/agents/task-record.d.ts +78 -0
  73. package/dist/agents/task-record.js +141 -0
  74. package/dist/agents/types.d.ts +46 -0
  75. package/dist/agents/types.js +8 -0
  76. package/dist/ai/apis/anthropic-compat.d.ts +36 -0
  77. package/dist/ai/apis/anthropic-compat.js +92 -0
  78. package/dist/ai/apis/anthropic-messages.js +3 -2
  79. package/dist/ai/apis/anthropic-request.d.ts +7 -6
  80. package/dist/ai/apis/anthropic-request.js +10 -28
  81. package/dist/ai/apis/cache-params.d.ts +11 -2
  82. package/dist/ai/apis/cache-params.js +25 -6
  83. package/dist/ai/apis/google-generative-ai.js +3 -2
  84. package/dist/ai/apis/openai-compat.d.ts +4 -1
  85. package/dist/ai/apis/openai-compat.js +8 -1
  86. package/dist/ai/apis/openai-completions.js +3 -2
  87. package/dist/ai/apis/openai-responses.js +3 -2
  88. package/dist/ai/http.d.ts +28 -6
  89. package/dist/ai/http.js +41 -8
  90. package/dist/ai/image-limits.d.ts +45 -0
  91. package/dist/ai/image-limits.js +68 -0
  92. package/dist/ai/providers/builtin.d.ts +18 -6
  93. package/dist/ai/providers/builtin.js +135 -6
  94. package/dist/ai/providers/catalog-data.js +17 -13
  95. package/dist/ai/providers/catalog.d.ts +60 -7
  96. package/dist/ai/providers/catalog.js +197 -38
  97. package/dist/ai/providers/channels.d.ts +33 -3
  98. package/dist/ai/providers/channels.js +108 -7
  99. package/dist/ai/providers/enrich.d.ts +6 -3
  100. package/dist/ai/providers/enrich.js +19 -4
  101. package/dist/ai/providers/models-dev-cache.d.ts +28 -24
  102. package/dist/ai/providers/models-dev-cache.js +92 -78
  103. package/dist/ai/providers/models-dev-data.d.ts +7 -0
  104. package/dist/ai/providers/models-dev-data.js +32 -0
  105. package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
  106. package/dist/ai/providers/models-dev-snapshot.js +137 -0
  107. package/dist/ai/providers/models-dev.d.ts +51 -10
  108. package/dist/ai/providers/models-dev.js +132 -39
  109. package/dist/ai/providers/registry.d.ts +28 -11
  110. package/dist/ai/providers/registry.js +112 -65
  111. package/dist/ai/providers/suggest.d.ts +18 -0
  112. package/dist/ai/providers/suggest.js +72 -0
  113. package/dist/ai/sse.d.ts +6 -2
  114. package/dist/ai/sse.js +22 -2
  115. package/dist/ai/types.d.ts +37 -4
  116. package/dist/ai/types.js +5 -0
  117. package/dist/bundle/ama.cjs +41979 -21147
  118. package/dist/checkpoints/backend.d.ts +61 -0
  119. package/dist/checkpoints/backend.js +135 -0
  120. package/dist/checkpoints/blobs.d.ts +60 -0
  121. package/dist/checkpoints/blobs.js +203 -0
  122. package/dist/checkpoints/gc.d.ts +47 -0
  123. package/dist/checkpoints/gc.js +144 -0
  124. package/dist/checkpoints/git-head.d.ts +15 -0
  125. package/dist/checkpoints/git-head.js +89 -0
  126. package/dist/checkpoints/index.d.ts +17 -0
  127. package/dist/checkpoints/index.js +17 -0
  128. package/dist/checkpoints/replay.d.ts +48 -0
  129. package/dist/checkpoints/replay.js +154 -0
  130. package/dist/checkpoints/restore.d.ts +86 -0
  131. package/dist/checkpoints/restore.js +263 -0
  132. package/dist/checkpoints/settings.d.ts +14 -0
  133. package/dist/checkpoints/settings.js +23 -0
  134. package/dist/checkpoints/shadow-git.d.ts +108 -0
  135. package/dist/checkpoints/shadow-git.js +491 -0
  136. package/dist/checkpoints/shadow-restore.d.ts +25 -0
  137. package/dist/checkpoints/shadow-restore.js +128 -0
  138. package/dist/checkpoints/tracker.d.ts +64 -0
  139. package/dist/checkpoints/tracker.js +192 -0
  140. package/dist/checkpoints/types.d.ts +99 -0
  141. package/dist/checkpoints/types.js +12 -0
  142. package/dist/cli/args.d.ts +26 -7
  143. package/dist/cli/args.js +75 -82
  144. package/dist/cli/bootstrap.js +40 -4
  145. package/dist/cli/codemode-notice.d.ts +21 -0
  146. package/dist/cli/codemode-notice.js +56 -0
  147. package/dist/cli/compose-agents.d.ts +27 -0
  148. package/dist/cli/compose-agents.js +111 -0
  149. package/dist/cli/compose-extensions.d.ts +29 -0
  150. package/dist/cli/compose-extensions.js +44 -0
  151. package/dist/cli/compose-session.d.ts +8 -0
  152. package/dist/cli/compose-session.js +76 -2
  153. package/dist/cli/compose-store.d.ts +1 -1
  154. package/dist/cli/compose-store.js +3 -1
  155. package/dist/cli/compose.d.ts +17 -4
  156. package/dist/cli/compose.js +60 -14
  157. package/dist/cli/default-model.d.ts +38 -1
  158. package/dist/cli/default-model.js +96 -9
  159. package/dist/cli/deps.d.ts +42 -0
  160. package/dist/cli/exit-codes.d.ts +12 -0
  161. package/dist/cli/exit-codes.js +15 -0
  162. package/dist/cli/fake-visibility.d.ts +13 -0
  163. package/dist/cli/fake-visibility.js +26 -0
  164. package/dist/cli/from-prompt.d.ts +18 -0
  165. package/dist/cli/from-prompt.js +49 -0
  166. package/dist/cli/help-text.d.ts +4 -0
  167. package/dist/cli/help-text.js +102 -0
  168. package/dist/cli/main.d.ts +9 -2
  169. package/dist/cli/main.js +77 -3
  170. package/dist/cli/proxy.d.ts +51 -0
  171. package/dist/cli/proxy.js +135 -0
  172. package/dist/cli/startup-screen.d.ts +29 -0
  173. package/dist/cli/startup-screen.js +51 -2
  174. package/dist/cli/startup-steps.d.ts +1 -1
  175. package/dist/cli/startup-steps.js +21 -13
  176. package/dist/cli/subcommands/config.d.ts +22 -3
  177. package/dist/cli/subcommands/config.js +119 -21
  178. package/dist/cli/subcommands/context.js +4 -1
  179. package/dist/cli/subcommands/doctor.js +33 -1
  180. package/dist/cli/subcommands/init.js +2 -1
  181. package/dist/cli/subcommands/models-discover.d.ts +15 -9
  182. package/dist/cli/subcommands/models-discover.js +58 -52
  183. package/dist/cli/subcommands/models.d.ts +2 -0
  184. package/dist/cli/subcommands/models.js +33 -14
  185. package/dist/cli/subcommands/probe-runner.d.ts +96 -0
  186. package/dist/cli/subcommands/probe-runner.js +264 -0
  187. package/dist/cli/subcommands/providers-probe.d.ts +34 -0
  188. package/dist/cli/subcommands/providers-probe.js +87 -0
  189. package/dist/cli/subcommands/providers.d.ts +3 -2
  190. package/dist/cli/subcommands/providers.js +53 -51
  191. package/dist/cli/subcommands/sessions-export.d.ts +10 -0
  192. package/dist/cli/subcommands/sessions-export.js +59 -0
  193. package/dist/cli/subcommands/sessions-search.d.ts +13 -0
  194. package/dist/cli/subcommands/sessions-search.js +103 -0
  195. package/dist/cli/subcommands/sessions.d.ts +6 -3
  196. package/dist/cli/subcommands/sessions.js +58 -3
  197. package/dist/cli/subcommands/stats.d.ts +17 -0
  198. package/dist/cli/subcommands/stats.js +198 -0
  199. package/dist/cli/system-prompt-arg.d.ts +11 -0
  200. package/dist/cli/system-prompt-arg.js +34 -0
  201. package/dist/codemode/capability.d.ts +24 -7
  202. package/dist/codemode/capability.js +38 -10
  203. package/dist/codemode/host-side.d.ts +14 -0
  204. package/dist/codemode/host-side.js +24 -1
  205. package/dist/codemode/modes.d.ts +4 -11
  206. package/dist/codemode/modes.js +5 -27
  207. package/dist/codemode/tool.d.ts +18 -14
  208. package/dist/codemode/tool.js +76 -31
  209. package/dist/compaction/breaker.d.ts +25 -9
  210. package/dist/compaction/breaker.js +47 -17
  211. package/dist/compaction/estimate.d.ts +11 -3
  212. package/dist/compaction/estimate.js +64 -22
  213. package/dist/compaction/image-budget.d.ts +45 -0
  214. package/dist/compaction/image-budget.js +115 -0
  215. package/dist/compaction/post-compact.d.ts +38 -0
  216. package/dist/compaction/post-compact.js +152 -0
  217. package/dist/compaction/protect.d.ts +27 -0
  218. package/dist/compaction/protect.js +56 -0
  219. package/dist/compaction/prune-tier.d.ts +58 -12
  220. package/dist/compaction/prune-tier.js +120 -54
  221. package/dist/compaction/summarize-tier.d.ts +23 -4
  222. package/dist/compaction/summarize-tier.js +100 -29
  223. package/dist/config/checker.d.ts +28 -0
  224. package/dist/config/checker.js +97 -0
  225. package/dist/config/init.d.ts +6 -2
  226. package/dist/config/init.js +12 -5
  227. package/dist/config/json-schema.d.ts +1 -0
  228. package/dist/config/json-schema.js +98 -4
  229. package/dist/config/key-docs.d.ts +22 -0
  230. package/dist/config/key-docs.js +174 -0
  231. package/dist/config/merge.d.ts +12 -9
  232. package/dist/config/merge.js +102 -13
  233. package/dist/config/profile.d.ts +2 -0
  234. package/dist/config/profile.js +2 -0
  235. package/dist/config/schema-w5.d.ts +18 -0
  236. package/dist/config/schema-w5.js +109 -0
  237. package/dist/config/schema.d.ts +5 -9
  238. package/dist/config/schema.js +91 -118
  239. package/dist/config/types-w5.d.ts +118 -0
  240. package/dist/config/types-w5.js +20 -0
  241. package/dist/config/types.d.ts +84 -7
  242. package/dist/config/types.js +29 -1
  243. package/dist/drivers/acp/client.d.ts +57 -0
  244. package/dist/drivers/acp/client.js +160 -0
  245. package/dist/drivers/acp/driver.d.ts +31 -0
  246. package/dist/drivers/acp/driver.js +274 -0
  247. package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
  248. package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
  249. package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
  250. package/dist/drivers/acp/testing/fake-agent.js +211 -0
  251. package/dist/drivers/acp/types.d.ts +285 -0
  252. package/dist/drivers/acp/types.js +36 -0
  253. package/dist/drivers/agents.d.ts +58 -0
  254. package/dist/drivers/agents.js +142 -0
  255. package/dist/drivers/base.d.ts +35 -0
  256. package/dist/drivers/base.js +59 -0
  257. package/dist/drivers/catalog.d.ts +46 -0
  258. package/dist/drivers/catalog.js +167 -0
  259. package/dist/drivers/env.d.ts +20 -0
  260. package/dist/drivers/env.js +46 -0
  261. package/dist/drivers/host-runners.d.ts +18 -0
  262. package/dist/drivers/host-runners.js +45 -0
  263. package/dist/drivers/jsonrpc.d.ts +58 -0
  264. package/dist/drivers/jsonrpc.js +180 -0
  265. package/dist/drivers/native/claude-normalize.d.ts +46 -0
  266. package/dist/drivers/native/claude-normalize.js +106 -0
  267. package/dist/drivers/native/claude-stream.d.ts +29 -0
  268. package/dist/drivers/native/claude-stream.js +456 -0
  269. package/dist/drivers/native/codex-app-server.d.ts +26 -0
  270. package/dist/drivers/native/codex-app-server.js +407 -0
  271. package/dist/drivers/native/codex-normalize.d.ts +38 -0
  272. package/dist/drivers/native/codex-normalize.js +124 -0
  273. package/dist/drivers/native/oneshot.d.ts +28 -0
  274. package/dist/drivers/native/oneshot.js +312 -0
  275. package/dist/drivers/permissions.d.ts +40 -0
  276. package/dist/drivers/permissions.js +92 -0
  277. package/dist/drivers/pids.d.ts +32 -0
  278. package/dist/drivers/pids.js +93 -0
  279. package/dist/drivers/pool.d.ts +28 -0
  280. package/dist/drivers/pool.js +96 -0
  281. package/dist/drivers/probe.d.ts +47 -0
  282. package/dist/drivers/probe.js +172 -0
  283. package/dist/drivers/process.d.ts +48 -0
  284. package/dist/drivers/process.js +100 -0
  285. package/dist/drivers/runner.d.ts +61 -0
  286. package/dist/drivers/runner.js +388 -0
  287. package/dist/drivers/store.d.ts +49 -0
  288. package/dist/drivers/store.js +91 -0
  289. package/dist/drivers/turn.d.ts +41 -0
  290. package/dist/drivers/turn.js +99 -0
  291. package/dist/drivers/types.d.ts +122 -0
  292. package/dist/drivers/types.js +11 -0
  293. package/dist/git/info.d.ts +75 -0
  294. package/dist/git/info.js +191 -0
  295. package/dist/hooks/protocol.js +6 -1
  296. package/dist/hooks/types.d.ts +10 -1
  297. package/dist/hooks/types.js +2 -0
  298. package/dist/host/api-impl.d.ts +7 -0
  299. package/dist/host/api-impl.js +15 -0
  300. package/dist/host/types.d.ts +24 -2
  301. package/dist/host/types.js +4 -0
  302. package/dist/index.d.ts +3 -0
  303. package/dist/index.js +1 -0
  304. package/dist/modes/acp/acp-events.d.ts +46 -0
  305. package/dist/modes/acp/acp-events.js +233 -0
  306. package/dist/modes/acp/acp-mode.d.ts +17 -0
  307. package/dist/modes/acp/acp-mode.js +47 -0
  308. package/dist/modes/acp/acp-server.d.ts +79 -0
  309. package/dist/modes/acp/acp-server.js +315 -0
  310. package/dist/modes/commands-core.d.ts +7 -1
  311. package/dist/modes/commands-core.js +61 -5
  312. package/dist/modes/image-input.d.ts +12 -4
  313. package/dist/modes/image-input.js +22 -5
  314. package/dist/modes/interactive/agent-panels.d.ts +14 -0
  315. package/dist/modes/interactive/agent-panels.js +103 -0
  316. package/dist/modes/interactive/agent-ui.d.ts +73 -0
  317. package/dist/modes/interactive/agent-ui.js +234 -0
  318. package/dist/modes/interactive/approval-dialog.d.ts +40 -7
  319. package/dist/modes/interactive/approval-dialog.js +192 -35
  320. package/dist/modes/interactive/approval-merge.d.ts +41 -0
  321. package/dist/modes/interactive/approval-merge.js +89 -0
  322. package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
  323. package/dist/modes/interactive/clipboard-paste.js +28 -0
  324. package/dist/modes/interactive/commands.d.ts +20 -3
  325. package/dist/modes/interactive/commands.js +75 -16
  326. package/dist/modes/interactive/double-esc.d.ts +20 -0
  327. package/dist/modes/interactive/double-esc.js +34 -0
  328. package/dist/modes/interactive/event-notices.d.ts +32 -0
  329. package/dist/modes/interactive/event-notices.js +79 -0
  330. package/dist/modes/interactive/external-editor.d.ts +16 -0
  331. package/dist/modes/interactive/external-editor.js +39 -0
  332. package/dist/modes/interactive/interactive-mode.d.ts +16 -2
  333. package/dist/modes/interactive/interactive-mode.js +184 -202
  334. package/dist/modes/interactive/key-dispatch.d.ts +18 -2
  335. package/dist/modes/interactive/key-dispatch.js +53 -6
  336. package/dist/modes/interactive/line/line-mode.d.ts +3 -1
  337. package/dist/modes/interactive/line/line-mode.js +28 -9
  338. package/dist/modes/interactive/line/line-render.d.ts +6 -1
  339. package/dist/modes/interactive/line/line-render.js +66 -8
  340. package/dist/modes/interactive/message-view.d.ts +49 -10
  341. package/dist/modes/interactive/message-view.js +262 -46
  342. package/dist/modes/interactive/panels.d.ts +35 -0
  343. package/dist/modes/interactive/panels.js +157 -0
  344. package/dist/modes/interactive/pickers.d.ts +23 -2
  345. package/dist/modes/interactive/pickers.js +48 -15
  346. package/dist/modes/interactive/plan-command.d.ts +40 -0
  347. package/dist/modes/interactive/plan-command.js +129 -0
  348. package/dist/modes/interactive/plan-dialog.d.ts +98 -0
  349. package/dist/modes/interactive/plan-dialog.js +290 -0
  350. package/dist/modes/interactive/plan-flow.d.ts +34 -0
  351. package/dist/modes/interactive/plan-flow.js +98 -0
  352. package/dist/modes/interactive/rewind-command.d.ts +31 -0
  353. package/dist/modes/interactive/rewind-command.js +106 -0
  354. package/dist/modes/interactive/rewind-flow.d.ts +37 -0
  355. package/dist/modes/interactive/rewind-flow.js +151 -0
  356. package/dist/modes/interactive/rewind-list.d.ts +36 -0
  357. package/dist/modes/interactive/rewind-list.js +123 -0
  358. package/dist/modes/interactive/rewind-panel.d.ts +77 -0
  359. package/dist/modes/interactive/rewind-panel.js +309 -0
  360. package/dist/modes/interactive/rewind-text.d.ts +40 -0
  361. package/dist/modes/interactive/rewind-text.js +139 -0
  362. package/dist/modes/interactive/run-indicator.d.ts +51 -0
  363. package/dist/modes/interactive/run-indicator.js +189 -0
  364. package/dist/modes/interactive/session-events.d.ts +24 -0
  365. package/dist/modes/interactive/session-events.js +96 -0
  366. package/dist/modes/interactive/startup-header.d.ts +40 -0
  367. package/dist/modes/interactive/startup-header.js +169 -0
  368. package/dist/modes/interactive/status-area.d.ts +73 -0
  369. package/dist/modes/interactive/status-area.js +190 -0
  370. package/dist/modes/interactive/status-bar.d.ts +107 -16
  371. package/dist/modes/interactive/status-bar.js +306 -81
  372. package/dist/modes/interactive/status-line.d.ts +33 -0
  373. package/dist/modes/interactive/status-line.js +113 -0
  374. package/dist/modes/interactive/subagent-view.d.ts +56 -0
  375. package/dist/modes/interactive/subagent-view.js +154 -0
  376. package/dist/modes/interactive/tasks-report.d.ts +27 -0
  377. package/dist/modes/interactive/tasks-report.js +114 -0
  378. package/dist/modes/interactive/tool-summary.d.ts +46 -0
  379. package/dist/modes/interactive/tool-summary.js +218 -0
  380. package/dist/modes/interactive/tool-view.d.ts +58 -15
  381. package/dist/modes/interactive/tool-view.js +233 -145
  382. package/dist/modes/print/print-mode.d.ts +40 -4
  383. package/dist/modes/print/print-mode.js +161 -8
  384. package/dist/modes/rpc/commands.d.ts +9 -0
  385. package/dist/modes/rpc/commands.js +49 -0
  386. package/dist/modes/rpc/rpc-mode.js +7 -1
  387. package/dist/modes/session-report.d.ts +11 -0
  388. package/dist/modes/session-report.js +48 -1
  389. package/dist/permissions/auto-safe.d.ts +65 -0
  390. package/dist/permissions/auto-safe.js +547 -0
  391. package/dist/permissions/classifier.d.ts +68 -0
  392. package/dist/permissions/classifier.js +186 -0
  393. package/dist/permissions/dangerous.d.ts +5 -0
  394. package/dist/permissions/dangerous.js +1 -1
  395. package/dist/permissions/modes.d.ts +30 -0
  396. package/dist/permissions/modes.js +78 -0
  397. package/dist/permissions/pipeline.d.ts +72 -6
  398. package/dist/permissions/pipeline.js +306 -11
  399. package/dist/permissions/protected.d.ts +19 -0
  400. package/dist/permissions/protected.js +74 -0
  401. package/dist/permissions/readonly-bash.d.ts +30 -0
  402. package/dist/permissions/readonly-bash.js +118 -0
  403. package/dist/permissions/rules.js +3 -0
  404. package/dist/permissions/types.d.ts +92 -3
  405. package/dist/permissions/types.js +3 -0
  406. package/dist/plan/compose.d.ts +9 -0
  407. package/dist/plan/compose.js +19 -0
  408. package/dist/plan/controller.d.ts +71 -0
  409. package/dist/plan/controller.js +27 -0
  410. package/dist/plan/done-markers.d.ts +17 -0
  411. package/dist/plan/done-markers.js +51 -0
  412. package/dist/plan/extract.d.ts +29 -0
  413. package/dist/plan/extract.js +160 -0
  414. package/dist/plan/prompts.d.ts +36 -0
  415. package/dist/plan/prompts.js +89 -0
  416. package/dist/plan/store.d.ts +37 -0
  417. package/dist/plan/store.js +90 -0
  418. package/dist/rpc.d.ts +58 -2
  419. package/dist/rpc.js +7 -0
  420. package/dist/sandbox/bash.d.ts +74 -0
  421. package/dist/sandbox/bash.js +126 -0
  422. package/dist/sandbox/detect.d.ts +48 -0
  423. package/dist/sandbox/detect.js +149 -0
  424. package/dist/sandbox/index.d.ts +5 -0
  425. package/dist/sandbox/index.js +5 -0
  426. package/dist/sandbox/profile.d.ts +33 -0
  427. package/dist/sandbox/profile.js +76 -0
  428. package/dist/sandbox/wrap.d.ts +29 -0
  429. package/dist/sandbox/wrap.js +117 -0
  430. package/dist/sdk.d.ts +42 -5
  431. package/dist/sdk.js +34 -4
  432. package/dist/session/export.d.ts +32 -0
  433. package/dist/session/export.js +187 -0
  434. package/dist/session/redact.d.ts +15 -0
  435. package/dist/session/redact.js +55 -0
  436. package/dist/session/reuse.d.ts +33 -0
  437. package/dist/session/reuse.js +86 -0
  438. package/dist/session/scan.d.ts +34 -0
  439. package/dist/session/scan.js +140 -0
  440. package/dist/session/search.d.ts +52 -0
  441. package/dist/session/search.js +211 -0
  442. package/dist/session/stats-aggregate.d.ts +63 -0
  443. package/dist/session/stats-aggregate.js +163 -0
  444. package/dist/session/stats-index.d.ts +26 -0
  445. package/dist/session/stats-index.js +91 -0
  446. package/dist/session/stats-scan.d.ts +54 -0
  447. package/dist/session/stats-scan.js +236 -0
  448. package/dist/session/types.d.ts +3 -1
  449. package/dist/session/types.js +1 -0
  450. package/dist/skills/builtin.d.ts +31 -0
  451. package/dist/skills/builtin.js +109 -0
  452. package/dist/skills/discover.d.ts +2 -1
  453. package/dist/skills/index-prompt.js +5 -8
  454. package/dist/tools/background-jobs.d.ts +71 -0
  455. package/dist/tools/background-jobs.js +198 -0
  456. package/dist/tools/bash.d.ts +53 -1
  457. package/dist/tools/bash.js +158 -7
  458. package/dist/tools/clipboard-image.d.ts +44 -0
  459. package/dist/tools/clipboard-image.js +148 -0
  460. package/dist/tools/edit.d.ts +2 -0
  461. package/dist/tools/edit.js +18 -3
  462. package/dist/tools/image-file.d.ts +38 -3
  463. package/dist/tools/image-file.js +81 -10
  464. package/dist/tools/image-resize.d.ts +58 -0
  465. package/dist/tools/image-resize.js +97 -0
  466. package/dist/tools/presets.d.ts +40 -8
  467. package/dist/tools/presets.js +65 -19
  468. package/dist/tools/read.d.ts +5 -2
  469. package/dist/tools/read.js +13 -10
  470. package/dist/tools/registry.d.ts +7 -1
  471. package/dist/tools/registry.js +27 -4
  472. package/dist/tools/task-ctl.d.ts +22 -0
  473. package/dist/tools/task-ctl.js +116 -0
  474. package/dist/tools/task.d.ts +22 -10
  475. package/dist/tools/task.js +66 -26
  476. package/dist/tools/todo.d.ts +22 -2
  477. package/dist/tools/todo.js +58 -14
  478. package/dist/tools/truncate.d.ts +15 -0
  479. package/dist/tools/truncate.js +25 -0
  480. package/dist/tools/types.d.ts +113 -0
  481. package/dist/tools/types.js +5 -0
  482. package/dist/tools/write.js +3 -0
  483. package/dist/tui/component.d.ts +8 -2
  484. package/dist/tui/component.js +3 -1
  485. package/dist/tui/components/box.d.ts +6 -1
  486. package/dist/tui/components/box.js +16 -6
  487. package/dist/tui/components/card.d.ts +23 -0
  488. package/dist/tui/components/card.js +37 -0
  489. package/dist/tui/components/editor-history.d.ts +6 -0
  490. package/dist/tui/components/editor-history.js +45 -0
  491. package/dist/tui/components/editor-paste.d.ts +1 -1
  492. package/dist/tui/components/editor-paste.js +4 -4
  493. package/dist/tui/components/editor.d.ts +11 -5
  494. package/dist/tui/components/editor.js +52 -58
  495. package/dist/tui/components/key-value.d.ts +3 -0
  496. package/dist/tui/components/key-value.js +16 -6
  497. package/dist/tui/components/loader.d.ts +37 -7
  498. package/dist/tui/components/loader.js +84 -21
  499. package/dist/tui/components/markdown.d.ts +5 -1
  500. package/dist/tui/components/markdown.js +45 -21
  501. package/dist/tui/components/meter.d.ts +3 -3
  502. package/dist/tui/components/meter.js +13 -11
  503. package/dist/tui/components/select-list.d.ts +23 -1
  504. package/dist/tui/components/select-list.js +76 -13
  505. package/dist/tui/glyphs.d.ts +72 -0
  506. package/dist/tui/glyphs.js +118 -0
  507. package/dist/tui/keybindings.d.ts +5 -0
  508. package/dist/tui/keybindings.js +5 -0
  509. package/dist/tui/theme.d.ts +30 -6
  510. package/dist/tui/theme.js +103 -17
  511. package/dist/tui.d.ts +4 -2
  512. package/dist/tui.js +3 -1
  513. package/docs/acp.md +78 -0
  514. package/docs/agents.md +250 -0
  515. package/docs/codemode.md +28 -10
  516. package/docs/hooks.md +36 -32
  517. package/docs/permissions.md +212 -0
  518. package/docs/plan.md +107 -0
  519. package/docs/providers.md +261 -62
  520. package/docs/rewind-plan.md +181 -0
  521. package/docs/rpc.md +127 -40
  522. package/docs/sandbox.md +215 -0
  523. package/docs/session-format.md +43 -22
  524. package/docs/sessions.md +174 -0
  525. package/docs/tui-design.md +751 -0
  526. package/docs/tui.md +260 -64
  527. package/package.json +15 -2
@@ -16,6 +16,7 @@
16
16
  * 让宿主访问、Hook 公共字段与退出 dispose 跟随新会话。
17
17
  */
18
18
  import type { ProviderRegistryApi } from "../ai/types.js";
19
+ import type { BashSandbox } from "../sandbox/bash.js";
19
20
  import { AgentSessionImpl } from "../agent/session.js";
20
21
  import type { AgentSession, CacheSettings, SessionEvent } from "../agent/types.js";
21
22
  import { type AmaConfig } from "../config/types.js";
@@ -35,6 +36,8 @@ export interface ComposeState {
35
36
  session: AgentSession | undefined;
36
37
  /** 第 11 步建好的供应商注册表(read 工具判断当前模型收不收图片)。 */
37
38
  providers?: ProviderRegistryApi;
39
+ /** [S2] tools.create 算出的 bash 沙箱设定,permissions.create 用同一份。 */
40
+ bashSandbox?: BashSandbox;
38
41
  }
39
42
  export declare function emptyComposeState(): ComposeState;
40
43
  export type LogFn = (level: "debug" | "info" | "warn" | "error", message: string) => void;
@@ -47,6 +50,11 @@ export interface SessionComposeOptions {
47
50
  export declare function stderrLog(env?: NodeJS.ProcessEnv): LogFn;
48
51
  /** config `cache` 段 + 环境变量 → 会话缓存设置;非法的环境变量值忽略并 warning。 */
49
52
  export declare function cacheSettingsFrom(config: Pick<AmaConfig, "cache">, env?: NodeJS.ProcessEnv, warn?: (message: string) => void): Partial<CacheSettings>;
53
+ /**
54
+ * 模型请求的空闲超时:`AMA_IDLE_TIMEOUT_MS` > config `request.idleTimeoutMs`;都没有 → undefined
55
+ * (协议层取缺省 300 000)。0 关闭;非法的环境变量值忽略并 warning。
56
+ */
57
+ export declare function idleTimeoutFrom(config: Pick<AmaConfig, "request">, env?: NodeJS.ProcessEnv, warn?: (message: string) => void): number | undefined;
50
58
  /** §1.4:SessionEvent → AgentEvents。 */
51
59
  export declare function bridgeEvent(event: SessionEvent, bus: AgentEventBus): void;
52
60
  /** 第 14 步:组装主会话。 */
@@ -16,7 +16,9 @@
16
16
  * 让宿主访问、Hook 公共字段与退出 dispose 跟随新会话。
17
17
  */
18
18
  import { readFileSync } from "node:fs";
19
+ import { resolveLimits } from "../agent/limits.js";
19
20
  import { AgentSessionImpl } from "../agent/session.js";
21
+ import { DEFAULT_SUBAGENT_CONCURRENCY } from "../agent/session-subagent.js";
20
22
  import { WARMING_MODES } from "../ai/cache/types.js";
21
23
  import { isOverflowErrorText } from "../ai/overflow.js";
22
24
  import { CACHE_RETENTIONS } from "../config/types.js";
@@ -25,11 +27,13 @@ import { ApprovalBrokerChain, DEFAULT_APPROVAL_TIMEOUT_MS } from "../permissions
25
27
  import { PermissionPipeline } from "../permissions/pipeline.js";
26
28
  import { SessionManager } from "../session/manager.js";
27
29
  import { sessionDirForCwd } from "../session/store.js";
30
+ import { createCheckpointBackendFactory, resolveCheckpointSettings } from "../checkpoints/index.js";
28
31
  import { expandSkillCommand } from "../skills/expand.js";
29
32
  import { formatSkillIndex } from "../skills/index-prompt.js";
30
33
  import { expandPromptCommand } from "../skills/templates.js";
31
34
  import { PresetToolRegistry } from "../tools/presets.js";
32
35
  import { openSession } from "./compose-store.js";
36
+ import { composeExtensions } from "./compose-extensions.js";
33
37
  import { ExitCode } from "./exit-codes.js";
34
38
  export function emptyComposeState() {
35
39
  return { skills: [], templates: [], warnings: [], session: undefined };
@@ -83,6 +87,11 @@ function contextFiles(record) {
83
87
  }
84
88
  function systemInput(record, active) {
85
89
  const system = { contextFiles: contextFiles(record) };
90
+ const override = record.assembly.overrides?.systemPrompt;
91
+ if (override?.mode === "replace")
92
+ system.preamble = override.text;
93
+ else if (override !== undefined)
94
+ system.extraRules = [override.text];
86
95
  const index = formatSkillIndex(record.state.skills, {
87
96
  hasSkillTool: false,
88
97
  hasReadTool: active.includes("read"),
@@ -145,6 +154,20 @@ export function cacheSettingsFrom(config, env = process.env, warn = () => undefi
145
154
  }
146
155
  return settings;
147
156
  }
157
+ /**
158
+ * 模型请求的空闲超时:`AMA_IDLE_TIMEOUT_MS` > config `request.idleTimeoutMs`;都没有 → undefined
159
+ * (协议层取缺省 300 000)。0 关闭;非法的环境变量值忽略并 warning。
160
+ */
161
+ export function idleTimeoutFrom(config, env = process.env, warn = () => undefined) {
162
+ const raw = env["AMA_IDLE_TIMEOUT_MS"];
163
+ if (raw !== undefined && raw.trim() !== "") {
164
+ const value = Number(raw);
165
+ if (Number.isFinite(value) && value >= 0)
166
+ return value;
167
+ warn(`AMA_IDLE_TIMEOUT_MS=${raw} 无效(应为不小于 0 的毫秒数),已忽略`);
168
+ }
169
+ return config.request?.idleTimeoutMs;
170
+ }
148
171
  /** §1.4:SessionEvent → AgentEvents。 */
149
172
  export function bridgeEvent(event, bus) {
150
173
  switch (event.type) {
@@ -206,6 +229,27 @@ export function bridgeEvent(event, bus) {
206
229
  void bus.emit("context_pressure", pressure);
207
230
  return;
208
231
  }
232
+ // [W5-C0] 子 Agent 与计划事件
233
+ case "subagent_start": {
234
+ const { type: _type, ...payload } = event;
235
+ void bus.emit("subagent_start", payload);
236
+ return;
237
+ }
238
+ case "subagent_end": {
239
+ const { type: _type, ...payload } = event;
240
+ void bus.emit("subagent_end", payload);
241
+ return;
242
+ }
243
+ case "plan_proposed": {
244
+ const { type: _type, ...payload } = event;
245
+ void bus.emit("plan_proposed", payload);
246
+ return;
247
+ }
248
+ case "plan_resolved": {
249
+ const { type: _type, ...payload } = event;
250
+ void bus.emit("plan_resolved", payload);
251
+ return;
252
+ }
209
253
  default:
210
254
  return;
211
255
  }
@@ -237,17 +281,44 @@ function buildSession(record, manager, model, thinkingLevel) {
237
281
  retry: { ...config.retry },
238
282
  expandPrompt: (text) => expandPrompt(record, session, text),
239
283
  isContextOverflow: isOverflowErrorText,
240
- subagents: registry.get("task") === undefined ? false : { maxConcurrent: 4 },
284
+ subagents: registry.get("task") === undefined
285
+ ? false
286
+ : { maxConcurrent: config.subagents?.maxConcurrent ?? DEFAULT_SUBAGENT_CONCURRENCY },
241
287
  log: record.log,
242
288
  cache: cacheSettingsFrom(config, process.env, (message) => record.log("warn", message)),
243
289
  warmingDecider: () => assembly.host.warmingDecider?.(),
290
+ // [W5-C0] 会话扩展(组装表在 compose-extensions.ts)
291
+ extensions: composeExtensions({ assembly, env: process.env, log: record.log }),
244
292
  };
293
+ // [W5-H2] 预算:--max-turns / --max-cost 覆盖 config limits.*,由 limits 扩展执行(agent/limits.ts)
294
+ const limits = resolveLimits(config.limits, {
295
+ maxTurns: assembly.overrides?.maxTurns,
296
+ maxCostUsd: assembly.overrides?.maxCostUsd,
297
+ });
298
+ if (limits !== undefined)
299
+ options.limits = limits;
300
+ if (config.fallbackModel !== undefined)
301
+ options.fallbackModel = config.fallbackModel;
302
+ const idle = idleTimeoutFrom(config, process.env, (message) => record.log("warn", message));
303
+ if (idle !== undefined)
304
+ options.idleTimeoutMs = idle;
305
+ const autoModel = config.permission?.autoModel;
306
+ if (autoModel !== undefined)
307
+ options.permissionClassifier = { model: autoModel };
245
308
  const maxChars = config.tools?.maxToolResultChars;
246
309
  if (maxChars !== undefined)
247
310
  options.maxToolResultChars = maxChars;
248
311
  const hostId = assembly.host.handle?.adapter.id;
249
312
  if (hostId !== undefined)
250
313
  options.hostId = hostId;
314
+ // [RW-B] 回滚:中断即撤回与检查点后端(内存会话不调工厂;mode off 时工厂返回 undefined)
315
+ if (config.ui?.restoreOnCancel === false)
316
+ options.restoreOnCancel = false;
317
+ options.checkpoints = createCheckpointBackendFactory({
318
+ ...resolveCheckpointSettings(config, process.env, (message) => record.log("warn", message)),
319
+ dataDir: assembly.paths.dataDir,
320
+ sessionsRoot: assembly.paths.sessionDir,
321
+ });
251
322
  session = new AgentSessionImpl(options);
252
323
  session.subscribe((event) => bridgeEvent(event, assembly.events));
253
324
  records.set(session, record);
@@ -329,7 +400,10 @@ export async function switchSession(target, request) {
329
400
  let source;
330
401
  switch (request.kind) {
331
402
  case "new":
332
- manager = SessionManager.create(sessionDirForCwd(sessionDir, old.cwd), old.cwd);
403
+ manager =
404
+ assembly.overrides?.noSession === true
405
+ ? SessionManager.inMemory(old.cwd)
406
+ : SessionManager.create(sessionDirForCwd(sessionDir, old.cwd), old.cwd);
333
407
  source = "new";
334
408
  break;
335
409
  case "open":
@@ -2,7 +2,7 @@
2
2
  * 组装根:会话存储(实施计划 §1.1 `sessions.*`)。[B6]
3
3
  *
4
4
  * 会话根目录 `sessionDir` 下按 cwd 分子目录(`sessionDirForCwd`)。
5
- * - `new` → 延迟落盘新建;`continue` → 本目录最近一条(没有则新建);
5
+ * - `new` → 延迟落盘新建;`memory`(`--no-session`)→ 内存会话,从不落盘;`continue` → 本目录最近一条(没有则新建);
6
6
  * - `resume{id}` / `fork{id}`:先在本目录、再在全部子目录里按 id 或唯一前缀找文件;找不到 →
7
7
  * `session_not_found`,前缀不唯一 → `invalid_arguments` 并列出候选;
8
8
  * - `session-id{id}`:找到则打开,否则以该 id 新建;
@@ -2,7 +2,7 @@
2
2
  * 组装根:会话存储(实施计划 §1.1 `sessions.*`)。[B6]
3
3
  *
4
4
  * 会话根目录 `sessionDir` 下按 cwd 分子目录(`sessionDirForCwd`)。
5
- * - `new` → 延迟落盘新建;`continue` → 本目录最近一条(没有则新建);
5
+ * - `new` → 延迟落盘新建;`memory`(`--no-session`)→ 内存会话,从不落盘;`continue` → 本目录最近一条(没有则新建);
6
6
  * - `resume{id}` / `fork{id}`:先在本目录、再在全部子目录里按 id 或唯一前缀找文件;找不到 →
7
7
  * `session_not_found`,前缀不唯一 → `invalid_arguments` 并列出候选;
8
8
  * - `session-id{id}`:找到则打开,否则以该 id 新建;
@@ -67,6 +67,8 @@ export function openSession(request, context) {
67
67
  switch (request.kind) {
68
68
  case "new":
69
69
  return SessionManager.create(dir, cwd);
70
+ case "memory":
71
+ return SessionManager.inMemory(cwd);
70
72
  case "continue":
71
73
  return SessionManager.continueRecent(dir, cwd);
72
74
  case "resume":
@@ -27,6 +27,8 @@ import type { ModelRef, ProviderData } from "../ai/types.js";
27
27
  import type { AgentSession } from "../agent/types.js";
28
28
  import type { AmaConfig } from "../config/types.js";
29
29
  import type { Rule } from "../permissions/types.js";
30
+ import { type SandboxCapability } from "../codemode/capability.js";
31
+ import { type BashSandbox } from "../sandbox/bash.js";
30
32
  import { PresetToolRegistry } from "../tools/presets.js";
31
33
  import type { ToolDefinition, ToolRegistryApi } from "../tools/types.js";
32
34
  import { type ComposeState, type LogFn } from "./compose-session.js";
@@ -46,7 +48,7 @@ export interface ToolFactoryContext {
46
48
  }
47
49
  /** 返回 undefined = 本次不注册(例如配置关闭)。 */
48
50
  export type ToolFactory = (ctx: ToolFactoryContext) => ToolDefinition | undefined;
49
- /** 缺省工具工厂:codemode(`codemode.mode` 生效值为 off 时不注册)。 */
51
+ /** 缺省工具工厂:codemode(生效模式为 off 时不注册;缺省跟随预设,见 tools/presets.ts)。 */
50
52
  export declare const DEFAULT_TOOL_FACTORIES: readonly ToolFactory[];
51
53
  export interface ComposeOptions {
52
54
  /** 追加 / 覆盖供应商(SDK)。 */
@@ -56,6 +58,13 @@ export interface ComposeOptions {
56
58
  extraTools?: ToolDefinition[];
57
59
  /** 缺省 DEFAULT_TOOL_FACTORIES。 */
58
60
  toolFactories?: readonly ToolFactory[];
61
+ /**
62
+ * 沙箱能力(缺省按运行时 Node 探测)。决定 default 预设是否开 codemode;给了且没给
63
+ * `toolFactories` 时 codemode 工厂也用它(测试据此不随 Node 版本变化)。
64
+ */
65
+ sandboxCapability?: SandboxCapability;
66
+ /** [S2] bash 的 OS 沙箱设定(缺省按 `sandbox.*` 配置与本机探测;测试注入)。 */
67
+ bashSandbox?: BashSandbox;
59
68
  /** 覆盖启动期问答;缺省见 `defaultStartupUi`。 */
60
69
  ui?: InteractiveUi;
61
70
  modes?: Partial<Record<RuntimeMode, ModeRunner>>;
@@ -73,14 +82,18 @@ export declare const DEFAULT_MODES: Readonly<Partial<Record<RuntimeMode, ModeRun
73
82
  /**
74
83
  * 第 12 步:内置工具 + 工厂 + extraTools,按预设定活动集;warning 留给组装会话时报告。
75
84
  *
76
- * 先跑工厂(产物暂不注册)再解析预设:codemode 是否可用决定预设与模式;`on` 模式下注册时给
77
- * 其它工具的描述追加 codemode 提示,`only` 模式活动集独占(codemode/modes.ts)。工厂拿到的
78
- * `registry` 在执行期才读,此时已登记完全部工具。
85
+ * 先跑工厂(产物暂不注册)再解析预设:codemode 是否可用决定预设与模式;`only` 模式活动集独占
86
+ * (codemode/modes.ts)。工厂拿到的 `registry` 在执行期才读,此时已登记完全部工具。default 预设
87
+ * 跟随预设而 codemode 缺省关闭时(非 strict 运行时)提示一次(cli/codemode-notice.ts)。
79
88
  */
80
89
  export declare function createTools(input: {
81
90
  config: AmaConfig;
82
91
  cwd: string;
83
92
  mode: RuntimeMode;
93
+ paths?: {
94
+ configDir: string;
95
+ dataDir: string;
96
+ } | undefined;
84
97
  }, options: ComposeOptions, state: ComposeState): PresetToolRegistry;
85
98
  /** 当前模型是否收图片(read 工具用);查不到模型时按收(交给协议层过滤)。 */
86
99
  export declare function modelAcceptsImages(state: ComposeState, model: ModelRef | undefined): boolean;
@@ -25,17 +25,25 @@
25
25
  import { formatModelRef } from "../ai/providers/channels.js";
26
26
  import { PermissionPipeline } from "../permissions/pipeline.js";
27
27
  import { BUILTIN_DENY_RULES, parseRule } from "../permissions/rules.js";
28
+ import { withBuiltinSkills } from "../skills/builtin.js";
28
29
  import { discoverSkills, skillSources } from "../skills/discover.js";
29
30
  import { discoverPromptTemplates, promptSources } from "../skills/templates.js";
30
- import { applyCodemodeMode, decorateForMode } from "../codemode/modes.js";
31
+ import { applyCodemodeMode } from "../codemode/modes.js";
32
+ import { sandboxCapabilityFor } from "../codemode/capability.js";
31
33
  import { codemodeToolFactory } from "../codemode/tool.js";
34
+ import { configureOsSandbox } from "../sandbox/detect.js";
35
+ import { resolveBashSandbox } from "../sandbox/bash.js";
36
+ import { join } from "node:path";
37
+ import { AUTH_FILE } from "../config/paths.js";
32
38
  import { PresetToolRegistry, resolvePreset } from "../tools/presets.js";
33
39
  import { builtinTools } from "../tools/registry.js";
40
+ import { takeCodemodeNotice } from "./codemode-notice.js";
34
41
  import { buildProviderRegistry } from "./compose-providers.js";
35
42
  import { composeSession, emptyComposeState, } from "./compose-session.js";
36
43
  import { createSessionStore } from "./compose-store.js";
37
44
  import { defaultSendUser } from "./startup-steps.js";
38
- /** 缺省工具工厂:codemode(`codemode.mode` 生效值为 off 时不注册)。 */
45
+ import { imageFitOptionsFor } from "../modes/image-input.js";
46
+ /** 缺省工具工厂:codemode(生效模式为 off 时不注册;缺省跟随预设,见 tools/presets.ts)。 */
39
47
  export const DEFAULT_TOOL_FACTORIES = [codemodeToolFactory()];
40
48
  export function lazyMode(load) {
41
49
  return async (runtime, context) => (await load())(runtime, context);
@@ -50,18 +58,38 @@ export const DEFAULT_MODES = {
50
58
  /**
51
59
  * 第 12 步:内置工具 + 工厂 + extraTools,按预设定活动集;warning 留给组装会话时报告。
52
60
  *
53
- * 先跑工厂(产物暂不注册)再解析预设:codemode 是否可用决定预设与模式;`on` 模式下注册时给
54
- * 其它工具的描述追加 codemode 提示,`only` 模式活动集独占(codemode/modes.ts)。工厂拿到的
55
- * `registry` 在执行期才读,此时已登记完全部工具。
61
+ * 先跑工厂(产物暂不注册)再解析预设:codemode 是否可用决定预设与模式;`only` 模式活动集独占
62
+ * (codemode/modes.ts)。工厂拿到的 `registry` 在执行期才读,此时已登记完全部工具。default 预设
63
+ * 跟随预设而 codemode 缺省关闭时(非 strict 运行时)提示一次(cli/codemode-notice.ts)。
56
64
  */
57
65
  export function createTools(input, options, state) {
58
66
  const registry = new PresetToolRegistry();
59
- const bash = input.config.tools?.bashTimeoutMs !== undefined
60
- ? { defaultTimeoutMs: input.config.tools.bashTimeoutMs }
61
- : {};
67
+ // 记下 sandbox.enabled:拿不到配置的只读调用方(状态栏)与这里得到同一结论。
68
+ const osStatus = configureOsSandbox(input.config.sandbox?.enabled);
69
+ // [S2] bash 沙箱:工具与权限管线用同一份设定(tools.create 先于 permissions.create)
70
+ const bashSandbox = options.bashSandbox ??
71
+ resolveBashSandbox(input.config.sandbox, {
72
+ status: osStatus,
73
+ ...(input.paths === undefined ? {} : { hidden: [join(input.paths.configDir, AUTH_FILE)] }),
74
+ });
75
+ state.bashSandbox = bashSandbox;
76
+ const capability = options.sandboxCapability ?? sandboxCapabilityFor(input.config);
77
+ const factories = options.toolFactories ??
78
+ (options.sandboxCapability !== undefined
79
+ ? [codemodeToolFactory({ capability })]
80
+ : DEFAULT_TOOL_FACTORIES);
81
+ const bash = {
82
+ ...(input.config.tools?.bashTimeoutMs !== undefined
83
+ ? { defaultTimeoutMs: input.config.tools.bashTimeoutMs }
84
+ : {}),
85
+ ...(bashSandbox.active ? { sandbox: bashSandbox } : {}),
86
+ };
62
87
  const builtins = builtinTools({
63
88
  bash,
64
- read: { supportsImages: (ctx) => modelAcceptsImages(state, ctx.model) },
89
+ read: {
90
+ supportsImages: (ctx) => modelAcceptsImages(state, ctx.model),
91
+ imageOptions: (ctx) => imageFitOptionsFor(state.providers, ctx.model, input.config.images),
92
+ },
65
93
  });
66
94
  const ctx = {
67
95
  ...input,
@@ -70,7 +98,7 @@ export function createTools(input, options, state) {
70
98
  warn: (message) => state.warnings.push(message),
71
99
  };
72
100
  const produced = [];
73
- for (const factory of options.toolFactories ?? DEFAULT_TOOL_FACTORIES) {
101
+ for (const factory of factories) {
74
102
  try {
75
103
  const tool = factory(ctx);
76
104
  if (tool !== undefined)
@@ -82,20 +110,29 @@ export function createTools(input, options, state) {
82
110
  }
83
111
  const extra = options.extraTools ?? [];
84
112
  const names = new Set([...builtins, ...produced, ...extra].map((tool) => tool.name));
85
- const preset = resolvePreset({ config: input.config, available: (name) => names.has(name) });
86
- const decorate = decorateForMode(preset.codemode);
113
+ const preset = resolvePreset({
114
+ config: input.config,
115
+ available: (name) => names.has(name),
116
+ strict: capability.strict,
117
+ });
87
118
  for (const tool of [...builtins, ...produced]) {
88
119
  try {
89
- registry.register(decorate(tool), "builtin");
120
+ registry.register(tool, "builtin");
90
121
  }
91
122
  catch (error) {
92
123
  state.warnings.push(`工具 ${tool.name} 注册失败:${error.message}`);
93
124
  }
94
125
  }
95
126
  for (const tool of extra)
96
- registry.register(decorate(tool), "sdk");
127
+ registry.register(tool, "sdk");
97
128
  applyCodemodeMode(registry, preset);
98
129
  state.warnings.push(...preset.warnings);
130
+ // 一次性提示只给有人看的界面(交互 / 行式);-p 与 RPC 的 stderr 常被脚本解析,不打扰。
131
+ if (input.paths !== undefined && (input.mode === "interactive" || input.mode === "line")) {
132
+ const notice = takeCodemodeNotice({ config: input.config, capability, ...input.paths });
133
+ if (notice !== undefined)
134
+ state.warnings.push(notice);
135
+ }
99
136
  return registry;
100
137
  }
101
138
  /** 当前模型是否收图片(read 工具用);查不到模型时按收(交给协议层过滤)。 */
@@ -173,6 +210,10 @@ export function createRuntimeDeps(options = {}) {
173
210
  mode: input.mode,
174
211
  rules: buildRules(input.rules, input.builtinDeny, (m) => state.warnings.push(m)),
175
212
  cwd: input.cwd,
213
+ ...(input.autoSafeCommands !== undefined
214
+ ? { autoSafeCommands: input.autoSafeCommands }
215
+ : {}),
216
+ ...(state.bashSandbox?.active === true ? { bashSandbox: state.bashSandbox } : {}),
176
217
  }),
177
218
  },
178
219
  resources: {
@@ -182,6 +223,11 @@ export function createRuntimeDeps(options = {}) {
182
223
  configDir: input.configDir,
183
224
  cliDirs: input.extraSkillDirs,
184
225
  }), { trusted: input.trusted });
226
+ if (input.dataDir !== undefined) {
227
+ const builtin = await withBuiltinSkills(skills.skills, input.dataDir);
228
+ skills.skills = builtin.skills;
229
+ skills.warnings.push(...builtin.warnings);
230
+ }
185
231
  const prompts = await discoverPromptTemplates(promptSources({
186
232
  cwd: input.cwd,
187
233
  configDir: input.configDir,
@@ -1,16 +1,53 @@
1
1
  /**
2
2
  * 零配置选模型(设计 §10.0、§11.1 第 11 步):没有 `--model`、续会话的 model_change 与
3
- * `config.defaultModel` 时,按内置供应商顺序(§3.3)选第一个**可用**供应商的缺省模型(目录首条)。
3
+ * `config.defaultModel` 时,按供应商顺序(内置 §3.3 在前,config 里的自定义供应商在后)选第一个
4
+ * **可用**供应商,再在它的模型里挑一个:
5
+ *
6
+ * - 内置供应商:目录首条(目录按推荐顺序整理过);
7
+ * - 自定义供应商(中转站,模型表是上游 /v1/models 的顺序):按 `pickByPrice` 的规则挑——
8
+ * models.dev 有价格(输入价 > 0)且支持工具调用、上下文 ≥ 64k 的模型里输入价最低的;同价取上下文
9
+ * 大的,再同取列表靠前的。没有满足条件的才退回列表首条。`ama providers add` 写 defaultModel 用同一规则。
4
10
  *
5
11
  * 可用 = 有 key(`requiresApiKey`)或本地服务已探测到模型(ollama / lmstudio,组装根在
6
12
  * 无 key 时探测)。跳过 `fake`(测试供应商只能显式 `--model fake/…`)与协议尚未实现的供应商。
7
13
  */
8
14
  import type { Model, ProviderData, ProviderRegistryApi } from "../ai/types.js";
15
+ /** 缺省模型的最小上下文(token)。 */
16
+ export declare const MIN_DEFAULT_CONTEXT = 64000;
17
+ export interface PriceCandidate {
18
+ id: string;
19
+ contextWindow?: number | undefined;
20
+ /** $/M 输入 token。 */
21
+ inputCost?: number | undefined;
22
+ /** models.dev 的 tool_call。 */
23
+ toolCall?: boolean | undefined;
24
+ }
25
+ export interface PricePick {
26
+ id: string;
27
+ /** 为什么选它(一句话)。 */
28
+ reason: string;
29
+ }
30
+ /** 规则说明(帮助与输出共用)。 */
31
+ export declare const PRICE_RULE = "\u652F\u6301\u5DE5\u5177\u8C03\u7528\u3001\u4E0A\u4E0B\u6587 \u2265 64k \u4E14\u6709\u4EF7\u683C\u7684\u6A21\u578B\u91CC\u8F93\u5165\u4EF7\u6700\u4F4E";
32
+ /** 按价格挑缺省模型;没有满足条件的返回 undefined(规则见文件头)。 */
33
+ export declare function pickByPrice(candidates: readonly PriceCandidate[]): PricePick | undefined;
9
34
  export interface DefaultModelChoice {
10
35
  model: Model;
11
36
  provider: ProviderData;
12
37
  /** 选中原因:`key`(有 key,来源见 keySource)或 `local`(本地服务)。 */
13
38
  via: "key" | "local";
14
39
  keySource?: string;
40
+ /** 为什么是这个模型(内置目录首条 / 价格规则 / 列表首条)。 */
41
+ rule: string;
15
42
  }
43
+ /** 供应商内挑模型:内置取目录首条;自定义按价格规则,挑不出再取首条。 */
44
+ export declare function pickProviderModel(registry: ProviderRegistryApi, provider: ProviderData): {
45
+ model: Model;
46
+ rule: string;
47
+ } | undefined;
16
48
  export declare function pickDefaultModel(registry: ProviderRegistryApi): Promise<DefaultModelChoice | undefined>;
49
+ /**
50
+ * 没有可用模型时的引导(一行,选择器的说明行与报错共用):列出前几个内置供应商的 key 环境变量,
51
+ * 以及 `ama auth set` / `ama providers add`。
52
+ */
53
+ export declare function noModelGuidance(registry: Pick<ProviderRegistryApi, "list">): string;
@@ -1,24 +1,111 @@
1
1
  /**
2
2
  * 零配置选模型(设计 §10.0、§11.1 第 11 步):没有 `--model`、续会话的 model_change 与
3
- * `config.defaultModel` 时,按内置供应商顺序(§3.3)选第一个**可用**供应商的缺省模型(目录首条)。
3
+ * `config.defaultModel` 时,按供应商顺序(内置 §3.3 在前,config 里的自定义供应商在后)选第一个
4
+ * **可用**供应商,再在它的模型里挑一个:
5
+ *
6
+ * - 内置供应商:目录首条(目录按推荐顺序整理过);
7
+ * - 自定义供应商(中转站,模型表是上游 /v1/models 的顺序):按 `pickByPrice` 的规则挑——
8
+ * models.dev 有价格(输入价 > 0)且支持工具调用、上下文 ≥ 64k 的模型里输入价最低的;同价取上下文
9
+ * 大的,再同取列表靠前的。没有满足条件的才退回列表首条。`ama providers add` 写 defaultModel 用同一规则。
4
10
  *
5
11
  * 可用 = 有 key(`requiresApiKey`)或本地服务已探测到模型(ollama / lmstudio,组装根在
6
12
  * 无 key 时探测)。跳过 `fake`(测试供应商只能显式 `--model fake/…`)与协议尚未实现的供应商。
7
13
  */
14
+ import { compactTokens, metadataOf } from "./subcommands/model-meta.js";
15
+ /** 缺省模型的最小上下文(token)。 */
16
+ export const MIN_DEFAULT_CONTEXT = 64_000;
17
+ /** 规则说明(帮助与输出共用)。 */
18
+ export const PRICE_RULE = "支持工具调用、上下文 ≥ 64k 且有价格的模型里输入价最低";
19
+ /** 按价格挑缺省模型;没有满足条件的返回 undefined(规则见文件头)。 */
20
+ export function pickByPrice(candidates) {
21
+ let best;
22
+ candidates.forEach((c, index) => {
23
+ if (c.toolCall !== true)
24
+ return;
25
+ if (c.inputCost === undefined || !(c.inputCost > 0))
26
+ return;
27
+ if ((c.contextWindow ?? 0) < MIN_DEFAULT_CONTEXT)
28
+ return;
29
+ if (best === undefined) {
30
+ best = { c, index };
31
+ return;
32
+ }
33
+ const a = best.c;
34
+ const cheaper = c.inputCost < a.inputCost;
35
+ const same = c.inputCost === a.inputCost;
36
+ if (cheaper || (same && (c.contextWindow ?? 0) > (a.contextWindow ?? 0)))
37
+ best = { c, index };
38
+ });
39
+ if (best === undefined)
40
+ return undefined;
41
+ const { c } = best;
42
+ return {
43
+ id: c.id,
44
+ reason: `${PRICE_RULE}($${c.inputCost}/M 输入,上下文 ${compactTokens(c.contextWindow)})`,
45
+ };
46
+ }
47
+ /** 供应商内挑模型:内置取目录首条;自定义按价格规则,挑不出再取首条。 */
48
+ export function pickProviderModel(registry, provider) {
49
+ const usable = provider.models.filter((m) => registry.getApi(m.api) !== undefined);
50
+ const first = usable[0];
51
+ if (first === undefined)
52
+ return undefined;
53
+ if (provider.builtin)
54
+ return { model: first, rule: "内置目录推荐的首个模型" };
55
+ const picked = pickByPrice(usable.map((m) => ({
56
+ id: m.id,
57
+ contextWindow: m.contextWindow,
58
+ inputCost: m.cost?.input,
59
+ toolCall: metadataOf(registry, provider.id, m.id)?.toolCall,
60
+ })));
61
+ const model = picked === undefined ? undefined : usable.find((m) => m.id === picked.id);
62
+ if (picked !== undefined && model !== undefined)
63
+ return { model, rule: picked.reason };
64
+ return {
65
+ model: first,
66
+ rule: "列表首个模型(没有同时支持工具调用、上下文 ≥ 64k 且有价格的模型)",
67
+ };
68
+ }
8
69
  export async function pickDefaultModel(registry) {
9
70
  for (const provider of registry.list()) {
10
71
  if (provider.id === "fake" && !provider.requiresApiKey)
11
72
  continue;
12
- const model = provider.models[0];
13
- if (model === undefined)
73
+ const head = provider.models[0];
74
+ if (head === undefined)
75
+ continue;
76
+ if (registry.getApi(head.api) === undefined)
14
77
  continue;
15
- if (registry.getApi(model.api) === undefined)
78
+ let via = "local";
79
+ let keySource;
80
+ if (provider.requiresApiKey) {
81
+ const key = await registry.resolveApiKey(provider.id);
82
+ if (key.apiKey === undefined)
83
+ continue;
84
+ via = "key";
85
+ keySource = key.source;
86
+ }
87
+ const picked = pickProviderModel(registry, provider);
88
+ if (picked === undefined)
16
89
  continue;
17
- if (!provider.requiresApiKey)
18
- return { model, provider, via: "local" };
19
- const key = await registry.resolveApiKey(provider.id);
20
- if (key.apiKey !== undefined)
21
- return { model, provider, via: "key", keySource: key.source };
90
+ const choice = { model: picked.model, provider, via, rule: picked.rule };
91
+ if (keySource !== undefined)
92
+ choice.keySource = keySource;
93
+ return choice;
22
94
  }
23
95
  return undefined;
24
96
  }
97
+ /**
98
+ * 没有可用模型时的引导(一行,选择器的说明行与报错共用):列出前几个内置供应商的 key 环境变量,
99
+ * 以及 `ama auth set` / `ama providers add`。
100
+ */
101
+ export function noModelGuidance(registry) {
102
+ const envs = registry
103
+ .list()
104
+ .filter((p) => p.builtin && p.requiresApiKey && p.id !== "fake")
105
+ .map((p) => p.envKeys[0])
106
+ .filter((name) => name !== undefined);
107
+ const shown = envs.slice(0, 3).join(" / ");
108
+ const more = envs.length > 3 ? " 等" : "";
109
+ return (`没有可用模型:设置 ${shown}${more}环境变量,或 \`ama auth set <provider>\` 保存 key,` +
110
+ "或 `ama providers add <id> --base-url <url>` 接入中转站(也可 --model 指定)");
111
+ }
@@ -37,6 +37,10 @@ export type SessionRequest = {
37
37
  } | {
38
38
  kind: "fork";
39
39
  id: string;
40
+ }
41
+ /** `--no-session`:内存会话,从不落盘。 */
42
+ | {
43
+ kind: "memory";
40
44
  };
41
45
  export interface ProviderBuildInput {
42
46
  config: AmaConfig;
@@ -61,6 +65,8 @@ export interface ResourceDiscoveryInput {
61
65
  /** 按 §5.3 顺序:`--skill-dir` → profile.skillDirs → config.skills.dirs。 */
62
66
  extraSkillDirs: readonly string[];
63
67
  promptDirs: readonly string[];
68
+ /** 数据目录:内置 Skill 的正文写在 `<dataDir>/builtin/`;缺省不加内置 Skill。 */
69
+ dataDir?: string;
64
70
  }
65
71
  export interface ResourceDiscoveryResult {
66
72
  skills: LoadedResources["skills"];
@@ -107,8 +113,26 @@ export interface SessionAssembly {
107
113
  sessionStartContext(): string | undefined;
108
114
  /** print:ask → deny。 */
109
115
  unattended: boolean;
116
+ /** 命令行对会话的覆盖(W4-C):`-p --max-turns`、`--system-prompt`、`--no-session`。 */
117
+ overrides?: SessionOverrides;
110
118
  warn(message: string): void;
111
119
  }
120
+ export interface SessionOverrides {
121
+ /** 一次运行(prompt)的回合上限。 */
122
+ maxTurns?: number;
123
+ /** [W5-C0] `--max-cost`:并入会话 `limits.maxCostUsd`(W5-H2 实现)。 */
124
+ maxCostUsd?: number;
125
+ /** `--system-prompt`:追加进 rules 节,或替换 preamble。 */
126
+ systemPrompt?: SystemPromptOverride;
127
+ /** `--no-session`:`/new` 等切换出的新会话也只在内存里。 */
128
+ noSession?: boolean;
129
+ /** [W5-G] `--agent-dir`(可重复)与 profile `agentDirs`,按此顺序:子 Agent 定义目录。 */
130
+ agentDirs?: string[];
131
+ }
132
+ export interface SystemPromptOverride {
133
+ text: string;
134
+ mode: "append" | "replace";
135
+ }
112
136
  export interface ModeContext {
113
137
  args: ParsedArgs;
114
138
  /** 位置参数拼成的首条提示。 */
@@ -166,6 +190,11 @@ export interface RuntimeDeps {
166
190
  config: AmaConfig;
167
191
  cwd: string;
168
192
  mode: RuntimeMode;
193
+ /** CLI 启动时给出(一次性提示记在数据目录);SDK 不给。 */
194
+ paths?: {
195
+ configDir: string;
196
+ dataDir: string;
197
+ };
169
198
  }): ToolRegistryApi;
170
199
  };
171
200
  /** B3:权限管线。 */
@@ -178,6 +207,8 @@ export interface RuntimeDeps {
178
207
  cwd: string;
179
208
  /** config `permission.builtinDeny`(只来自用户级 / profile);缺省 = 启用全部内置 deny。 */
180
209
  builtinDeny?: boolean | string[];
210
+ /** config `permission.autoSafeCommands`(auto 模式安全名单追加)。 */
211
+ autoSafeCommands?: string[];
181
212
  }): PermissionPipelineApi;
182
213
  };
183
214
  /** B3:skills / prompts 发现;缺省为空。 */
@@ -204,4 +235,15 @@ export interface CliIo {
204
235
  cwd: string;
205
236
  /** 读取 stdin 全部内容(auth set)。 */
206
237
  readStdin(): Promise<string>;
238
+ /**
239
+ * 等首字节至多 `timeoutMs`:期间没有任何字节 → undefined(停止读取,不再占着 stdin);收到首字节
240
+ * 后读到 EOF(不再超时);期间就 EOF → 已读到的内容。缺省实现见 cli/main.ts。
241
+ */
242
+ readStdinFirstByte?(timeoutMs: number): Promise<string | undefined>;
243
+ /**
244
+ * stdin 的类型(`-p` 据此决定读不读):`file` / `null`(/dev/null 等字符设备)读了不会卡;
245
+ * `fifo` 是 shell 管道;`socket` 多为父进程 spawn 时留的管道。未提供时按 `other` 处理(不读、不提示)。
246
+ */
247
+ stdinKind?(): StdinKind;
207
248
  }
249
+ export type StdinKind = "tty" | "file" | "null" | "fifo" | "socket" | "other";