stageflow 0.25.0 → 0.27.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 (501) hide show
  1. package/README.md +10 -3
  2. package/dist/a2a/contracts.d.ts +1 -0
  3. package/dist/a2a/contracts.js +1 -0
  4. package/dist/a2a/registry.d.ts +2 -0
  5. package/dist/a2a/registry.js +20 -1
  6. package/dist/a2a/server.d.ts +7 -0
  7. package/dist/a2a/server.js +5 -2
  8. package/dist/a2a/service.d.ts +1 -1
  9. package/dist/a2a/service.js +57 -8
  10. package/dist/a2a/store.d.ts +8 -5
  11. package/dist/a2a/store.js +24 -67
  12. package/dist/agent/activity.d.ts +3 -0
  13. package/dist/agent/bootProviderConfig.d.ts +21 -0
  14. package/dist/agent/bootProviderConfig.js +74 -0
  15. package/dist/agent/piAdapter.d.ts +9 -1
  16. package/dist/agent/piAdapter.js +58 -3
  17. package/dist/agent/piIsolatedMcp.d.ts +2 -0
  18. package/dist/agent/piIsolatedMcp.js +10 -2
  19. package/dist/agent/port.d.ts +6 -0
  20. package/dist/agent/streamLogRedact.d.ts +1 -1
  21. package/dist/agent/streamLogRedact.js +4 -11
  22. package/dist/cli/artifactCommand.js +9 -16
  23. package/dist/cli/backupCommand.d.ts +9 -0
  24. package/dist/cli/backupCommand.js +111 -0
  25. package/dist/cli/debugRunCommand.d.ts +10 -0
  26. package/dist/cli/debugRunCommand.js +109 -0
  27. package/dist/cli/doctorCommand.d.ts +32 -0
  28. package/dist/cli/doctorCommand.js +453 -0
  29. package/dist/cli/envelopeCommand.js +9 -2
  30. package/dist/cli/exportAllCommand.d.ts +55 -0
  31. package/dist/cli/exportAllCommand.js +218 -0
  32. package/dist/cli/exportRunCommand.js +23 -21
  33. package/dist/cli/hostClient.d.ts +21 -3
  34. package/dist/cli/hostClient.js +93 -12
  35. package/dist/cli/initTemplates.d.ts +1 -1
  36. package/dist/cli/initTemplates.js +8 -1
  37. package/dist/cli/resolveSafeOutPath.d.ts +2 -0
  38. package/dist/cli/resolveSafeOutPath.js +40 -0
  39. package/dist/cli/restoreCommand.d.ts +10 -0
  40. package/dist/cli/restoreCommand.js +90 -0
  41. package/dist/cli/runCommand.d.ts +3 -2
  42. package/dist/cli/runCommand.js +93 -11
  43. package/dist/cli/runOutput.d.ts +4 -0
  44. package/dist/cli/runOutput.js +33 -7
  45. package/dist/cli/runStageCommand.d.ts +1 -0
  46. package/dist/cli/runStageCommand.js +44 -25
  47. package/dist/cli/runsCommand.d.ts +1 -1
  48. package/dist/cli/runsCommand.js +162 -8
  49. package/dist/cli.js +171 -30
  50. package/dist/config/catalogRelativePath.d.ts +62 -0
  51. package/dist/config/catalogRelativePath.js +118 -0
  52. package/dist/config/configOrigin.d.ts +27 -0
  53. package/dist/config/configOrigin.js +59 -0
  54. package/dist/config/hostConfig.d.ts +55 -0
  55. package/dist/config/hostConfig.js +333 -0
  56. package/dist/config/listSkills.d.ts +26 -0
  57. package/dist/config/listSkills.js +190 -3
  58. package/dist/config/loadOutcome.d.ts +1 -1
  59. package/dist/config/loadPipeline.js +23 -2
  60. package/dist/config/loadStage.js +18 -0
  61. package/dist/config/loadTask.d.ts +2 -0
  62. package/dist/config/loadTask.js +57 -18
  63. package/dist/config/materializeStageModels.js +5 -1
  64. package/dist/config/mergePipelineIncludes.d.ts +3 -0
  65. package/dist/config/mergePipelineIncludes.js +19 -0
  66. package/dist/config/migrateYaml.js +6 -11
  67. package/dist/config/multiProjectCatalog.d.ts +30 -0
  68. package/dist/config/multiProjectCatalog.js +142 -0
  69. package/dist/config/normalizePipelineStageEntry.js +20 -1
  70. package/dist/config/pipelineStageKeys.js +2 -0
  71. package/dist/config/resolveCatalogRoots.d.ts +27 -0
  72. package/dist/config/resolveCatalogRoots.js +76 -0
  73. package/dist/config/resolveModel.d.ts +7 -1
  74. package/dist/config/resolveModel.js +11 -1
  75. package/dist/config/resolveStageMcpServers.d.ts +9 -1
  76. package/dist/config/resolveStageMcpServers.js +36 -9
  77. package/dist/config/secretFromEnvOrFile.d.ts +9 -0
  78. package/dist/config/secretFromEnvOrFile.js +34 -0
  79. package/dist/config/seededCatalog.d.ts +11 -0
  80. package/dist/config/seededCatalog.js +29 -0
  81. package/dist/config/toolRequires.d.ts +24 -0
  82. package/dist/config/toolRequires.js +115 -0
  83. package/dist/config/validateCatalog.d.ts +5 -1
  84. package/dist/config/validateCatalog.js +140 -1
  85. package/dist/diagnostics/checks.d.ts +39 -0
  86. package/dist/diagnostics/checks.js +135 -0
  87. package/dist/errors/codes.d.ts +14 -0
  88. package/dist/errors/codes.js +59 -0
  89. package/dist/git/cache.d.ts +14 -0
  90. package/dist/git/cache.js +150 -0
  91. package/dist/git/credentials.d.ts +9 -0
  92. package/dist/git/credentials.js +88 -0
  93. package/dist/git/errors.d.ts +20 -0
  94. package/dist/git/errors.js +94 -0
  95. package/dist/git/exec.d.ts +16 -0
  96. package/dist/git/exec.js +135 -0
  97. package/dist/git/operations.d.ts +29 -0
  98. package/dist/git/operations.js +153 -0
  99. package/dist/git/version.d.ts +1 -0
  100. package/dist/git/version.js +10 -0
  101. package/dist/logging/audit.d.ts +16 -0
  102. package/dist/logging/audit.js +19 -0
  103. package/dist/logging/commonWords.d.ts +2 -0
  104. package/dist/logging/commonWords.js +13 -0
  105. package/dist/logging/logger.d.ts +49 -0
  106. package/dist/logging/logger.js +193 -0
  107. package/dist/logging/namedSecrets.d.ts +6 -0
  108. package/dist/logging/namedSecrets.js +58 -0
  109. package/dist/logging/redact.d.ts +13 -0
  110. package/dist/logging/redact.js +88 -0
  111. package/dist/mcp/catalogTools.js +456 -80
  112. package/dist/mcp/checkoutTools.d.ts +52 -0
  113. package/dist/mcp/checkoutTools.js +332 -0
  114. package/dist/mcp/controlTools.js +179 -5
  115. package/dist/mcp/deps.d.ts +1 -0
  116. package/dist/mcp/getStartedTool.d.ts +3 -0
  117. package/dist/mcp/getStartedTool.js +62 -0
  118. package/dist/mcp/readArtifact.d.ts +11 -0
  119. package/dist/mcp/readArtifact.js +46 -30
  120. package/dist/mcp/server.js +1 -0
  121. package/dist/mcp/tools.js +4 -0
  122. package/dist/net/proxy.d.ts +14 -0
  123. package/dist/net/proxy.js +78 -0
  124. package/dist/package-meta.d.ts +2 -1
  125. package/dist/package-meta.js +2 -1
  126. package/dist/preflight/bash.d.ts +8 -0
  127. package/dist/preflight/bash.js +34 -0
  128. package/dist/preflight/claudeRoot.d.ts +11 -0
  129. package/dist/preflight/claudeRoot.js +23 -0
  130. package/dist/preflight/mcpCommands.d.ts +8 -0
  131. package/dist/preflight/mcpCommands.js +36 -0
  132. package/dist/preflight/pipelinePreflight.d.ts +40 -0
  133. package/dist/preflight/pipelinePreflight.js +192 -0
  134. package/dist/preflight/tls.d.ts +6 -0
  135. package/dist/preflight/tls.js +18 -0
  136. package/dist/preflight/toolchain.d.ts +45 -0
  137. package/dist/preflight/toolchain.js +219 -0
  138. package/dist/project/findProjectRoot.js +3 -4
  139. package/dist/project/globalHome.d.ts +7 -0
  140. package/dist/project/globalHome.js +63 -2
  141. package/dist/project/resolveProjectContext.js +2 -2
  142. package/dist/project/resolveStageflowContext.js +2 -2
  143. package/dist/projection/projectRun.d.ts +2 -1
  144. package/dist/projection/projectRun.js +1 -0
  145. package/dist/runstore/assertTmpdir.d.ts +1 -0
  146. package/dist/runstore/assertTmpdir.js +21 -0
  147. package/dist/runstore/backup.d.ts +52 -0
  148. package/dist/runstore/backup.js +292 -0
  149. package/dist/runstore/createStore.d.ts +18 -1
  150. package/dist/runstore/createStore.js +64 -5
  151. package/dist/runstore/debugBundle.d.ts +60 -0
  152. package/dist/runstore/debugBundle.js +143 -0
  153. package/dist/runstore/diskUsage.d.ts +50 -0
  154. package/dist/runstore/diskUsage.js +214 -0
  155. package/dist/runstore/exportRunPayload.d.ts +8 -0
  156. package/dist/runstore/exportRunPayload.js +23 -0
  157. package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
  158. package/dist/runstore/normalizeCatalogPath.js +10 -0
  159. package/dist/runstore/paths.d.ts +5 -0
  160. package/dist/runstore/paths.js +145 -1
  161. package/dist/runstore/port.d.ts +111 -13
  162. package/dist/runstore/port.js +8 -1
  163. package/dist/runstore/restore.d.ts +81 -0
  164. package/dist/runstore/restore.js +355 -0
  165. package/dist/runstore/retention.d.ts +27 -0
  166. package/dist/runstore/retention.js +74 -0
  167. package/dist/runstore/runManifest.d.ts +146 -0
  168. package/dist/runstore/runManifest.js +288 -0
  169. package/dist/runstore/runProjection.d.ts +3 -1
  170. package/dist/runstore/runProjection.js +63 -1
  171. package/dist/runstore/sqlite/SqliteRunStore.d.ts +28 -3
  172. package/dist/runstore/sqlite/SqliteRunStore.js +352 -219
  173. package/dist/runstore/sqlite/applyStorePragmas.d.ts +39 -0
  174. package/dist/runstore/sqlite/applyStorePragmas.js +145 -0
  175. package/dist/runstore/sqlite/migrations/001-baseline.d.ts +7 -0
  176. package/dist/runstore/sqlite/migrations/001-baseline.js +10 -0
  177. package/dist/runstore/sqlite/migrations/002-repository-binding.d.ts +7 -0
  178. package/dist/runstore/sqlite/migrations/002-repository-binding.js +29 -0
  179. package/dist/runstore/sqlite/migrations/003-run-lifecycle.d.ts +7 -0
  180. package/dist/runstore/sqlite/migrations/003-run-lifecycle.js +28 -0
  181. package/dist/runstore/sqlite/migrations/004-auto-resume-count.d.ts +7 -0
  182. package/dist/runstore/sqlite/migrations/004-auto-resume-count.js +19 -0
  183. package/dist/runstore/sqlite/migrations/005-config-origins.d.ts +7 -0
  184. package/dist/runstore/sqlite/migrations/005-config-origins.js +19 -0
  185. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.d.ts +7 -0
  186. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.js +28 -0
  187. package/dist/runstore/sqlite/migrations/007-projects-registry.d.ts +7 -0
  188. package/dist/runstore/sqlite/migrations/007-projects-registry.js +31 -0
  189. package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
  190. package/dist/runstore/sqlite/migrations/index.js +72 -0
  191. package/dist/runstore/sqlite/schema.d.ts +20 -1
  192. package/dist/runstore/sqlite/schema.js +277 -1
  193. package/dist/runstore/sqlite/storeOpenError.d.ts +6 -0
  194. package/dist/runstore/sqlite/storeOpenError.js +11 -0
  195. package/dist/runstore/sqlite/storeSchemaError.d.ts +5 -0
  196. package/dist/runstore/sqlite/storeSchemaError.js +8 -0
  197. package/dist/runstore/stageExecution.js +3 -0
  198. package/dist/runstore/storeFilesystem.d.ts +32 -0
  199. package/dist/runstore/storeFilesystem.js +148 -0
  200. package/dist/runstore/trackProjection.js +2 -0
  201. package/dist/runstore/workspaceLayout.d.ts +13 -0
  202. package/dist/runstore/workspaceLayout.js +76 -0
  203. package/dist/runtime/completionCheckRunner.d.ts +3 -0
  204. package/dist/runtime/completionCheckRunner.js +45 -7
  205. package/dist/runtime/containerLimits.d.ts +16 -0
  206. package/dist/runtime/containerLimits.js +84 -0
  207. package/dist/runtime/credentialMaterialisation.d.ts +28 -0
  208. package/dist/runtime/credentialMaterialisation.js +128 -0
  209. package/dist/runtime/gitCheckoutCapability.js +7 -13
  210. package/dist/runtime/pipelineRunner.d.ts +36 -1
  211. package/dist/runtime/pipelineRunner.js +178 -17
  212. package/dist/runtime/pipelineScheduler.d.ts +15 -0
  213. package/dist/runtime/pipelineScheduler.js +135 -27
  214. package/dist/runtime/reloadRunCatalog.js +6 -1
  215. package/dist/runtime/repositoryMaterialize.d.ts +47 -0
  216. package/dist/runtime/repositoryMaterialize.js +235 -0
  217. package/dist/runtime/resumeTimedOut.d.ts +1 -1
  218. package/dist/runtime/resumeTimedOut.js +5 -2
  219. package/dist/runtime/runChangeBus.js +9 -0
  220. package/dist/runtime/runDeletion.d.ts +7 -0
  221. package/dist/runtime/runDeletion.js +37 -0
  222. package/dist/runtime/runManager.d.ts +158 -4
  223. package/dist/runtime/runManager.js +1596 -79
  224. package/dist/runtime/runRetentionSweep.d.ts +31 -0
  225. package/dist/runtime/runRetentionSweep.js +328 -0
  226. package/dist/runtime/runRetryCoordinator.d.ts +2 -0
  227. package/dist/runtime/runRetryCoordinator.js +19 -2
  228. package/dist/runtime/runSkills.d.ts +40 -0
  229. package/dist/runtime/runSkills.js +173 -0
  230. package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
  231. package/dist/runtime/stageAttemptBootstrap.js +195 -24
  232. package/dist/runtime/stageCacheEnv.d.ts +6 -0
  233. package/dist/runtime/stageCacheEnv.js +34 -0
  234. package/dist/runtime/stageConcurrency.d.ts +2 -1
  235. package/dist/runtime/stageConcurrency.js +4 -2
  236. package/dist/runtime/stageEnvironment.d.ts +38 -0
  237. package/dist/runtime/stageEnvironment.js +193 -0
  238. package/dist/runtime/stageProcessLauncher.d.ts +18 -0
  239. package/dist/runtime/stageProcessLauncher.js +194 -38
  240. package/dist/runtime/stageRecovery.d.ts +3 -1
  241. package/dist/runtime/stageRecovery.js +19 -4
  242. package/dist/runtime/stageRoots.d.ts +38 -1
  243. package/dist/runtime/stageRoots.js +118 -0
  244. package/dist/runtime/stageRunner.d.ts +1 -0
  245. package/dist/runtime/stageRunner.js +3 -1
  246. package/dist/runtime/stageSecretDecl.d.ts +9 -0
  247. package/dist/runtime/stageSecretDecl.js +102 -0
  248. package/dist/runtime/stageSecrets.d.ts +40 -0
  249. package/dist/runtime/stageSecrets.js +181 -0
  250. package/dist/runtime/stageWorker.d.ts +3 -2
  251. package/dist/runtime/stageWorker.js +58 -10
  252. package/dist/runtime/stageWorkerProtocol.d.ts +5 -0
  253. package/dist/runtime/stageWorkerProtocol.js +8 -0
  254. package/dist/runtime/startPayload.d.ts +32 -0
  255. package/dist/runtime/startPayload.js +59 -0
  256. package/dist/runtime/taskInput.js +14 -5
  257. package/dist/runtime/verifiedStageExecution.d.ts +1 -0
  258. package/dist/runtime/verifiedStageExecution.js +2 -1
  259. package/dist/runtime/workspaceBinding.d.ts +20 -0
  260. package/dist/runtime/workspaceBinding.js +60 -0
  261. package/dist/server/allowedHosts.d.ts +19 -0
  262. package/dist/server/allowedHosts.js +179 -0
  263. package/dist/server/bootstrap.d.ts +36 -2
  264. package/dist/server/bootstrap.js +209 -5
  265. package/dist/server/controlToken.d.ts +47 -0
  266. package/dist/server/controlToken.js +241 -0
  267. package/dist/server/createHttpHost.d.ts +11 -2
  268. package/dist/server/createHttpHost.js +103 -10
  269. package/dist/server/ensureGlobalService.d.ts +5 -1
  270. package/dist/server/ensureGlobalService.js +35 -1
  271. package/dist/server/healthSurfaces.d.ts +6 -0
  272. package/dist/server/healthSurfaces.js +98 -0
  273. package/dist/server/http.d.ts +12 -1
  274. package/dist/server/http.js +1085 -485
  275. package/dist/server/listenHost.d.ts +5 -0
  276. package/dist/server/listenHost.js +56 -0
  277. package/dist/server/mcpHost.d.ts +10 -1
  278. package/dist/server/mcpHost.js +36 -6
  279. package/dist/server/operatorResults.d.ts +2 -2
  280. package/dist/server/operatorResults.js +40 -29
  281. package/dist/server/requestAuthContext.d.ts +12 -0
  282. package/dist/server/requestAuthContext.js +21 -0
  283. package/dist/server/shutdown.d.ts +69 -0
  284. package/dist/server/shutdown.js +219 -0
  285. package/dist/types/pipeline.d.ts +7 -0
  286. package/dist/types/stage.d.ts +8 -0
  287. package/dist/types/task.d.ts +8 -0
  288. package/dist/ui/assets/index-B6hlSXXn.js +120 -0
  289. package/dist/ui/index.html +1 -1
  290. package/examples/README.md +98 -0
  291. package/examples/archify-on-pr/README.md +213 -0
  292. package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +19 -0
  293. package/examples/archify-on-pr/archify-on-pr.task.yaml +19 -0
  294. package/examples/archify-on-pr/author-diagrams.yaml +106 -0
  295. package/examples/archify-on-pr/detect-changes.yaml +89 -0
  296. package/examples/ci-validate/README.md +35 -0
  297. package/examples/ci-validate/check.yaml +13 -0
  298. package/examples/ci-validate/ci-demo.pipeline.yaml +4 -0
  299. package/examples/ci-validate/validate.sh +5 -0
  300. package/examples/compliance-review-demo/README.md +125 -0
  301. package/examples/compliance-review-demo/compliance-review-demo.pipeline.yaml +29 -0
  302. package/examples/compliance-review-demo/connect-account.yaml +47 -0
  303. package/examples/compliance-review-demo/map-to-control.yaml +123 -0
  304. package/examples/compliance-review-demo/poll-bucket-config.yaml +103 -0
  305. package/examples/compliance-review-demo/publish-report.yaml +79 -0
  306. package/examples/compliance-review-demo/review-verdict.yaml +122 -0
  307. package/examples/compliance-review-demo/run-compliance-check.yaml +96 -0
  308. package/examples/compliance-review-demo/store-evidence.yaml +143 -0
  309. package/examples/conditional-fork/README.md +89 -0
  310. package/examples/conditional-fork/branch-a.yaml +13 -0
  311. package/examples/conditional-fork/branch-b.yaml +13 -0
  312. package/examples/conditional-fork/decide.yaml +35 -0
  313. package/examples/conditional-fork/fork-demo.pipeline.yaml +20 -0
  314. package/examples/conditional-fork/fork-demo.task.yaml +8 -0
  315. package/examples/context7-mcp/README.md +42 -0
  316. package/examples/context7-mcp/context7-mcp.pipeline.yaml +15 -0
  317. package/examples/context7-mcp/context7-mcp.task.yaml +4 -0
  318. package/examples/context7-mcp/fetch-docs.yaml +52 -0
  319. package/examples/context7-mcp/resolve-library.yaml +31 -0
  320. package/examples/context7-mcp/write-brief.yaml +52 -0
  321. package/examples/feature-loop/README.md +104 -0
  322. package/examples/feature-loop/address-feedback.yaml +148 -0
  323. package/examples/feature-loop/align.yaml +116 -0
  324. package/examples/feature-loop/decompose.yaml +86 -0
  325. package/examples/feature-loop/default-model-hierarchy.task.yaml +58 -0
  326. package/examples/feature-loop/feature-loop.pipeline.yaml +140 -0
  327. package/examples/feature-loop/feature-loop.task.yaml +25 -0
  328. package/examples/feature-loop/implement.yaml +128 -0
  329. package/examples/feature-loop/plan.yaml +111 -0
  330. package/examples/feature-loop/publish.yaml +167 -0
  331. package/examples/feature-loop/review.yaml +146 -0
  332. package/examples/feature-loop/verify.yaml +106 -0
  333. package/examples/feedback-loop/README.md +72 -0
  334. package/examples/feedback-loop/VERIFY.md +208 -0
  335. package/examples/feedback-loop/continue-only.task.yaml +4 -0
  336. package/examples/feedback-loop/exhaust-require-continue.task.yaml +6 -0
  337. package/examples/feedback-loop/exhaust-wait-human.task.yaml +11 -0
  338. package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +23 -0
  339. package/examples/feedback-loop/feedback-loop.pipeline.yaml +23 -0
  340. package/examples/feedback-loop/feedback-loop.task.yaml +4 -0
  341. package/examples/feedback-loop/implement.yaml +14 -0
  342. package/examples/feedback-loop/plan.yaml +14 -0
  343. package/examples/feedback-loop/review.yaml +15 -0
  344. package/examples/feedback-loop/send-back-once.task.yaml +6 -0
  345. package/examples/feedback-loop/submit.yaml +12 -0
  346. package/examples/generic-fan-in/README.md +151 -0
  347. package/examples/generic-fan-in/clarify.yaml +18 -0
  348. package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +19 -0
  349. package/examples/generic-fan-in/generic-fan-in-accepted.task.yaml +8 -0
  350. package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +18 -0
  351. package/examples/generic-fan-in/generic-fan-in.task.yaml +9 -0
  352. package/examples/generic-fan-in/research.yaml +45 -0
  353. package/examples/generic-fan-in/synthesize.yaml +66 -0
  354. package/examples/generic-fan-in/validation.yaml +45 -0
  355. package/examples/github-release/README.md +78 -0
  356. package/examples/github-release/draft-release-notes.yaml +64 -0
  357. package/examples/github-release/github-release.pipeline.yaml +11 -0
  358. package/examples/github-release/github-release.task.yaml +13 -0
  359. package/examples/github-release/publish-github-release.yaml +64 -0
  360. package/examples/hello-world/README.md +28 -0
  361. package/examples/hello-world/hello.pipeline.yaml +4 -0
  362. package/examples/hello-world/my-task.task.yaml +6 -0
  363. package/examples/hello-world/research.yaml +18 -0
  364. package/examples/mcp-hitl-tour/README.md +113 -0
  365. package/examples/mcp-hitl-tour/draft-angle.yaml +33 -0
  366. package/examples/mcp-hitl-tour/draft-short.yaml +32 -0
  367. package/examples/mcp-hitl-tour/emit-angles.yaml +45 -0
  368. package/examples/mcp-hitl-tour/gather.yaml +31 -0
  369. package/examples/mcp-hitl-tour/intake.yaml +62 -0
  370. package/examples/mcp-hitl-tour/mcp-hitl-tour-exhaust.task.yaml +13 -0
  371. package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +54 -0
  372. package/examples/mcp-hitl-tour/mcp-hitl-tour.task.yaml +16 -0
  373. package/examples/mcp-hitl-tour/polish.yaml +33 -0
  374. package/examples/mcp-hitl-tour/review.yaml +17 -0
  375. package/examples/mcp-hitl-tour/ship.yaml +25 -0
  376. package/examples/oss-issue-contribution/README.md +218 -0
  377. package/examples/oss-issue-contribution/oss-address-review-feedback.yaml +117 -0
  378. package/examples/oss-issue-contribution/oss-approve-contribution.yaml +181 -0
  379. package/examples/oss-issue-contribution/oss-approve-plan.yaml +111 -0
  380. package/examples/oss-issue-contribution/oss-explain-fix.yaml +108 -0
  381. package/examples/oss-issue-contribution/oss-explain-issue.yaml +114 -0
  382. package/examples/oss-issue-contribution/oss-implement-source-fix.yaml +171 -0
  383. package/examples/oss-issue-contribution/oss-investigate-area.yaml +116 -0
  384. package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +125 -0
  385. package/examples/oss-issue-contribution/oss-issue-intake.yaml +106 -0
  386. package/examples/oss-issue-contribution/oss-plan-investigation.yaml +112 -0
  387. package/examples/oss-issue-contribution/oss-plan-review.yaml +109 -0
  388. package/examples/oss-issue-contribution/oss-reproduce-issue.yaml +140 -0
  389. package/examples/oss-issue-contribution/oss-review-change.yaml +107 -0
  390. package/examples/oss-issue-contribution/oss-verify-fix.yaml +130 -0
  391. package/examples/oss-issue-contribution/oss-write-regression-test.yaml +135 -0
  392. package/examples/oss-issue-contribution/pi-7629.task.yaml +79 -0
  393. package/examples/oss-issue-contribution/pi-8919.task.yaml +75 -0
  394. package/examples/oss-issue-contribution/pydantic-ai-7971.task.yaml +53 -0
  395. package/examples/oss-quick-fix/README.md +65 -0
  396. package/examples/oss-quick-fix/implement-fix.yaml +84 -0
  397. package/examples/oss-quick-fix/oss-quick-fix.pipeline.yaml +35 -0
  398. package/examples/oss-quick-fix/oss-quick-fix.task.yaml +19 -0
  399. package/examples/oss-quick-fix/ship-fix.yaml +81 -0
  400. package/examples/oss-quick-fix/understand-issue.yaml +67 -0
  401. package/examples/oss-quick-fix/verify-fix.yaml +73 -0
  402. package/examples/plan-review/README.md +37 -0
  403. package/examples/plan-review/plan-review-followup.yaml +13 -0
  404. package/examples/plan-review/plan-review.pipeline.yaml +9 -0
  405. package/examples/plan-review/plan-review.task.yaml +9 -0
  406. package/examples/plan-review/plan-review.yaml +25 -0
  407. package/examples/playwright-mcp/README.md +39 -0
  408. package/examples/playwright-mcp/playwright-mcp.pipeline.yaml +5 -0
  409. package/examples/playwright-mcp/playwright-mcp.task.yaml +4 -0
  410. package/examples/playwright-mcp/screenshot.yaml +40 -0
  411. package/examples/retry-tour/README.md +75 -0
  412. package/examples/retry-tour/retry-tour.pipeline.yaml +122 -0
  413. package/examples/retry-tour/retry-tour.task.yaml +9 -0
  414. package/examples/route-if-tour/README.md +202 -0
  415. package/examples/route-if-tour/route-if-tour.pipeline.yaml +950 -0
  416. package/examples/route-if-tour/route-if-tour.task.yaml +4 -0
  417. package/examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml +168 -0
  418. package/examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml +44 -0
  419. package/examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml +28 -0
  420. package/examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml +27 -0
  421. package/examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml +110 -0
  422. package/examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml +82 -0
  423. package/examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml +82 -0
  424. package/examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml +77 -0
  425. package/examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml +102 -0
  426. package/examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml +23 -0
  427. package/examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml +37 -0
  428. package/examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml +138 -0
  429. package/examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml +84 -0
  430. package/examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml +50 -0
  431. package/examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml +37 -0
  432. package/examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml +65 -0
  433. package/examples/route-wiring-smoke-test/17-if-join.pipeline.yaml +80 -0
  434. package/examples/route-wiring-smoke-test/README.md +377 -0
  435. package/examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml +26 -0
  436. package/examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml +25 -0
  437. package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml +30 -0
  438. package/examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml +24 -0
  439. package/examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml +35 -0
  440. package/examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml +37 -0
  441. package/examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml +27 -0
  442. package/examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml +42 -0
  443. package/examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml +26 -0
  444. package/examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml +55 -0
  445. package/examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml +51 -0
  446. package/examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml +35 -0
  447. package/examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml +15 -0
  448. package/examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml +15 -0
  449. package/examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml +33 -0
  450. package/examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml +51 -0
  451. package/examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml +55 -0
  452. package/examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml +36 -0
  453. package/examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml +42 -0
  454. package/examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml +33 -0
  455. package/examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml +32 -0
  456. package/examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml +31 -0
  457. package/examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml +33 -0
  458. package/examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml +36 -0
  459. package/examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml +63 -0
  460. package/examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml +46 -0
  461. package/examples/route-wiring-smoke-test/smoke-test.task.yaml +4 -0
  462. package/examples/route-wiring-smoke-test/stages/branch-a.yaml +12 -0
  463. package/examples/route-wiring-smoke-test/stages/branch-b.yaml +12 -0
  464. package/examples/route-wiring-smoke-test/stages/decide.yaml +12 -0
  465. package/examples/route-wiring-smoke-test/stages/finish.yaml +12 -0
  466. package/examples/ship-feature/README.md +190 -0
  467. package/examples/ship-feature/feat-address-feedback.yaml +119 -0
  468. package/examples/ship-feature/feat-implement.yaml +180 -0
  469. package/examples/ship-feature/feat-plan.yaml +120 -0
  470. package/examples/ship-feature/feat-review.yaml +109 -0
  471. package/examples/ship-feature/feat-ship.yaml +203 -0
  472. package/examples/ship-feature/ship-feature.pipeline.yaml +44 -0
  473. package/examples/ship-feature/ship-feature.task.yaml +78 -0
  474. package/examples/stage-mcp/README.md +144 -0
  475. package/examples/stage-mcp/echo-mcp.mjs +20 -0
  476. package/examples/stage-mcp/stage-mcp-dead.pipeline.yaml +5 -0
  477. package/examples/stage-mcp/stage-mcp-dead.task.yaml +3 -0
  478. package/examples/stage-mcp/stage-mcp-missing-var.pipeline.yaml +5 -0
  479. package/examples/stage-mcp/stage-mcp-missing-var.task.yaml +3 -0
  480. package/examples/stage-mcp/stage-mcp.pipeline.yaml +5 -0
  481. package/examples/stage-mcp/stage-mcp.task.yaml +4 -0
  482. package/examples/stage-mcp/use-echo.yaml +20 -0
  483. package/examples/verify-tour/README.md +80 -0
  484. package/examples/verify-tour/verify-tour.pipeline.yaml +162 -0
  485. package/examples/verify-tour/verify-tour.task.yaml +11 -0
  486. package/package.json +5 -1
  487. package/skills/stageflow/SKILL.md +6 -6
  488. package/skills/stageflow/references/control-surface.md +11 -5
  489. package/skills/stageflow/scripts/detect-host.mjs +14 -1
  490. package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
  491. package/skills/stageflow-author/SKILL.md +4 -3
  492. package/skills/stageflow-author/references/catalog-mapping.md +16 -0
  493. package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
  494. package/skills/stageflow-run/SKILL.md +20 -12
  495. package/skills/stageflow-run/references/mcp-call.md +9 -1
  496. package/skills/stageflow-run/references/task-and-pipeline-selection.md +16 -5
  497. package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
  498. package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
  499. package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
  500. package/skills/stageflow-setup/SKILL.md +40 -8
  501. package/dist/ui/assets/index-Da5EHU6M.js +0 -119
