@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
@@ -0,0 +1,149 @@
1
+ /**
2
+ * 操作系统沙箱能力探测(docs/sandbox.md「探测与降级」)。
3
+ *
4
+ * - 「存在」不等于「可用」(嵌套在别的沙箱里、容器里没有用户命名空间):用目标配置跑一次最小探针,退出码 0
5
+ * 才算可用;
6
+ * - macOS:`/usr/bin/sandbox-exec`;Linux:PATH 里的 `bwrap`,失败再试 `unshare -r -n`(只隔离网络);
7
+ * 其它平台:none;
8
+ * - 开关:`sandbox.enabled: off` 或环境变量 `AMA_SANDBOX=off`;
9
+ * - 结果在进程内缓存(按开关分两份);`configureOsSandbox` 记下组装根读到的配置,供拿不到配置的只读调用方
10
+ * (状态栏)得到一致的结论。
11
+ */
12
+ import { spawnSync } from "node:child_process";
13
+ import { accessSync, constants } from "node:fs";
14
+ import { posix, win32 } from "node:path";
15
+ import { buildBwrapArgs, buildSbplProfile, buildUnshareArgs, } from "./profile.js";
16
+ export const NO_OS_SANDBOX = Object.freeze({
17
+ kind: "none",
18
+ isolatesNetwork: false,
19
+ restrictsWrites: false,
20
+ detail: "没有可用的操作系统沙箱",
21
+ });
22
+ export const SANDBOX_EXEC_PATH = "/usr/bin/sandbox-exec";
23
+ export const PROBE_TIMEOUT_MS = 5000;
24
+ /** 探针用的策略:拒绝网络、不可写——与 codemode 实际使用的最严配置相同。 */
25
+ const PROBE_POLICY = { network: "deny", writable: [] };
26
+ function isExecutable(path) {
27
+ try {
28
+ accessSync(path, constants.X_OK);
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ export const REAL_PROBE_DEPS = {
36
+ platform: process.platform,
37
+ env: process.env,
38
+ isExecutable,
39
+ run(command, args) {
40
+ const result = spawnSync(command, args, {
41
+ stdio: "ignore",
42
+ timeout: PROBE_TIMEOUT_MS,
43
+ env: { PATH: process.env["PATH"] ?? "/usr/bin:/bin" },
44
+ });
45
+ return result.error !== undefined ? null : result.status;
46
+ },
47
+ };
48
+ /** 在 PATH 里找可执行文件(按目标平台的路径规则)。 */
49
+ export function findExecutable(name, env, check, platform = process.platform) {
50
+ const path = platform === "win32" ? win32 : posix;
51
+ for (const dir of (env["PATH"] ?? "").split(path.delimiter)) {
52
+ if (dir === "")
53
+ continue;
54
+ const candidate = path.join(dir, name);
55
+ if (check(candidate))
56
+ return candidate;
57
+ }
58
+ return undefined;
59
+ }
60
+ /** 生效的开关:环境变量 `AMA_SANDBOX=off` 优先于配置。 */
61
+ export function resolveSandboxEnabled(configured, env = process.env) {
62
+ const fromEnv = env["AMA_SANDBOX"]?.trim().toLowerCase();
63
+ if (fromEnv === "off" || fromEnv === "0" || fromEnv === "false")
64
+ return "off";
65
+ return configured ?? "auto";
66
+ }
67
+ /** 不缓存的探测(测试注入 deps)。 */
68
+ export function probeOsSandbox(enabled, deps = REAL_PROBE_DEPS) {
69
+ if (enabled === "off")
70
+ return { ...NO_OS_SANDBOX, detail: "已关闭(sandbox.enabled: off 或 AMA_SANDBOX=off)" };
71
+ if (deps.platform === "darwin") {
72
+ if (!deps.isExecutable(SANDBOX_EXEC_PATH))
73
+ return { ...NO_OS_SANDBOX, detail: `没有 ${SANDBOX_EXEC_PATH}` };
74
+ const code = deps.run(SANDBOX_EXEC_PATH, [
75
+ "-p",
76
+ buildSbplProfile(PROBE_POLICY),
77
+ "/usr/bin/true",
78
+ ]);
79
+ if (code === 0)
80
+ return {
81
+ kind: "sandbox-exec",
82
+ path: SANDBOX_EXEC_PATH,
83
+ isolatesNetwork: true,
84
+ restrictsWrites: true,
85
+ detail: "macOS sandbox-exec",
86
+ };
87
+ return {
88
+ ...NO_OS_SANDBOX,
89
+ detail: `sandbox-exec 探针失败(${code === null ? "无法启动" : `退出码 ${code}`};可能已在别的沙箱里)`,
90
+ };
91
+ }
92
+ if (deps.platform === "linux") {
93
+ const failures = [];
94
+ const bwrap = findExecutable("bwrap", deps.env, deps.isExecutable, deps.platform);
95
+ if (bwrap !== undefined) {
96
+ const code = deps.run(bwrap, [...buildBwrapArgs(PROBE_POLICY), "true"]);
97
+ if (code === 0)
98
+ return {
99
+ kind: "bwrap",
100
+ path: bwrap,
101
+ isolatesNetwork: true,
102
+ restrictsWrites: true,
103
+ detail: "Linux bubblewrap",
104
+ };
105
+ failures.push(`bwrap 探针失败(${code === null ? "无法启动" : `退出码 ${code}`})`);
106
+ }
107
+ else
108
+ failures.push("没有 bwrap");
109
+ const unshare = findExecutable("unshare", deps.env, deps.isExecutable, deps.platform);
110
+ if (unshare !== undefined) {
111
+ const code = deps.run(unshare, [...buildUnshareArgs(), "true"]);
112
+ if (code === 0)
113
+ return {
114
+ kind: "unshare",
115
+ path: unshare,
116
+ isolatesNetwork: true,
117
+ restrictsWrites: false,
118
+ detail: `Linux unshare -r -n(只隔离网络;${failures.join(",")})`,
119
+ };
120
+ failures.push(`unshare 探针失败(${code === null ? "无法启动" : `退出码 ${code}`};可能不允许非特权用户命名空间)`);
121
+ }
122
+ else
123
+ failures.push("没有 unshare");
124
+ return { ...NO_OS_SANDBOX, detail: failures.join(",") };
125
+ }
126
+ return { ...NO_OS_SANDBOX, detail: `${deps.platform} 上没有操作系统沙箱实现` };
127
+ }
128
+ const cache = new Map();
129
+ let configured;
130
+ /** 组装根读到配置后记下(拿不到配置的只读调用方据此得到一致结论);返回生效的状态。 */
131
+ export function configureOsSandbox(enabled) {
132
+ configured = enabled;
133
+ return osSandboxStatus(enabled);
134
+ }
135
+ /** 进程内缓存的探测结果;不传开关时用 `configureOsSandbox` 记下的配置(缺省 auto)。 */
136
+ export function osSandboxStatus(enabled = configured) {
137
+ const effective = resolveSandboxEnabled(enabled);
138
+ let status = cache.get(effective);
139
+ if (status === undefined) {
140
+ status = probeOsSandbox(effective);
141
+ cache.set(effective, status);
142
+ }
143
+ return status;
144
+ }
145
+ /** 测试用:清空缓存与记下的配置。 */
146
+ export function resetOsSandboxForTests() {
147
+ cache.clear();
148
+ configured = undefined;
149
+ }
@@ -0,0 +1,5 @@
1
+ /** 操作系统级沙箱(docs/sandbox.md):探测、参数生成与命令包装。 */
2
+ export { NO_OS_SANDBOX, configureOsSandbox, osSandboxStatus, probeOsSandbox, resetOsSandboxForTests, resolveSandboxEnabled, type OsSandboxStatus, type ProbeDeps, type SandboxEnabled, } from "./detect.js";
3
+ export { buildBwrapArgs, buildSbplProfile, buildUnshareArgs, type OsSandboxKind, type OsSandboxPolicy, } from "./profile.js";
4
+ export { resolveExtras, resolveWritable, wrapCommand, type WrappedCommand } from "./wrap.js";
5
+ export { DEFAULT_BASH_SANDBOX_MODE, DEFAULT_SANDBOX_NETWORK, NO_BASH_SANDBOX, bashSandboxPolicy, looksLikeSandboxDenial, resolveBashSandbox, runsSandboxed, sandboxDenialHint, wantsUnsandboxed, wrapBashCommand, type BashCallPlace, type BashSandbox, type BashSandboxConfig, type BashSandboxMode, type SandboxNetwork, } from "./bash.js";
@@ -0,0 +1,5 @@
1
+ /** 操作系统级沙箱(docs/sandbox.md):探测、参数生成与命令包装。 */
2
+ export { NO_OS_SANDBOX, configureOsSandbox, osSandboxStatus, probeOsSandbox, resetOsSandboxForTests, resolveSandboxEnabled, } from "./detect.js";
3
+ export { buildBwrapArgs, buildSbplProfile, buildUnshareArgs, } from "./profile.js";
4
+ export { resolveExtras, resolveWritable, wrapCommand } from "./wrap.js";
5
+ export { DEFAULT_BASH_SANDBOX_MODE, DEFAULT_SANDBOX_NETWORK, NO_BASH_SANDBOX, bashSandboxPolicy, looksLikeSandboxDenial, resolveBashSandbox, runsSandboxed, sandboxDenialHint, wantsUnsandboxed, wrapBashCommand, } from "./bash.js";
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 操作系统沙箱的参数生成(docs/sandbox.md「各平台实现」):纯函数,不探测、不读文件系统。
3
+ *
4
+ * - `buildSbplProfile`:macOS `sandbox-exec -p` 的 SBPL 配置;
5
+ * - `buildBwrapArgs`:Linux bubblewrap 的参数(到 `--` 为止);
6
+ * - `buildUnshareArgs`:Linux `unshare -r -n`(只隔离网络)。
7
+ *
8
+ * 路径由调用方先取 realpath(wrap.ts);这里只做转义与校验。
9
+ */
10
+ export type OsSandboxKind = "sandbox-exec" | "bwrap" | "unshare";
11
+ export interface OsSandboxPolicy {
12
+ /** deny:拒绝一切网络(含 Unix 域套接字与 DNS)。 */
13
+ network: "deny" | "allow";
14
+ /** 允许写入的目录(绝对路径,已 realpath);其余位置一律不可写。 */
15
+ writable: readonly string[];
16
+ /** 可写目录里仍然只读的路径(已 realpath;bash 用:项目 `.ama/`、`.git/hooks`、`.git/config`)。 */
17
+ readOnly?: readonly string[];
18
+ /** 不可读的目录(已 realpath;bash 用:`~/.ssh` 等凭据目录)。 */
19
+ hiddenDirs?: readonly string[];
20
+ /** 不可读的文件(已 realpath;bash 用:`~/.netrc`、ama 的 `auth.json` 等)。 */
21
+ hiddenFiles?: readonly string[];
22
+ }
23
+ /** 沙箱里始终可写的设备文件(stdio 是继承的描述符,不经路径检查)。 */
24
+ export declare const SBPL_DEVICE_WRITES: readonly ["/dev/null", "/dev/zero", "/dev/tty", "/dev/dtracehelper"];
25
+ /** 含控制字符的路径不进配置(SBPL 字符串 / 命令行里都难以安全表达)。 */
26
+ export declare function assertSafePath(path: string): void;
27
+ /** SBPL 字符串字面量:转义反斜杠与双引号。 */
28
+ export declare function sbplString(value: string): string;
29
+ export declare function buildSbplProfile(policy: OsSandboxPolicy): string;
30
+ /** bwrap 参数(不含可执行文件与目标命令):只读根 + 最小 /dev + 可写目录逐个绑回。 */
31
+ export declare function buildBwrapArgs(policy: OsSandboxPolicy): string[];
32
+ /** unshare 参数(不含可执行文件与目标命令):只隔离网络,不限制写入。 */
33
+ export declare function buildUnshareArgs(): string[];
@@ -0,0 +1,76 @@
1
+ /**
2
+ * 操作系统沙箱的参数生成(docs/sandbox.md「各平台实现」):纯函数,不探测、不读文件系统。
3
+ *
4
+ * - `buildSbplProfile`:macOS `sandbox-exec -p` 的 SBPL 配置;
5
+ * - `buildBwrapArgs`:Linux bubblewrap 的参数(到 `--` 为止);
6
+ * - `buildUnshareArgs`:Linux `unshare -r -n`(只隔离网络)。
7
+ *
8
+ * 路径由调用方先取 realpath(wrap.ts);这里只做转义与校验。
9
+ */
10
+ /** 沙箱里始终可写的设备文件(stdio 是继承的描述符,不经路径检查)。 */
11
+ export const SBPL_DEVICE_WRITES = [
12
+ "/dev/null",
13
+ "/dev/zero",
14
+ "/dev/tty",
15
+ "/dev/dtracehelper",
16
+ ];
17
+ /** 含控制字符的路径不进配置(SBPL 字符串 / 命令行里都难以安全表达)。 */
18
+ export function assertSafePath(path) {
19
+ // eslint-disable-next-line no-control-regex
20
+ if (path === "" || /[\u0000-\u001f\u007f]/.test(path))
21
+ throw new Error(`sandbox: unsupported path ${JSON.stringify(path)}`);
22
+ }
23
+ /** SBPL 字符串字面量:转义反斜杠与双引号。 */
24
+ export function sbplString(value) {
25
+ assertSafePath(value);
26
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
27
+ }
28
+ export function buildSbplProfile(policy) {
29
+ const lines = ["(version 1)", "(allow default)"];
30
+ if (policy.network === "deny") {
31
+ lines.push("(deny network*)");
32
+ // DNS 经 mDNSResponder:Unix 套接字已被 network* 拒绝,mach 服务也拒绝,堵住经 DNS 查询外带数据。
33
+ lines.push('(deny mach-lookup (global-name "com.apple.dnssd.service"))');
34
+ }
35
+ lines.push("(deny file-write*)");
36
+ for (const dir of policy.writable)
37
+ lines.push(`(allow file-write* (subpath ${sbplString(dir)}))`);
38
+ const devices = SBPL_DEVICE_WRITES.map((d) => `(literal ${sbplString(d)})`).join(" ");
39
+ lines.push(`(allow file-write* ${devices} (regex #"^/dev/fd/"))`);
40
+ // SBPL 后出现的规则优先:只读与不可读放在最后,覆盖前面的允许。
41
+ for (const path of policy.readOnly ?? [])
42
+ lines.push(`(deny file-write* (subpath ${sbplString(path)}))`);
43
+ for (const path of [...(policy.hiddenDirs ?? []), ...(policy.hiddenFiles ?? [])])
44
+ lines.push(`(deny file-read* file-write* (subpath ${sbplString(path)}))`);
45
+ return lines.join("\n");
46
+ }
47
+ /** bwrap 参数(不含可执行文件与目标命令):只读根 + 最小 /dev + 可写目录逐个绑回。 */
48
+ export function buildBwrapArgs(policy) {
49
+ const args = ["--die-with-parent", "--ro-bind", "/", "/", "--dev", "/dev"];
50
+ if (policy.network === "deny")
51
+ args.push("--unshare-net");
52
+ for (const dir of policy.writable) {
53
+ assertSafePath(dir);
54
+ args.push("--bind", dir, dir);
55
+ }
56
+ // 之后的挂载盖住前面的:只读路径重新只读绑定,不可读目录换成空 tmpfs、文件换成 /dev/null。
57
+ // bwrap 只能挂到已存在的路径上,调用方只传存在的。
58
+ for (const path of policy.readOnly ?? []) {
59
+ assertSafePath(path);
60
+ args.push("--ro-bind", path, path);
61
+ }
62
+ for (const dir of policy.hiddenDirs ?? []) {
63
+ assertSafePath(dir);
64
+ args.push("--tmpfs", dir);
65
+ }
66
+ for (const file of policy.hiddenFiles ?? []) {
67
+ assertSafePath(file);
68
+ args.push("--ro-bind", "/dev/null", file);
69
+ }
70
+ args.push("--");
71
+ return args;
72
+ }
73
+ /** unshare 参数(不含可执行文件与目标命令):只隔离网络,不限制写入。 */
74
+ export function buildUnshareArgs() {
75
+ return ["-r", "-n", "--"];
76
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * 包装命令行(docs/sandbox.md「分层」):输入命令、参数与策略 → 输出经 OS 沙箱启动的命令行。使用方自己
3
+ * spawn(进程组、stdio、环境都不变)。
4
+ *
5
+ * - 可写目录取 realpath(SBPL 按真实路径匹配,macOS 的 /tmp、/var 是符号链接;bwrap 绑定也要求存在),
6
+ * 不存在的丢弃;
7
+ * - `unshare` 只能隔离网络:策略要求联网时等于不包装;
8
+ * - `none`:原样返回(调用方按 `sandboxed: false` 决定是否继续);
9
+ * - 只读路径(`readOnly`):存在的取 realpath;不存在的按「父目录 realpath + 名字」只给 SBPL(挡住新建),
10
+ * bwrap 只能挂到已存在的路径,跳过;不可读路径(`hiddenDirs` / `hiddenFiles`)只保留存在的,并按实际
11
+ * 类型重新归类(bwrap 对目录挂 tmpfs、对文件挂 /dev/null)。
12
+ */
13
+ import type { OsSandboxStatus } from "./detect.js";
14
+ import { type OsSandboxPolicy } from "./profile.js";
15
+ export interface WrappedCommand {
16
+ command: string;
17
+ args: string[];
18
+ /** 实际经 OS 沙箱启动。 */
19
+ sandboxed: boolean;
20
+ /** 本次包装拒绝了网络。 */
21
+ networkDenied: boolean;
22
+ /** 本次包装把写入限制在 `writable`。 */
23
+ writesRestricted: boolean;
24
+ }
25
+ /** 可写目录 → realpath,去掉不存在的与重复的。 */
26
+ export declare function resolveWritable(dirs: readonly string[], realpath?: (path: string) => string): string[];
27
+ /** 解析只读与不可读路径(见文件头)。`missingOk`:不存在的只读路径按父目录解析保留(SBPL)。 */
28
+ export declare function resolveExtras(policy: OsSandboxPolicy, missingOk: boolean, realpath?: (path: string) => string, isDir?: (path: string) => boolean): Pick<OsSandboxPolicy, "readOnly" | "hiddenDirs" | "hiddenFiles">;
29
+ export declare function wrapCommand(status: Pick<OsSandboxStatus, "kind" | "path">, command: string, args: readonly string[], policy: OsSandboxPolicy, realpath?: (path: string) => string, isDir?: (path: string) => boolean): WrappedCommand;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * 包装命令行(docs/sandbox.md「分层」):输入命令、参数与策略 → 输出经 OS 沙箱启动的命令行。使用方自己
3
+ * spawn(进程组、stdio、环境都不变)。
4
+ *
5
+ * - 可写目录取 realpath(SBPL 按真实路径匹配,macOS 的 /tmp、/var 是符号链接;bwrap 绑定也要求存在),
6
+ * 不存在的丢弃;
7
+ * - `unshare` 只能隔离网络:策略要求联网时等于不包装;
8
+ * - `none`:原样返回(调用方按 `sandboxed: false` 决定是否继续);
9
+ * - 只读路径(`readOnly`):存在的取 realpath;不存在的按「父目录 realpath + 名字」只给 SBPL(挡住新建),
10
+ * bwrap 只能挂到已存在的路径,跳过;不可读路径(`hiddenDirs` / `hiddenFiles`)只保留存在的,并按实际
11
+ * 类型重新归类(bwrap 对目录挂 tmpfs、对文件挂 /dev/null)。
12
+ */
13
+ import { realpathSync, statSync } from "node:fs";
14
+ import { basename, dirname, join } from "node:path";
15
+ import { buildBwrapArgs, buildSbplProfile, buildUnshareArgs, } from "./profile.js";
16
+ /** 可写目录 → realpath,去掉不存在的与重复的。 */
17
+ export function resolveWritable(dirs, realpath = realpathSync) {
18
+ const out = [];
19
+ for (const dir of dirs) {
20
+ let real;
21
+ try {
22
+ real = realpath(dir);
23
+ }
24
+ catch {
25
+ continue;
26
+ }
27
+ if (!out.includes(real))
28
+ out.push(real);
29
+ }
30
+ return out;
31
+ }
32
+ function isDirectory(path) {
33
+ try {
34
+ return statSync(path).isDirectory();
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ /** 解析只读与不可读路径(见文件头)。`missingOk`:不存在的只读路径按父目录解析保留(SBPL)。 */
41
+ export function resolveExtras(policy, missingOk, realpath = realpathSync, isDir = isDirectory) {
42
+ const readOnly = [];
43
+ for (const path of policy.readOnly ?? []) {
44
+ let real;
45
+ try {
46
+ real = realpath(path);
47
+ }
48
+ catch {
49
+ if (missingOk) {
50
+ try {
51
+ real = join(realpath(dirname(path)), basename(path));
52
+ }
53
+ catch {
54
+ real = undefined;
55
+ }
56
+ }
57
+ }
58
+ if (real !== undefined && !readOnly.includes(real))
59
+ readOnly.push(real);
60
+ }
61
+ const hidden = resolveWritable([...(policy.hiddenDirs ?? []), ...(policy.hiddenFiles ?? [])], realpath);
62
+ const out = {};
63
+ if (readOnly.length > 0)
64
+ out.readOnly = readOnly;
65
+ const dirs = hidden.filter((p) => isDir(p));
66
+ const files = hidden.filter((p) => !dirs.includes(p));
67
+ if (dirs.length > 0)
68
+ out.hiddenDirs = dirs;
69
+ if (files.length > 0)
70
+ out.hiddenFiles = files;
71
+ return out;
72
+ }
73
+ export function wrapCommand(status, command, args, policy, realpath, isDir) {
74
+ const plain = {
75
+ command,
76
+ args: [...args],
77
+ sandboxed: false,
78
+ networkDenied: false,
79
+ writesRestricted: false,
80
+ };
81
+ if (status.kind === "none" || status.path === undefined)
82
+ return plain;
83
+ const resolved = {
84
+ network: policy.network,
85
+ writable: resolveWritable(policy.writable, realpath),
86
+ ...resolveExtras(policy, status.kind === "sandbox-exec", realpath, isDir),
87
+ };
88
+ const networkDenied = policy.network === "deny";
89
+ switch (status.kind) {
90
+ case "sandbox-exec":
91
+ return {
92
+ command: status.path,
93
+ args: ["-p", buildSbplProfile(resolved), command, ...args],
94
+ sandboxed: true,
95
+ networkDenied,
96
+ writesRestricted: true,
97
+ };
98
+ case "bwrap":
99
+ return {
100
+ command: status.path,
101
+ args: [...buildBwrapArgs(resolved), command, ...args],
102
+ sandboxed: true,
103
+ networkDenied,
104
+ writesRestricted: true,
105
+ };
106
+ case "unshare":
107
+ if (!networkDenied)
108
+ return plain;
109
+ return {
110
+ command: status.path,
111
+ args: [...buildUnshareArgs(), command, ...args],
112
+ sandboxed: true,
113
+ networkDenied: true,
114
+ writesRestricted: false,
115
+ };
116
+ }
117
+ }
package/dist/sdk.d.ts CHANGED
@@ -6,17 +6,24 @@
6
6
  * 也可以直接给 `argv`(与 `ama` 命令行同语法)。
7
7
  * - `createAgentSession(options)`:不读文件系统配置的轻量装配——内存会话(或传入的
8
8
  * SessionManager)、选定的工具、规则与回调审批,直接返回 `AgentSessionImpl`
9
- * (含 `addTool / updateSystem / navigate` 等扩展方法)。
9
+ * (含 `addTool / updateSystem / navigate` 等扩展方法;回滚 `rewindPoints / rewind /
10
+ * summarizeFrom / summarizeUpTo / undoAbortedTurn`,内存会话只能仅对话)。
10
11
  *
11
12
  * 两者共用组装根(cli/compose*.ts),审批链、系统提示装配、工具预设与缓存行为与 CLI 一致。
13
+ * - [W5-F] 计划(docs/plan.md):`CreateSessionOptions.plan`(plan.* 配置 + `onProposed` 审批回调);
14
+ * 返回的会话带 `plan.current() / respond() / todos()`。没有 `onProposed` 时按 `plan.unattended`
15
+ * (缺省 stop:计划落盘后停下,不替人批准)。
12
16
  */
13
17
  import type { ApiRegistry } from "./ai/apis/api.js";
14
18
  import type { ModelThinkingLevel, ProviderData } from "./ai/types.js";
15
19
  import type { AgentSessionImpl } from "./agent/session.js";
20
+ import { type PlanDecision, type PlanResponse, type PlanResponseResult } from "./agent/session-plan.js";
21
+ import type { PlanData, TodoItemView } from "./agent/types.js";
22
+ import type { PlanConfig } from "./config/types-w5.js";
16
23
  import { type LogFn } from "./cli/compose-session.js";
17
24
  import { type ComposeOptions } from "./cli/compose.js";
18
25
  import type { Runtime } from "./cli/runtime.js";
19
- import type { AmaConfig, ToolsPreset } from "./config/types.js";
26
+ import { type AmaConfig, type ToolsPresetInput } from "./config/types.js";
20
27
  import type { HookConfig } from "./hooks/types.js";
21
28
  import type { InstructionSource } from "./host/types.js";
22
29
  import type { ApprovalDecision, ApprovalRequest, PermissionMode } from "./permissions/types.js";
@@ -24,6 +31,8 @@ import { SessionManager } from "./session/manager.js";
24
31
  import type { ToolDefinition } from "./tools/types.js";
25
32
  /** [W3-C2] 统计类型:`session.getStats()`、RPC `get_session_stats`、`-p --output-format json` 的 `cache`。 */
26
33
  export type { SessionCacheStats, SessionStats } from "./agent/types.js";
34
+ /** [RW-B] 回滚:`session.rewindPoints()`、`session.rewind()`、`summarizeFrom / summarizeUpTo`。 */
35
+ export type { CodeRestoreResult, RewindMode, RewindPoint, RewindRequest, RewindResult, } from "./checkpoints/types.js";
27
36
  export type { CacheMiss, CacheMissReason, CacheReporting, WarmerStatus, WarmingMode, } from "./ai/cache/types.js";
28
37
  export interface RuntimeOptions {
29
38
  cwd?: string;
@@ -32,7 +41,8 @@ export interface RuntimeOptions {
32
41
  model?: string;
33
42
  thinkingLevel?: ModelThinkingLevel;
34
43
  permissionMode?: PermissionMode;
35
- toolsPreset?: ToolsPreset;
44
+ /** `codemode` 是 `codemode-only` 的别名。 */
45
+ toolsPreset?: ToolsPresetInput;
36
46
  /** 信任项目(项目级 Hook / Skill / 提示模板)。 */
37
47
  trust?: boolean;
38
48
  sessionDir?: string;
@@ -45,6 +55,26 @@ export interface RuntimeOptions {
45
55
  compose?: ComposeOptions;
46
56
  }
47
57
  export declare function createRuntime(options?: RuntimeOptions): Promise<Runtime>;
58
+ /** [W5-F] 计划:类型与 RPC 同形(`plan_proposed` / `plan_response`)。 */
59
+ export type { PlanData, PlanDecision, PlanResponse, PlanResponseResult, TodoItemView };
60
+ /** [W5-F] `CreateSessionOptions.plan`:plan.* 配置 + 审批回调。 */
61
+ export interface SessionPlanOptions extends PlanConfig {
62
+ /**
63
+ * 计划待审批时调用(运行结束后;不阻塞运行)。返回回答即生效;返回 undefined 留待
64
+ * `session.plan.respond()`。不给时按 `unattended`(缺省 stop)。
65
+ */
66
+ onProposed?(plan: PlanData): Promise<PlanDecision | undefined>;
67
+ }
68
+ /** [W5-F] `session.plan`。 */
69
+ export interface SessionPlanApi {
70
+ /** 分支上最近的计划;没有为 null。 */
71
+ current(): PlanData | null;
72
+ respond(response: PlanResponse): Promise<PlanResponseResult>;
73
+ todos(): TodoItemView[];
74
+ }
75
+ export type SdkAgentSession = AgentSessionImpl & {
76
+ readonly plan: SessionPlanApi;
77
+ };
48
78
  export type SessionAuth = {
49
79
  kind: "file";
50
80
  path: string;
@@ -73,7 +103,8 @@ export interface CreateSessionOptions {
73
103
  sessionManager?: SessionManager;
74
104
  /** `default`(缺省,按预设)/ `none` / 指定工具全集。 */
75
105
  tools?: "default" | "none" | ToolDefinition[];
76
- toolsPreset?: ToolsPreset;
106
+ /** `codemode` 是 `codemode-only` 的别名。 */
107
+ toolsPreset?: ToolsPresetInput;
77
108
  extraTools?: ToolDefinition[];
78
109
  disableTools?: string[];
79
110
  /** 进系统提示 host 节。 */
@@ -85,14 +116,20 @@ export interface CreateSessionOptions {
85
116
  mode?: PermissionMode;
86
117
  allow?: string[];
87
118
  deny?: string[];
119
+ /** auto 模式分类器的模型(`provider/model`);缺省 config `permission.autoModel`,再缺省当前模型。 */
120
+ autoModel?: string;
121
+ /** auto 模式安全名单追加(与 config `permission.autoSafeCommands` 合并)。 */
122
+ autoSafeCommands?: string[];
88
123
  /** 审批回调;缺省无人作答 → deny。 */
89
124
  ask?(request: ApprovalRequest, signal: AbortSignal): Promise<ApprovalDecision>;
90
125
  };
91
126
  /** 命令式 Hook(缺省不加载文件系统里的 hooks.json)。 */
92
127
  hooks?: HookConfig | false;
93
128
  config?: Partial<AmaConfig>;
129
+ /** [W5-F] 计划(plan.* 配置与审批回调),见 docs/plan.md。 */
130
+ plan?: SessionPlanOptions;
94
131
  unattended?: boolean;
95
132
  onWarning?: (message: string) => void;
96
133
  log?: LogFn;
97
134
  }
98
- export declare function createAgentSession(options?: CreateSessionOptions): Promise<AgentSessionImpl>;
135
+ export declare function createAgentSession(options?: CreateSessionOptions): Promise<SdkAgentSession>;
package/dist/sdk.js CHANGED
@@ -6,12 +6,17 @@
6
6
  * 也可以直接给 `argv`(与 `ama` 命令行同语法)。
7
7
  * - `createAgentSession(options)`:不读文件系统配置的轻量装配——内存会话(或传入的
8
8
  * SessionManager)、选定的工具、规则与回调审批,直接返回 `AgentSessionImpl`
9
- * (含 `addTool / updateSystem / navigate` 等扩展方法)。
9
+ * (含 `addTool / updateSystem / navigate` 等扩展方法;回滚 `rewindPoints / rewind /
10
+ * summarizeFrom / summarizeUpTo / undoAbortedTurn`,内存会话只能仅对话)。
10
11
  *
11
12
  * 两者共用组装根(cli/compose*.ts),审批链、系统提示装配、工具预设与缓存行为与 CLI 一致。
13
+ * - [W5-F] 计划(docs/plan.md):`CreateSessionOptions.plan`(plan.* 配置 + `onProposed` 审批回调);
14
+ * 返回的会话带 `plan.current() / respond() / todos()`。没有 `onProposed` 时按 `plan.unattended`
15
+ * (缺省 stop:计划落盘后停下,不替人批准)。
12
16
  */
13
17
  import { resolve } from "node:path";
14
18
  import { ProviderRegistry } from "./ai/providers/registry.js";
19
+ import { planController, } from "./agent/session-plan.js";
15
20
  import { parseArgs } from "./cli/args.js";
16
21
  import { bootstrap } from "./cli/bootstrap.js";
17
22
  import { withExtraProviders } from "./cli/compose-providers.js";
@@ -21,6 +26,7 @@ import { pickDefaultModel } from "./cli/default-model.js";
21
26
  import { findContextFiles } from "./config/context-files.js";
22
27
  import { DEFAULT_CONFIG, mergeConfig } from "./config/merge.js";
23
28
  import { resolveConfigDir, resolveDataDir } from "./config/paths.js";
29
+ import { canonicalPreset } from "./config/types.js";
24
30
  import { AmaError } from "./errors.js";
25
31
  import { hooksFromConfig } from "./hooks/config.js";
26
32
  import { HookDispatcher } from "./hooks/dispatcher.js";
@@ -41,7 +47,7 @@ export async function createRuntime(options = {}) {
41
47
  if (options.permissionMode !== undefined)
42
48
  args.permissionMode = options.permissionMode;
43
49
  if (options.toolsPreset !== undefined)
44
- args.toolsPreset = options.toolsPreset;
50
+ args.toolsPreset = canonicalPreset(options.toolsPreset);
45
51
  if (options.trust !== undefined)
46
52
  args.trust = options.trust;
47
53
  if (options.sessionDir !== undefined)
@@ -80,6 +86,9 @@ export async function createAgentSession(options = {}) {
80
86
  const cwd = resolve(options.cwd ?? process.cwd());
81
87
  const warn = options.onWarning ?? (() => undefined);
82
88
  let config = mergeConfig(DEFAULT_CONFIG, options.config);
89
+ const { onProposed, ...planConfig } = options.plan ?? {};
90
+ if (options.plan !== undefined)
91
+ config = { ...config, plan: { ...config.plan, ...planConfig } };
83
92
  if (options.toolsPreset !== undefined)
84
93
  config = mergeConfig(config, { tools: { preset: options.toolsPreset } });
85
94
  const providers = new ProviderRegistry({
@@ -131,7 +140,14 @@ export async function createAgentSession(options = {}) {
131
140
  source: "sdk",
132
141
  })),
133
142
  ], config.permission?.builtinDeny, warn);
134
- const permission = new PermissionPipeline({ mode, rules, cwd });
143
+ const autoSafeCommands = [
144
+ ...(config.permission?.autoSafeCommands ?? []),
145
+ ...(options.permission?.autoSafeCommands ?? []),
146
+ ];
147
+ const permission = new PermissionPipeline({ mode, rules, cwd, autoSafeCommands });
148
+ const autoModel = options.permission?.autoModel;
149
+ if (autoModel !== undefined)
150
+ config.permission = { ...config.permission, autoModel };
135
151
  const manager = options.sessionManager ?? SessionManager.inMemory(cwd);
136
152
  let session;
137
153
  const hooks = new HookDispatcher({
@@ -191,5 +207,19 @@ export async function createAgentSession(options = {}) {
191
207
  warn,
192
208
  };
193
209
  session = composeSession(assembly, state, { log: options.log ?? (() => undefined) });
194
- return session;
210
+ return withPlanApi(session, onProposed);
211
+ }
212
+ /** SDK 会话:审批交给 `onProposed`(没有则无人值守策略),并挂上 `session.plan`。 */
213
+ function withPlanApi(session, onProposed) {
214
+ const controller = planController(session);
215
+ controller?.setAttendance(onProposed === undefined ? "unattended" : "callback", onProposed);
216
+ const missing = () => {
217
+ throw new AmaError("not_implemented", "该会话没有装配 plan 扩展");
218
+ };
219
+ const plan = {
220
+ current: () => controller?.current() ?? null,
221
+ respond: (response) => (controller ?? missing()).respond(response),
222
+ todos: () => controller?.todos() ?? [],
223
+ };
224
+ return Object.assign(session, { plan });
195
225
  }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * 会话导出(`ama sessions export`):md(给人读)/ json(结构化)/ jsonl(原格式子集)。[W4-D]
3
+ *
4
+ * - 范围:`leaf` = 根 → 当前叶子的分支(同 `/tree` 当前位置),`all` = 文件里全部条目(文件顺序)。
5
+ * - 三种格式都先脱敏(redact.ts):json / jsonl 对每个字符串值做(图片 base64 保留),md 对成文做。
6
+ * - md:用户 / 助手消息、工具调用(参数 JSON 截到 500 字符)与结果(截到 2000 字符)、压缩与分支摘要、
7
+ * 末尾用量合计;思考块与 system 消息不写;图片写成占位 `[图片 image/png]`。
8
+ * - jsonl:头 + 所选条目,形状与会话文件相同(可以再被 ama 读),不带 leaf 行。
9
+ */
10
+ import type { SessionEntry, SessionHeader } from "./types.js";
11
+ export type ExportFormat = "md" | "json" | "jsonl";
12
+ export type ExportBranch = "leaf" | "all";
13
+ export interface ExportInput {
14
+ header: SessionHeader;
15
+ entries: readonly SessionEntry[];
16
+ leaf: string | null;
17
+ }
18
+ export interface UsageTotals {
19
+ requests: number;
20
+ input: number;
21
+ output: number;
22
+ cacheRead: number;
23
+ cacheWrite: number;
24
+ /** 有价请求的费用;没有有价请求时缺省。 */
25
+ cost?: number;
26
+ }
27
+ export declare function selectEntries(input: ExportInput, branch: ExportBranch): SessionEntry[];
28
+ export declare function usageTotals(entries: readonly SessionEntry[]): UsageTotals;
29
+ export declare function renderMarkdown(input: ExportInput, branch: ExportBranch): string;
30
+ export declare function renderJson(input: ExportInput, branch: ExportBranch): string;
31
+ export declare function renderJsonl(input: ExportInput, branch: ExportBranch): string;
32
+ export declare function renderExport(input: ExportInput, format: ExportFormat, branch: ExportBranch): string;