@armadra/agent 0.4.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 (422) hide show
  1. package/CHANGELOG.md +174 -1
  2. package/README.md +201 -82
  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/session-cache.d.ts +5 -0
  17. package/dist/agent/session-cache.js +17 -1
  18. package/dist/agent/session-classifier.d.ts +1 -1
  19. package/dist/agent/session-classifier.js +3 -1
  20. package/dist/agent/session-compaction.d.ts +35 -6
  21. package/dist/agent/session-compaction.js +157 -31
  22. package/dist/agent/session-core.d.ts +27 -1
  23. package/dist/agent/session-extensions.d.ts +61 -0
  24. package/dist/agent/session-extensions.js +129 -0
  25. package/dist/agent/session-images.d.ts +23 -0
  26. package/dist/agent/session-images.js +97 -0
  27. package/dist/agent/session-plan.d.ts +21 -0
  28. package/dist/agent/session-plan.js +524 -0
  29. package/dist/agent/session-rewind.d.ts +81 -0
  30. package/dist/agent/session-rewind.js +354 -0
  31. package/dist/agent/session-run.d.ts +28 -1
  32. package/dist/agent/session-run.js +157 -6
  33. package/dist/agent/session-settings.d.ts +49 -0
  34. package/dist/agent/session-settings.js +95 -0
  35. package/dist/agent/session-subagent.d.ts +36 -24
  36. package/dist/agent/session-subagent.js +259 -129
  37. package/dist/agent/session-sync.d.ts +10 -3
  38. package/dist/agent/session-sync.js +37 -8
  39. package/dist/agent/session-telemetry.d.ts +39 -0
  40. package/dist/agent/session-telemetry.js +231 -0
  41. package/dist/agent/session-tools.js +40 -1
  42. package/dist/agent/session.d.ts +30 -29
  43. package/dist/agent/session.js +79 -123
  44. package/dist/agent/subagent-registry.d.ts +91 -0
  45. package/dist/agent/subagent-registry.js +494 -0
  46. package/dist/agent/system-prompt.d.ts +6 -3
  47. package/dist/agent/system-prompt.js +7 -2
  48. package/dist/agent/tool-runner.d.ts +8 -1
  49. package/dist/agent/tool-runner.js +57 -4
  50. package/dist/agent/types-w5.d.ts +192 -0
  51. package/dist/agent/types-w5.js +10 -0
  52. package/dist/agent/types.d.ts +47 -4
  53. package/dist/agent/types.js +2 -0
  54. package/dist/agent/worktree.d.ts +36 -0
  55. package/dist/agent/worktree.js +86 -0
  56. package/dist/agents/builtin.d.ts +14 -0
  57. package/dist/agents/builtin.js +39 -0
  58. package/dist/agents/catalog.d.ts +43 -0
  59. package/dist/agents/catalog.js +82 -0
  60. package/dist/agents/discover.d.ts +35 -0
  61. package/dist/agents/discover.js +83 -0
  62. package/dist/agents/external.d.ts +82 -0
  63. package/dist/agents/external.js +326 -0
  64. package/dist/agents/parse.d.ts +18 -0
  65. package/dist/agents/parse.js +116 -0
  66. package/dist/agents/result.d.ts +32 -0
  67. package/dist/agents/result.js +67 -0
  68. package/dist/agents/task-control.d.ts +17 -0
  69. package/dist/agents/task-control.js +17 -0
  70. package/dist/agents/task-record.d.ts +78 -0
  71. package/dist/agents/task-record.js +141 -0
  72. package/dist/agents/types.d.ts +46 -0
  73. package/dist/agents/types.js +8 -0
  74. package/dist/ai/apis/anthropic-compat.d.ts +36 -0
  75. package/dist/ai/apis/anthropic-compat.js +92 -0
  76. package/dist/ai/apis/anthropic-request.d.ts +7 -6
  77. package/dist/ai/apis/anthropic-request.js +10 -28
  78. package/dist/ai/apis/cache-params.d.ts +11 -2
  79. package/dist/ai/apis/cache-params.js +25 -6
  80. package/dist/ai/apis/openai-compat.d.ts +4 -1
  81. package/dist/ai/apis/openai-compat.js +8 -1
  82. package/dist/ai/image-limits.d.ts +45 -0
  83. package/dist/ai/image-limits.js +68 -0
  84. package/dist/ai/providers/builtin.d.ts +18 -6
  85. package/dist/ai/providers/builtin.js +135 -6
  86. package/dist/ai/providers/catalog-data.js +17 -13
  87. package/dist/ai/providers/catalog.d.ts +60 -7
  88. package/dist/ai/providers/catalog.js +197 -38
  89. package/dist/ai/providers/channels.d.ts +33 -3
  90. package/dist/ai/providers/channels.js +108 -7
  91. package/dist/ai/providers/enrich.d.ts +6 -3
  92. package/dist/ai/providers/enrich.js +19 -4
  93. package/dist/ai/providers/models-dev-cache.d.ts +28 -24
  94. package/dist/ai/providers/models-dev-cache.js +92 -78
  95. package/dist/ai/providers/models-dev-data.d.ts +7 -0
  96. package/dist/ai/providers/models-dev-data.js +32 -0
  97. package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
  98. package/dist/ai/providers/models-dev-snapshot.js +137 -0
  99. package/dist/ai/providers/models-dev.d.ts +51 -10
  100. package/dist/ai/providers/models-dev.js +132 -39
  101. package/dist/ai/providers/registry.d.ts +20 -10
  102. package/dist/ai/providers/registry.js +82 -43
  103. package/dist/ai/types.d.ts +28 -2
  104. package/dist/ai/types.js +5 -0
  105. package/dist/bundle/ama.cjs +36203 -20499
  106. package/dist/checkpoints/backend.d.ts +61 -0
  107. package/dist/checkpoints/backend.js +135 -0
  108. package/dist/checkpoints/blobs.d.ts +60 -0
  109. package/dist/checkpoints/blobs.js +203 -0
  110. package/dist/checkpoints/gc.d.ts +47 -0
  111. package/dist/checkpoints/gc.js +144 -0
  112. package/dist/checkpoints/git-head.d.ts +15 -0
  113. package/dist/checkpoints/git-head.js +89 -0
  114. package/dist/checkpoints/index.d.ts +17 -0
  115. package/dist/checkpoints/index.js +17 -0
  116. package/dist/checkpoints/replay.d.ts +48 -0
  117. package/dist/checkpoints/replay.js +154 -0
  118. package/dist/checkpoints/restore.d.ts +86 -0
  119. package/dist/checkpoints/restore.js +263 -0
  120. package/dist/checkpoints/settings.d.ts +14 -0
  121. package/dist/checkpoints/settings.js +23 -0
  122. package/dist/checkpoints/shadow-git.d.ts +108 -0
  123. package/dist/checkpoints/shadow-git.js +491 -0
  124. package/dist/checkpoints/shadow-restore.d.ts +25 -0
  125. package/dist/checkpoints/shadow-restore.js +128 -0
  126. package/dist/checkpoints/tracker.d.ts +64 -0
  127. package/dist/checkpoints/tracker.js +192 -0
  128. package/dist/checkpoints/types.d.ts +99 -0
  129. package/dist/checkpoints/types.js +12 -0
  130. package/dist/cli/args.d.ts +8 -4
  131. package/dist/cli/args.js +17 -97
  132. package/dist/cli/bootstrap.js +13 -1
  133. package/dist/cli/codemode-notice.d.ts +3 -2
  134. package/dist/cli/codemode-notice.js +3 -2
  135. package/dist/cli/compose-agents.d.ts +27 -0
  136. package/dist/cli/compose-agents.js +111 -0
  137. package/dist/cli/compose-extensions.d.ts +29 -0
  138. package/dist/cli/compose-extensions.js +44 -0
  139. package/dist/cli/compose-session.d.ts +3 -0
  140. package/dist/cli/compose-session.js +47 -4
  141. package/dist/cli/compose.d.ts +3 -0
  142. package/dist/cli/compose.js +33 -6
  143. package/dist/cli/deps.d.ts +6 -0
  144. package/dist/cli/exit-codes.d.ts +10 -0
  145. package/dist/cli/exit-codes.js +12 -0
  146. package/dist/cli/help-text.d.ts +4 -0
  147. package/dist/cli/help-text.js +102 -0
  148. package/dist/cli/startup-screen.js +5 -3
  149. package/dist/cli/startup-steps.js +7 -1
  150. package/dist/cli/subcommands/config.d.ts +4 -1
  151. package/dist/cli/subcommands/config.js +17 -6
  152. package/dist/cli/subcommands/doctor.js +21 -0
  153. package/dist/cli/subcommands/models-discover.js +5 -6
  154. package/dist/cli/subcommands/models.d.ts +2 -0
  155. package/dist/cli/subcommands/models.js +33 -14
  156. package/dist/cli/subcommands/providers.js +5 -6
  157. package/dist/cli/subcommands/sessions.d.ts +3 -1
  158. package/dist/cli/subcommands/sessions.js +36 -2
  159. package/dist/codemode/capability.d.ts +24 -7
  160. package/dist/codemode/capability.js +38 -10
  161. package/dist/codemode/host-side.d.ts +14 -0
  162. package/dist/codemode/host-side.js +24 -1
  163. package/dist/codemode/tool.d.ts +1 -1
  164. package/dist/codemode/tool.js +6 -4
  165. package/dist/compaction/breaker.d.ts +25 -9
  166. package/dist/compaction/breaker.js +47 -17
  167. package/dist/compaction/estimate.d.ts +11 -3
  168. package/dist/compaction/estimate.js +64 -22
  169. package/dist/compaction/image-budget.d.ts +45 -0
  170. package/dist/compaction/image-budget.js +115 -0
  171. package/dist/compaction/post-compact.d.ts +38 -0
  172. package/dist/compaction/post-compact.js +152 -0
  173. package/dist/compaction/protect.d.ts +27 -0
  174. package/dist/compaction/protect.js +56 -0
  175. package/dist/compaction/prune-tier.d.ts +58 -12
  176. package/dist/compaction/prune-tier.js +120 -54
  177. package/dist/compaction/summarize-tier.d.ts +23 -4
  178. package/dist/compaction/summarize-tier.js +100 -29
  179. package/dist/config/checker.d.ts +28 -0
  180. package/dist/config/checker.js +97 -0
  181. package/dist/config/json-schema.js +63 -2
  182. package/dist/config/key-docs.js +72 -3
  183. package/dist/config/merge.d.ts +5 -3
  184. package/dist/config/merge.js +81 -7
  185. package/dist/config/profile.d.ts +2 -0
  186. package/dist/config/profile.js +2 -0
  187. package/dist/config/schema-w5.d.ts +18 -0
  188. package/dist/config/schema-w5.js +109 -0
  189. package/dist/config/schema.d.ts +5 -9
  190. package/dist/config/schema.js +68 -114
  191. package/dist/config/types-w5.d.ts +118 -0
  192. package/dist/config/types-w5.js +20 -0
  193. package/dist/config/types.d.ts +50 -1
  194. package/dist/config/types.js +12 -0
  195. package/dist/drivers/acp/client.d.ts +57 -0
  196. package/dist/drivers/acp/client.js +160 -0
  197. package/dist/drivers/acp/driver.d.ts +31 -0
  198. package/dist/drivers/acp/driver.js +274 -0
  199. package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
  200. package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
  201. package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
  202. package/dist/drivers/acp/testing/fake-agent.js +211 -0
  203. package/dist/drivers/acp/types.d.ts +285 -0
  204. package/dist/drivers/acp/types.js +36 -0
  205. package/dist/drivers/agents.d.ts +58 -0
  206. package/dist/drivers/agents.js +142 -0
  207. package/dist/drivers/base.d.ts +35 -0
  208. package/dist/drivers/base.js +59 -0
  209. package/dist/drivers/catalog.d.ts +46 -0
  210. package/dist/drivers/catalog.js +167 -0
  211. package/dist/drivers/env.d.ts +20 -0
  212. package/dist/drivers/env.js +46 -0
  213. package/dist/drivers/host-runners.d.ts +18 -0
  214. package/dist/drivers/host-runners.js +45 -0
  215. package/dist/drivers/jsonrpc.d.ts +58 -0
  216. package/dist/drivers/jsonrpc.js +180 -0
  217. package/dist/drivers/native/claude-normalize.d.ts +46 -0
  218. package/dist/drivers/native/claude-normalize.js +106 -0
  219. package/dist/drivers/native/claude-stream.d.ts +29 -0
  220. package/dist/drivers/native/claude-stream.js +456 -0
  221. package/dist/drivers/native/codex-app-server.d.ts +26 -0
  222. package/dist/drivers/native/codex-app-server.js +407 -0
  223. package/dist/drivers/native/codex-normalize.d.ts +38 -0
  224. package/dist/drivers/native/codex-normalize.js +124 -0
  225. package/dist/drivers/native/oneshot.d.ts +28 -0
  226. package/dist/drivers/native/oneshot.js +312 -0
  227. package/dist/drivers/permissions.d.ts +40 -0
  228. package/dist/drivers/permissions.js +92 -0
  229. package/dist/drivers/pids.d.ts +32 -0
  230. package/dist/drivers/pids.js +93 -0
  231. package/dist/drivers/pool.d.ts +28 -0
  232. package/dist/drivers/pool.js +96 -0
  233. package/dist/drivers/probe.d.ts +47 -0
  234. package/dist/drivers/probe.js +172 -0
  235. package/dist/drivers/process.d.ts +48 -0
  236. package/dist/drivers/process.js +100 -0
  237. package/dist/drivers/runner.d.ts +61 -0
  238. package/dist/drivers/runner.js +388 -0
  239. package/dist/drivers/store.d.ts +49 -0
  240. package/dist/drivers/store.js +91 -0
  241. package/dist/drivers/turn.d.ts +41 -0
  242. package/dist/drivers/turn.js +99 -0
  243. package/dist/drivers/types.d.ts +122 -0
  244. package/dist/drivers/types.js +11 -0
  245. package/dist/git/info.d.ts +75 -0
  246. package/dist/git/info.js +191 -0
  247. package/dist/hooks/protocol.js +6 -1
  248. package/dist/hooks/types.d.ts +10 -1
  249. package/dist/hooks/types.js +2 -0
  250. package/dist/host/api-impl.d.ts +7 -0
  251. package/dist/host/api-impl.js +15 -0
  252. package/dist/host/types.d.ts +24 -2
  253. package/dist/host/types.js +4 -0
  254. package/dist/index.d.ts +3 -0
  255. package/dist/index.js +1 -0
  256. package/dist/modes/acp/acp-events.d.ts +46 -0
  257. package/dist/modes/acp/acp-events.js +233 -0
  258. package/dist/modes/acp/acp-mode.d.ts +17 -0
  259. package/dist/modes/acp/acp-mode.js +47 -0
  260. package/dist/modes/acp/acp-server.d.ts +79 -0
  261. package/dist/modes/acp/acp-server.js +315 -0
  262. package/dist/modes/commands-core.d.ts +7 -1
  263. package/dist/modes/commands-core.js +55 -0
  264. package/dist/modes/image-input.d.ts +12 -4
  265. package/dist/modes/image-input.js +22 -5
  266. package/dist/modes/interactive/agent-panels.d.ts +14 -0
  267. package/dist/modes/interactive/agent-panels.js +103 -0
  268. package/dist/modes/interactive/agent-ui.d.ts +73 -0
  269. package/dist/modes/interactive/agent-ui.js +234 -0
  270. package/dist/modes/interactive/approval-dialog.d.ts +21 -4
  271. package/dist/modes/interactive/approval-dialog.js +98 -20
  272. package/dist/modes/interactive/approval-merge.d.ts +41 -0
  273. package/dist/modes/interactive/approval-merge.js +89 -0
  274. package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
  275. package/dist/modes/interactive/clipboard-paste.js +28 -0
  276. package/dist/modes/interactive/commands.d.ts +9 -1
  277. package/dist/modes/interactive/commands.js +19 -0
  278. package/dist/modes/interactive/double-esc.d.ts +20 -0
  279. package/dist/modes/interactive/double-esc.js +34 -0
  280. package/dist/modes/interactive/event-notices.d.ts +32 -0
  281. package/dist/modes/interactive/event-notices.js +79 -0
  282. package/dist/modes/interactive/external-editor.d.ts +16 -0
  283. package/dist/modes/interactive/external-editor.js +39 -0
  284. package/dist/modes/interactive/interactive-mode.d.ts +14 -1
  285. package/dist/modes/interactive/interactive-mode.js +134 -136
  286. package/dist/modes/interactive/key-dispatch.d.ts +16 -2
  287. package/dist/modes/interactive/key-dispatch.js +49 -1
  288. package/dist/modes/interactive/line/line-mode.d.ts +2 -1
  289. package/dist/modes/interactive/line/line-mode.js +22 -5
  290. package/dist/modes/interactive/line/line-render.d.ts +2 -1
  291. package/dist/modes/interactive/line/line-render.js +40 -4
  292. package/dist/modes/interactive/message-view.d.ts +1 -1
  293. package/dist/modes/interactive/message-view.js +24 -2
  294. package/dist/modes/interactive/panels.d.ts +18 -1
  295. package/dist/modes/interactive/panels.js +19 -5
  296. package/dist/modes/interactive/plan-command.d.ts +40 -0
  297. package/dist/modes/interactive/plan-command.js +129 -0
  298. package/dist/modes/interactive/plan-dialog.d.ts +98 -0
  299. package/dist/modes/interactive/plan-dialog.js +290 -0
  300. package/dist/modes/interactive/plan-flow.d.ts +34 -0
  301. package/dist/modes/interactive/plan-flow.js +98 -0
  302. package/dist/modes/interactive/rewind-command.d.ts +31 -0
  303. package/dist/modes/interactive/rewind-command.js +106 -0
  304. package/dist/modes/interactive/rewind-flow.d.ts +37 -0
  305. package/dist/modes/interactive/rewind-flow.js +151 -0
  306. package/dist/modes/interactive/rewind-list.d.ts +36 -0
  307. package/dist/modes/interactive/rewind-list.js +123 -0
  308. package/dist/modes/interactive/rewind-panel.d.ts +77 -0
  309. package/dist/modes/interactive/rewind-panel.js +309 -0
  310. package/dist/modes/interactive/rewind-text.d.ts +40 -0
  311. package/dist/modes/interactive/rewind-text.js +139 -0
  312. package/dist/modes/interactive/session-events.d.ts +24 -0
  313. package/dist/modes/interactive/session-events.js +96 -0
  314. package/dist/modes/interactive/status-area.d.ts +73 -0
  315. package/dist/modes/interactive/status-area.js +190 -0
  316. package/dist/modes/interactive/status-bar.d.ts +99 -11
  317. package/dist/modes/interactive/status-bar.js +273 -90
  318. package/dist/modes/interactive/status-line.d.ts +33 -0
  319. package/dist/modes/interactive/status-line.js +113 -0
  320. package/dist/modes/interactive/subagent-view.d.ts +56 -0
  321. package/dist/modes/interactive/subagent-view.js +154 -0
  322. package/dist/modes/interactive/tasks-report.d.ts +27 -0
  323. package/dist/modes/interactive/tasks-report.js +114 -0
  324. package/dist/modes/interactive/tool-view.d.ts +12 -2
  325. package/dist/modes/interactive/tool-view.js +34 -4
  326. package/dist/modes/print/print-mode.d.ts +13 -4
  327. package/dist/modes/print/print-mode.js +56 -12
  328. package/dist/modes/rpc/commands.d.ts +9 -0
  329. package/dist/modes/rpc/commands.js +44 -0
  330. package/dist/modes/rpc/rpc-mode.js +7 -1
  331. package/dist/modes/session-report.d.ts +11 -0
  332. package/dist/modes/session-report.js +48 -1
  333. package/dist/permissions/auto-safe.d.ts +5 -0
  334. package/dist/permissions/auto-safe.js +18 -0
  335. package/dist/permissions/classifier.d.ts +4 -0
  336. package/dist/permissions/classifier.js +2 -0
  337. package/dist/permissions/modes.js +1 -1
  338. package/dist/permissions/pipeline.d.ts +43 -4
  339. package/dist/permissions/pipeline.js +114 -9
  340. package/dist/permissions/readonly-bash.d.ts +30 -0
  341. package/dist/permissions/readonly-bash.js +118 -0
  342. package/dist/permissions/types.d.ts +42 -0
  343. package/dist/plan/compose.d.ts +9 -0
  344. package/dist/plan/compose.js +19 -0
  345. package/dist/plan/controller.d.ts +71 -0
  346. package/dist/plan/controller.js +27 -0
  347. package/dist/plan/done-markers.d.ts +17 -0
  348. package/dist/plan/done-markers.js +51 -0
  349. package/dist/plan/extract.d.ts +29 -0
  350. package/dist/plan/extract.js +160 -0
  351. package/dist/plan/prompts.d.ts +36 -0
  352. package/dist/plan/prompts.js +89 -0
  353. package/dist/plan/store.d.ts +37 -0
  354. package/dist/plan/store.js +90 -0
  355. package/dist/rpc.d.ts +58 -2
  356. package/dist/rpc.js +7 -0
  357. package/dist/sandbox/bash.d.ts +74 -0
  358. package/dist/sandbox/bash.js +126 -0
  359. package/dist/sandbox/detect.d.ts +48 -0
  360. package/dist/sandbox/detect.js +149 -0
  361. package/dist/sandbox/index.d.ts +5 -0
  362. package/dist/sandbox/index.js +5 -0
  363. package/dist/sandbox/profile.d.ts +33 -0
  364. package/dist/sandbox/profile.js +76 -0
  365. package/dist/sandbox/wrap.d.ts +29 -0
  366. package/dist/sandbox/wrap.js +117 -0
  367. package/dist/sdk.d.ts +33 -2
  368. package/dist/sdk.js +24 -2
  369. package/dist/session/types.d.ts +3 -1
  370. package/dist/session/types.js +1 -0
  371. package/dist/skills/builtin.d.ts +31 -0
  372. package/dist/skills/builtin.js +109 -0
  373. package/dist/skills/discover.d.ts +2 -1
  374. package/dist/skills/index-prompt.js +5 -8
  375. package/dist/tools/background-jobs.d.ts +71 -0
  376. package/dist/tools/background-jobs.js +198 -0
  377. package/dist/tools/bash.d.ts +53 -1
  378. package/dist/tools/bash.js +158 -7
  379. package/dist/tools/clipboard-image.d.ts +44 -0
  380. package/dist/tools/clipboard-image.js +148 -0
  381. package/dist/tools/edit.d.ts +2 -0
  382. package/dist/tools/edit.js +18 -3
  383. package/dist/tools/image-file.d.ts +38 -3
  384. package/dist/tools/image-file.js +81 -10
  385. package/dist/tools/image-resize.d.ts +58 -0
  386. package/dist/tools/image-resize.js +97 -0
  387. package/dist/tools/presets.d.ts +7 -2
  388. package/dist/tools/presets.js +11 -4
  389. package/dist/tools/read.d.ts +5 -2
  390. package/dist/tools/read.js +13 -10
  391. package/dist/tools/registry.d.ts +7 -1
  392. package/dist/tools/registry.js +27 -4
  393. package/dist/tools/task-ctl.d.ts +22 -0
  394. package/dist/tools/task-ctl.js +116 -0
  395. package/dist/tools/task.d.ts +22 -10
  396. package/dist/tools/task.js +66 -26
  397. package/dist/tools/todo.d.ts +22 -2
  398. package/dist/tools/todo.js +58 -14
  399. package/dist/tools/truncate.d.ts +15 -0
  400. package/dist/tools/truncate.js +25 -0
  401. package/dist/tools/types.d.ts +113 -0
  402. package/dist/tools/types.js +5 -0
  403. package/dist/tools/write.js +3 -0
  404. package/dist/tui/glyphs.d.ts +4 -0
  405. package/dist/tui/glyphs.js +4 -0
  406. package/dist/tui/keybindings.d.ts +5 -0
  407. package/dist/tui/keybindings.js +5 -0
  408. package/docs/acp.md +78 -0
  409. package/docs/agents.md +250 -0
  410. package/docs/codemode.md +12 -8
  411. package/docs/hooks.md +26 -22
  412. package/docs/permissions.md +77 -13
  413. package/docs/plan.md +107 -0
  414. package/docs/providers.md +228 -52
  415. package/docs/rewind-plan.md +181 -0
  416. package/docs/rpc.md +92 -5
  417. package/docs/sandbox.md +215 -0
  418. package/docs/session-format.md +41 -21
  419. package/docs/sessions.md +41 -1
  420. package/docs/tui-design.md +751 -0
  421. package/docs/tui.md +125 -6
  422. package/package.json +13 -2
