stageflow 0.39.0 → 0.42.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 (360) hide show
  1. package/README.md +46 -19
  2. package/dist/agent/claudeAdapter.js +15 -1
  3. package/dist/agent/claudeTools.d.ts +13 -0
  4. package/dist/agent/claudeTools.js +98 -0
  5. package/dist/agent/piAdapter.js +38 -16
  6. package/dist/agent/sandboxPiTools.d.ts +99 -0
  7. package/dist/agent/sandboxPiTools.js +109 -0
  8. package/dist/agents/authorChat.d.ts +4 -0
  9. package/dist/agents/authorChat.js +113 -12
  10. package/dist/agents/authorSessionStore.d.ts +35 -0
  11. package/dist/agents/authorSessionStore.js +152 -0
  12. package/dist/agents/chatTurn.d.ts +2 -0
  13. package/dist/agents/chatTurn.js +17 -1
  14. package/dist/agents/errors.d.ts +1 -1
  15. package/dist/agents/errors.js +1 -0
  16. package/dist/agents/evalGate.d.ts +61 -0
  17. package/dist/agents/evalGate.js +103 -0
  18. package/dist/agents/evalSession.d.ts +26 -0
  19. package/dist/agents/evalSession.js +29 -0
  20. package/dist/agents/hostContext.d.ts +3 -0
  21. package/dist/agents/hostContext.js +4 -1
  22. package/dist/agents/runtime/piRuntime.d.ts +1 -1
  23. package/dist/agents/runtime/piRuntime.js +4 -4
  24. package/dist/agents/runtime/types.d.ts +3 -1
  25. package/dist/agents/service.d.ts +27 -2
  26. package/dist/agents/service.js +88 -13
  27. package/dist/agents/sessions.d.ts +8 -0
  28. package/dist/agents/sessions.js +50 -10
  29. package/dist/agents/store.d.ts +14 -3
  30. package/dist/agents/store.js +45 -7
  31. package/dist/agents/toolRisk.d.ts +21 -0
  32. package/dist/agents/toolRisk.js +50 -0
  33. package/dist/cli/doctorCommand.js +26 -0
  34. package/dist/cli/evalCommand.d.ts +20 -0
  35. package/dist/cli/evalCommand.js +720 -0
  36. package/dist/cli/exportAllCommand.js +1 -1
  37. package/dist/cli/hostClient.d.ts +60 -0
  38. package/dist/cli/hostClient.js +71 -0
  39. package/dist/cli/validateOutput.d.ts +2 -2
  40. package/dist/cli/validateOutput.js +2 -2
  41. package/dist/cli.js +10 -0
  42. package/dist/config/atomicWrite.d.ts +15 -0
  43. package/dist/config/atomicWrite.js +43 -0
  44. package/dist/config/browseCatalog.d.ts +2 -0
  45. package/dist/config/browseCatalog.js +4 -2
  46. package/dist/config/csv.d.ts +9 -0
  47. package/dist/config/csv.js +81 -0
  48. package/dist/config/datasetAgentCheck.d.ts +18 -0
  49. package/dist/config/datasetAgentCheck.js +109 -0
  50. package/dist/config/datasetCandidates.d.ts +22 -0
  51. package/dist/config/datasetCandidates.js +86 -0
  52. package/dist/config/datasetFromSessions.d.ts +34 -0
  53. package/dist/config/datasetFromSessions.js +105 -0
  54. package/dist/config/datasetHash.d.ts +1 -0
  55. package/dist/config/datasetHash.js +4 -0
  56. package/dist/config/datasetImport.d.ts +21 -0
  57. package/dist/config/datasetImport.js +120 -0
  58. package/dist/config/datasetStageCheck.d.ts +9 -0
  59. package/dist/config/datasetStageCheck.js +17 -0
  60. package/dist/config/datasetTypes.d.ts +27 -0
  61. package/dist/config/datasetTypes.js +1 -0
  62. package/dist/config/ensureCatalogScanRoot.d.ts +2 -1
  63. package/dist/config/ensureCatalogScanRoot.js +2 -6
  64. package/dist/config/evalCatalog.d.ts +22 -0
  65. package/dist/config/evalCatalog.js +67 -0
  66. package/dist/config/evalWriteRoots.d.ts +17 -0
  67. package/dist/config/evalWriteRoots.js +109 -0
  68. package/dist/config/hostConfig.js +3 -0
  69. package/dist/config/installEvalSample.d.ts +34 -0
  70. package/dist/config/installEvalSample.js +182 -0
  71. package/dist/config/loadDataset.d.ts +16 -0
  72. package/dist/config/loadDataset.js +318 -0
  73. package/dist/config/loadEval.d.ts +32 -0
  74. package/dist/config/loadEval.js +1085 -0
  75. package/dist/config/loadOutcome.d.ts +5 -0
  76. package/dist/config/loadStageflowManifest.js +64 -0
  77. package/dist/config/loadTask.js +34 -1
  78. package/dist/config/resolveAgentTarget.d.ts +32 -0
  79. package/dist/config/resolveAgentTarget.js +118 -0
  80. package/dist/config/resolveEvalTarget.d.ts +21 -0
  81. package/dist/config/resolveEvalTarget.js +89 -0
  82. package/dist/config/scanCatalogPaths.d.ts +1 -1
  83. package/dist/config/scanCatalogPaths.js +17 -5
  84. package/dist/config/validateCatalog.d.ts +1 -1
  85. package/dist/config/validateCatalog.js +9 -1
  86. package/dist/config/validateEval.d.ts +36 -0
  87. package/dist/config/validateEval.js +405 -0
  88. package/dist/config/writeDataset.d.ts +54 -0
  89. package/dist/config/writeDataset.js +186 -0
  90. package/dist/config/writeEval.d.ts +25 -0
  91. package/dist/config/writeEval.js +398 -0
  92. package/dist/diagnostics/checks.js +1 -1
  93. package/dist/evals/agentDiff.d.ts +13 -0
  94. package/dist/evals/agentDiff.js +11 -0
  95. package/dist/evals/canonical.d.ts +3 -0
  96. package/dist/evals/canonical.js +24 -0
  97. package/dist/evals/caseTask.d.ts +3 -0
  98. package/dist/evals/caseTask.js +9 -0
  99. package/dist/evals/compare.d.ts +94 -0
  100. package/dist/evals/compare.js +201 -0
  101. package/dist/evals/constants.d.ts +60 -0
  102. package/dist/evals/constants.js +95 -0
  103. package/dist/evals/engine/FakeEngine.d.ts +33 -0
  104. package/dist/evals/engine/FakeEngine.js +176 -0
  105. package/dist/evals/engine/index.d.ts +9 -0
  106. package/dist/evals/engine/index.js +19 -0
  107. package/dist/evals/engine/promptfoo/PromptfooEngine.d.ts +52 -0
  108. package/dist/evals/engine/promptfoo/PromptfooEngine.js +311 -0
  109. package/dist/evals/engine/promptfoo/errors.d.ts +5 -0
  110. package/dist/evals/engine/promptfoo/errors.js +8 -0
  111. package/dist/evals/engine/promptfoo/generate.d.ts +30 -0
  112. package/dist/evals/engine/promptfoo/generate.js +342 -0
  113. package/dist/evals/engine/promptfoo/guard.d.ts +10 -0
  114. package/dist/evals/engine/promptfoo/guard.js +116 -0
  115. package/dist/evals/engine/promptfoo/install.d.ts +17 -0
  116. package/dist/evals/engine/promptfoo/install.js +73 -0
  117. package/dist/evals/engine/promptfoo/judgeProviders.d.ts +2 -0
  118. package/dist/evals/engine/promptfoo/judgeProviders.js +9 -0
  119. package/dist/evals/engine/promptfoo/judgeServices.d.ts +6 -0
  120. package/dist/evals/engine/promptfoo/judgeServices.js +41 -0
  121. package/dist/evals/engine/promptfoo/locate.d.ts +21 -0
  122. package/dist/evals/engine/promptfoo/locate.js +68 -0
  123. package/dist/evals/engine/promptfoo/nodeVersion.d.ts +7 -0
  124. package/dist/evals/engine/promptfoo/nodeVersion.js +14 -0
  125. package/dist/evals/engine/promptfoo/normalize.d.ts +66 -0
  126. package/dist/evals/engine/promptfoo/normalize.js +261 -0
  127. package/dist/evals/engine/promptfoo/pinned.d.ts +5 -0
  128. package/dist/evals/engine/promptfoo/pinned.js +5 -0
  129. package/dist/evals/engine/promptfoo/rubricPrompt.d.ts +14 -0
  130. package/dist/evals/engine/promptfoo/rubricPrompt.js +103 -0
  131. package/dist/evals/engine/promptfoo/runTokens.d.ts +18 -0
  132. package/dist/evals/engine/promptfoo/runTokens.js +31 -0
  133. package/dist/evals/engine/promptfoo/status.d.ts +13 -0
  134. package/dist/evals/engine/promptfoo/status.js +16 -0
  135. package/dist/evals/estimate.d.ts +56 -0
  136. package/dist/evals/estimate.js +66 -0
  137. package/dist/evals/graders/codeGrader.d.ts +6 -0
  138. package/dist/evals/graders/codeGrader.js +85 -0
  139. package/dist/evals/graders/conversationCheckGrader.d.ts +6 -0
  140. package/dist/evals/graders/conversationCheckGrader.js +62 -0
  141. package/dist/evals/graders/fieldGrader.d.ts +11 -0
  142. package/dist/evals/graders/fieldGrader.js +117 -0
  143. package/dist/evals/graders/goal.d.ts +3 -0
  144. package/dist/evals/graders/goal.js +14 -0
  145. package/dist/evals/graders/index.d.ts +18 -0
  146. package/dist/evals/graders/index.js +34 -0
  147. package/dist/evals/graders/notApplicable.d.ts +5 -0
  148. package/dist/evals/graders/notApplicable.js +9 -0
  149. package/dist/evals/graders/path.d.ts +26 -0
  150. package/dist/evals/graders/path.js +75 -0
  151. package/dist/evals/graders/referenceGrader.d.ts +5 -0
  152. package/dist/evals/graders/referenceGrader.js +59 -0
  153. package/dist/evals/graders/schemaGrader.d.ts +5 -0
  154. package/dist/evals/graders/schemaGrader.js +29 -0
  155. package/dist/evals/graders/subject.d.ts +6 -0
  156. package/dist/evals/graders/subject.js +33 -0
  157. package/dist/evals/graders/toolCallsGrader.d.ts +6 -0
  158. package/dist/evals/graders/toolCallsGrader.js +100 -0
  159. package/dist/evals/graders/transcript.d.ts +12 -0
  160. package/dist/evals/graders/transcript.js +57 -0
  161. package/dist/evals/graders/types.d.ts +20 -0
  162. package/dist/evals/graders/types.js +1 -0
  163. package/dist/evals/judgeProviders.d.ts +16 -0
  164. package/dist/evals/judgeProviders.js +27 -0
  165. package/dist/evals/lineDiff.d.ts +5 -0
  166. package/dist/evals/lineDiff.js +34 -0
  167. package/dist/evals/listStatus.d.ts +31 -0
  168. package/dist/evals/listStatus.js +48 -0
  169. package/dist/evals/manager.d.ts +174 -0
  170. package/dist/evals/manager.js +787 -0
  171. package/dist/evals/plan.d.ts +58 -0
  172. package/dist/evals/plan.js +602 -0
  173. package/dist/evals/providerKeys.d.ts +1 -0
  174. package/dist/evals/providerKeys.js +21 -0
  175. package/dist/evals/read/agentTargets.d.ts +37 -0
  176. package/dist/evals/read/agentTargets.js +101 -0
  177. package/dist/evals/read/api.d.ts +196 -0
  178. package/dist/evals/read/api.js +358 -0
  179. package/dist/evals/read/compare.d.ts +4 -0
  180. package/dist/evals/read/compare.js +39 -0
  181. package/dist/evals/read/datasets.d.ts +105 -0
  182. package/dist/evals/read/datasets.js +318 -0
  183. package/dist/evals/read/list.d.ts +66 -0
  184. package/dist/evals/read/list.js +173 -0
  185. package/dist/evals/read/results.d.ts +46 -0
  186. package/dist/evals/read/results.js +107 -0
  187. package/dist/evals/read/runs.d.ts +149 -0
  188. package/dist/evals/read/runs.js +289 -0
  189. package/dist/evals/read/suggestions.d.ts +43 -0
  190. package/dist/evals/read/suggestions.js +73 -0
  191. package/dist/evals/runner/FakeAgentBackend.d.ts +40 -0
  192. package/dist/evals/runner/FakeAgentBackend.js +82 -0
  193. package/dist/evals/runner/agentCaseRunner.d.ts +24 -0
  194. package/dist/evals/runner/agentCaseRunner.js +388 -0
  195. package/dist/evals/runner/caseRunner.d.ts +7 -0
  196. package/dist/evals/runner/caseRunner.js +17 -0
  197. package/dist/evals/runner/conversationSubject.d.ts +18 -0
  198. package/dist/evals/runner/conversationSubject.js +123 -0
  199. package/dist/evals/runner/simulatorModel.d.ts +51 -0
  200. package/dist/evals/runner/simulatorModel.js +58 -0
  201. package/dist/evals/runner/simulatorPrompt.d.ts +29 -0
  202. package/dist/evals/runner/simulatorPrompt.js +59 -0
  203. package/dist/evals/runner/stageCaseRunner.d.ts +30 -0
  204. package/dist/evals/runner/stageCaseRunner.js +279 -0
  205. package/dist/evals/runner/userDriver.d.ts +71 -0
  206. package/dist/evals/runner/userDriver.js +104 -0
  207. package/dist/evals/scoring.d.ts +34 -0
  208. package/dist/evals/scoring.js +67 -0
  209. package/dist/evals/snapshot.d.ts +183 -0
  210. package/dist/evals/snapshot.js +65 -0
  211. package/dist/evals/stageDiff.d.ts +8 -0
  212. package/dist/evals/stageDiff.js +48 -0
  213. package/dist/evals/stats.d.ts +95 -0
  214. package/dist/evals/stats.js +220 -0
  215. package/dist/evals/statsAdapter.d.ts +4 -0
  216. package/dist/evals/statsAdapter.js +30 -0
  217. package/dist/evals/statsTypes.d.ts +51 -0
  218. package/dist/evals/statsTypes.js +18 -0
  219. package/dist/evals/storeError.d.ts +5 -0
  220. package/dist/evals/storeError.js +8 -0
  221. package/dist/evals/storeTypes.d.ts +207 -0
  222. package/dist/evals/storeTypes.js +1 -0
  223. package/dist/evals/tTable.d.ts +3 -0
  224. package/dist/evals/tTable.js +15 -0
  225. package/dist/evals/triage/constants.d.ts +26 -0
  226. package/dist/evals/triage/constants.js +33 -0
  227. package/dist/evals/triage/credentials.d.ts +13 -0
  228. package/dist/evals/triage/credentials.js +20 -0
  229. package/dist/evals/triage/jevClassifier.d.ts +14 -0
  230. package/dist/evals/triage/jevClassifier.js +124 -0
  231. package/dist/evals/triage/judgeClassifier.d.ts +10 -0
  232. package/dist/evals/triage/judgeClassifier.js +76 -0
  233. package/dist/evals/triage/prompts.d.ts +16 -0
  234. package/dist/evals/triage/prompts.js +64 -0
  235. package/dist/evals/triage/service.d.ts +79 -0
  236. package/dist/evals/triage/service.js +217 -0
  237. package/dist/evals/triage/stateBuilder.d.ts +19 -0
  238. package/dist/evals/triage/stateBuilder.js +125 -0
  239. package/dist/evals/triage/types.d.ts +60 -0
  240. package/dist/evals/triage/types.js +8 -0
  241. package/dist/evals/types.d.ts +347 -0
  242. package/dist/evals/types.js +1 -0
  243. package/dist/mcp/catalogTools.js +11 -1
  244. package/dist/mcp/deps.d.ts +7 -0
  245. package/dist/mcp/evalTools.d.ts +3 -0
  246. package/dist/mcp/evalTools.js +280 -0
  247. package/dist/mcp/server.js +1 -0
  248. package/dist/mcp/tools.js +2 -0
  249. package/dist/models/response.d.ts +7 -2
  250. package/dist/models/response.js +6 -1
  251. package/dist/operatorAgent/agentAuthorContext.d.ts +1 -1
  252. package/dist/operatorAgent/agentAuthorContext.js +1 -1
  253. package/dist/operatorAgent/piModel.js +17 -4
  254. package/dist/operatorAgent/profiles/agentAuthor.d.ts +3 -1
  255. package/dist/operatorAgent/profiles/agentAuthor.js +145 -20
  256. package/dist/operatorAgent/profiles/agentAuthorPlaybook.d.ts +1 -1
  257. package/dist/operatorAgent/profiles/agentAuthorPlaybook.js +48 -15
  258. package/dist/operatorAgent/profiles/authorReadable.d.ts +2 -0
  259. package/dist/operatorAgent/profiles/authorReadable.js +26 -0
  260. package/dist/package-meta.d.ts +1 -1
  261. package/dist/package-meta.js +1 -1
  262. package/dist/runstore/port.d.ts +43 -0
  263. package/dist/runstore/sqlite/SqliteRunStore.d.ts +28 -0
  264. package/dist/runstore/sqlite/SqliteRunStore.js +99 -5
  265. package/dist/runstore/sqlite/evalStore.d.ts +20 -0
  266. package/dist/runstore/sqlite/evalStore.js +541 -0
  267. package/dist/runstore/sqlite/migrations/015-evals.d.ts +12 -0
  268. package/dist/runstore/sqlite/migrations/015-evals.js +157 -0
  269. package/dist/runstore/sqlite/migrations/016-eval-subject-ref.d.ts +12 -0
  270. package/dist/runstore/sqlite/migrations/016-eval-subject-ref.js +20 -0
  271. package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.d.ts +11 -0
  272. package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.js +36 -0
  273. package/dist/runstore/sqlite/migrations/index.js +6 -0
  274. package/dist/runstore/sqlite/suggestionStore.d.ts +14 -0
  275. package/dist/runstore/sqlite/suggestionStore.js +132 -0
  276. package/dist/runtime/gitCheckoutCapability.d.ts +1 -0
  277. package/dist/runtime/gitCheckoutCapability.js +1 -1
  278. package/dist/runtime/gitWorktreeCheckout.d.ts +22 -0
  279. package/dist/runtime/gitWorktreeCheckout.js +120 -0
  280. package/dist/runtime/pipelineRunner.d.ts +2 -1
  281. package/dist/runtime/pipelineRunner.js +2 -0
  282. package/dist/runtime/runManager.d.ts +2 -1
  283. package/dist/runtime/runManager.js +8 -6
  284. package/dist/runtime/runRetentionSweep.js +2 -2
  285. package/dist/runtime/sandboxContainer.d.ts +62 -0
  286. package/dist/runtime/sandboxContainer.js +151 -0
  287. package/dist/runtime/sandboxDesk.d.ts +28 -0
  288. package/dist/runtime/sandboxDesk.js +242 -0
  289. package/dist/runtime/sandboxFiles.d.ts +20 -0
  290. package/dist/runtime/sandboxFiles.js +150 -0
  291. package/dist/runtime/stageEnvironment.js +2 -0
  292. package/dist/runtime/stageRoots.d.ts +9 -0
  293. package/dist/runtime/stageRoots.js +14 -0
  294. package/dist/runtime/stageRunner.d.ts +5 -0
  295. package/dist/runtime/stageRunner.js +38 -4
  296. package/dist/runtime/stageSandbox.d.ts +16 -0
  297. package/dist/runtime/stageSandbox.js +54 -0
  298. package/dist/runtime/stageWorker.js +138 -105
  299. package/dist/runtime/workspaceBinding.d.ts +2 -1
  300. package/dist/runtime/workspaceBinding.js +20 -4
  301. package/dist/server/agentAuthorRoutes.js +50 -1
  302. package/dist/server/bootstrap.d.ts +8 -0
  303. package/dist/server/bootstrap.js +56 -0
  304. package/dist/server/controlToken.js +3 -0
  305. package/dist/server/evalInternalRoutes.d.ts +14 -0
  306. package/dist/server/evalInternalRoutes.js +87 -0
  307. package/dist/server/evalRouteContext.d.ts +46 -0
  308. package/dist/server/evalRouteContext.js +43 -0
  309. package/dist/server/evalRoutes.d.ts +5 -0
  310. package/dist/server/evalRoutes.js +1427 -0
  311. package/dist/server/evalTriageRoutes.d.ts +2 -0
  312. package/dist/server/evalTriageRoutes.js +95 -0
  313. package/dist/server/http.d.ts +5 -0
  314. package/dist/server/http.js +32 -2
  315. package/dist/server/mcpHost.js +3 -0
  316. package/dist/toolkit/meta.d.ts +1 -1
  317. package/dist/toolkit/meta.js +15 -0
  318. package/dist/toolkit/profiles.js +1 -1
  319. package/dist/tools/readEmail.d.ts +3 -3
  320. package/dist/types/stageflowManifest.d.ts +6 -0
  321. package/dist/types/task.d.ts +11 -1
  322. package/dist/ui/assets/AssistantRuntimeProvider-qIX1xNoH.js +9 -0
  323. package/dist/ui/assets/{MarkdownText-D7tYaIFO.js → MarkdownText-BTrOqu5J.js} +1 -1
  324. package/dist/ui/assets/chat-Df_wCpak.js +5 -0
  325. package/dist/ui/assets/chat-P7KQznHm.css +2 -0
  326. package/dist/ui/assets/{main-BFo79krC.css → main-CHlmTNJe.css} +1 -1
  327. package/dist/ui/assets/main-CvVfxmMd.js +271 -0
  328. package/dist/ui/chat.html +3 -3
  329. package/dist/ui/index.html +3 -3
  330. package/examples/README.md +2 -0
  331. package/examples/document-policy-review/README.md +35 -0
  332. package/examples/document-policy-review/agents/compliance.agent.yaml +42 -0
  333. package/examples/document-policy-review/documents/acme-vendor-sow.md +15 -0
  334. package/examples/document-policy-review/documents/support-runbook.md +13 -0
  335. package/examples/document-policy-review/policies/acceptable-use.md +13 -0
  336. package/examples/document-policy-review/policies/data-handling.md +17 -0
  337. package/examples/document-policy-review/policies/vendor-security.md +17 -0
  338. package/examples/evals/README.md +123 -0
  339. package/examples/evals/critique-sample.dataset.jsonl +8 -0
  340. package/examples/evals/critique-sample.eval.yaml +34 -0
  341. package/examples/evals/critique-sample.task.yaml +4 -0
  342. package/examples/evals/eval-sample.pipeline.yaml +35 -0
  343. package/examples/evals/support-sample.agent.yaml +20 -0
  344. package/examples/evals/support-sample.dataset.jsonl +6 -0
  345. package/examples/evals/support-sample.eval.yaml +38 -0
  346. package/examples/memory/README.md +2 -0
  347. package/examples/memory/probe-bash.task.yaml +3 -0
  348. package/examples/memory/sandbox-memory-bash.pipeline.yaml +28 -0
  349. package/examples/ship-feature/README.md +15 -0
  350. package/examples/stageflow.yaml +6 -0
  351. package/package.json +1 -1
  352. package/skills/stageflow/SKILL.md +5 -2
  353. package/skills/stageflow/references/control-surface.md +4 -2
  354. package/skills/stageflow/references/evals.md +68 -0
  355. package/skills/stageflow-author/SKILL.md +4 -0
  356. package/skills/stageflow-run/SKILL.md +4 -0
  357. package/dist/ui/assets/AssistantRuntimeProvider-CsiPFhCT.js +0 -9
  358. package/dist/ui/assets/chat-BbLukq9W.js +0 -5
  359. package/dist/ui/assets/chat-zIZU_bP1.css +0 -2
  360. package/dist/ui/assets/main-CijYMeM0.js +0 -259
