stageflow 0.23.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 (511) hide show
  1. package/README.md +24 -5
  2. package/dist/a2a/configDiscovery.d.ts +9 -0
  3. package/dist/a2a/configDiscovery.js +18 -0
  4. package/dist/a2a/contracts.d.ts +94 -0
  5. package/dist/a2a/contracts.js +164 -0
  6. package/dist/a2a/limits.d.ts +14 -0
  7. package/dist/a2a/limits.js +29 -0
  8. package/dist/a2a/registry.d.ts +46 -0
  9. package/dist/a2a/registry.js +178 -0
  10. package/dist/a2a/server.d.ts +36 -0
  11. package/dist/a2a/server.js +344 -0
  12. package/dist/a2a/service.d.ts +97 -0
  13. package/dist/a2a/service.js +545 -0
  14. package/dist/a2a/store.d.ts +109 -0
  15. package/dist/a2a/store.js +202 -0
  16. package/dist/agent/activity.d.ts +3 -0
  17. package/dist/agent/bootProviderConfig.d.ts +21 -0
  18. package/dist/agent/bootProviderConfig.js +74 -0
  19. package/dist/agent/piAdapter.d.ts +9 -1
  20. package/dist/agent/piAdapter.js +58 -3
  21. package/dist/agent/piIsolatedMcp.d.ts +2 -0
  22. package/dist/agent/piIsolatedMcp.js +10 -2
  23. package/dist/agent/port.d.ts +6 -0
  24. package/dist/agent/streamLogRedact.d.ts +1 -1
  25. package/dist/agent/streamLogRedact.js +4 -11
  26. package/dist/cli/a2aCommand.d.ts +8 -0
  27. package/dist/cli/a2aCommand.js +131 -0
  28. package/dist/cli/artifactCommand.js +9 -16
  29. package/dist/cli/backupCommand.d.ts +9 -0
  30. package/dist/cli/backupCommand.js +111 -0
  31. package/dist/cli/debugRunCommand.d.ts +10 -0
  32. package/dist/cli/debugRunCommand.js +109 -0
  33. package/dist/cli/doctorCommand.d.ts +32 -0
  34. package/dist/cli/doctorCommand.js +453 -0
  35. package/dist/cli/envelopeCommand.js +9 -2
  36. package/dist/cli/exportAllCommand.d.ts +55 -0
  37. package/dist/cli/exportAllCommand.js +218 -0
  38. package/dist/cli/exportRunCommand.js +23 -21
  39. package/dist/cli/hostClient.d.ts +21 -3
  40. package/dist/cli/hostClient.js +93 -12
  41. package/dist/cli/initTemplates.d.ts +1 -1
  42. package/dist/cli/initTemplates.js +8 -1
  43. package/dist/cli/resolveSafeOutPath.d.ts +2 -0
  44. package/dist/cli/resolveSafeOutPath.js +40 -0
  45. package/dist/cli/restoreCommand.d.ts +10 -0
  46. package/dist/cli/restoreCommand.js +90 -0
  47. package/dist/cli/runCommand.d.ts +3 -2
  48. package/dist/cli/runCommand.js +93 -11
  49. package/dist/cli/runOutput.d.ts +4 -0
  50. package/dist/cli/runOutput.js +33 -7
  51. package/dist/cli/runStageCommand.d.ts +34 -0
  52. package/dist/cli/runStageCommand.js +426 -0
  53. package/dist/cli/runsCommand.d.ts +1 -1
  54. package/dist/cli/runsCommand.js +162 -8
  55. package/dist/cli.js +190 -30
  56. package/dist/config/catalogRelativePath.d.ts +62 -0
  57. package/dist/config/catalogRelativePath.js +118 -0
  58. package/dist/config/configOrigin.d.ts +27 -0
  59. package/dist/config/configOrigin.js +59 -0
  60. package/dist/config/hostConfig.d.ts +55 -0
  61. package/dist/config/hostConfig.js +333 -0
  62. package/dist/config/listSkills.d.ts +26 -0
  63. package/dist/config/listSkills.js +190 -3
  64. package/dist/config/loadOutcome.d.ts +1 -1
  65. package/dist/config/loadPipeline.js +23 -2
  66. package/dist/config/loadStage.js +18 -0
  67. package/dist/config/loadTask.d.ts +2 -0
  68. package/dist/config/loadTask.js +57 -18
  69. package/dist/config/materializeStageModels.js +5 -1
  70. package/dist/config/mergePipelineIncludes.d.ts +3 -0
  71. package/dist/config/mergePipelineIncludes.js +19 -0
  72. package/dist/config/migrateYaml.js +6 -11
  73. package/dist/config/multiProjectCatalog.d.ts +30 -0
  74. package/dist/config/multiProjectCatalog.js +142 -0
  75. package/dist/config/normalizePipelineStageEntry.js +20 -1
  76. package/dist/config/pipelineStageKeys.js +2 -0
  77. package/dist/config/resolveCatalogRoots.d.ts +27 -0
  78. package/dist/config/resolveCatalogRoots.js +76 -0
  79. package/dist/config/resolveModel.d.ts +7 -1
  80. package/dist/config/resolveModel.js +11 -1
  81. package/dist/config/resolveStageMcpServers.d.ts +9 -1
  82. package/dist/config/resolveStageMcpServers.js +36 -9
  83. package/dist/config/secretFromEnvOrFile.d.ts +9 -0
  84. package/dist/config/secretFromEnvOrFile.js +34 -0
  85. package/dist/config/seededCatalog.d.ts +11 -0
  86. package/dist/config/seededCatalog.js +29 -0
  87. package/dist/config/toolRequires.d.ts +24 -0
  88. package/dist/config/toolRequires.js +115 -0
  89. package/dist/config/validateCatalog.d.ts +5 -1
  90. package/dist/config/validateCatalog.js +140 -1
  91. package/dist/diagnostics/checks.d.ts +39 -0
  92. package/dist/diagnostics/checks.js +135 -0
  93. package/dist/errors/codes.d.ts +14 -0
  94. package/dist/errors/codes.js +59 -0
  95. package/dist/git/cache.d.ts +14 -0
  96. package/dist/git/cache.js +150 -0
  97. package/dist/git/credentials.d.ts +9 -0
  98. package/dist/git/credentials.js +88 -0
  99. package/dist/git/errors.d.ts +20 -0
  100. package/dist/git/errors.js +94 -0
  101. package/dist/git/exec.d.ts +16 -0
  102. package/dist/git/exec.js +135 -0
  103. package/dist/git/operations.d.ts +29 -0
  104. package/dist/git/operations.js +153 -0
  105. package/dist/git/version.d.ts +1 -0
  106. package/dist/git/version.js +10 -0
  107. package/dist/logging/audit.d.ts +16 -0
  108. package/dist/logging/audit.js +19 -0
  109. package/dist/logging/commonWords.d.ts +2 -0
  110. package/dist/logging/commonWords.js +13 -0
  111. package/dist/logging/logger.d.ts +49 -0
  112. package/dist/logging/logger.js +193 -0
  113. package/dist/logging/namedSecrets.d.ts +6 -0
  114. package/dist/logging/namedSecrets.js +58 -0
  115. package/dist/logging/redact.d.ts +13 -0
  116. package/dist/logging/redact.js +88 -0
  117. package/dist/mcp/catalogTools.js +591 -76
  118. package/dist/mcp/checkoutTools.d.ts +52 -0
  119. package/dist/mcp/checkoutTools.js +332 -0
  120. package/dist/mcp/controlTools.js +179 -5
  121. package/dist/mcp/deps.d.ts +1 -0
  122. package/dist/mcp/getStartedTool.d.ts +3 -0
  123. package/dist/mcp/getStartedTool.js +62 -0
  124. package/dist/mcp/readArtifact.d.ts +11 -0
  125. package/dist/mcp/readArtifact.js +46 -30
  126. package/dist/mcp/server.js +1 -0
  127. package/dist/mcp/tools.js +4 -0
  128. package/dist/net/proxy.d.ts +14 -0
  129. package/dist/net/proxy.js +78 -0
  130. package/dist/package-meta.d.ts +2 -1
  131. package/dist/package-meta.js +2 -1
  132. package/dist/preflight/bash.d.ts +8 -0
  133. package/dist/preflight/bash.js +34 -0
  134. package/dist/preflight/claudeRoot.d.ts +11 -0
  135. package/dist/preflight/claudeRoot.js +23 -0
  136. package/dist/preflight/mcpCommands.d.ts +8 -0
  137. package/dist/preflight/mcpCommands.js +36 -0
  138. package/dist/preflight/pipelinePreflight.d.ts +40 -0
  139. package/dist/preflight/pipelinePreflight.js +192 -0
  140. package/dist/preflight/tls.d.ts +6 -0
  141. package/dist/preflight/tls.js +18 -0
  142. package/dist/preflight/toolchain.d.ts +45 -0
  143. package/dist/preflight/toolchain.js +219 -0
  144. package/dist/project/findProjectRoot.js +3 -4
  145. package/dist/project/globalHome.d.ts +7 -0
  146. package/dist/project/globalHome.js +63 -2
  147. package/dist/project/resolveProjectContext.js +2 -2
  148. package/dist/project/resolveStageflowContext.js +2 -2
  149. package/dist/projection/projectRun.d.ts +2 -1
  150. package/dist/projection/projectRun.js +1 -0
  151. package/dist/runstore/assertTmpdir.d.ts +1 -0
  152. package/dist/runstore/assertTmpdir.js +21 -0
  153. package/dist/runstore/backup.d.ts +52 -0
  154. package/dist/runstore/backup.js +292 -0
  155. package/dist/runstore/createStore.d.ts +27 -0
  156. package/dist/runstore/createStore.js +75 -7
  157. package/dist/runstore/debugBundle.d.ts +60 -0
  158. package/dist/runstore/debugBundle.js +143 -0
  159. package/dist/runstore/diskUsage.d.ts +50 -0
  160. package/dist/runstore/diskUsage.js +214 -0
  161. package/dist/runstore/exportRunPayload.d.ts +8 -0
  162. package/dist/runstore/exportRunPayload.js +23 -0
  163. package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
  164. package/dist/runstore/normalizeCatalogPath.js +10 -0
  165. package/dist/runstore/paths.d.ts +5 -0
  166. package/dist/runstore/paths.js +145 -1
  167. package/dist/runstore/port.d.ts +119 -8
  168. package/dist/runstore/port.js +8 -1
  169. package/dist/runstore/restore.d.ts +81 -0
  170. package/dist/runstore/restore.js +355 -0
  171. package/dist/runstore/retention.d.ts +27 -0
  172. package/dist/runstore/retention.js +74 -0
  173. package/dist/runstore/runManifest.d.ts +146 -0
  174. package/dist/runstore/runManifest.js +288 -0
  175. package/dist/runstore/runProjection.d.ts +3 -1
  176. package/dist/runstore/runProjection.js +63 -1
  177. package/dist/runstore/sqlite/SqliteRunStore.d.ts +37 -3
  178. package/dist/runstore/sqlite/SqliteRunStore.js +401 -227
  179. package/dist/runstore/sqlite/applyStorePragmas.d.ts +39 -0
  180. package/dist/runstore/sqlite/applyStorePragmas.js +145 -0
  181. package/dist/runstore/sqlite/migrations/001-baseline.d.ts +7 -0
  182. package/dist/runstore/sqlite/migrations/001-baseline.js +10 -0
  183. package/dist/runstore/sqlite/migrations/002-repository-binding.d.ts +7 -0
  184. package/dist/runstore/sqlite/migrations/002-repository-binding.js +29 -0
  185. package/dist/runstore/sqlite/migrations/003-run-lifecycle.d.ts +7 -0
  186. package/dist/runstore/sqlite/migrations/003-run-lifecycle.js +28 -0
  187. package/dist/runstore/sqlite/migrations/004-auto-resume-count.d.ts +7 -0
  188. package/dist/runstore/sqlite/migrations/004-auto-resume-count.js +19 -0
  189. package/dist/runstore/sqlite/migrations/005-config-origins.d.ts +7 -0
  190. package/dist/runstore/sqlite/migrations/005-config-origins.js +19 -0
  191. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.d.ts +7 -0
  192. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.js +28 -0
  193. package/dist/runstore/sqlite/migrations/007-projects-registry.d.ts +7 -0
  194. package/dist/runstore/sqlite/migrations/007-projects-registry.js +31 -0
  195. package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
  196. package/dist/runstore/sqlite/migrations/index.js +72 -0
  197. package/dist/runstore/sqlite/schema.d.ts +20 -1
  198. package/dist/runstore/sqlite/schema.js +283 -1
  199. package/dist/runstore/sqlite/storeOpenError.d.ts +6 -0
  200. package/dist/runstore/sqlite/storeOpenError.js +11 -0
  201. package/dist/runstore/sqlite/storeSchemaError.d.ts +5 -0
  202. package/dist/runstore/sqlite/storeSchemaError.js +8 -0
  203. package/dist/runstore/stageExecution.js +3 -0
  204. package/dist/runstore/storeFilesystem.d.ts +32 -0
  205. package/dist/runstore/storeFilesystem.js +148 -0
  206. package/dist/runstore/submission.d.ts +11 -0
  207. package/dist/runstore/submission.js +7 -0
  208. package/dist/runstore/trackProjection.js +2 -0
  209. package/dist/runstore/workspaceLayout.d.ts +13 -0
  210. package/dist/runstore/workspaceLayout.js +76 -0
  211. package/dist/runtime/completionCheckRunner.d.ts +3 -0
  212. package/dist/runtime/completionCheckRunner.js +45 -7
  213. package/dist/runtime/containerLimits.d.ts +16 -0
  214. package/dist/runtime/containerLimits.js +84 -0
  215. package/dist/runtime/credentialMaterialisation.d.ts +28 -0
  216. package/dist/runtime/credentialMaterialisation.js +128 -0
  217. package/dist/runtime/gitCheckoutCapability.js +7 -13
  218. package/dist/runtime/pipelineRunner.d.ts +38 -1
  219. package/dist/runtime/pipelineRunner.js +179 -15
  220. package/dist/runtime/pipelineScheduler.d.ts +15 -0
  221. package/dist/runtime/pipelineScheduler.js +167 -42
  222. package/dist/runtime/reloadRunCatalog.js +12 -1
  223. package/dist/runtime/repositoryMaterialize.d.ts +47 -0
  224. package/dist/runtime/repositoryMaterialize.js +235 -0
  225. package/dist/runtime/resolveEnvelopeRef.d.ts +30 -0
  226. package/dist/runtime/resolveEnvelopeRef.js +79 -0
  227. package/dist/runtime/resumeTimedOut.d.ts +1 -1
  228. package/dist/runtime/resumeTimedOut.js +5 -2
  229. package/dist/runtime/runChangeBus.js +9 -0
  230. package/dist/runtime/runDeletion.d.ts +7 -0
  231. package/dist/runtime/runDeletion.js +37 -0
  232. package/dist/runtime/runManager.d.ts +179 -4
  233. package/dist/runtime/runManager.js +1644 -83
  234. package/dist/runtime/runRetentionSweep.d.ts +31 -0
  235. package/dist/runtime/runRetentionSweep.js +328 -0
  236. package/dist/runtime/runRetryCoordinator.d.ts +2 -0
  237. package/dist/runtime/runRetryCoordinator.js +19 -2
  238. package/dist/runtime/runSkills.d.ts +40 -0
  239. package/dist/runtime/runSkills.js +173 -0
  240. package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
  241. package/dist/runtime/stageAttemptBootstrap.js +195 -24
  242. package/dist/runtime/stageCacheEnv.d.ts +6 -0
  243. package/dist/runtime/stageCacheEnv.js +34 -0
  244. package/dist/runtime/stageConcurrency.d.ts +2 -1
  245. package/dist/runtime/stageConcurrency.js +4 -2
  246. package/dist/runtime/stageEnvironment.d.ts +38 -0
  247. package/dist/runtime/stageEnvironment.js +193 -0
  248. package/dist/runtime/stageProcessLauncher.d.ts +18 -0
  249. package/dist/runtime/stageProcessLauncher.js +194 -38
  250. package/dist/runtime/stageRecovery.d.ts +3 -1
  251. package/dist/runtime/stageRecovery.js +19 -4
  252. package/dist/runtime/stageRoots.d.ts +38 -1
  253. package/dist/runtime/stageRoots.js +118 -0
  254. package/dist/runtime/stageRunner.d.ts +1 -0
  255. package/dist/runtime/stageRunner.js +3 -1
  256. package/dist/runtime/stageSecretDecl.d.ts +9 -0
  257. package/dist/runtime/stageSecretDecl.js +102 -0
  258. package/dist/runtime/stageSecrets.d.ts +40 -0
  259. package/dist/runtime/stageSecrets.js +181 -0
  260. package/dist/runtime/stageWorker.d.ts +3 -2
  261. package/dist/runtime/stageWorker.js +58 -10
  262. package/dist/runtime/stageWorkerProtocol.d.ts +5 -0
  263. package/dist/runtime/stageWorkerProtocol.js +8 -0
  264. package/dist/runtime/startPayload.d.ts +32 -0
  265. package/dist/runtime/startPayload.js +59 -0
  266. package/dist/runtime/taskInput.js +14 -5
  267. package/dist/runtime/verifiedStageExecution.d.ts +1 -0
  268. package/dist/runtime/verifiedStageExecution.js +2 -1
  269. package/dist/runtime/workspaceBinding.d.ts +20 -0
  270. package/dist/runtime/workspaceBinding.js +60 -0
  271. package/dist/server/allowedHosts.d.ts +19 -0
  272. package/dist/server/allowedHosts.js +179 -0
  273. package/dist/server/bootstrap.d.ts +38 -2
  274. package/dist/server/bootstrap.js +219 -4
  275. package/dist/server/controlToken.d.ts +47 -0
  276. package/dist/server/controlToken.js +241 -0
  277. package/dist/server/createHttpHost.d.ts +11 -2
  278. package/dist/server/createHttpHost.js +109 -10
  279. package/dist/server/ensureGlobalService.d.ts +5 -1
  280. package/dist/server/ensureGlobalService.js +35 -1
  281. package/dist/server/healthSurfaces.d.ts +6 -0
  282. package/dist/server/healthSurfaces.js +98 -0
  283. package/dist/server/http.d.ts +12 -1
  284. package/dist/server/http.js +1085 -485
  285. package/dist/server/listenHost.d.ts +5 -0
  286. package/dist/server/listenHost.js +56 -0
  287. package/dist/server/mcpHost.d.ts +10 -1
  288. package/dist/server/mcpHost.js +36 -6
  289. package/dist/server/operatorResults.d.ts +2 -2
  290. package/dist/server/operatorResults.js +40 -29
  291. package/dist/server/requestAuthContext.d.ts +12 -0
  292. package/dist/server/requestAuthContext.js +21 -0
  293. package/dist/server/shutdown.d.ts +69 -0
  294. package/dist/server/shutdown.js +219 -0
  295. package/dist/types/pipeline.d.ts +7 -0
  296. package/dist/types/stage.d.ts +8 -0
  297. package/dist/types/task.d.ts +8 -0
  298. package/dist/ui/assets/index-B6hlSXXn.js +120 -0
  299. package/dist/ui/index.html +1 -1
  300. package/examples/README.md +98 -0
  301. package/examples/archify-on-pr/README.md +213 -0
  302. package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +19 -0
  303. package/examples/archify-on-pr/archify-on-pr.task.yaml +19 -0
  304. package/examples/archify-on-pr/author-diagrams.yaml +106 -0
  305. package/examples/archify-on-pr/detect-changes.yaml +89 -0
  306. package/examples/ci-validate/README.md +35 -0
  307. package/examples/ci-validate/check.yaml +13 -0
  308. package/examples/ci-validate/ci-demo.pipeline.yaml +4 -0
  309. package/examples/ci-validate/validate.sh +5 -0
  310. package/examples/compliance-review-demo/README.md +125 -0
  311. package/examples/compliance-review-demo/compliance-review-demo.pipeline.yaml +29 -0
  312. package/examples/compliance-review-demo/connect-account.yaml +47 -0
  313. package/examples/compliance-review-demo/map-to-control.yaml +123 -0
  314. package/examples/compliance-review-demo/poll-bucket-config.yaml +103 -0
  315. package/examples/compliance-review-demo/publish-report.yaml +79 -0
  316. package/examples/compliance-review-demo/review-verdict.yaml +122 -0
  317. package/examples/compliance-review-demo/run-compliance-check.yaml +96 -0
  318. package/examples/compliance-review-demo/store-evidence.yaml +143 -0
  319. package/examples/conditional-fork/README.md +89 -0
  320. package/examples/conditional-fork/branch-a.yaml +13 -0
  321. package/examples/conditional-fork/branch-b.yaml +13 -0
  322. package/examples/conditional-fork/decide.yaml +35 -0
  323. package/examples/conditional-fork/fork-demo.pipeline.yaml +20 -0
  324. package/examples/conditional-fork/fork-demo.task.yaml +8 -0
  325. package/examples/context7-mcp/README.md +42 -0
  326. package/examples/context7-mcp/context7-mcp.pipeline.yaml +15 -0
  327. package/examples/context7-mcp/context7-mcp.task.yaml +4 -0
  328. package/examples/context7-mcp/fetch-docs.yaml +52 -0
  329. package/examples/context7-mcp/resolve-library.yaml +31 -0
  330. package/examples/context7-mcp/write-brief.yaml +52 -0
  331. package/examples/feature-loop/README.md +104 -0
  332. package/examples/feature-loop/address-feedback.yaml +148 -0
  333. package/examples/feature-loop/align.yaml +116 -0
  334. package/examples/feature-loop/decompose.yaml +86 -0
  335. package/examples/feature-loop/default-model-hierarchy.task.yaml +58 -0
  336. package/examples/feature-loop/feature-loop.pipeline.yaml +140 -0
  337. package/examples/feature-loop/feature-loop.task.yaml +25 -0
  338. package/examples/feature-loop/implement.yaml +128 -0
  339. package/examples/feature-loop/plan.yaml +111 -0
  340. package/examples/feature-loop/publish.yaml +167 -0
  341. package/examples/feature-loop/review.yaml +146 -0
  342. package/examples/feature-loop/verify.yaml +106 -0
  343. package/examples/feedback-loop/README.md +72 -0
  344. package/examples/feedback-loop/VERIFY.md +208 -0
  345. package/examples/feedback-loop/continue-only.task.yaml +4 -0
  346. package/examples/feedback-loop/exhaust-require-continue.task.yaml +6 -0
  347. package/examples/feedback-loop/exhaust-wait-human.task.yaml +11 -0
  348. package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +23 -0
  349. package/examples/feedback-loop/feedback-loop.pipeline.yaml +23 -0
  350. package/examples/feedback-loop/feedback-loop.task.yaml +4 -0
  351. package/examples/feedback-loop/implement.yaml +14 -0
  352. package/examples/feedback-loop/plan.yaml +14 -0
  353. package/examples/feedback-loop/review.yaml +15 -0
  354. package/examples/feedback-loop/send-back-once.task.yaml +6 -0
  355. package/examples/feedback-loop/submit.yaml +12 -0
  356. package/examples/generic-fan-in/README.md +151 -0
  357. package/examples/generic-fan-in/clarify.yaml +18 -0
  358. package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +19 -0
  359. package/examples/generic-fan-in/generic-fan-in-accepted.task.yaml +8 -0
  360. package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +18 -0
  361. package/examples/generic-fan-in/generic-fan-in.task.yaml +9 -0
  362. package/examples/generic-fan-in/research.yaml +45 -0
  363. package/examples/generic-fan-in/synthesize.yaml +66 -0
  364. package/examples/generic-fan-in/validation.yaml +45 -0
  365. package/examples/github-release/README.md +78 -0
  366. package/examples/github-release/draft-release-notes.yaml +64 -0
  367. package/examples/github-release/github-release.pipeline.yaml +11 -0
  368. package/examples/github-release/github-release.task.yaml +13 -0
  369. package/examples/github-release/publish-github-release.yaml +64 -0
  370. package/examples/hello-world/README.md +28 -0
  371. package/examples/hello-world/hello.pipeline.yaml +4 -0
  372. package/examples/hello-world/my-task.task.yaml +6 -0
  373. package/examples/hello-world/research.yaml +18 -0
  374. package/examples/mcp-hitl-tour/README.md +113 -0
  375. package/examples/mcp-hitl-tour/draft-angle.yaml +33 -0
  376. package/examples/mcp-hitl-tour/draft-short.yaml +32 -0
  377. package/examples/mcp-hitl-tour/emit-angles.yaml +45 -0
  378. package/examples/mcp-hitl-tour/gather.yaml +31 -0
  379. package/examples/mcp-hitl-tour/intake.yaml +62 -0
  380. package/examples/mcp-hitl-tour/mcp-hitl-tour-exhaust.task.yaml +13 -0
  381. package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +54 -0
  382. package/examples/mcp-hitl-tour/mcp-hitl-tour.task.yaml +16 -0
  383. package/examples/mcp-hitl-tour/polish.yaml +33 -0
  384. package/examples/mcp-hitl-tour/review.yaml +17 -0
  385. package/examples/mcp-hitl-tour/ship.yaml +25 -0
  386. package/examples/oss-issue-contribution/README.md +218 -0
  387. package/examples/oss-issue-contribution/oss-address-review-feedback.yaml +117 -0
  388. package/examples/oss-issue-contribution/oss-approve-contribution.yaml +181 -0
  389. package/examples/oss-issue-contribution/oss-approve-plan.yaml +111 -0
  390. package/examples/oss-issue-contribution/oss-explain-fix.yaml +108 -0
  391. package/examples/oss-issue-contribution/oss-explain-issue.yaml +114 -0
  392. package/examples/oss-issue-contribution/oss-implement-source-fix.yaml +171 -0
  393. package/examples/oss-issue-contribution/oss-investigate-area.yaml +116 -0
  394. package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +125 -0
  395. package/examples/oss-issue-contribution/oss-issue-intake.yaml +106 -0
  396. package/examples/oss-issue-contribution/oss-plan-investigation.yaml +112 -0
  397. package/examples/oss-issue-contribution/oss-plan-review.yaml +109 -0
  398. package/examples/oss-issue-contribution/oss-reproduce-issue.yaml +140 -0
  399. package/examples/oss-issue-contribution/oss-review-change.yaml +107 -0
  400. package/examples/oss-issue-contribution/oss-verify-fix.yaml +130 -0
  401. package/examples/oss-issue-contribution/oss-write-regression-test.yaml +135 -0
  402. package/examples/oss-issue-contribution/pi-7629.task.yaml +79 -0
  403. package/examples/oss-issue-contribution/pi-8919.task.yaml +75 -0
  404. package/examples/oss-issue-contribution/pydantic-ai-7971.task.yaml +53 -0
  405. package/examples/oss-quick-fix/README.md +65 -0
  406. package/examples/oss-quick-fix/implement-fix.yaml +84 -0
  407. package/examples/oss-quick-fix/oss-quick-fix.pipeline.yaml +35 -0
  408. package/examples/oss-quick-fix/oss-quick-fix.task.yaml +19 -0
  409. package/examples/oss-quick-fix/ship-fix.yaml +81 -0
  410. package/examples/oss-quick-fix/understand-issue.yaml +67 -0
  411. package/examples/oss-quick-fix/verify-fix.yaml +73 -0
  412. package/examples/plan-review/README.md +37 -0
  413. package/examples/plan-review/plan-review-followup.yaml +13 -0
  414. package/examples/plan-review/plan-review.pipeline.yaml +9 -0
  415. package/examples/plan-review/plan-review.task.yaml +9 -0
  416. package/examples/plan-review/plan-review.yaml +25 -0
  417. package/examples/playwright-mcp/README.md +39 -0
  418. package/examples/playwright-mcp/playwright-mcp.pipeline.yaml +5 -0
  419. package/examples/playwright-mcp/playwright-mcp.task.yaml +4 -0
  420. package/examples/playwright-mcp/screenshot.yaml +40 -0
  421. package/examples/retry-tour/README.md +75 -0
  422. package/examples/retry-tour/retry-tour.pipeline.yaml +122 -0
  423. package/examples/retry-tour/retry-tour.task.yaml +9 -0
  424. package/examples/route-if-tour/README.md +202 -0
  425. package/examples/route-if-tour/route-if-tour.pipeline.yaml +950 -0
  426. package/examples/route-if-tour/route-if-tour.task.yaml +4 -0
  427. package/examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml +168 -0
  428. package/examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml +44 -0
  429. package/examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml +28 -0
  430. package/examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml +27 -0
  431. package/examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml +110 -0
  432. package/examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml +82 -0
  433. package/examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml +82 -0
  434. package/examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml +77 -0
  435. package/examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml +102 -0
  436. package/examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml +23 -0
  437. package/examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml +37 -0
  438. package/examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml +138 -0
  439. package/examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml +84 -0
  440. package/examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml +50 -0
  441. package/examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml +37 -0
  442. package/examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml +65 -0
  443. package/examples/route-wiring-smoke-test/17-if-join.pipeline.yaml +80 -0
  444. package/examples/route-wiring-smoke-test/README.md +377 -0
  445. package/examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml +26 -0
  446. package/examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml +25 -0
  447. package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml +30 -0
  448. package/examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml +24 -0
  449. package/examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml +35 -0
  450. package/examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml +37 -0
  451. package/examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml +27 -0
  452. package/examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml +42 -0
  453. package/examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml +26 -0
  454. package/examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml +55 -0
  455. package/examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml +51 -0
  456. package/examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml +35 -0
  457. package/examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml +15 -0
  458. package/examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml +15 -0
  459. package/examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml +33 -0
  460. package/examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml +51 -0
  461. package/examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml +55 -0
  462. package/examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml +36 -0
  463. package/examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml +42 -0
  464. package/examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml +33 -0
  465. package/examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml +32 -0
  466. package/examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml +31 -0
  467. package/examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml +33 -0
  468. package/examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml +36 -0
  469. package/examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml +63 -0
  470. package/examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml +46 -0
  471. package/examples/route-wiring-smoke-test/smoke-test.task.yaml +4 -0
  472. package/examples/route-wiring-smoke-test/stages/branch-a.yaml +12 -0
  473. package/examples/route-wiring-smoke-test/stages/branch-b.yaml +12 -0
  474. package/examples/route-wiring-smoke-test/stages/decide.yaml +12 -0
  475. package/examples/route-wiring-smoke-test/stages/finish.yaml +12 -0
  476. package/examples/ship-feature/README.md +190 -0
  477. package/examples/ship-feature/feat-address-feedback.yaml +119 -0
  478. package/examples/ship-feature/feat-implement.yaml +180 -0
  479. package/examples/ship-feature/feat-plan.yaml +120 -0
  480. package/examples/ship-feature/feat-review.yaml +109 -0
  481. package/examples/ship-feature/feat-ship.yaml +203 -0
  482. package/examples/ship-feature/ship-feature.pipeline.yaml +44 -0
  483. package/examples/ship-feature/ship-feature.task.yaml +78 -0
  484. package/examples/stage-mcp/README.md +144 -0
  485. package/examples/stage-mcp/echo-mcp.mjs +20 -0
  486. package/examples/stage-mcp/stage-mcp-dead.pipeline.yaml +5 -0
  487. package/examples/stage-mcp/stage-mcp-dead.task.yaml +3 -0
  488. package/examples/stage-mcp/stage-mcp-missing-var.pipeline.yaml +5 -0
  489. package/examples/stage-mcp/stage-mcp-missing-var.task.yaml +3 -0
  490. package/examples/stage-mcp/stage-mcp.pipeline.yaml +5 -0
  491. package/examples/stage-mcp/stage-mcp.task.yaml +4 -0
  492. package/examples/stage-mcp/use-echo.yaml +20 -0
  493. package/examples/verify-tour/README.md +80 -0
  494. package/examples/verify-tour/verify-tour.pipeline.yaml +162 -0
  495. package/examples/verify-tour/verify-tour.task.yaml +11 -0
  496. package/package.json +6 -1
  497. package/skills/stageflow/SKILL.md +6 -6
  498. package/skills/stageflow/references/control-surface.md +11 -5
  499. package/skills/stageflow/scripts/detect-host.mjs +14 -1
  500. package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
  501. package/skills/stageflow-author/SKILL.md +4 -3
  502. package/skills/stageflow-author/references/catalog-mapping.md +16 -0
  503. package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
  504. package/skills/stageflow-run/SKILL.md +20 -12
  505. package/skills/stageflow-run/references/mcp-call.md +9 -1
  506. package/skills/stageflow-run/references/task-and-pipeline-selection.md +16 -5
  507. package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
  508. package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
  509. package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
  510. package/skills/stageflow-setup/SKILL.md +40 -8
  511. package/dist/ui/assets/index-Da5EHU6M.js +0 -119