@@ -0,0 +1,109 @@
1
+ /**
2
+ * 内置 Skill(替代把 ama 自身文档塞进系统提示)。
3
+ *
4
+ * 系统提示里只常驻索引的一条(名字 + 一句描述,约 60 token),正文按需读取。单文件 bundle 没有
5
+ * docs 目录,所以正文是内联的配置速查(≤ 3 KB),会话发现时写到 `<dataDir>/builtin/<名>.md`(路径短,进前缀)
6
+ * (内容不变不重写),模型用 read 读、用户用 `/skill:ama-docs` 调用都走现成路径。
7
+ *
8
+ * - 排在全部用户 / 项目 Skill 之后:同名时用户的优先,内置的静默让位(不报重名 warning)。
9
+ * - 路径只取决于数据目录,会话开始时确定、会话内不变,不影响前缀稳定(设计 §9.1)。
10
+ * - 写盘失败只记 warning 并跳过该内置 Skill。
11
+ */
12
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
13
+ import { dirname, join } from "node:path";
14
+ export const BUILTIN_SKILLS_DIR = "builtin";
15
+ const AMA_DOCS_BODY = `# ama quick reference
16
+
17
+ ama is the coding agent running this session. Docs: https://github.com/Owlbay/armadra-agent (README.md, docs/).
18
+
19
+ ## Files
20
+ - User config dir \`~/.config/ama/\` (\`AMA_CONFIG_DIR\`; Windows \`%APPDATA%\\ama\`): \`config.json\`, \`auth.json\` (keys, 0600), \`hooks.json\`, \`keybindings.json\`, \`trust.json\`, \`AGENTS.md\`, \`skills/\`, \`prompts/\`.
21
+ - Data dir \`~/.local/share/ama/\` (\`AMA_DATA_DIR\`): \`sessions/\` (JSONL), \`models-dev.json\`.
22
+ - Project: \`AGENTS.md\` (found upward from cwd), \`.ama/config.json\` (can only tighten), \`.ama/hooks.json\`, \`.ama/skills/\`, \`.ama/prompts/\` (need trust).
23
+ - Merge order: defaults < user < profile < project. \`ama config show\` prints effective values and sources; \`ama config path\`, \`ama config edit\`, \`ama doctor\`.
24
+
25
+ ## config.json (common keys)
26
+ \`\`\`json
27
+ { "version": 1, "defaultModel": "provider/model-id", "thinkingLevel": "medium",
28
+ "permission": { "mode": "default", "allow": ["bash(git status*)"], "deny": ["write(**/.env*)"] },
29
+ "tools": { "preset": "default", "default": ["+task", "-glob"] }, "providers": {} }
30
+ \`\`\`
31
+ Other sections have defaults: compaction, retry, codemode, hooks, ui, skills, cache, request.
32
+
33
+ ## Providers and models
34
+ - Zero config: set a standard key env var (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY, ...). \`OPENAI_BASE_URL\` / \`ANTHROPIC_BASE_URL\` are honored.
35
+ - Store a key: \`ama auth set <provider>\` (reads stdin), \`ama auth list\`, \`ama auth remove <provider>\`. Never put keys in config; use \`"apiKey": "$ENV_VAR"\` or \`"!command"\`.
36
+ - Relay / custom endpoint: \`ama providers add <name> --base-url <url> --key-env VAR --probe\`; models may set \`"api"\`: openai-completions | openai-responses | anthropic-messages | google-generative-ai.
37
+ - \`ama models list\`, \`ama models discover <provider>\`, \`ama models check provider/model\`. Model refs are \`provider/model[@channel]\`; switch with \`--model\` or \`/model\`.
38
+
39
+ ## Permissions
40
+ Modes (\`--permission-mode\`, \`permission.mode\`, \`/permission\`, Shift+Tab): plan, default (ask for writes and commands), auto-edit, auto, full-auto, allowlist. Rules like \`bash(git push*)\`, \`write(src/**)\`; \`--allow\` / \`--deny\`. Dangerous commands always ask. Unattended runs (-p, RPC) treat "ask" as deny.
41
+
42
+ ## Tools
43
+ Presets (\`--tools-preset\`, \`tools.preset\`): default, minimal, codemode-only, coordinator. \`/tools\` toggles tools; \`--codemode off|on|only\`.
44
+
45
+ ## Sessions and rewind
46
+ - \`-c\` continues the latest session here, \`-r [id]\` resumes; \`/resume\`, \`/new\`, \`/fork\`, \`/tree\`, \`/compact\`.
47
+ - \`/rewind\` (or Esc Esc when idle) returns to before a user message: both, conversation only, or code only (edit/write checkpoints).
48
+ - \`ama sessions search|show|export\`, \`ama stats\`.
49
+
50
+ ## Skills and hooks
51
+ Skills: \`<dir>/<name>/SKILL.md\` with \`name\` and \`description\` frontmatter in \`~/.config/ama/skills/\` or \`.ama/skills/\`; invoke with \`/skill:<name>\`. Hooks: \`hooks.json\` runs commands on PreToolUse, PostToolUse, UserPromptSubmit, Stop and more.
52
+ `;
53
+ export const BUILTIN_SKILLS = Object.freeze([
54
+ {
55
+ name: "ama-docs",
56
+ description: "How to configure and use ama itself.",
57
+ body: AMA_DOCS_BODY,
58
+ },
59
+ ]);
60
+ export function builtinSkillPath(dataDir, name) {
61
+ return join(dataDir, BUILTIN_SKILLS_DIR, `${name}.md`);
62
+ }
63
+ /** 是否内置 Skill(启动头的「已加载」只数用户 / 项目的)。 */
64
+ export function isBuiltinSkill(skill) {
65
+ return (BUILTIN_SKILLS.some((b) => b.name === skill.name) &&
66
+ skill.location.endsWith(join(BUILTIN_SKILLS_DIR, `${skill.name}.md`)));
67
+ }
68
+ export function builtinSkillText(skill) {
69
+ return `---\nname: ${skill.name}\ndescription: ${skill.description}\n---\n\n${skill.body}`;
70
+ }
71
+ async function ensureFile(path, text) {
72
+ try {
73
+ if ((await readFile(path, "utf8")) === text)
74
+ return;
75
+ }
76
+ catch {
77
+ // 不存在:下面写
78
+ }
79
+ await mkdir(dirname(path), { recursive: true });
80
+ await writeFile(path, text, "utf8");
81
+ }
82
+ /** 在已发现的 Skill 之后追加内置 Skill(同名让位给已有的);返回新数组与 warning。 */
83
+ export async function withBuiltinSkills(skills, dataDir, builtins = BUILTIN_SKILLS) {
84
+ const out = [...skills];
85
+ const warnings = [];
86
+ const taken = new Set(skills.map((skill) => skill.name));
87
+ for (const builtin of builtins) {
88
+ if (taken.has(builtin.name))
89
+ continue;
90
+ const baseDir = join(dataDir, BUILTIN_SKILLS_DIR);
91
+ const location = builtinSkillPath(dataDir, builtin.name);
92
+ try {
93
+ await ensureFile(location, builtinSkillText(builtin));
94
+ }
95
+ catch (error) {
96
+ warnings.push(`内置 Skill ${builtin.name} 写入失败:${error.message}`);
97
+ continue;
98
+ }
99
+ out.push({
100
+ name: builtin.name,
101
+ description: builtin.description,
102
+ location,
103
+ baseDir,
104
+ disableModelInvocation: false,
105
+ scope: "builtin",
106
+ });
107
+ }
108
+ return { skills: out, warnings };
109
+ }
@@ -10,7 +10,8 @@
10
10
  * frontmatter:`name`(≤ 64,`^[a-z0-9-]+$`,缺省取目录名)、`description`(必填,≤ 1024)、