@@ -530,7 +530,7 @@ export class RunManager {
530
530
  */
531
531
  async attachWaitingStages() {
532
532
  const found = [];
533
- const runs = await this.options.store.listRuns();
533
+ const runs = await this.options.store.listRuns({ origin: "any" });
534
534
  for (const summary of runs) {
535
535
  if (summary.status !== "running")
536
536
  continue;
@@ -627,7 +627,7 @@ export class RunManager {
627
627
  }
628
628
  async reconcileOrphanedStages() {
629
629
  const reconciled = [];
630
- const runs = await this.options.store.listRuns();
630
+ const runs = await this.options.store.listRuns({ origin: "any" });
631
631
  for (const summary of runs) {
632
632
  let meta;
633
633
  try {
@@ -806,7 +806,7 @@ export class RunManager {
806
806
  }
807
807
  async resumeStalledSchedules() {
808
808
  const resumed = [];
809
- const runs = await this.options.store.listRuns();
809
+ const runs = await this.options.store.listRuns({ origin: "any" });
810
810
  for (const summary of runs) {
811
811
  if (summary.status !== "running")
812
812
  continue;
@@ -828,7 +828,7 @@ export class RunManager {
828
828
  }
829
829
  /** Rebuild in-memory admission queue from persisted `queued` rows (R27). */
830
830
  async reenqueuePersistedQueuedRuns() {
831
- const queued = await this.options.store.listRuns({ status: "queued" });
831
+ const queued = await this.options.store.listRuns({ status: "queued", origin: "any" });
832
832
  const ordered = [...queued].sort((a, b) => a.created_at.localeCompare(b.created_at));
833
833
  this.admissionQueue.clear();
834
834
  for (const row of ordered) {
@@ -1273,7 +1273,7 @@ export class RunManager {
1273
1273
  gitSha: input.gitSha,
1274
1274
  ciPrUrl: input.ciPrUrl,
1275
1275
  ciJobUrl: input.ciJobUrl,
1276
- }, derivedProjectRoot, resolved.kind === "path" ? resolved.taskPath : undefined, submission, undefined, input.callerId, input.skills, input.dispatchKey);
1276
+ }, derivedProjectRoot, resolved.kind === "path" ? resolved.taskPath : undefined, submission, undefined, input.callerId, input.skills, input.dispatchKey, input.origin);
1277
1277
  }
1278
1278
  async rerun(runId, options) {
1279
1279
  if (!this.acceptingWork) {
@@ -2219,7 +2219,7 @@ export class RunManager {
2219
2219
  this.attachedWaiting.delete(`${runId}\0${stageId}`);
2220
2220
  }
2221
2221
  }
2222
- async reserveAndStartPipeline(taskYaml, pipeline, taskLabel, cwd, checkoutOverride, skipGates, ciIdentity, projectRoot, taskPath, submission, pinned, callerId, skills, dispatchKey) {
2222
+ async reserveAndStartPipeline(taskYaml, pipeline, taskLabel, cwd, checkoutOverride, skipGates, ciIdentity, projectRoot, taskPath, submission, pinned, callerId, skills, dispatchKey, origin) {
2223
2223
  const persistence = pipelinePersistenceForStart(pipeline);
2224
2224
  if (!persistence.ok) {
2225
2225
  return {
@@ -2419,6 +2419,7 @@ export class RunManager {
2419
2419
  ...(callerId !== undefined && callerId !== null
2420
2420
  ? { callerId }
2421
2421
  : {}),
2422
+ ...(origin !== undefined ? { origin } : {}),
2422
2423
  runManifest,
2423
2424
  skipGates,
2424
2425
  });
@@ -2506,6 +2507,7 @@ export class RunManager {
2506
2507
  skipGates,
2507
2508
  schedulingHalt,
2508
2509
  callerId,
2510
+ ...(origin !== undefined ? { origin } : {}),
2509
2511
  ...(hasSkills ? { skills: validatedSkills } : {}),
2510
2512
  });
2511
2513
  if (started.created === false)
@@ -252,7 +252,7 @@ export async function runRetentionSweep(store, a2aStore, options = {}) {
252
252
  const windows = options.windows ?? retentionWindowsFromEnv(env);
253
253
  const artifactMaxBytes = options.artifactMaxBytes ?? slimArtifactMaxBytesFromEnv(env);
254
254
  const bareCacheTtlMs = options.bareCacheTtlMs ?? bareCacheTtlFromEnv(env);
255
- const runs = await store.listRuns();
255
+ const runs = await store.listRuns({ origin: "any" });
256
256
  const slimmed = [];
257
257
  const purged = [];
258
258
  const metas = new Map();
@@ -305,7 +305,7 @@ export async function runRetentionSweep(store, a2aStore, options = {}) {
305
305
  }
306
306
  }
307
307
  // Re-list for bare-cache decisions after PURGE removed rows when execute.
308
- const runsForBare = execute ? await store.listRuns() : runs;
308
+ const runsForBare = execute ? await store.listRuns({ origin: "any" }) : runs;
309
309
  const bareCachesEvicted = await evictBareCaches({
310
310
  runs: runsForBare,
311
311
  now,
@@ -0,0 +1,62 @@
1
+ export declare const SANDBOX_CONTAINER_IMAGE_ENV = "STAGEFLOW_STAGE_CONTAINER_IMAGE";
2
+ export declare const SANDBOX_CONTAINER_DOCKER_BIN_ENV = "STAGEFLOW_STAGE_CONTAINER_DOCKER_BIN";
3
+ /** Docker container names allow only `[a-zA-Z0-9_.-]`. */
4
+ export declare function sanitizeContainerNameSegment(value: string): string;
5
+ export declare function buildContainerName(input: {
6
+ runId: string;
7
+ stageId: string;
8
+ attempt?: number;
9
+ }, suffix: string): string;
10
+ export type SandboxContainerOptions = {
11
+ image: string;
12
+ dockerBin: string;
13
+ };
14
+ export declare function resolveSandboxContainerOptions(env: Record<string, string | undefined>, override?: {
15
+ image: string;
16
+ dockerBin?: string;
17
+ }): SandboxContainerOptions | undefined;
18
+ /** Fixed path inside the sandbox. The daemon owns the volume; we never pass it a path from this process. */
19
+ export declare const SANDBOX_MOUNT_PATH = "/workspace";
20
+ export declare function sandboxVolumeName(containerName: string): string;
21
+ export declare function buildStartContainerArgs(params: {
22
+ image: string;
23
+ containerName: string;
24
+ }): string[];
25
+ export declare function startSandboxContainer(params: {
26
+ image: string;
27
+ runId: string;
28
+ stageId: string;
29
+ attempt?: number;
30
+ dockerBin?: string;
31
+ }): Promise<{
32
+ containerName: string;
33
+ }>;
34
+ export declare function stopSandboxContainer(params: {
35
+ containerName: string;
36
+ dockerBin?: string;
37
+ }): Promise<void>;
38
+ export type SandboxExecResult = {
39
+ stdout: string;
40
+ stderr: string;
41
+ exitCode: number;
42
+ };
43
+ export declare function execInSandboxContainer(params: {
44
+ containerName: string;
45
+ command: string;
46
+ dockerBin?: string;
47
+ timeoutMs?: number;
48
+ }): Promise<SandboxExecResult>;
49
+ export declare function copyToSandboxContainer(params: {
50
+ containerName: string;
51
+ hostPath: string;
52
+ containerPath: string;
53
+ dockerBin?: string;
54
+ contents?: boolean;
55
+ }): Promise<void>;
56
+ export declare function copyFromSandboxContainer(params: {
57
+ containerName: string;
58
+ containerPath: string;
59
+ hostPath: string;
60
+ dockerBin?: string;
61
+ contents?: boolean;
62
+ }): Promise<void>;
@@ -0,0 +1,151 @@
1
+ import { execFile } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+ import { promisify } from "node:util";
4
+ export const SANDBOX_CONTAINER_IMAGE_ENV = "STAGEFLOW_STAGE_CONTAINER_IMAGE";
5
+ export const SANDBOX_CONTAINER_DOCKER_BIN_ENV = "STAGEFLOW_STAGE_CONTAINER_DOCKER_BIN";
6
+ const execFileAsync = promisify(execFile);
7
+ /** Docker container names allow only `[a-zA-Z0-9_.-]`. */
8
+ export function sanitizeContainerNameSegment(value) {
9
+ return value.replace(/[^a-zA-Z0-9_.-]/g, "-");
10
+ }
11
+ export function buildContainerName(input, suffix) {
12
+ const runId = sanitizeContainerNameSegment(input.runId);
13
+ const stageId = sanitizeContainerNameSegment(input.stageId);
14
+ const attempt = input.attempt ?? 1;
15
+ return `stageflow-${runId}-${stageId}-${attempt}-${suffix}`;
16
+ }
17
+ export function resolveSandboxContainerOptions(env, override) {
18
+ if (override) {
19
+ if (!override.image || override.image.trim() === "") {
20
+ throw new Error("sandboxContainer: image must be a non-empty string");
21
+ }
22
+ return { image: override.image, dockerBin: override.dockerBin || "docker" };
23
+ }
24
+ const image = env[SANDBOX_CONTAINER_IMAGE_ENV];
25
+ if (!image || image.trim() === "")
26
+ return undefined;
27
+ return {
28
+ image,
29
+ dockerBin: env[SANDBOX_CONTAINER_DOCKER_BIN_ENV] || "docker",
30
+ };
31
+ }
32
+ /** Fixed path inside the sandbox. The daemon owns the volume; we never pass it a path from this process. */
33
+ export const SANDBOX_MOUNT_PATH = "/workspace";
34
+ export function sandboxVolumeName(containerName) {
35
+ const safe = containerName.replace(/[^A-Za-z0-9_.-]/g, "_");
36
+ return `sf-bash-${safe}`;
37
+ }
38
+ export function buildStartContainerArgs(params) {
39
+ const { image, containerName } = params;
40
+ return [
41
+ "run",
42
+ "-d",
43
+ "--name",
44
+ containerName,
45
+ "-v",
46
+ `${sandboxVolumeName(containerName)}:${SANDBOX_MOUNT_PATH}`,
47
+ "-w",
48
+ SANDBOX_MOUNT_PATH,
49
+ image,
50
+ "sleep",
51
+ "infinity",
52
+ ];
53
+ }
54
+ function errorMessage(err) {
55
+ if (err && typeof err === "object" && "stderr" in err) {
56
+ const stderr = err.stderr;
57
+ if (typeof stderr === "string" && stderr.trim().length > 0)
58
+ return stderr;
59
+ }
60
+ return err instanceof Error ? err.message : String(err);
61
+ }
62
+ export async function startSandboxContainer(params) {
63
+ const containerName = buildContainerName({ runId: params.runId, stageId: params.stageId, attempt: params.attempt }, randomUUID().slice(0, 8));
64
+ const args = buildStartContainerArgs({
65
+ image: params.image,
66
+ containerName,
67
+ });
68
+ try {
69
+ await execFileAsync(params.dockerBin ?? "docker", args);
70
+ }
71
+ catch (err) {
72
+ throw new Error(`failed to start sandbox container: ${errorMessage(err)}`);
73
+ }
74
+ return { containerName };
75
+ }
76
+ const NO_SUCH_CONTAINER_PATTERN = /no such container/i;
77
+ const NO_SUCH_VOLUME_PATTERN = /no such volume/i;
78
+ export async function stopSandboxContainer(params) {
79
+ try {
80
+ await execFileAsync(params.dockerBin ?? "docker", [
81
+ "rm",
82
+ "-f",
83
+ params.containerName,
84
+ ]);
85
+ }
86
+ catch (err) {
87
+ const stderr = stderrOf(err);
88
+ if (!NO_SUCH_CONTAINER_PATTERN.test(stderr)) {
89
+ throw new Error(`failed to stop sandbox container: ${errorMessage(err)}`);
90
+ }
91
+ }
92
+ try {
93
+ await execFileAsync(params.dockerBin ?? "docker", [
94
+ "volume",
95
+ "rm",
96
+ sandboxVolumeName(params.containerName),
97
+ ]);
98
+ }
99
+ catch (err) {
100
+ const stderr = stderrOf(err);
101
+ if (NO_SUCH_VOLUME_PATTERN.test(stderr))
102
+ return;
103
+ throw new Error(`failed to remove sandbox volume: ${errorMessage(err)}`);
104
+ }
105
+ }
106
+ function stderrOf(err) {
107
+ if (err && typeof err === "object" && "stderr" in err) {
108
+ return String(err.stderr ?? "");
109
+ }
110
+ return "";
111
+ }
112
+ export async function execInSandboxContainer(params) {
113
+ const args = ["exec", "-w", SANDBOX_MOUNT_PATH, params.containerName, "bash", "-c", params.command];
114
+ try {
115
+ const { stdout, stderr } = await execFileAsync(params.dockerBin ?? "docker", args, {
116
+ maxBuffer: 8 * 1024 * 1024,
117
+ ...(params.timeoutMs !== undefined ? { timeout: params.timeoutMs } : {}),
118
+ });
119
+ return { stdout, stderr, exitCode: 0 };
120
+ }
121
+ catch (err) {
122
+ const e = err;
123
+ // `code` is a number only for a completed exec that exited non-zero.
124
+ // Anything else (ENOENT for a missing docker binary, the container
125
+ // having been removed mid-exec, etc.) is an infra failure, not a
126
+ // command result — rethrow so callers don't mistake it for "the
127
+ // command ran and exited 1".
128
+ if (typeof e.code !== "number") {
129
+ throw new Error(`failed to exec in sandbox container: ${errorMessage(err)}`);
130
+ }
131
+ return { stdout: e.stdout ?? "", stderr: e.stderr ?? "", exitCode: e.code };
132
+ }
133
+ }
134
+ export async function copyToSandboxContainer(params) {
135
+ const src = params.contents ? `${params.hostPath}/.` : params.hostPath;
136
+ await dockerCp(params.dockerBin, src, `${params.containerName}:${params.containerPath}`, "into");
137
+ }
138
+ export async function copyFromSandboxContainer(params) {
139
+ const src = params.contents
140
+ ? `${params.containerName}:${params.containerPath}/.`
141
+ : `${params.containerName}:${params.containerPath}`;
142
+ await dockerCp(params.dockerBin, src, params.hostPath, "from");
143
+ }
144
+ async function dockerCp(dockerBin, src, dest, direction) {
145
+ try {
146
+ await execFileAsync(dockerBin ?? "docker", ["cp", src, dest]);
147
+ }
148
+ catch (err) {
149
+ throw new Error(`failed to copy ${direction} sandbox: ${errorMessage(err)}`);
150
+ }
151
+ }
@@ -0,0 +1,28 @@
1
+ export type SandboxDeskRole = "artifacts" | "envelope" | "checkout" | "grant" | "work";
2
+ export type SandboxDeskBinding = {
3
+ role: SandboxDeskRole;
4
+ hostPath: string;
5
+ containerPath: string;
6
+ shape: "directory" | "file" | "mirror";
7
+ copyIn: boolean;
8
+ copyOut: boolean;
9
+ optional: boolean;
10
+ };
11
+ export type SandboxDesk = {
12
+ bindings: readonly SandboxDeskBinding[];
13
+ };
14
+ export declare function buildSandboxDesk(input: {
15
+ attemptDir: string;
16
+ checkoutRoot?: string;
17
+ grantedPaths?: readonly string[];
18
+ }): SandboxDesk;
19
+ export declare function populateSandboxDesk(params: {
20
+ containerName: string;
21
+ dockerBin?: string;
22
+ desk: SandboxDesk;
23
+ }): Promise<void>;
24
+ export declare function syncSandboxDesk(params: {
25
+ containerName: string;
26
+ dockerBin?: string;
27
+ desk: SandboxDesk;
28
+ }): Promise<void>;
@@ -0,0 +1,242 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { access, mkdir, rename, rm, stat } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { copyFromSandboxContainer, copyToSandboxContainer, execInSandboxContainer, SANDBOX_MOUNT_PATH, } from "./sandboxContainer.js";
5
+ import { shellQuote } from "./sandboxFiles.js";
6
+ export function buildSandboxDesk(input) {
7
+ const attemptDir = input.attemptDir;
8
+ const bindings = [
9
+ {
10
+ role: "artifacts",
11
+ hostPath: path.join(attemptDir, "artifacts"),
12
+ containerPath: `${SANDBOX_MOUNT_PATH}/artifacts`,
13
+ shape: "directory",
14
+ copyIn: true,
15
+ copyOut: false,
16
+ optional: true,
17
+ },
18
+ {
19
+ role: "envelope",
20
+ hostPath: path.join(attemptDir, "envelope.json"),
21
+ containerPath: `${SANDBOX_MOUNT_PATH}/envelope.json`,
22
+ shape: "file",
23
+ copyIn: true,
24
+ copyOut: false,
25
+ optional: true,
26
+ },
27
+ ];
28
+ const checkout = input.checkoutRoot?.trim();
29
+ if (checkout) {
30
+ bindings.push({
31
+ role: "checkout",
32
+ hostPath: checkout,
33
+ containerPath: `${SANDBOX_MOUNT_PATH}/checkout`,
34
+ shape: "directory",
35
+ copyIn: true,
36
+ copyOut: true,
37
+ optional: false,
38
+ });
39
+ }
40
+ const grants = input.grantedPaths ?? [];
41
+ for (let index = 0; index < grants.length; index += 1) {
42
+ const hostPath = grants[index];
43
+ bindings.push({
44
+ role: "grant",
45
+ hostPath,
46
+ containerPath: `${SANDBOX_MOUNT_PATH}/grants/${grantSegment(index, hostPath)}`,
47
+ shape: "mirror",
48
+ copyIn: true,
49
+ copyOut: true,
50
+ optional: false,
51
+ });
52
+ }
53
+ bindings.push({
54
+ role: "work",
55
+ hostPath: path.join(attemptDir, "work"),
56
+ containerPath: `${SANDBOX_MOUNT_PATH}/work`,
57
+ shape: "directory",
58
+ copyIn: false,
59
+ copyOut: true,
60
+ optional: true,
61
+ });
62
+ return { bindings };
63
+ }
64
+ function grantSegment(index, hostPath) {
65
+ const base = path.basename(hostPath).replace(/[^A-Za-z0-9_.-]/g, "_");
66
+ const safe = base.length > 0 && base !== "." && base !== ".." ? base : "path";
67
+ return `${index}-${safe}`;
68
+ }
69
+ async function pathExists(target) {
70
+ try {
71
+ await access(target);
72
+ return true;
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ export async function populateSandboxDesk(params) {
79
+ const dirs = new Set([
80
+ `${SANDBOX_MOUNT_PATH}/artifacts`,
81
+ `${SANDBOX_MOUNT_PATH}/work`,
82
+ `${SANDBOX_MOUNT_PATH}/grants`,
83
+ ]);
84
+ for (const binding of params.desk.bindings) {
85
+ if (binding.role === "checkout" || binding.shape === "mirror") {
86
+ dirs.add(binding.containerPath);
87
+ }
88
+ }
89
+ const made = await execInSandboxContainer({
90
+ containerName: params.containerName,
91
+ dockerBin: params.dockerBin,
92
+ command: `mkdir -p -- ${[...dirs].map(shellQuote).join(" ")}`,
93
+ });
94
+ if (made.exitCode !== 0) {
95
+ throw new Error(`failed to prepare sandbox desk: ${made.stderr.trim() || made.stdout.trim() || `exit ${made.exitCode}`}`);
96
+ }
97
+ for (const binding of params.desk.bindings) {
98
+ if (!binding.copyIn)
99
+ continue;
100
+ if (!(await pathExists(binding.hostPath))) {
101
+ if (binding.optional)
102
+ continue;
103
+ throw new Error(`sandbox desk source missing: ${binding.hostPath}`);
104
+ }
105
+ await copyBindingIn(params, binding);
106
+ }
107
+ }
108
+ export async function syncSandboxDesk(params) {
109
+ for (const binding of params.desk.bindings) {
110
+ if (!binding.copyOut)
111
+ continue;
112
+ await copyBindingOut(params, binding);
113
+ }
114
+ }
115
+ async function copyBindingIn(params, binding) {
116
+ if (binding.shape === "file") {
117
+ await copyToSandboxContainer({
118
+ containerName: params.containerName,
119
+ dockerBin: params.dockerBin,
120
+ hostPath: binding.hostPath,
121
+ containerPath: binding.containerPath,
122
+ });
123
+ return;
124
+ }
125
+ if (binding.shape === "directory") {
126
+ await copyToSandboxContainer({
127
+ containerName: params.containerName,
128
+ dockerBin: params.dockerBin,
129
+ hostPath: binding.hostPath,
130
+ containerPath: binding.containerPath,
131
+ contents: true,
132
+ });
133
+ return;
134
+ }
135
+ const info = await stat(binding.hostPath);
136
+ if (info.isDirectory()) {
137
+ await copyToSandboxContainer({
138
+ containerName: params.containerName,
139
+ dockerBin: params.dockerBin,
140
+ hostPath: binding.hostPath,
141
+ containerPath: binding.containerPath,
142
+ contents: true,
143
+ });
144
+ return;
145
+ }
146
+ await copyToSandboxContainer({
147
+ containerName: params.containerName,
148
+ dockerBin: params.dockerBin,
149
+ hostPath: binding.hostPath,
150
+ containerPath: path.posix.join(binding.containerPath, path.basename(binding.hostPath)),
151
+ });
152
+ }
153
+ async function copyBindingOut(params, binding) {
154
+ if (binding.role === "checkout" || binding.role === "work") {
155
+ await mirrorDirectoryFromContainer(params, binding.containerPath, binding.hostPath);
156
+ return;
157
+ }
158
+ if (binding.shape === "directory") {
159
+ await mkdir(binding.hostPath, { recursive: true });
160
+ await copyFromSandboxContainer({
161
+ containerName: params.containerName,
162
+ dockerBin: params.dockerBin,
163
+ containerPath: binding.containerPath,
164
+ hostPath: binding.hostPath,
165
+ contents: true,
166
+ });
167
+ return;
168
+ }
169
+ const info = await stat(binding.hostPath);
170
+ if (info.isDirectory()) {
171
+ await mkdir(binding.hostPath, { recursive: true });
172
+ await copyFromSandboxContainer({
173
+ containerName: params.containerName,
174
+ dockerBin: params.dockerBin,
175
+ containerPath: binding.containerPath,
176
+ hostPath: binding.hostPath,
177
+ contents: true,
178
+ });
179
+ return;
180
+ }
181
+ await mkdir(path.dirname(binding.hostPath), { recursive: true });
182
+ await copyFromSandboxContainer({
183
+ containerName: params.containerName,
184
+ dockerBin: params.dockerBin,
185
+ containerPath: path.posix.join(binding.containerPath, path.basename(binding.hostPath)),
186
+ hostPath: binding.hostPath,
187
+ });
188
+ }
189
+ async function mirrorDirectoryFromContainer(params, containerPath, hostPath) {
190
+ let probe;
191
+ try {
192
+ probe = await execInSandboxContainer({
193
+ containerName: params.containerName,
194
+ dockerBin: params.dockerBin,
195
+ command: `test -d ${shellQuote(containerPath)}`,
196
+ });
197
+ }
198
+ catch (err) {
199
+ throw new Error(`sandbox desk directory unavailable, not replacing ${hostPath}: ${err instanceof Error ? err.message : String(err)}`);
200
+ }
201
+ if (probe.exitCode !== 0) {
202
+ throw new Error(`sandbox desk directory missing, not replacing ${hostPath}`);
203
+ }
204
+ await mkdir(path.dirname(hostPath), { recursive: true });
205
+ const staging = path.join(path.dirname(hostPath), `.${path.basename(hostPath)}.sf-sync-${randomBytes(4).toString("hex")}`);
206
+ await mkdir(staging);
207
+ try {
208
+ await copyFromSandboxContainer({
209
+ containerName: params.containerName,
210
+ dockerBin: params.dockerBin,
211
+ containerPath,
212
+ hostPath: staging,
213
+ contents: true,
214
+ });
215
+ await replaceDirectory(hostPath, staging);
216
+ }
217
+ catch (err) {
218
+ await rm(staging, { recursive: true, force: true });
219
+ throw err;
220
+ }
221
+ }
222
+ async function replaceDirectory(hostPath, staging) {
223
+ const backup = path.join(path.dirname(hostPath), `.${path.basename(hostPath)}.sf-sync-bak-${randomBytes(4).toString("hex")}`);
224
+ let hostMoved = false;
225
+ try {
226
+ if (await pathExists(hostPath)) {
227
+ await rename(hostPath, backup);
228
+ hostMoved = true;
229
+ }
230
+ await rename(staging, hostPath);
231
+ hostMoved = false;
232
+ }
233
+ catch (err) {
234
+ if (hostMoved && !(await pathExists(hostPath)) && (await pathExists(backup))) {
235
+ await rename(backup, hostPath);
236
+ }
237
+ throw err;
238
+ }
239
+ if (await pathExists(backup)) {
240
+ await rm(backup, { recursive: true, force: true });
241
+ }
242
+ }
@@ -0,0 +1,20 @@
1
+ import { type SandboxExecResult } from "./sandboxContainer.js";
2
+ export declare class SandboxPathError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare function shellQuote(value: string): string;
6
+ /** Resolve a tool path onto the sandbox mount. Host absolutes and `..` escapes are rejected. */
7
+ export declare function confineSandboxPath(inputPath: string): string;
8
+ export type SandboxFileTarget = {
9
+ containerName: string;
10
+ dockerBin?: string;
11
+ };
12
+ export declare function readSandboxFile(target: SandboxFileTarget, inputPath: string): Promise<string>;
13
+ export declare function writeSandboxFile(target: SandboxFileTarget, inputPath: string, content: string): Promise<void>;
14
+ export declare function editSandboxFile(target: SandboxFileTarget, inputPath: string, edits: readonly {
15
+ oldText: string;
16
+ newText: string;
17
+ }[]): Promise<void>;
18
+ export declare function sliceSandboxLines(text: string, offset?: number, limit?: number): string;
19
+ export declare function formatSandboxBashResult(result: SandboxExecResult): string;
20
+ export declare function runSandboxBash(target: SandboxFileTarget, command: string, timeoutMs?: number): Promise<string>;