@@ -0,0 +1,6 @@
1
+ export declare const CA_ENV_VARS: readonly ["NODE_EXTRA_CA_CERTS", "SSL_CERT_FILE", "SSL_CERT_DIR"];
2
+ export type CaPathWarning = {
3
+ name: (typeof CA_ENV_VARS)[number];
4
+ path: string;
5
+ };
6
+ export declare function warnMissingCaPaths(env?: NodeJS.ProcessEnv): CaPathWarning[];
@@ -0,0 +1,18 @@
1
+ import { existsSync } from "node:fs";
2
+ export const CA_ENV_VARS = [
3
+ "NODE_EXTRA_CA_CERTS",
4
+ "SSL_CERT_FILE",
5
+ "SSL_CERT_DIR",
6
+ ];
7
+ export function warnMissingCaPaths(env = process.env) {
8
+ const warnings = [];
9
+ for (const name of CA_ENV_VARS) {
10
+ const value = env[name]?.trim();
11
+ if (!value)
12
+ continue;
13
+ if (!existsSync(value)) {
14
+ warnings.push({ name, path: value });
15
+ }
16
+ }
17
+ return warnings;
18
+ }
@@ -0,0 +1,45 @@
1
+ import type { ToolRequirement } from "../config/toolRequires.js";
2
+ export declare const DEFAULT_TOOLCHAIN_MANIFEST_PATH = "/etc/stageflow/toolchain.json";
3
+ export declare const TOOLCHAIN_MANIFEST_ENV = "STAGEFLOW_TOOLCHAIN_MANIFEST";
4
+ export type ToolchainManifestEntry = {
5
+ path: string;
6
+ version: string;
7
+ };
8
+ export type ToolchainManifest = {
9
+ tools: Record<string, ToolchainManifestEntry>;
10
+ };
11
+ export type ToolchainCheckStatus = "ok" | "missing_tool" | "tool_version_mismatch" | "unknown_version";
12
+ export type ToolchainCheck = {
13
+ tool: string;
14
+ required?: string;
15
+ found?: string;
16
+ path?: string;
17
+ status: ToolchainCheckStatus;
18
+ origin: "manifest" | "path" | "none";
19
+ };
20
+ export type ToolchainCheckResult = {
21
+ ok: boolean;
22
+ checks: ToolchainCheck[];
23
+ };
24
+ export type ToolchainHealthMap = Record<string, string>;
25
+ export declare function resolveToolchainManifestPath(env?: NodeJS.ProcessEnv): string;
26
+ export declare function loadToolchainManifest(manifestPath?: string): ToolchainManifest | undefined;
27
+ /** Build the curated stage env PATH (Slot 6 allowlist) for preflight checks. */
28
+ export declare function curatedStageEnv(hostEnv?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
29
+ export declare function toolchainHealthMap(options?: {
30
+ manifest?: ToolchainManifest;
31
+ env?: NodeJS.ProcessEnv;
32
+ }): ToolchainHealthMap;
33
+ export type CheckToolchainOptions = {
34
+ /** Injected manifest (tests); when omitted, load from disk. */
35
+ manifest?: ToolchainManifest | null;
36
+ env?: NodeJS.ProcessEnv;
37
+ /** When true, unknown_version is a failing status. */
38
+ strict?: boolean;
39
+ /** Fail start/doctor when mismatch/missing; unknown_version fails only if strict. */
40
+ failOnUnknownVersion?: boolean;
41
+ };
42
+ export declare function checkToolchainRequirements(requirements: readonly ToolRequirement[], options?: CheckToolchainOptions): ToolchainCheckResult;
43
+ export declare function firstFailingToolchainCode(result: ToolchainCheckResult, options?: {
44
+ strict?: boolean;
45
+ }): "missing_tool" | "tool_version_mismatch" | "unknown_version" | undefined;
@@ -0,0 +1,219 @@
1
+ import { accessSync, constants, existsSync, readFileSync } from "node:fs";
2
+ import { spawnSync } from "node:child_process";
3
+ import semver from "semver";
4
+ import { resolveCommandOnPath } from "./mcpCommands.js";
5
+ import { buildStageEnvironment } from "../runtime/stageEnvironment.js";
6
+ export const DEFAULT_TOOLCHAIN_MANIFEST_PATH = "/etc/stageflow/toolchain.json";
7
+ export const TOOLCHAIN_MANIFEST_ENV = "STAGEFLOW_TOOLCHAIN_MANIFEST";
8
+ export function resolveToolchainManifestPath(env = process.env) {
9
+ const fromEnv = env[TOOLCHAIN_MANIFEST_ENV]?.trim();
10
+ if (fromEnv)
11
+ return fromEnv;
12
+ return DEFAULT_TOOLCHAIN_MANIFEST_PATH;
13
+ }
14
+ export function loadToolchainManifest(manifestPath = resolveToolchainManifestPath()) {
15
+ if (!existsSync(manifestPath))
16
+ return undefined;
17
+ try {
18
+ const raw = JSON.parse(readFileSync(manifestPath, "utf8"));
19
+ if (typeof raw !== "object" ||
20
+ raw === null ||
21
+ Array.isArray(raw) ||
22
+ typeof raw.tools !== "object" ||
23
+ raw.tools === null ||
24
+ Array.isArray(raw.tools)) {
25
+ return undefined;
26
+ }
27
+ const tools = {};
28
+ for (const [name, entry] of Object.entries(raw.tools)) {
29
+ if (typeof entry !== "object" ||
30
+ entry === null ||
31
+ Array.isArray(entry) ||
32
+ typeof entry.path !== "string" ||
33
+ typeof entry.version !== "string") {
34
+ continue;
35
+ }
36
+ tools[name] = {
37
+ path: entry.path,
38
+ version: entry.version,
39
+ };
40
+ }
41
+ return { tools };
42
+ }
43
+ catch {
44
+ return undefined;
45
+ }
46
+ }
47
+ function parseVersionFromOutput(output) {
48
+ const coerced = semver.coerce(output, { loose: true });
49
+ return coerced?.version;
50
+ }
51
+ function probeToolVersion(commandPath, env) {
52
+ const result = spawnSync(commandPath, ["--version"], {
53
+ encoding: "utf8",
54
+ env,
55
+ timeout: 5_000,
56
+ });
57
+ const output = `${result.stdout ?? ""}\n${result.stderr ?? ""}`.trim();
58
+ if (!output)
59
+ return { parsable: false };
60
+ const version = parseVersionFromOutput(output);
61
+ if (version === undefined)
62
+ return { parsable: false };
63
+ return { version, parsable: true };
64
+ }
65
+ function resolveToolFromPath(tool, env) {
66
+ const resolved = resolveCommandOnPath(tool, env);
67
+ if (resolved === undefined)
68
+ return undefined;
69
+ try {
70
+ accessSync(resolved, constants.X_OK);
71
+ }
72
+ catch {
73
+ return undefined;
74
+ }
75
+ const probed = probeToolVersion(resolved, env);
76
+ return { path: resolved, version: probed.version, parsable: probed.parsable };
77
+ }
78
+ /** Build the curated stage env PATH (Slot 6 allowlist) for preflight checks. */
79
+ export function curatedStageEnv(hostEnv = process.env) {
80
+ const built = buildStageEnvironment({ hostEnv });
81
+ return { ...built.env };
82
+ }
83
+ export function toolchainHealthMap(options) {
84
+ const env = options?.env ?? process.env;
85
+ const manifest = options?.manifest ?? loadToolchainManifest(resolveToolchainManifestPath(env));
86
+ const map = {};
87
+ if (manifest) {
88
+ for (const [name, entry] of Object.entries(manifest.tools)) {
89
+ map[name] = entry.version;
90
+ }
91
+ }
92
+ for (const name of ["node", "git", "bash"]) {
93
+ if (map[name] !== undefined)
94
+ continue;
95
+ if (name === "node") {
96
+ map.node = process.versions.node;
97
+ continue;
98
+ }
99
+ const live = resolveToolFromPath(name, curatedStageEnv(env));
100
+ if (live?.version)
101
+ map[name] = live.version;
102
+ }
103
+ return map;
104
+ }
105
+ export function checkToolchainRequirements(requirements, options = {}) {
106
+ const hostEnv = options.env ?? process.env;
107
+ const stageEnv = curatedStageEnv(hostEnv);
108
+ const failOnUnknown = options.failOnUnknownVersion === true || options.strict === true;
109
+ let manifest;
110
+ if (options.manifest === null) {
111
+ manifest = undefined;
112
+ }
113
+ else if (options.manifest !== undefined) {
114
+ manifest = options.manifest;
115
+ }
116
+ else {
117
+ manifest = loadToolchainManifest(resolveToolchainManifestPath(hostEnv));
118
+ }
119
+ const checks = [];
120
+ for (const req of requirements) {
121
+ const fromManifest = manifest?.tools[req.tool];
122
+ let foundPath;
123
+ let foundVersion;
124
+ let origin = "none";
125
+ let parsable = false;
126
+ if (fromManifest) {
127
+ foundPath = fromManifest.path;
128
+ foundVersion = fromManifest.version;
129
+ origin = "manifest";
130
+ parsable = Boolean(semver.valid(fromManifest.version));
131
+ if (!parsable) {
132
+ const coerced = semver.coerce(fromManifest.version, { loose: true });
133
+ if (coerced) {
134
+ foundVersion = coerced.version;
135
+ parsable = true;
136
+ }
137
+ }
138
+ }
139
+ else {
140
+ const live = resolveToolFromPath(req.tool, stageEnv);
141
+ if (live) {
142
+ foundPath = live.path;
143
+ foundVersion = live.version;
144
+ origin = "path";
145
+ parsable = live.parsable;
146
+ }
147
+ }
148
+ if (foundPath === undefined) {
149
+ checks.push({
150
+ tool: req.tool,
151
+ required: req.version,
152
+ status: "missing_tool",
153
+ origin: "none",
154
+ });
155
+ continue;
156
+ }
157
+ if (req.version === undefined) {
158
+ checks.push({
159
+ tool: req.tool,
160
+ found: foundVersion,
161
+ path: foundPath,
162
+ status: "ok",
163
+ origin,
164
+ });
165
+ continue;
166
+ }
167
+ if (!parsable || foundVersion === undefined) {
168
+ checks.push({
169
+ tool: req.tool,
170
+ required: req.version,
171
+ found: foundVersion,
172
+ path: foundPath,
173
+ status: "unknown_version",
174
+ origin,
175
+ });
176
+ continue;
177
+ }
178
+ if (!semver.satisfies(foundVersion, req.version)) {
179
+ checks.push({
180
+ tool: req.tool,
181
+ required: req.version,
182
+ found: foundVersion,
183
+ path: foundPath,
184
+ status: "tool_version_mismatch",
185
+ origin,
186
+ });
187
+ continue;
188
+ }
189
+ checks.push({
190
+ tool: req.tool,
191
+ required: req.version,
192
+ found: foundVersion,
193
+ path: foundPath,
194
+ status: "ok",
195
+ origin,
196
+ });
197
+ }
198
+ const ok = !checks.some((c) => {
199
+ if (c.status === "missing_tool" || c.status === "tool_version_mismatch") {
200
+ return true;
201
+ }
202
+ if (c.status === "unknown_version")
203
+ return failOnUnknown;
204
+ return false;
205
+ });
206
+ return { ok, checks };
207
+ }
208
+ export function firstFailingToolchainCode(result, options = {}) {
209
+ for (const check of result.checks) {
210
+ if (check.status === "missing_tool")
211
+ return "missing_tool";
212
+ if (check.status === "tool_version_mismatch")
213
+ return "tool_version_mismatch";
214
+ if (check.status === "unknown_version" && options.strict) {
215
+ return "unknown_version";
216
+ }
217
+ }
218
+ return undefined;
219
+ }
@@ -1,6 +1,6 @@
1
1
  import { existsSync, realpathSync } from "node:fs";
2
- import { execFileSync } from "node:child_process";
3
2
  import path from "node:path";
3
+ import { runGitSync } from "../git/exec.js";
4
4
  const cache = new Map();
5
5
  function normalizeRoot(dir) {
6
6
  try {
@@ -17,10 +17,9 @@ export function findProjectRoot(startDir) {
17
17
  }
18
18
  let result = null;
19
19
  try {
20
- const stdout = execFileSync("git", ["rev-parse", "--show-toplevel"], {
20
+ const { stdout } = runGitSync({
21
21
  cwd: normalized,
22
- encoding: "utf8",
23
- stdio: ["ignore", "pipe", "ignore"],
22
+ args: ["rev-parse", "--show-toplevel"],
24
23
  });
25
24
  const trimmed = stdout.trim();
26
25
  if (trimmed.length > 0) {
@@ -1,2 +1,9 @@
1
+ export type StageflowHomeErrorCode = "stageflow_home_not_writable";
2
+ export declare class StageflowHomeError extends Error {
3
+ readonly code: StageflowHomeErrorCode;
4
+ constructor(message: string, code: StageflowHomeErrorCode);
5
+ }
6
+ export declare function resetGlobalStageflowHomeForTests(): void;
1
7
  export declare function globalStageflowHome(): string;
8
+ export declare function assertStageflowHomeWritable(): void;
2
9
  export declare function ensureGlobalHome(): string;
@@ -1,10 +1,71 @@
1
- import { chmodSync, mkdirSync } from "node:fs";
1
+ import { accessSync, chmodSync, constants, mkdirSync } from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
+ export class StageflowHomeError extends Error {
5
+ code;
6
+ constructor(message, code) {
7
+ super(message);
8
+ this.name = "StageflowHomeError";
9
+ this.code = code;
10
+ }
11
+ }
12
+ let memoizedHome;
13
+ export function resetGlobalStageflowHomeForTests() {
14
+ memoizedHome = undefined;
15
+ }
16
+ function resolveStageflowHomeFromEnv() {
17
+ const raw = process.env.STAGEFLOW_HOME?.trim();
18
+ if (!raw) {
19
+ return path.join(os.homedir(), ".stageflow");
20
+ }
21
+ if (path.isAbsolute(raw)) {
22
+ return path.resolve(raw);
23
+ }
24
+ return path.resolve(process.cwd(), raw);
25
+ }
4
26
  export function globalStageflowHome() {
5
- return path.join(os.homedir(), ".stageflow");
27
+ if (memoizedHome === undefined) {
28
+ memoizedHome = resolveStageflowHomeFromEnv();
29
+ process.env.STAGEFLOW_HOME = memoizedHome;
30
+ }
31
+ return memoizedHome;
32
+ }
33
+ function stageflowHomeNotWritableMessage(resolvedPath) {
34
+ const uid = process.getuid?.() ?? 0;
35
+ const gid = process.getgid?.() ?? 0;
36
+ return `STAGEFLOW_HOME is not writable (${resolvedPath}). Running as uid=${uid} gid=${gid}. Try: sudo chown -R ${uid}:${gid} ${resolvedPath}`;
37
+ }
38
+ function isStageflowHomeWritable(home) {
39
+ try {
40
+ accessSync(home, constants.W_OK);
41
+ return true;
42
+ }
43
+ catch (err) {
44
+ const code = err.code;
45
+ if (code === "ENOENT") {
46
+ const parent = path.dirname(home);
47
+ if (parent === home) {
48
+ return false;
49
+ }
50
+ try {
51
+ accessSync(parent, constants.W_OK);
52
+ return true;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
58
+ return false;
59
+ }
60
+ }
61
+ export function assertStageflowHomeWritable() {
62
+ const home = globalStageflowHome();
63
+ if (!isStageflowHomeWritable(home)) {
64
+ throw new StageflowHomeError(stageflowHomeNotWritableMessage(home), "stageflow_home_not_writable");
65
+ }
6
66
  }
7
67
  export function ensureGlobalHome() {
68
+ assertStageflowHomeWritable();
8
69
  const globalHome = globalStageflowHome();
9
70
  mkdirSync(globalHome, { recursive: true });
10
71
  const agentDir = path.join(globalHome, "agent");
@@ -1,11 +1,11 @@
1
1
  import os from "node:os";
2
2
  import path from "node:path";
3
3
  import { findProjectRoot } from "./findProjectRoot.js";
4
- import { ensureGlobalHome, globalStageflowHome } from "./globalHome.js";
4
+ import { globalStageflowHome } from "./globalHome.js";
5
5
  export function resolveProjectContext(invocationCwd) {
6
6
  const resolvedInvocation = path.resolve(invocationCwd);
7
7
  const gitRoot = findProjectRoot(resolvedInvocation);
8
- const globalHome = ensureGlobalHome();
8
+ const globalHome = globalStageflowHome();
9
9
  if (gitRoot !== null) {
10
10
  return {
11
11
  invocationCwd: resolvedInvocation,
@@ -3,7 +3,7 @@ import os from "node:os";
3
3
  import path from "node:path";
4
4
  import { loadStageflowManifestOutcome, manifestPathForProject, } from "../config/loadStageflowManifest.js";
5
5
  import { findProjectRoot } from "./findProjectRoot.js";
6
- import { ensureGlobalHome } from "./globalHome.js";
6
+ import { globalStageflowHome } from "./globalHome.js";
7
7
  export function projectContextFromStageflow(ctx) {
8
8
  return {
9
9
  invocationCwd: ctx.invocationCwd,
@@ -15,7 +15,7 @@ export function projectContextFromStageflow(ctx) {
15
15
  export async function resolveStageflowContext(invocationCwd) {
16
16
  const resolvedInvocation = path.resolve(invocationCwd);
17
17
  const gitRoot = findProjectRoot(resolvedInvocation);
18
- const globalHome = ensureGlobalHome();
18
+ const globalHome = globalStageflowHome();
19
19
  if (gitRoot === null) {
20
20
  return {
21
21
  invocationCwd: resolvedInvocation,
@@ -1,4 +1,4 @@
1
- import type { FeedbackLoopHistory, FeedbackLoopRecord, RunDetail, StageSnapshot } from "../runstore/port.js";
1
+ import type { FeedbackLoopHistory, FeedbackLoopRecord, RunBindingDetail, RunDetail, StageSnapshot } from "../runstore/port.js";
2
2
  import type { PipelineTrackProjection, RunSummary } from "../runstore/port.js";
3
3
  import type { AskOperatorPrompt } from "../tools/askOperator.js";
4
4
  import type { StageEnvelope } from "../types/envelope.js";
@@ -29,6 +29,7 @@ export type RunProjection = {
29
29
  status: RunDetail["status"];
30
30
  created_at: string;
31
31
  updated_at?: string;
32
+ binding: RunBindingDetail;
32
33
  stages: StageProjection[];
33
34
  pipeline_track: PipelineTrackProjection;
34
35
  waiting_stage_id?: RunSummary["waiting_stage_id"];
@@ -13,6 +13,7 @@ export function projectRun(detail) {
13
13
  status: detail.status,
14
14
  created_at: detail.created_at,
15
15
  updated_at: detail.updated_at,
16
+ binding: detail.binding,
16
17
  pipeline_track: detail.pipeline_track,
17
18
  ...(detail.waiting_stage_id !== undefined
18
19
  ? { waiting_stage_id: detail.waiting_stage_id }
@@ -0,0 +1 @@
1
+ export declare function assertTmpdirUsable(env?: NodeJS.ProcessEnv): string;
@@ -0,0 +1,21 @@
1
+ import { accessSync, constants, mkdirSync } from "node:fs";
2
+ import { StoreOpenError } from "./sqlite/storeOpenError.js";
3
+ export function assertTmpdirUsable(env = process.env) {
4
+ const raw = env.TMPDIR ?? env.TMP ?? env.TEMP;
5
+ if (raw === undefined || raw.trim() === "") {
6
+ throw new StoreOpenError("tmpdir_unusable: TMPDIR is unset. Set TMPDIR to a writable path (supported writable set: $STAGEFLOW_HOME and TMPDIR).", "tmpdir_unusable");
7
+ }
8
+ const dir = raw.trim();
9
+ try {
10
+ mkdirSync(dir, { recursive: true });
11
+ accessSync(dir, constants.W_OK);
12
+ }
13
+ catch (err) {
14
+ const message = err instanceof Error ? err.message : String(err);
15
+ throw new StoreOpenError(`tmpdir_unusable: TMPDIR=${dir} is not writable (${message})`, "tmpdir_unusable", { path: dir });
16
+ }
17
+ if (env.SQLITE_TMPDIR === undefined || env.SQLITE_TMPDIR.trim() === "") {
18
+ process.env.SQLITE_TMPDIR = dir;
19
+ }
20
+ return dir;
21
+ }
@@ -0,0 +1,52 @@
1
+ import { createReadStream } from "node:fs";
2
+ import type { RunStore } from "./port.js";
3
+ export type BackupErrorCode = "backup_insufficient_disk" | "backup_verify_failed" | "backup_out_denied" | "backup_cross_device" | "backup_fingerprint_skew";
4
+ export declare class BackupError extends Error {
5
+ readonly code: BackupErrorCode;
6
+ readonly detail?: Record<string, unknown>;
7
+ constructor(message: string, code: BackupErrorCode, detail?: Record<string, unknown>);
8
+ }
9
+ export type BackupContentsFlag = "state.db" | "settings.json" | "agent/auth.json" | "a2a-artifacts" | "manifest.json";
10
+ export type BackupManifest = {
11
+ created_at: string;
12
+ stageflow_version: string;
13
+ schema_version: number;
14
+ contents: BackupContentsFlag[];
15
+ db_only: boolean;
16
+ credentials_included: boolean;
17
+ a2a_artifacts_included: boolean;
18
+ settings_fingerprint_before: string | null;
19
+ settings_fingerprint_after: string | null;
20
+ auth_fingerprint_before: string | null;
21
+ auth_fingerprint_after: string | null;
22
+ fingerprint_skew: boolean;
23
+ secret_warning: string;
24
+ };
25
+ export type BackupResult = {
26
+ path: string;
27
+ bytes: number;
28
+ sha256: string;
29
+ schema_version: number;
30
+ stageflow_version: string;
31
+ created_at: string;
32
+ contents: BackupContentsFlag[];
33
+ };
34
+ export type CreateBackupOptions = {
35
+ store: RunStore;
36
+ homeDir?: string;
37
+ outPath?: string;
38
+ dbOnly?: boolean;
39
+ noCredentials?: boolean;
40
+ includeA2aArtifacts?: boolean;
41
+ freeSpace?: (rootPath: string) => Promise<{
42
+ freeBytes: number;
43
+ }>;
44
+ now?: () => Date;
45
+ };
46
+ export declare function backupsDir(homeDir?: string): string;
47
+ export declare function defaultBackupOutPath(homeDir?: string, now?: Date, dbOnly?: boolean): string;
48
+ export declare function assertBackupOutPathAllowed(outPath: string, homeDir?: string): string;
49
+ export declare function verifyDbSnapshot(snapshotPath: string, expectedUserVersion: number): void;
50
+ export declare function createBackup(options: CreateBackupOptions): Promise<BackupResult>;
51
+ export declare function resolveBackupDownloadPath(name: string, homeDir?: string): Promise<string>;
52
+ export declare function openBackupReadStream(filePath: string): ReturnType<typeof createReadStream>;