11
11
  * `disable-model-invocation`、`allowed-tools`(只做提示)。
12
12
  */
13
- export type SkillScope = "cli" | "profile" | "config" | "user" | "project" | "ancestor";
13
+ /** `builtin`:随 ama 分发的内置 Skill(builtin.ts),排在最后,同名让位。 */
14
+ export type SkillScope = "cli" | "profile" | "config" | "user" | "project" | "ancestor" | "builtin";
14
15
  export interface SkillSource {
15
16
  dir: string;
16
17
  scope: SkillScope;
@@ -18,24 +18,21 @@ export function formatSkillIndex(skills, options) {
18
18
  return "";
19
19
  let how;
20
20
  if (options.hasSkillTool) {
21
- how =
22
- "Call the skill tool with a skill's name to load it when the task matches its description.";
21
+ how = "call the skill tool with its name";
23
22
  }
24
23
  else if (options.hasReadTool) {
25
- how = "Use the read tool to load a skill's file when the task matches its description.";
24
+ how = "read its file";
26
25
  }
27
26
  else {
28
27
  return "";
29
28
  }
29
+ // 每个字都进缓存前缀(预算见 src/cli/prompt-budget.test.ts),说明保持一行。
30
30
  const lines = [
31
- "The following skills provide specialized instructions for specific tasks.",
32
- how,
33
- "When a skill file references a relative path, resolve it against the skill's directory.",
34
- "",
31
+ `Skills: when a task matches one, ${how} first; resolve its relative paths against its directory.`,
35
32
  "<available_skills>",
36
33
  ];
37
34
  for (const s of visible) {
38
- lines.push(" <skill>", ` <name>${escapeXml(s.name)}</name>`, ` <description>${escapeXml(s.description)}</description>`, ` <location>${escapeXml(s.location)}</location>`, " </skill>");
35
+ lines.push(`<skill name="${escapeXml(s.name)}" location="${escapeXml(s.location)}">${escapeXml(s.description)}</skill>`);
39
36
  }
40
37
  lines.push("</available_skills>");
41
38
  return lines.join("\n");
@@ -0,0 +1,71 @@
1
+ /**
2
+ * 后台命令(docs/wave5-plan.md §8.3 H6,D29:不加新工具,`bash{background}` + `bash{job, action}`)。[W5-H2]
3
+ *
4
+ * - `start`:调用方(bash.ts)给出 `spawn(stdout)`——**进程只在 bash.ts 的 `spawnShell` 里创建**,
5
+ * 这里只拿到 ChildProcess;stdout / stderr 直接写进 `outputPath`(文件描述符交给子进程,ama 退出也不
6
+ * 会因管道断开而 SIGPIPE)。POSIX 自成进程组并登记(进程退出时同步 SIGKILL 残留组)。
7
+ * - `wait(id, timeoutMs)`:等到退出或超时;`stop(id)`:杀整棵树(SIGTERM → 宽限 → SIGKILL);
8
+ * `output(id)`:读输出文件尾部(2000 行 / 50 KB)。
9
+ * - 生命周期事件经 `onChange` 发出(started / exited / stopped);`takeExited()` 取走尚未通知的已退出
10
+ * 任务(提醒通道 reminders.ts 据此告诉模型「后台命令 jobId 已退出(码 N)」)。
11
+ * - 按会话 id 登记(`jobsForSession`);`disposeSessionJobs` 在会话 dispose 时回收进程树。
12
+ */
13
+ import type { ChildProcess } from "node:child_process";
14
+ import { type ProcessDeps } from "./process-tree.js";
15
+ import { type TruncateResult } from "./truncate.js";
16
+ export type JobStatus = "running" | "exited" | "stopped";
17
+ export interface Job {
18
+ id: string;
19
+ command: string;
20
+ cwd: string;
21
+ pid?: number;
22
+ outputPath: string;
23
+ startedAt: number;
24
+ status: JobStatus;
25
+ /** 退出码(信号退出为 128 + signo);运行中 undefined。 */
26
+ exitCode?: number;
27
+ endedAt?: number;
28
+ }
29
+ export interface JobStartOptions {
30
+ cwd: string;
31
+ outputPath: string;
32
+ /** 用给定的输出文件描述符启动进程(bash.ts 的 spawnShell)。 */
33
+ spawn(outputFd: number): ChildProcess;
34
+ processDeps?: ProcessDeps;
35
+ }
36
+ export type JobChange = {
37
+ phase: "started" | "exited" | "stopped";
38
+ job: Job;
39
+ };
40
+ /** 后台 bash 的查询形状:`{ job, action: wait | stop | output }`,不带 command。 */
41
+ export declare function isBackgroundJobQuery(toolName: string, input: unknown): boolean;
42
+ export declare class BackgroundJobs {
43
+ private readonly entries;
44
+ private readonly listeners;
45
+ private seq;
46
+ start(command: string, options: JobStartOptions): Job;
47
+ get(id: string): Job | undefined;
48
+ list(): Job[];
49
+ /** 等到退出或超时(`signal` 可提前结束等待,不杀进程)。 */
50
+ wait(id: string, timeoutMs: number, signal?: AbortSignal): Promise<Job | undefined>;
51
+ stop(id: string): Promise<Job | undefined>;
52
+ /** 输出文件尾部(2000 行 / 50 KB)。 */
53
+ output(id: string): (TruncateResult & {
54
+ job: Job;
55
+ }) | undefined;
56
+ /** 取走已退出、尚未通知的任务(提醒通道用;wait 已看到退出的也算已知)。 */
57
+ takeExited(): Job[];
58
+ /** 标记为已知(模型已经通过 wait / output 看到了退出)。 */
59
+ markSeen(id: string): void;
60
+ onChange(listener: (change: JobChange) => void): () => void;
61
+ get running(): number;
62
+ /** 杀掉全部仍在运行的任务(会话 dispose)。 */
63
+ disposeAll(): Promise<void>;
64
+ private notify;
65
+ }
66
+ /** 会话的后台任务表(按会话 id,首次使用时建)。 */
67
+ export declare function jobsForSession(sessionId: string): BackgroundJobs;
68
+ /** 已有的任务表(不新建)。 */
69
+ export declare function existingJobs(sessionId: string): BackgroundJobs | undefined;
70
+ /** 会话 dispose:杀掉该会话仍在运行的后台任务并注销。 */
71
+ export declare function disposeSessionJobs(sessionId: string): Promise<void>;
@@ -0,0 +1,198 @@
1
+ /**
2
+ * 后台命令(docs/wave5-plan.md §8.3 H6,D29:不加新工具,`bash{background}` + `bash{job, action}`)。[W5-H2]
3
+ *
4
+ * - `start`:调用方(bash.ts)给出 `spawn(stdout)`——**进程只在 bash.ts 的 `spawnShell` 里创建**,
5
+ * 这里只拿到 ChildProcess;stdout / stderr 直接写进 `outputPath`(文件描述符交给子进程,ama 退出也不
6
+ * 会因管道断开而 SIGPIPE)。POSIX 自成进程组并登记(进程退出时同步 SIGKILL 残留组)。
7
+ * - `wait(id, timeoutMs)`:等到退出或超时;`stop(id)`:杀整棵树(SIGTERM → 宽限 → SIGKILL);
8
+ * `output(id)`:读输出文件尾部(2000 行 / 50 KB)。
9
+ * - 生命周期事件经 `onChange` 发出(started / exited / stopped);`takeExited()` 取走尚未通知的已退出
10
+ * 任务(提醒通道 reminders.ts 据此告诉模型「后台命令 jobId 已退出(码 N)」)。
11
+ * - 按会话 id 登记(`jobsForSession`);`disposeSessionJobs` 在会话 dispose 时回收进程树。
12
+ */
13
+ import { closeSync, mkdirSync, openSync, readFileSync, statSync } from "node:fs";
14
+ import { dirname } from "node:path";
15
+ import { exitCodeOf, isGroupAlive, killProcessTree, trackProcessGroup, untrackProcessGroup, } from "./process-tree.js";
16
+ import { truncateTail } from "./truncate.js";
17
+ /** 后台 bash 的查询形状:`{ job, action: wait | stop | output }`,不带 command。 */
18
+ export function isBackgroundJobQuery(toolName, input) {
19
+ if (toolName !== "bash" || typeof input !== "object" || input === null)
20
+ return false;
21
+ const record = input;
22
+ return typeof record.job === "string" && record.command === undefined;
23
+ }
24
+ export class BackgroundJobs {
25
+ entries = new Map();
26
+ listeners = new Set();
27
+ seq = 0;
28
+ start(command, options) {
29
+ mkdirSync(dirname(options.outputPath), { recursive: true });
30
+ const fd = openSync(options.outputPath, "a");
31
+ let child;
32
+ try {
33
+ child = options.spawn(fd);
34
+ }
35
+ finally {
36
+ closeSync(fd);
37
+ }
38
+ const id = `bg${++this.seq}`;
39
+ const job = {
40
+ id,
41
+ command,
42
+ cwd: options.cwd,
43
+ outputPath: options.outputPath,
44
+ startedAt: Date.now(),
45
+ status: "running",
46
+ };
47
+ if (child.pid !== undefined)
48
+ job.pid = child.pid;
49
+ const isWindows = (options.processDeps?.platform ?? process.platform) === "win32";
50
+ if (job.pid !== undefined && !isWindows)
51
+ trackProcessGroup(job.pid);
52
+ const entry = {
53
+ job,
54
+ notified: false,
55
+ stopping: false,
56
+ processDeps: options.processDeps,
57
+ done: new Promise((resolve) => {
58
+ const finish = (code, signal) => {
59
+ if (job.status !== "running")
60
+ return resolve();
61
+ job.exitCode = exitCodeOf(code, signal);
62
+ job.endedAt = Date.now();
63
+ job.status = entry.stopping ? "stopped" : "exited";
64
+ const pid = job.pid;
65
+ if (pid !== undefined && !isWindows && !isGroupAlive(pid, options.processDeps ?? {}))
66
+ untrackProcessGroup(pid);
67
+ this.notify({ phase: job.status === "stopped" ? "stopped" : "exited", job });
68
+ resolve();
69
+ };
70
+ child.once("exit", finish);
71
+ child.once("error", () => finish(127, null));
72
+ }),
73
+ };
74
+ child.unref();
75
+ this.entries.set(id, entry);
76
+ this.notify({ phase: "started", job });
77
+ return job;
78
+ }
79
+ get(id) {
80
+ return this.entries.get(id)?.job;
81
+ }
82
+ list() {
83
+ return [...this.entries.values()].map((entry) => entry.job);
84
+ }
85
+ /** 等到退出或超时(`signal` 可提前结束等待,不杀进程)。 */
86
+ async wait(id, timeoutMs, signal) {
87
+ const entry = this.entries.get(id);
88
+ if (entry === undefined)
89
+ return undefined;
90
+ if (entry.job.status !== "running")
91
+ return entry.job;
92
+ let timer;
93
+ let onAbort;
94
+ await Promise.race([
95
+ entry.done,
96
+ new Promise((resolve) => {
97
+ timer = setTimeout(resolve, Math.max(0, timeoutMs));
98
+ onAbort = () => resolve();
99
+ signal?.addEventListener("abort", onAbort, { once: true });
100
+ }),
101
+ ]);
102
+ if (timer !== undefined)
103
+ clearTimeout(timer);
104
+ if (onAbort !== undefined)
105
+ signal?.removeEventListener("abort", onAbort);
106
+ return entry.job;
107
+ }
108
+ async stop(id) {
109
+ const entry = this.entries.get(id);
110
+ if (entry === undefined)
111
+ return undefined;
112
+ if (entry.job.status !== "running")
113
+ return entry.job;
114
+ entry.stopping = true;
115
+ // 已经由调用方知道结果:停止的任务不再经提醒通道通知
116
+ entry.notified = true;
117
+ if (entry.job.pid !== undefined)
118
+ await killProcessTree(entry.job.pid, entry.processDeps);
119
+ await entry.done;
120
+ return entry.job;
121
+ }
122
+ /** 输出文件尾部(2000 行 / 50 KB)。 */
123
+ output(id) {
124
+ const entry = this.entries.get(id);
125
+ if (entry === undefined)
126
+ return undefined;
127
+ let text = "";
128
+ try {
129
+ if (statSync(entry.job.outputPath).size > 0)
130
+ text = readFileSync(entry.job.outputPath, "utf8");
131
+ }
132
+ catch {
133
+ // 输出文件被删:按空输出
134
+ }
135
+ return { ...truncateTail(text), job: entry.job };
136
+ }
137
+ /** 取走已退出、尚未通知的任务(提醒通道用;wait 已看到退出的也算已知)。 */
138
+ takeExited() {
139
+ const out = [];
140
+ for (const entry of this.entries.values()) {
141
+ if (entry.job.status === "running" || entry.notified)
142
+ continue;
143
+ entry.notified = true;
144
+ out.push(entry.job);
145
+ }
146
+ return out;
147
+ }
148
+ /** 标记为已知(模型已经通过 wait / output 看到了退出)。 */
149
+ markSeen(id) {
150
+ const entry = this.entries.get(id);
151
+ if (entry !== undefined && entry.job.status !== "running")
152
+ entry.notified = true;
153
+ }
154
+ onChange(listener) {
155
+ this.listeners.add(listener);
156
+ return () => this.listeners.delete(listener);
157
+ }
158
+ get running() {
159
+ return this.list().filter((job) => job.status === "running").length;
160
+ }
161
+ /** 杀掉全部仍在运行的任务(会话 dispose)。 */
162
+ async disposeAll() {
163
+ await Promise.all([...this.entries.keys()].map((id) => this.stop(id).catch(() => undefined)));
164
+ this.listeners.clear();
165
+ }
166
+ notify(change) {
167
+ for (const listener of this.listeners) {
168
+ try {
169
+ listener(change);
170
+ }
171
+ catch {
172
+ // 监听器异常不影响任务
173
+ }
174
+ }
175
+ }
176
+ }
177
+ const registry = new Map();
178
+ /** 会话的后台任务表(按会话 id,首次使用时建)。 */
179
+ export function jobsForSession(sessionId) {
180
+ let jobs = registry.get(sessionId);
181
+ if (jobs === undefined) {
182
+ jobs = new BackgroundJobs();
183
+ registry.set(sessionId, jobs);
184
+ }
185
+ return jobs;
186
+ }
187
+ /** 已有的任务表(不新建)。 */
188
+ export function existingJobs(sessionId) {
189
+ return registry.get(sessionId);
190
+ }
191
+ /** 会话 dispose:杀掉该会话仍在运行的后台任务并注销。 */
192
+ export async function disposeSessionJobs(sessionId) {
193
+ const jobs = registry.get(sessionId);
194
+ if (jobs === undefined)
195
+ return;
196
+ registry.delete(sessionId);
197
+ await jobs.disposeAll();
198
+ }
@@ -7,17 +7,43 @@
7
7
  * - 结构化结果 `{ output, exit_code, truncated, full_output_path?, wall_time_seconds }`;
8
8
  * 信号退出 `128 + signo`;非零退出码 → isError;
9
9
  * - 注入 `AMA_*` 环境变量(shell.ts)。shell 退出后不等仍占着管道的后台进程。
10
+ * - [W5-H2] 后台命令(§8.3 H6,不加新工具):`{ command, background: true }` 立即返回
11
+ * `{ jobId, outputPath, pid }`;`{ job, action: "wait" | "output" | "stop" }` 查询 / 结束
12
+ * (background-jobs.ts,按会话登记,会话 dispose 时回收进程树;退出经提醒通道通知)。
13
+ * - **进程只在 `spawnShell` 里创建**(前台与后台共用)。[S2] `sandbox.bash: auto` 且有能限制写入的
14
+ * OS 沙箱时在这一处包一层(src/sandbox/bash.ts);`sandbox: false` 不包装(权限管线照常审批)。
15
+ * 失败输出像是被沙箱拒绝时末尾追加一行说明。
10
16
  */
17
+ import { type ChildProcess } from "node:child_process";
11
18
  import type { ToolContext, ToolDefinition, ToolResult } from "./types.js";
12
19
  import { type ShellConfig } from "./shell.js";
13
20
  import { type ProcessDeps } from "./process-tree.js";
21
+ import { type BackgroundJobs } from "./background-jobs.js";
22
+ import { type BashCallPlace, type BashSandbox } from "../sandbox/bash.js";
14
23
  export declare const DEFAULT_BASH_TIMEOUT_MS = 120000;
15
24
  export declare const MAX_BASH_TIMEOUT_MS = 600000;
16
25
  export interface BashInput {
17
- command: string;
26
+ /** 前台 / 后台命令;查询后台任务时不给。 */
27
+ command?: string;
18
28
  timeoutMs?: number;
19
29
  cwd?: string;
20
30
  description?: string;
31
+ /** [W5-H2] 后台运行:立即返回 jobId。 */
32
+ background?: boolean;
33
+ /** [W5-H2] 后台任务 id(与 action 一起用)。 */
34
+ job?: string;
35
+ action?: "wait" | "output" | "stop";
36
+ /** [S2] false:不经 OS 沙箱运行(走正常审批)。只在沙箱生效时出现在 schema 里。 */
37
+ sandbox?: boolean;
38
+ }
39
+ /** [W5-H2] `wait` 的缺省等待(毫秒)。 */
40
+ export declare const DEFAULT_JOB_WAIT_MS = 30000;
41
+ export interface BackgroundStart {
42
+ jobId: string;
43
+ outputPath: string;
44
+ pid?: number;
45
+ /** [S2] 经 OS 沙箱运行。 */
46
+ sandboxed?: true;
21
47
  }
22
48
  export interface BashStructured {
23
49
  output: string;
@@ -25,6 +51,8 @@ export interface BashStructured {
25
51
  truncated: boolean;
26
52
  full_output_path?: string;
27
53
  wall_time_seconds: number;
54
+ /** [S2] 经 OS 沙箱运行。 */
55
+ sandboxed?: true;
28
56
  }
29
57
  export interface BashDetails extends BashStructured {
30
58
  timedOut: boolean;
@@ -44,6 +72,30 @@ export interface BashToolOptions {
44
72
  processDeps?: ProcessDeps;
45
73
  /** 测试注入:基础环境,缺省 process.env。 */
46
74
  baseEnv?(): NodeJS.ProcessEnv;
75
+ /** 测试注入:会话的后台任务表,缺省按会话 id 登记(background-jobs.ts)。 */
76
+ jobs?(sessionId: string): BackgroundJobs;
77
+ /** [S2] bash 的 OS 沙箱设定(组装时算一次,会话内不变);缺省不用沙箱。 */
78
+ sandbox?: BashSandbox;
79
+ }
80
+ export interface SpawnShellOptions {
81
+ cwd: string;
82
+ env: NodeJS.ProcessEnv;
83
+ /** POSIX 自成进程组(杀树用);Windows 为 false。 */
84
+ detached: boolean;
85
+ /** 前台 `["ignore", "pipe", "pipe"]`;后台把输出文件描述符直接交给子进程。 */
86
+ stdio: ["ignore", "pipe" | number, "pipe" | number];
87
+ /** [S2] 经 OS 沙箱运行:设定与这次调用的位置(工作区、输出目录)。 */
88
+ sandbox?: {
89
+ settings: BashSandbox;
90
+ place: BashCallPlace;
91
+ };
47
92
  }
93
+ /**
94
+ * bash 工具唯一的进程创建点(前台 / 后台共用);[S2] 给了 `sandbox` 时经 OS 沙箱包装(包不上抛错,
95
+ * 不悄悄裸跑)。
96
+ */
97
+ export declare function spawnShell(shell: ShellConfig, command: string, options: SpawnShellOptions): ChildProcess;
48
98
  export declare function executeBash(input: BashInput, ctx: ToolContext, options?: BashToolOptions): Promise<ToolResult>;
99
+ /** [S2] 沙箱生效时追加到描述末尾的一句(会话内不变)。 */
100
+ export declare function sandboxDescription(sandbox: BashSandbox | undefined): string;
49
101
  export declare function createBashTool(options?: BashToolOptions): ToolDefinition<BashInput>;