@@ -20,6 +20,17 @@ There is no CLI list command. Read `stageflow.yaml` at the project root (git top
20
20
 
21
21
  Walk each `catalog.pipelines` / `catalog.tasks` root. Match `catalog.patterns.pipeline` (default `*.pipeline.yaml`) and `catalog.patterns.task` (default `*.task.yaml`). Skip paths whose repo-relative prefix is in `catalog.exclude`.
22
22
 
23
+ ## Repository binding
24
+
25
+ Task binding is **`repository` + `ref` XOR `checkout`** (code `task.binding_conflict` if both). Do not set both.
26
+
27
+ | Binding | Meaning |
28
+ |---|---|
29
+ | `repository` + `ref` | GitHub `owner/repo` plus branch/tag/SHA. Host creates a worktree at `$STAGEFLOW_HOME/worktrees/<runId>/`. On **succeeded**, that worktree may be reclaimed (`run_branch` kept; path may be gone → checkout tools return `checkout_reclaimed`). Repository-bound runs parallelize; they do not take the path `busy_checkout` lease. |
30
+ | `checkout` | Path-bound working tree. `busy_checkout` is this path lease only — conflicting path-bound starts fail and never queue. |
31
+
32
+ CLI parity with MCP inline: `sf run --repository owner/repo --ref <ref>` (or `--checkout <path>`), and the same fields on throwaway scratch YAML.
33
+
23
34
  ## Task input
24
35
 
25
36
  ### MCP
@@ -27,14 +38,14 @@ Walk each `catalog.pipelines` / `catalog.tasks` root. Match `catalog.patterns.pi
27
38
  An existing `task_path` from `list_tasks`, or an inline `task` object built from the stated goal:
28
39
 
29
40
  ```json
30
- { "id": "<slug>", "goal": "<goal>", "context": "optional", "constraints": "optional", "checkout": "optional" }
41
+ { "id": "<slug>", "goal": "<goal>", "context": "optional", "constraints": "optional", "checkout": "optional", "repository": "optional", "ref": "optional" }
31
42
  ```
32
43
 
33
- `start_run` accepts that object. Do not write a scratch file on the MCP path.
44
+ Use either `repository`+`ref` or `checkout`, not both. `start_run` accepts that object. Do not write a scratch file on the MCP path. After start, inspect checkout state with `list_checkout_changes`, `get_run_diff`, or `read_checkout_file` when the human asks what changed in the bound tree (reclaimed succeeded worktrees → `checkout_reclaimed`).
34
45
 
35
46
  ### CLI
36
47
 
37
- `sf run` accepts `--task <path>` only. Reuse a catalog `*.task.yaml`, or write a throwaway file at the project root:
48
+ `sf run` accepts `--task <path>` plus optional `--repository` / `--ref` or `--checkout`. Reuse a catalog `*.task.yaml`, or write a throwaway file at the project root:
38
49
 
39
50
  ```
40
51
  .scratch/stageflow-run/<id>.task.yaml
@@ -45,8 +56,8 @@ id: <slug>
45
56
  goal: <human goal>
46
57
  ```
47
58
 
48
- Add `context`, `constraints`, or `checkout` only when the human gave them. Pass that path as `--task`.
59
+ Add `context`, `constraints`, `checkout`, or `repository` + `ref` only when the human gave them (same XOR as MCP). Pass that path as `--task`. Overrides: `--repository owner/repo --ref <ref>` or `--checkout <path>`.
49
60
 
50
61
  ## Optional run flags
51
62
 
52
- `--checkout`, `--git-sha`, `--ci-pr-url`, `--ci-job-url` only when the human supplied them.
63
+ `--checkout`, `--repository`, `--ref`, `--git-sha`, `--ci-pr-url`, `--ci-job-url` only when the human supplied them. Do not use `--operator-cwd` / `--operator-agent-dir` (no-ops); set `STAGEFLOW_OPERATOR_CWD` / `STAGEFLOW_OPERATOR_AGENT_DIR` before Host first start.
@@ -1,17 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import { readFileSync } from "node:fs";
4
+
3
5
  const DEFAULT_BASE_URL = "http://127.0.0.1:3847";
4
6
  const ALLOWED_TOOLS = new Set([
5
7
  "list_pipelines",
6
8
  "list_tasks",
7
9
  "start_run",
10
+ "run_stage",
8
11
  "get_run",
9
12
  "wait_run",
10
13
  "list_waiting",
11
14
  "list_runs",
12
15
  "answer_gate",
13
16
  "decide_feedback_loop",
17
+ "get_envelope",
14
18
  "read_artifact",
19
+ "list_checkout_changes",
20
+ "get_run_diff",
21
+ "read_checkout_file",
15
22
  "describe_pipeline",
16
23
  "validate",
17
24
  "list_providers",
@@ -27,6 +34,34 @@ const WAIT_RUN_DEFAULT_MS = 60_000;
27
34
  const WAIT_RUN_BUFFER_MS = 5_000;
28
35
  const WAIT_RUN_CAP_MS = 250_000;
29
36
 
37
+ function controlTokenFromEnv(env = process.env) {
38
+ const plain = env.STAGEFLOW_CONTROL_TOKEN;
39
+ const filePath = env.STAGEFLOW_CONTROL_TOKEN_FILE;
40
+ const hasPlain = plain !== undefined && plain.length > 0;
41
+ const hasFile = filePath !== undefined && filePath.length > 0;
42
+ if (hasPlain && hasFile) {
43
+ console.error("mcp-call: set only one of STAGEFLOW_CONTROL_TOKEN or STAGEFLOW_CONTROL_TOKEN_FILE");
44
+ process.exit(2);
45
+ }
46
+ if (hasFile) {
47
+ try {
48
+ return readFileSync(filePath, "utf8").replace(/\r?\n$/, "");
49
+ } catch (err) {
50
+ console.error(
51
+ `mcp-call: failed to read STAGEFLOW_CONTROL_TOKEN_FILE=${filePath}: ${err instanceof Error ? err.message : String(err)}`,
52
+ );
53
+ process.exit(2);
54
+ }
55
+ }
56
+ if (hasPlain) return plain;
57
+ return undefined;
58
+ }
59
+
60
+ function authHeaders(token) {
61
+ if (!token) return {};
62
+ return { Authorization: `Bearer ${token}` };
63
+ }
64
+
30
65
  function usage() {
31
66
  return "Usage: mcp-call.mjs --base-url URL --tool NAME --args JSON [--stateless]";
32
67
  }
@@ -156,13 +191,14 @@ function extractToolPayload(message) {
156
191
  return { payload, isError: result.isError === true };
157
192
  }
158
193
 
159
- async function postMcp(mcpUrl, { body, sessionId, timeoutMs }) {
194
+ async function postMcp(mcpUrl, { body, sessionId, timeoutMs, token }) {
160
195
  const ac = new AbortController();
161
196
  const timer = setTimeout(() => ac.abort(), timeoutMs);
162
197
  try {
163
198
  const headers = {
164
199
  "Content-Type": "application/json",
165
200
  Accept: "application/json, text/event-stream",
201
+ ...authHeaders(token),
166
202
  };
167
203
  if (sessionId) headers["mcp-session-id"] = sessionId;
168
204
  const res = await fetch(mcpUrl, {
@@ -185,7 +221,7 @@ function failTransport(detail, extra) {
185
221
  console.error(`mcp-call: ${detail}`);
186
222
  }
187
223
 
188
- async function initializeSession(mcpUrl) {
224
+ async function initializeSession(mcpUrl, token) {
189
225
  const { res, text } = await postMcp(mcpUrl, {
190
226
  body: {
191
227
  jsonrpc: "2.0",
@@ -198,6 +234,7 @@ async function initializeSession(mcpUrl) {
198
234
  },
199
235
  },
200
236
  timeoutMs: INIT_TIMEOUT_MS,
237
+ token,
201
238
  });
202
239
  if (res.status < 200 || res.status >= 300) {
203
240
  let extra;
@@ -215,19 +252,20 @@ async function initializeSession(mcpUrl) {
215
252
  body: { jsonrpc: "2.0", method: "notifications/initialized" },
216
253
  sessionId,
217
254
  timeoutMs: INIT_TIMEOUT_MS,
255
+ token,
218
256
  });
219
257
  } catch {}
220
258
  return sessionId;
221
259
  }
222
260
 
223
- async function closeSession(mcpUrl, sessionId) {
261
+ async function closeSession(mcpUrl, sessionId, token) {
224
262
  if (!sessionId) return;
225
263
  const ac = new AbortController();
226
264
  const timer = setTimeout(() => ac.abort(), INIT_TIMEOUT_MS);
227
265
  try {
228
266
  await fetch(mcpUrl, {
229
267
  method: "DELETE",
230
- headers: { "mcp-session-id": sessionId },
268
+ headers: { "mcp-session-id": sessionId, ...authHeaders(token) },
231
269
  signal: ac.signal,
232
270
  });
233
271
  } catch {
@@ -274,12 +312,13 @@ if (!ALLOWED_TOOLS.has(tool)) {
274
312
  const toolArgs = parseToolArgs(argsText);
275
313
  const mcpUrl = `${baseUrl}/mcp`;
276
314
  const timeoutMs = toolTimeoutMs(tool, toolArgs);
315
+ const token = controlTokenFromEnv();
277
316
 
278
317
  let sessionId;
279
318
  let exitCode = 1;
280
319
  try {
281
320
  if (!stateless) {
282
- sessionId = await initializeSession(mcpUrl);
321
+ sessionId = await initializeSession(mcpUrl, token);
283
322
  }
284
323
  const { res, text } = await postMcp(mcpUrl, {
285
324
  body: {
@@ -290,6 +329,7 @@ try {
290
329
  },
291
330
  sessionId,
292
331
  timeoutMs,
332
+ token,
293
333
  });
294
334
  exitCode = handleToolResponse(res, text);
295
335
  } catch (err) {
@@ -302,7 +342,7 @@ try {
302
342
  }
303
343
  } finally {
304
344
  if (sessionId) {
305
- await closeSession(mcpUrl, sessionId);
345
+ await closeSession(mcpUrl, sessionId, token);
306
346
  }
307
347
  }
308
348
  process.exit(exitCode);
@@ -7,10 +7,18 @@ import { test } from "node:test";
7
7
 
8
8
  const script = path.join(path.dirname(fileURLToPath(import.meta.url)), "mcp-call.mjs");
9
9
 
10
+ function cleanEnv(extra = {}) {
11
+ const env = { ...process.env };
12
+ delete env.STAGEFLOW_CONTROL_TOKEN;
13
+ delete env.STAGEFLOW_CONTROL_TOKEN_FILE;
14
+ return { ...env, ...extra };
15
+ }
16
+
10
17
  function run(args, opts = {}) {
11
18
  return new Promise((resolve) => {
12
19
  const child = spawn(process.execPath, [script, ...args], {
13
20
  stdio: ["ignore", "pipe", "pipe"],
21
+ env: opts.env ?? cleanEnv(),
14
22
  });
15
23
  let stdout = "";
16
24
  let stderr = "";
@@ -238,6 +246,62 @@ test("isError true exits non-zero and prints the payload", async () => {
238
246
  }
239
247
  });
240
248
 
249
+ test("sends Authorization Bearer when STAGEFLOW_CONTROL_TOKEN is set", async () => {
250
+ let sawAuth;
251
+ const { server, baseUrl } = await listen(async (req, res) => {
252
+ sawAuth = req.headers.authorization;
253
+ const body = await readJsonBody(req);
254
+ writeToolResult(res, body.id, HEALTH);
255
+ });
256
+ try {
257
+ const token = "a".repeat(32);
258
+ const result = await run(
259
+ [
260
+ "--base-url",
261
+ baseUrl,
262
+ "--tool",
263
+ "get_health",
264
+ "--args",
265
+ "{}",
266
+ "--stateless",
267
+ ],
268
+ {
269
+ env: cleanEnv({ STAGEFLOW_CONTROL_TOKEN: token }),
270
+ },
271
+ );
272
+ assert.equal(result.status, 0);
273
+ assert.equal(sawAuth, `Bearer ${token}`);
274
+ } finally {
275
+ server.close();
276
+ }
277
+ });
278
+
279
+ test("allows run_stage and get_envelope tool names", async () => {
280
+ const seen = [];
281
+ const { server, baseUrl } = await listen(async (req, res) => {
282
+ const body = await readJsonBody(req);
283
+ seen.push(body?.params?.name);
284
+ writeToolResult(res, body.id, { ok: true });
285
+ });
286
+ try {
287
+ for (const tool of ["run_stage", "get_envelope"]) {
288
+ const result = await run([
289
+ "--base-url",
290
+ baseUrl,
291
+ "--tool",
292
+ tool,
293
+ "--args",
294
+ "{}",
295
+ "--stateless",
296
+ ]);
297
+ assert.equal(result.status, 0, tool);
298
+ }
299
+ assert.deepEqual(seen, ["run_stage", "get_envelope"]);
300
+ } finally {
301
+ server.close();
302
+ }
303
+ });
304
+
241
305
  test("--stateless against a session-mode-only mock errors without hanging", async () => {
242
306
  const { server, baseUrl } = await listen((_req, res) => {
243
307
  res.writeHead(400, { "content-type": "application/json" });
@@ -24,6 +24,8 @@ Write reviewable or required outputs with `write_stage_artifact`, not checkout `
24
24
 
25
25
  Omit `gate_kinds`. A human-review checkpoint from the source session stays as prose in the stage approach, not a HITL gate.
26
26
 
27
+ When a captured phase pushes, opens a PR, or otherwise needs git/`gh` credentials, declare `secrets:` on that stage (or its pipeline entry) — stages do not inherit Host ambient `GITHUB_TOKEN`. See [`../../stageflow-author/references/catalog-mapping.md`](../../stageflow-author/references/catalog-mapping.md#stage-secrets).
28
+
27
29
  Worked example: `assets/example-pipeline/research.yaml` and `assets/example-pipeline/implement.yaml`.
28
30
 
29
31
  ## Pipeline file
@@ -2,11 +2,12 @@
2
2
  name: stageflow-setup
3
3
  description: >-
4
4
  Installs Stageflow, scaffolds a starter catalog with sf init, then hard-stops
5
- for provider login. Use when this project has no Stageflow install, sf is not
6
- found, there is no catalog, first time running Stageflow here, the user asks
7
- to set up Stageflow, or a provider is not logged in. Install, scaffold, and
8
- provider-gate only — does not author pipelines or stages, capture a session,
9
- or manage an MCP host.
5
+ for provider login. Optional Docker Compose path for a standing Host (UI+MCP).
6
+ Use when this project has no Stageflow install, sf is not found, there is no
7
+ catalog, first time running Stageflow here, the user asks to set up Stageflow,
8
+ a provider is not logged in, or the operator wants Compose local try. Install,
9
+ scaffold, and provider-gate only — does not author pipelines or stages, capture
10
+ a session, or auto-start an MCP host.
10
11
  disable-model-invocation: true
11
12
  ---
12
13
 
@@ -16,7 +17,7 @@ Install the CLI, scaffold a catalog, then hard-stop until a provider is configur
16
17
 
17
18
  Author pipelines and stages with `stageflow-author`. Capture a chat or past session with `stageflow-session-capture`. Start, watch, or answer a run with `stageflow-run`. Codify a repeating pattern with `stageflow-delegate`.
18
19
 
19
- This job does not author catalog YAML, capture a session, or manage an MCP host. Its surface is the `sf` CLI. Talking jobs cite [`../stageflow/references/control-surface.md`](../stageflow/references/control-surface.md) for MCP-vs-CLI; do not run the host probe in that file from this job.
20
+ This job does not author catalog YAML, capture a session, or auto-start an MCP host. Its default surface is the `sf` CLI; Compose local try (below) is the optional standing-Host path. Talking jobs cite [`../stageflow/references/control-surface.md`](../stageflow/references/control-surface.md) for MCP-vs-CLI; do not run the host probe in that file from this job.
20
21
 
21
22
  ## Detect-before-mutate
22
23
 
@@ -68,9 +69,14 @@ Skip `$SF init` when probe 2 passed.
68
69
 
69
70
  Run this phase only after Install and Scaffold have succeeded or were already satisfied. Never print `ready to author` while no provider is `configured`.
70
71
 
72
+ **Credential surface (do not mix):**
73
+
74
+ - **Local CLI** (this job's default path): `providers login --api-key-env` / bare `<ID>_API_KEY` (e.g. `ANTHROPIC_API_KEY`). See Stageflow docs: Providers.
75
+ - **Host / Compose boot:** `STAGEFLOW_PROVIDER_<ID>_API_KEY` or `STAGEFLOW_PROVIDER_<ID>_API_KEY_FILE`. Bare `OPENROUTER_API_KEY` / `ANTHROPIC_API_KEY` alone does **not** configure Host boot. See Stageflow docs: Providers — Non-interactive Host boot credentials; Docker and self-hosting — Local try.
76
+
71
77
  1. Run `$SF providers status`. **Done when** any row is `configured` — go to Completion. If a non-interactive login just succeeded, name that provider id.
72
78
 
73
- 2. If none are configured, run `$SF providers list`. For each id (first column), test whether the environment has `<ID>_API_KEY` with `ID` uppercased (`anthropic` → `ANTHROPIC_API_KEY`). Test presence only — do not read or print the value.
79
+ 2. If none are configured, run `$SF providers list`. For each id (first column), test whether the environment has `<ID>_API_KEY` with `ID` uppercased (`anthropic` → `ANTHROPIC_API_KEY`). Test presence only — do not read or print the value. Do not treat `STAGEFLOW_PROVIDER_*` as satisfying this local CLI gate.
74
80
 
75
81
  3. On the first match, run:
76
82
 
@@ -90,7 +96,7 @@ Run this phase only after Install and Scaffold have succeeded or were already sa
90
96
  $SF providers login <id> --type oauth
91
97
  ```
92
98
 
93
- Point at `docs/providers.md` for `pi_home` vs `sf_owned`. Leave the storage mode to the human.
99
+ Point at Stageflow docs: Providers (`pi_home` vs `sf_owned`). Leave the storage mode to the human. If the operator will use Compose instead, point them at the Docker Compose section below and `STAGEFLOW_PROVIDER_<ID>_API_KEY(_FILE)`.
94
100
 
95
101
  ## Completion
96
102
 
@@ -108,3 +114,29 @@ If this invocation used the `npx` fallback, add a following line:
108
114
  `CLI: npx stageflow (EACCES on npm i -g stageflow; this session only — a later invocation will re-check the global install)`
109
115
 
110
116
  A later job calls this skill as preflight. It does not re-implement the provider gate.
117
+
118
+ ## Optional: Docker Compose (standing Host)
119
+
120
+ This job does **not** auto-start `sf ui` or `sf mcp`. Compose local try is the path to a standing Host (operator console **and** MCP on port **3847**). Keep the npm / `sf init` / local provider path above for CLI authoring; use Compose when the operator wants a container Host.
121
+
122
+ Do not invent compose flags or env names. See Stageflow docs: Docker and self-hosting — Local try (checkout: `docs/docker.md`; also `.env.example`).
123
+
124
+ 1. From a Stageflow checkout (or image + compose that matches shipped contracts), copy `.env.example` → `.env`. Do not commit `.env`.
125
+
126
+ 2. Set `STAGEFLOW_CONTROL_TOKEN` to ≥32 characters, no whitespace (e.g. `openssl rand -hex 32`). Required when the image binds non-loopback.
127
+
128
+ 3. Set Host boot providers as `STAGEFLOW_PROVIDER_<ID>_API_KEY` or `_FILE` (e.g. `STAGEFLOW_PROVIDER_OPENROUTER_API_KEY`). Not bare `OPENROUTER_API_KEY` alone.
129
+
130
+ 4. Optional: `GITHUB_TOKEN` (or `GH_TOKEN`) for Host clone/fetch askpass — needed even for public repos.
131
+
132
+ 5. **Shell env overrides Compose `.env`.** Empty exported `GITHUB_TOKEN` / `GH_TOKEN` blanks the container value. Prefer:
133
+
134
+ ```bash
135
+ env -u GITHUB_TOKEN -u GH_TOKEN docker compose up --build -d
136
+ ```
137
+
138
+ 6. Wait for live: `curl -fsS http://127.0.0.1:3847/livez` → `{"ok":true,"status":"live",…}`.
139
+
140
+ 7. Open `http://127.0.0.1:3847` and paste the same control token under **Settings** (drive bearer for API/MCP).
141
+
142
+ After Compose is up, talking jobs use MCP with `Authorization: Bearer <drive-token>` — see [`../stageflow/references/control-surface.md`](../stageflow/references/control-surface.md). `/api/health` is ungated; a health 200 is not authenticated MCP.