stageflow 0.25.0 → 0.30.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 (681) hide show
  1. package/README.md +14 -3
  2. package/builtin-skills/browser/SKILL.md +42 -0
  3. package/dist/a2a/contracts.d.ts +1 -0
  4. package/dist/a2a/contracts.js +1 -0
  5. package/dist/a2a/registry.d.ts +2 -0
  6. package/dist/a2a/registry.js +20 -1
  7. package/dist/a2a/server.d.ts +7 -0
  8. package/dist/a2a/server.js +5 -2
  9. package/dist/a2a/service.d.ts +1 -1
  10. package/dist/a2a/service.js +57 -8
  11. package/dist/a2a/store.d.ts +8 -5
  12. package/dist/a2a/store.js +24 -67
  13. package/dist/agent/activity.d.ts +3 -0
  14. package/dist/agent/bootProviderConfig.d.ts +21 -0
  15. package/dist/agent/bootProviderConfig.js +74 -0
  16. package/dist/agent/claudeAdapter.js +2 -2
  17. package/dist/agent/cursorProvider.d.ts +2 -0
  18. package/dist/agent/cursorProvider.js +30 -5
  19. package/dist/agent/fakeAgent.d.ts +1 -0
  20. package/dist/agent/fakeAgent.js +13 -0
  21. package/dist/agent/piAdapter.d.ts +11 -24
  22. package/dist/agent/piAdapter.js +107 -50
  23. package/dist/agent/piIsolatedMcp.d.ts +2 -0
  24. package/dist/agent/piIsolatedMcp.js +10 -2
  25. package/dist/agent/piSessionFactory.d.ts +38 -0
  26. package/dist/agent/piSessionFactory.js +60 -0
  27. package/dist/agent/port.d.ts +8 -0
  28. package/dist/agent/streamLogRedact.d.ts +7 -1
  29. package/dist/agent/streamLogRedact.js +26 -11
  30. package/dist/browser/anchor.d.ts +27 -0
  31. package/dist/browser/anchor.js +127 -0
  32. package/dist/browser/auditSink.d.ts +38 -0
  33. package/dist/browser/auditSink.js +34 -0
  34. package/dist/browser/browserHost.d.ts +86 -0
  35. package/dist/browser/browserHost.js +7 -0
  36. package/dist/browser/browserSweep.d.ts +14 -0
  37. package/dist/browser/browserSweep.js +54 -0
  38. package/dist/browser/browserTeardown.d.ts +56 -0
  39. package/dist/browser/browserTeardown.js +235 -0
  40. package/dist/browser/fakeRemoteBrowserHost.d.ts +2 -0
  41. package/dist/browser/fakeRemoteBrowserHost.js +34 -0
  42. package/dist/browser/gateHandoff.d.ts +25 -0
  43. package/dist/browser/gateHandoff.js +83 -0
  44. package/dist/browser/humanLogin.d.ts +18 -0
  45. package/dist/browser/humanLogin.js +34 -0
  46. package/dist/browser/keyProvider.d.ts +10 -0
  47. package/dist/browser/keyProvider.js +39 -0
  48. package/dist/browser/localBrowserHost.d.ts +10 -0
  49. package/dist/browser/localBrowserHost.js +152 -0
  50. package/dist/browser/localProfileLock.d.ts +2 -0
  51. package/dist/browser/localProfileLock.js +218 -0
  52. package/dist/browser/localProfileStore.d.ts +5 -0
  53. package/dist/browser/localProfileStore.js +91 -0
  54. package/dist/browser/loginCheck.d.ts +53 -0
  55. package/dist/browser/loginCheck.js +147 -0
  56. package/dist/browser/memoryProfileLock.d.ts +2 -0
  57. package/dist/browser/memoryProfileLock.js +53 -0
  58. package/dist/browser/memoryProfileStore.d.ts +2 -0
  59. package/dist/browser/memoryProfileStore.js +31 -0
  60. package/dist/browser/navigationAudit.d.ts +16 -0
  61. package/dist/browser/navigationAudit.js +53 -0
  62. package/dist/browser/persistedEnv.d.ts +3 -0
  63. package/dist/browser/persistedEnv.js +15 -0
  64. package/dist/browser/profileLock.d.ts +40 -0
  65. package/dist/browser/profileLock.js +10 -0
  66. package/dist/browser/profileStore.d.ts +23 -0
  67. package/dist/browser/profileStore.js +39 -0
  68. package/dist/browser/runLiveness.d.ts +13 -0
  69. package/dist/browser/runLiveness.js +39 -0
  70. package/dist/browser/sitePolicy.d.ts +10 -0
  71. package/dist/browser/sitePolicy.js +61 -0
  72. package/dist/browser/stageBrowserEnv.d.ts +22 -0
  73. package/dist/browser/stageBrowserEnv.js +147 -0
  74. package/dist/browser/stageProfileLock.d.ts +17 -0
  75. package/dist/browser/stageProfileLock.js +39 -0
  76. package/dist/cli/artifactCommand.js +9 -16
  77. package/dist/cli/backupCommand.d.ts +9 -0
  78. package/dist/cli/backupCommand.js +111 -0
  79. package/dist/cli/browserCommand.d.ts +44 -0
  80. package/dist/cli/browserCommand.js +472 -0
  81. package/dist/cli/debugRunCommand.d.ts +10 -0
  82. package/dist/cli/debugRunCommand.js +109 -0
  83. package/dist/cli/doctorCommand.d.ts +32 -0
  84. package/dist/cli/doctorCommand.js +453 -0
  85. package/dist/cli/envelopeCommand.js +9 -2
  86. package/dist/cli/exportAllCommand.d.ts +55 -0
  87. package/dist/cli/exportAllCommand.js +218 -0
  88. package/dist/cli/exportRunCommand.js +23 -21
  89. package/dist/cli/hostClient.d.ts +41 -3
  90. package/dist/cli/hostClient.js +129 -14
  91. package/dist/cli/initCommand.d.ts +1 -0
  92. package/dist/cli/initCommand.js +23 -7
  93. package/dist/cli/initTemplates.d.ts +5 -2
  94. package/dist/cli/initTemplates.js +32 -2
  95. package/dist/cli/resolveSafeOutPath.d.ts +2 -0
  96. package/dist/cli/resolveSafeOutPath.js +40 -0
  97. package/dist/cli/restoreCommand.d.ts +10 -0
  98. package/dist/cli/restoreCommand.js +90 -0
  99. package/dist/cli/runCommand.d.ts +3 -2
  100. package/dist/cli/runCommand.js +93 -11
  101. package/dist/cli/runOutput.d.ts +4 -0
  102. package/dist/cli/runOutput.js +33 -7
  103. package/dist/cli/runStageCommand.d.ts +1 -0
  104. package/dist/cli/runStageCommand.js +44 -25
  105. package/dist/cli/runsCommand.d.ts +1 -1
  106. package/dist/cli/runsCommand.js +168 -10
  107. package/dist/cli/triggerCommand.d.ts +12 -0
  108. package/dist/cli/triggerCommand.js +183 -0
  109. package/dist/cli/validateCommand.d.ts +1 -1
  110. package/dist/cli/validateCommand.js +23 -6
  111. package/dist/cli.js +202 -32
  112. package/dist/config/browseCatalog.d.ts +1 -0
  113. package/dist/config/browseCatalog.js +5 -4
  114. package/dist/config/builtinSkills.d.ts +4 -0
  115. package/dist/config/builtinSkills.js +23 -0
  116. package/dist/config/catalogRelativePath.d.ts +63 -0
  117. package/dist/config/catalogRelativePath.js +126 -0
  118. package/dist/config/configOrigin.d.ts +27 -0
  119. package/dist/config/configOrigin.js +59 -0
  120. package/dist/config/createTrigger.d.ts +27 -0
  121. package/dist/config/createTrigger.js +232 -0
  122. package/dist/config/draftPackage.d.ts +117 -0
  123. package/dist/config/draftPackage.js +550 -0
  124. package/dist/config/ensureCatalogScanRoot.d.ts +16 -0
  125. package/dist/config/ensureCatalogScanRoot.js +73 -0
  126. package/dist/config/hostConfig.d.ts +57 -0
  127. package/dist/config/hostConfig.js +360 -0
  128. package/dist/config/listSkills.d.ts +26 -0
  129. package/dist/config/listSkills.js +206 -5
  130. package/dist/config/loadOutcome.d.ts +7 -1
  131. package/dist/config/loadPipeline.js +39 -2
  132. package/dist/config/loadStage.js +25 -0
  133. package/dist/config/loadStageflowManifest.js +25 -0
  134. package/dist/config/loadTask.d.ts +2 -0
  135. package/dist/config/loadTask.js +57 -18
  136. package/dist/config/loadTrigger.d.ts +9 -0
  137. package/dist/config/loadTrigger.js +120 -0
  138. package/dist/config/materializeStageModels.js +5 -1
  139. package/dist/config/mergePipelineIncludes.d.ts +3 -0
  140. package/dist/config/mergePipelineIncludes.js +19 -0
  141. package/dist/config/migrateYaml.js +6 -11
  142. package/dist/config/multiProjectCatalog.d.ts +32 -0
  143. package/dist/config/multiProjectCatalog.js +150 -0
  144. package/dist/config/normalizePipelineStageEntry.js +27 -1
  145. package/dist/config/parseCompletionContract.js +6 -0
  146. package/dist/config/pipelineStageKeys.js +3 -0
  147. package/dist/config/publishDraftPackage.d.ts +7 -0
  148. package/dist/config/publishDraftPackage.js +25 -0
  149. package/dist/config/resolveCatalogContext.js +1 -1
  150. package/dist/config/resolveCatalogRoots.d.ts +27 -0
  151. package/dist/config/resolveCatalogRoots.js +76 -0
  152. package/dist/config/resolveModel.d.ts +7 -1
  153. package/dist/config/resolveModel.js +11 -1
  154. package/dist/config/resolvePipelineDag.js +1 -1
  155. package/dist/config/resolveStageMcpServers.d.ts +9 -1
  156. package/dist/config/resolveStageMcpServers.js +36 -9
  157. package/dist/config/scanCatalogPaths.d.ts +1 -1
  158. package/dist/config/scanCatalogPaths.js +6 -2
  159. package/dist/config/secretFromEnvOrFile.d.ts +9 -0
  160. package/dist/config/secretFromEnvOrFile.js +34 -0
  161. package/dist/config/seededCatalog.d.ts +11 -0
  162. package/dist/config/seededCatalog.js +29 -0
  163. package/dist/config/stageBrowser.d.ts +12 -0
  164. package/dist/config/stageBrowser.js +118 -0
  165. package/dist/config/toolRequires.d.ts +24 -0
  166. package/dist/config/toolRequires.js +115 -0
  167. package/dist/config/triggerCatalog.d.ts +10 -0
  168. package/dist/config/triggerCatalog.js +37 -0
  169. package/dist/config/validateCatalog.d.ts +17 -3
  170. package/dist/config/validateCatalog.js +223 -3
  171. package/dist/config/validateCompletionContract.js +8 -0
  172. package/dist/diagnostics/checks.d.ts +39 -0
  173. package/dist/diagnostics/checks.js +135 -0
  174. package/dist/envelope/preEmitChecks.d.ts +1 -1
  175. package/dist/envelope/preEmitChecks.js +8 -0
  176. package/dist/errors/codes.d.ts +14 -0
  177. package/dist/errors/codes.js +59 -0
  178. package/dist/git/cache.d.ts +14 -0
  179. package/dist/git/cache.js +150 -0
  180. package/dist/git/credentials.d.ts +9 -0
  181. package/dist/git/credentials.js +88 -0
  182. package/dist/git/errors.d.ts +20 -0
  183. package/dist/git/errors.js +94 -0
  184. package/dist/git/exec.d.ts +16 -0
  185. package/dist/git/exec.js +135 -0
  186. package/dist/git/operations.d.ts +29 -0
  187. package/dist/git/operations.js +153 -0
  188. package/dist/git/version.d.ts +1 -0
  189. package/dist/git/version.js +10 -0
  190. package/dist/logging/audit.d.ts +16 -0
  191. package/dist/logging/audit.js +19 -0
  192. package/dist/logging/commonWords.d.ts +2 -0
  193. package/dist/logging/commonWords.js +13 -0
  194. package/dist/logging/logger.d.ts +49 -0
  195. package/dist/logging/logger.js +193 -0
  196. package/dist/logging/namedSecrets.d.ts +6 -0
  197. package/dist/logging/namedSecrets.js +58 -0
  198. package/dist/logging/redact.d.ts +17 -0
  199. package/dist/logging/redact.js +105 -0
  200. package/dist/mcp/catalogTools.js +492 -81
  201. package/dist/mcp/checkoutTools.d.ts +52 -0
  202. package/dist/mcp/checkoutTools.js +332 -0
  203. package/dist/mcp/controlTools.js +182 -6
  204. package/dist/mcp/deps.d.ts +3 -0
  205. package/dist/mcp/getStartedTool.d.ts +3 -0
  206. package/dist/mcp/getStartedTool.js +62 -0
  207. package/dist/mcp/readArtifact.d.ts +11 -0
  208. package/dist/mcp/readArtifact.js +46 -30
  209. package/dist/mcp/server.js +2 -0
  210. package/dist/mcp/tools.js +6 -0
  211. package/dist/mcp/triggerTools.d.ts +3 -0
  212. package/dist/mcp/triggerTools.js +176 -0
  213. package/dist/net/proxy.d.ts +14 -0
  214. package/dist/net/proxy.js +78 -0
  215. package/dist/operatorAgent/docsRetrieval.d.ts +40 -0
  216. package/dist/operatorAgent/docsRetrieval.js +269 -0
  217. package/dist/operatorAgent/draftContext.d.ts +16 -0
  218. package/dist/operatorAgent/draftContext.js +68 -0
  219. package/dist/operatorAgent/fakeHost.d.ts +39 -0
  220. package/dist/operatorAgent/fakeHost.js +92 -0
  221. package/dist/operatorAgent/host.d.ts +40 -0
  222. package/dist/operatorAgent/host.js +179 -0
  223. package/dist/operatorAgent/index.d.ts +9 -0
  224. package/dist/operatorAgent/index.js +8 -0
  225. package/dist/operatorAgent/piModel.d.ts +80 -0
  226. package/dist/operatorAgent/piModel.js +528 -0
  227. package/dist/operatorAgent/profiles/workshopAuthor.d.ts +23 -0
  228. package/dist/operatorAgent/profiles/workshopAuthor.js +338 -0
  229. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +6 -0
  230. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +103 -0
  231. package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +57 -0
  232. package/dist/operatorAgent/profiles/workshopAuthorTools.js +623 -0
  233. package/dist/operatorAgent/proposals.d.ts +32 -0
  234. package/dist/operatorAgent/proposals.js +144 -0
  235. package/dist/operatorAgent/types.d.ts +128 -0
  236. package/dist/operatorAgent/types.js +1 -0
  237. package/dist/package-meta.d.ts +2 -1
  238. package/dist/package-meta.js +2 -1
  239. package/dist/preflight/bash.d.ts +8 -0
  240. package/dist/preflight/bash.js +34 -0
  241. package/dist/preflight/claudeRoot.d.ts +11 -0
  242. package/dist/preflight/claudeRoot.js +23 -0
  243. package/dist/preflight/mcpCommands.d.ts +8 -0
  244. package/dist/preflight/mcpCommands.js +36 -0
  245. package/dist/preflight/pipelinePreflight.d.ts +40 -0
  246. package/dist/preflight/pipelinePreflight.js +192 -0
  247. package/dist/preflight/tls.d.ts +6 -0
  248. package/dist/preflight/tls.js +18 -0
  249. package/dist/preflight/toolchain.d.ts +45 -0
  250. package/dist/preflight/toolchain.js +219 -0
  251. package/dist/project/findManifestRoot.d.ts +3 -0
  252. package/dist/project/findManifestRoot.js +35 -0
  253. package/dist/project/findProjectRoot.js +3 -4
  254. package/dist/project/globalHome.d.ts +7 -0
  255. package/dist/project/globalHome.js +63 -2
  256. package/dist/project/resolveProjectContext.js +2 -2
  257. package/dist/project/resolveStageflowContext.d.ts +7 -0
  258. package/dist/project/resolveStageflowContext.js +46 -30
  259. package/dist/projection/projectRun.d.ts +2 -1
  260. package/dist/projection/projectRun.js +1 -0
  261. package/dist/runstore/assertTmpdir.d.ts +1 -0
  262. package/dist/runstore/assertTmpdir.js +25 -0
  263. package/dist/runstore/backup.d.ts +52 -0
  264. package/dist/runstore/backup.js +292 -0
  265. package/dist/runstore/createStore.d.ts +18 -1
  266. package/dist/runstore/createStore.js +64 -5
  267. package/dist/runstore/debugBundle.d.ts +60 -0
  268. package/dist/runstore/debugBundle.js +143 -0
  269. package/dist/runstore/diskUsage.d.ts +50 -0
  270. package/dist/runstore/diskUsage.js +214 -0
  271. package/dist/runstore/exportRunPayload.d.ts +8 -0
  272. package/dist/runstore/exportRunPayload.js +23 -0
  273. package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
  274. package/dist/runstore/normalizeCatalogPath.js +10 -0
  275. package/dist/runstore/paths.d.ts +5 -0
  276. package/dist/runstore/paths.js +145 -1
  277. package/dist/runstore/port.d.ts +139 -13
  278. package/dist/runstore/port.js +8 -1
  279. package/dist/runstore/restore.d.ts +81 -0
  280. package/dist/runstore/restore.js +355 -0
  281. package/dist/runstore/retention.d.ts +27 -0
  282. package/dist/runstore/retention.js +74 -0
  283. package/dist/runstore/runManifest.d.ts +146 -0
  284. package/dist/runstore/runManifest.js +288 -0
  285. package/dist/runstore/runProjection.d.ts +3 -1
  286. package/dist/runstore/runProjection.js +63 -1
  287. package/dist/runstore/sqlite/SqliteRunStore.d.ts +35 -3
  288. package/dist/runstore/sqlite/SqliteRunStore.js +442 -219
  289. package/dist/runstore/sqlite/applyStorePragmas.d.ts +39 -0
  290. package/dist/runstore/sqlite/applyStorePragmas.js +145 -0
  291. package/dist/runstore/sqlite/migrations/001-baseline.d.ts +7 -0
  292. package/dist/runstore/sqlite/migrations/001-baseline.js +10 -0
  293. package/dist/runstore/sqlite/migrations/002-repository-binding.d.ts +7 -0
  294. package/dist/runstore/sqlite/migrations/002-repository-binding.js +29 -0
  295. package/dist/runstore/sqlite/migrations/003-run-lifecycle.d.ts +7 -0
  296. package/dist/runstore/sqlite/migrations/003-run-lifecycle.js +28 -0
  297. package/dist/runstore/sqlite/migrations/004-auto-resume-count.d.ts +7 -0
  298. package/dist/runstore/sqlite/migrations/004-auto-resume-count.js +19 -0
  299. package/dist/runstore/sqlite/migrations/005-config-origins.d.ts +7 -0
  300. package/dist/runstore/sqlite/migrations/005-config-origins.js +19 -0
  301. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.d.ts +7 -0
  302. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.js +28 -0
  303. package/dist/runstore/sqlite/migrations/007-projects-registry.d.ts +7 -0
  304. package/dist/runstore/sqlite/migrations/007-projects-registry.js +31 -0
  305. package/dist/runstore/sqlite/migrations/008-triggers-table.d.ts +7 -0
  306. package/dist/runstore/sqlite/migrations/008-triggers-table.js +19 -0
  307. package/dist/runstore/sqlite/migrations/009-trigger-next-run.d.ts +7 -0
  308. package/dist/runstore/sqlite/migrations/009-trigger-next-run.js +19 -0
  309. package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.d.ts +7 -0
  310. package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.js +17 -0
  311. package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
  312. package/dist/runstore/sqlite/migrations/index.js +78 -0
  313. package/dist/runstore/sqlite/schema.d.ts +20 -1
  314. package/dist/runstore/sqlite/schema.js +277 -1
  315. package/dist/runstore/sqlite/storeOpenError.d.ts +6 -0
  316. package/dist/runstore/sqlite/storeOpenError.js +11 -0
  317. package/dist/runstore/sqlite/storeSchemaError.d.ts +5 -0
  318. package/dist/runstore/sqlite/storeSchemaError.js +8 -0
  319. package/dist/runstore/stageExecution.js +3 -0
  320. package/dist/runstore/storeFilesystem.d.ts +32 -0
  321. package/dist/runstore/storeFilesystem.js +148 -0
  322. package/dist/runstore/trackProjection.js +2 -0
  323. package/dist/runstore/workspaceLayout.d.ts +13 -0
  324. package/dist/runstore/workspaceLayout.js +76 -0
  325. package/dist/runtime/answerResume.d.ts +1 -0
  326. package/dist/runtime/answerResume.js +3 -1
  327. package/dist/runtime/completionCheckRunner.d.ts +15 -1
  328. package/dist/runtime/completionCheckRunner.js +67 -7
  329. package/dist/runtime/containerLimits.d.ts +16 -0
  330. package/dist/runtime/containerLimits.js +84 -0
  331. package/dist/runtime/credentialBinding.d.ts +2 -0
  332. package/dist/runtime/credentialBinding.js +3 -0
  333. package/dist/runtime/credentialMaterialisation.d.ts +28 -0
  334. package/dist/runtime/credentialMaterialisation.js +128 -0
  335. package/dist/runtime/emailSource.d.ts +72 -0
  336. package/dist/runtime/emailSource.js +304 -0
  337. package/dist/runtime/gitCheckoutCapability.js +7 -13
  338. package/dist/runtime/githubPollSource.d.ts +86 -0
  339. package/dist/runtime/githubPollSource.js +284 -0
  340. package/dist/runtime/pipelineRunner.d.ts +40 -1
  341. package/dist/runtime/pipelineRunner.js +181 -17
  342. package/dist/runtime/pipelineScheduler.d.ts +17 -0
  343. package/dist/runtime/pipelineScheduler.js +220 -28
  344. package/dist/runtime/reloadRunCatalog.js +6 -1
  345. package/dist/runtime/repositoryMaterialize.d.ts +47 -0
  346. package/dist/runtime/repositoryMaterialize.js +235 -0
  347. package/dist/runtime/resumeTimedOut.d.ts +1 -1
  348. package/dist/runtime/resumeTimedOut.js +5 -2
  349. package/dist/runtime/runChangeBus.js +9 -0
  350. package/dist/runtime/runDeletion.d.ts +7 -0
  351. package/dist/runtime/runDeletion.js +37 -0
  352. package/dist/runtime/runManager.d.ts +169 -4
  353. package/dist/runtime/runManager.js +1748 -83
  354. package/dist/runtime/runRetentionSweep.d.ts +31 -0
  355. package/dist/runtime/runRetentionSweep.js +328 -0
  356. package/dist/runtime/runRetryCoordinator.d.ts +4 -0
  357. package/dist/runtime/runRetryCoordinator.js +20 -2
  358. package/dist/runtime/runSkills.d.ts +40 -0
  359. package/dist/runtime/runSkills.js +173 -0
  360. package/dist/runtime/scheduleSource.d.ts +38 -0
  361. package/dist/runtime/scheduleSource.js +119 -0
  362. package/dist/runtime/settingsFile.d.ts +5 -0
  363. package/dist/runtime/settingsFile.js +61 -54
  364. package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
  365. package/dist/runtime/stageAttemptBootstrap.js +250 -27
  366. package/dist/runtime/stageCacheEnv.d.ts +6 -0
  367. package/dist/runtime/stageCacheEnv.js +34 -0
  368. package/dist/runtime/stageConcurrency.d.ts +2 -1
  369. package/dist/runtime/stageConcurrency.js +4 -2
  370. package/dist/runtime/stageEnvironment.d.ts +38 -0
  371. package/dist/runtime/stageEnvironment.js +194 -0
  372. package/dist/runtime/stageHitl.d.ts +1 -0
  373. package/dist/runtime/stageHitl.js +5 -1
  374. package/dist/runtime/stageProcessLauncher.d.ts +20 -0
  375. package/dist/runtime/stageProcessLauncher.js +236 -41
  376. package/dist/runtime/stageRecovery.d.ts +3 -1
  377. package/dist/runtime/stageRecovery.js +19 -4
  378. package/dist/runtime/stageRoots.d.ts +38 -1
  379. package/dist/runtime/stageRoots.js +118 -0
  380. package/dist/runtime/stageRunner.d.ts +6 -0
  381. package/dist/runtime/stageRunner.js +32 -6
  382. package/dist/runtime/stageSecretDecl.d.ts +9 -0
  383. package/dist/runtime/stageSecretDecl.js +102 -0
  384. package/dist/runtime/stageSecrets.d.ts +40 -0
  385. package/dist/runtime/stageSecrets.js +181 -0
  386. package/dist/runtime/stageStreamLog.d.ts +1 -0
  387. package/dist/runtime/stageStreamLog.js +2 -1
  388. package/dist/runtime/stageWorker.d.ts +3 -2
  389. package/dist/runtime/stageWorker.js +58 -10
  390. package/dist/runtime/stageWorkerProtocol.d.ts +5 -0
  391. package/dist/runtime/stageWorkerProtocol.js +8 -0
  392. package/dist/runtime/startPayload.d.ts +32 -0
  393. package/dist/runtime/startPayload.js +59 -0
  394. package/dist/runtime/taskInput.js +14 -5
  395. package/dist/runtime/triggerCatalog.d.ts +6 -0
  396. package/dist/runtime/triggerCatalog.js +24 -0
  397. package/dist/runtime/triggerEventMatch.d.ts +2 -0
  398. package/dist/runtime/triggerEventMatch.js +6 -0
  399. package/dist/runtime/triggerPort.d.ts +14 -0
  400. package/dist/runtime/triggerPort.js +1 -0
  401. package/dist/runtime/triggerRunner.d.ts +17 -0
  402. package/dist/runtime/triggerRunner.js +89 -0
  403. package/dist/runtime/verifiedStageExecution.d.ts +8 -0
  404. package/dist/runtime/verifiedStageExecution.js +16 -1
  405. package/dist/runtime/webhookSignature.d.ts +1 -0
  406. package/dist/runtime/webhookSignature.js +12 -0
  407. package/dist/runtime/workspaceBinding.d.ts +20 -0
  408. package/dist/runtime/workspaceBinding.js +60 -0
  409. package/dist/server/allowedHosts.d.ts +19 -0
  410. package/dist/server/allowedHosts.js +179 -0
  411. package/dist/server/bootstrap.d.ts +42 -2
  412. package/dist/server/bootstrap.js +273 -5
  413. package/dist/server/controlToken.d.ts +47 -0
  414. package/dist/server/controlToken.js +254 -0
  415. package/dist/server/createHttpHost.d.ts +11 -2
  416. package/dist/server/createHttpHost.js +106 -10
  417. package/dist/server/ensureGlobalService.d.ts +5 -1
  418. package/dist/server/ensureGlobalService.js +35 -1
  419. package/dist/server/healthSurfaces.d.ts +6 -0
  420. package/dist/server/healthSurfaces.js +123 -0
  421. package/dist/server/http.d.ts +27 -1
  422. package/dist/server/http.js +2254 -477
  423. package/dist/server/listenHost.d.ts +5 -0
  424. package/dist/server/listenHost.js +56 -0
  425. package/dist/server/mcpHost.d.ts +10 -1
  426. package/dist/server/mcpHost.js +36 -6
  427. package/dist/server/operatorResults.d.ts +2 -2
  428. package/dist/server/operatorResults.js +40 -29
  429. package/dist/server/requestAuthContext.d.ts +12 -0
  430. package/dist/server/requestAuthContext.js +21 -0
  431. package/dist/server/shutdown.d.ts +69 -0
  432. package/dist/server/shutdown.js +219 -0
  433. package/dist/server/triggerRoutes.d.ts +15 -0
  434. package/dist/server/triggerRoutes.js +268 -0
  435. package/dist/tools/askOperator.d.ts +3 -2
  436. package/dist/types/completion.d.ts +3 -0
  437. package/dist/types/pipeline.d.ts +10 -1
  438. package/dist/types/preEmitCheck.d.ts +7 -0
  439. package/dist/types/stage.d.ts +22 -0
  440. package/dist/types/stageflowManifest.d.ts +3 -0
  441. package/dist/types/task.d.ts +8 -0
  442. package/dist/types/trigger.d.ts +18 -0
  443. package/dist/types/trigger.js +1 -0
  444. package/dist/ui/assets/{index-CSsDued1.css → index-Bv4p1aPK.css} +1 -1
  445. package/dist/ui/assets/index-CntB4bZR.js +133 -0
  446. package/dist/ui/index.html +2 -2
  447. package/dist/workshop/autosave.d.ts +58 -0
  448. package/dist/workshop/autosave.js +222 -0
  449. package/dist/workshop/buildStore.d.ts +79 -0
  450. package/dist/workshop/buildStore.js +326 -0
  451. package/dist/workshop/chatTurn.d.ts +232 -0
  452. package/dist/workshop/chatTurn.js +475 -0
  453. package/dist/workshop/modelSettings.d.ts +18 -0
  454. package/dist/workshop/modelSettings.js +44 -0
  455. package/dist/workshop/sessionStore.d.ts +61 -0
  456. package/dist/workshop/sessionStore.js +254 -0
  457. package/dist/workshop/workshopPin.d.ts +72 -0
  458. package/dist/workshop/workshopPin.js +193 -0
  459. package/examples/README.md +99 -0
  460. package/examples/archify-on-pr/README.md +213 -0
  461. package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +19 -0
  462. package/examples/archify-on-pr/archify-on-pr.task.yaml +19 -0
  463. package/examples/archify-on-pr/author-diagrams.yaml +106 -0
  464. package/examples/archify-on-pr/detect-changes.yaml +89 -0
  465. package/examples/browser-session/README.md +77 -0
  466. package/examples/browser-session/browser-session.pipeline.yaml +50 -0
  467. package/examples/browser-session/browser-session.task.yaml +6 -0
  468. package/examples/browser-session/check-login.yaml +22 -0
  469. package/examples/browser-session/fixture-server.mjs +64 -0
  470. package/examples/browser-session/human-login.yaml +31 -0
  471. package/examples/browser-session/merge.yaml +36 -0
  472. package/examples/browser-session/work-a.yaml +41 -0
  473. package/examples/browser-session/work-b.yaml +41 -0
  474. package/examples/ci-validate/README.md +35 -0
  475. package/examples/ci-validate/check.yaml +13 -0
  476. package/examples/ci-validate/ci-demo.pipeline.yaml +4 -0
  477. package/examples/ci-validate/validate.sh +5 -0
  478. package/examples/compliance-review-demo/README.md +125 -0
  479. package/examples/compliance-review-demo/compliance-review-demo.pipeline.yaml +29 -0
  480. package/examples/compliance-review-demo/connect-account.yaml +47 -0
  481. package/examples/compliance-review-demo/map-to-control.yaml +123 -0
  482. package/examples/compliance-review-demo/poll-bucket-config.yaml +103 -0
  483. package/examples/compliance-review-demo/publish-report.yaml +79 -0
  484. package/examples/compliance-review-demo/review-verdict.yaml +122 -0
  485. package/examples/compliance-review-demo/run-compliance-check.yaml +96 -0
  486. package/examples/compliance-review-demo/store-evidence.yaml +143 -0
  487. package/examples/conditional-fork/README.md +89 -0
  488. package/examples/conditional-fork/branch-a.yaml +13 -0
  489. package/examples/conditional-fork/branch-b.yaml +13 -0
  490. package/examples/conditional-fork/decide.yaml +35 -0
  491. package/examples/conditional-fork/fork-demo.pipeline.yaml +20 -0
  492. package/examples/conditional-fork/fork-demo.task.yaml +8 -0
  493. package/examples/context7-mcp/README.md +42 -0
  494. package/examples/context7-mcp/context7-mcp.pipeline.yaml +15 -0
  495. package/examples/context7-mcp/context7-mcp.task.yaml +4 -0
  496. package/examples/context7-mcp/fetch-docs.yaml +52 -0
  497. package/examples/context7-mcp/resolve-library.yaml +31 -0
  498. package/examples/context7-mcp/write-brief.yaml +52 -0
  499. package/examples/feature-loop/README.md +104 -0
  500. package/examples/feature-loop/address-feedback.yaml +148 -0
  501. package/examples/feature-loop/align.yaml +116 -0
  502. package/examples/feature-loop/decompose.yaml +86 -0
  503. package/examples/feature-loop/default-model-hierarchy.task.yaml +58 -0
  504. package/examples/feature-loop/feature-loop.pipeline.yaml +140 -0
  505. package/examples/feature-loop/feature-loop.task.yaml +25 -0
  506. package/examples/feature-loop/implement.yaml +128 -0
  507. package/examples/feature-loop/plan.yaml +111 -0
  508. package/examples/feature-loop/publish.yaml +167 -0
  509. package/examples/feature-loop/review.yaml +146 -0
  510. package/examples/feature-loop/verify.yaml +106 -0
  511. package/examples/feedback-loop/README.md +72 -0
  512. package/examples/feedback-loop/VERIFY.md +208 -0
  513. package/examples/feedback-loop/continue-only.task.yaml +4 -0
  514. package/examples/feedback-loop/exhaust-require-continue.task.yaml +6 -0
  515. package/examples/feedback-loop/exhaust-wait-human.task.yaml +11 -0
  516. package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +23 -0
  517. package/examples/feedback-loop/feedback-loop.pipeline.yaml +23 -0
  518. package/examples/feedback-loop/feedback-loop.task.yaml +4 -0
  519. package/examples/feedback-loop/implement.yaml +14 -0
  520. package/examples/feedback-loop/plan.yaml +14 -0
  521. package/examples/feedback-loop/review.yaml +15 -0
  522. package/examples/feedback-loop/send-back-once.task.yaml +6 -0
  523. package/examples/feedback-loop/submit.yaml +12 -0
  524. package/examples/generic-fan-in/README.md +151 -0
  525. package/examples/generic-fan-in/clarify.yaml +18 -0
  526. package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +19 -0
  527. package/examples/generic-fan-in/generic-fan-in-accepted.task.yaml +8 -0
  528. package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +18 -0
  529. package/examples/generic-fan-in/generic-fan-in.task.yaml +9 -0
  530. package/examples/generic-fan-in/research.yaml +45 -0
  531. package/examples/generic-fan-in/synthesize.yaml +66 -0
  532. package/examples/generic-fan-in/validation.yaml +45 -0
  533. package/examples/github-release/README.md +78 -0
  534. package/examples/github-release/draft-release-notes.yaml +64 -0
  535. package/examples/github-release/github-release.pipeline.yaml +11 -0
  536. package/examples/github-release/github-release.task.yaml +13 -0
  537. package/examples/github-release/publish-github-release.yaml +64 -0
  538. package/examples/hello-world/README.md +28 -0
  539. package/examples/hello-world/hello.pipeline.yaml +4 -0
  540. package/examples/hello-world/my-task.task.yaml +6 -0
  541. package/examples/hello-world/research.yaml +18 -0
  542. package/examples/mcp-hitl-tour/README.md +113 -0
  543. package/examples/mcp-hitl-tour/draft-angle.yaml +33 -0
  544. package/examples/mcp-hitl-tour/draft-short.yaml +32 -0
  545. package/examples/mcp-hitl-tour/emit-angles.yaml +45 -0
  546. package/examples/mcp-hitl-tour/gather.yaml +31 -0
  547. package/examples/mcp-hitl-tour/intake.yaml +62 -0
  548. package/examples/mcp-hitl-tour/mcp-hitl-tour-exhaust.task.yaml +13 -0
  549. package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +54 -0
  550. package/examples/mcp-hitl-tour/mcp-hitl-tour.task.yaml +16 -0
  551. package/examples/mcp-hitl-tour/polish.yaml +33 -0
  552. package/examples/mcp-hitl-tour/review.yaml +17 -0
  553. package/examples/mcp-hitl-tour/ship.yaml +25 -0
  554. package/examples/oss-issue-contribution/README.md +218 -0
  555. package/examples/oss-issue-contribution/oss-address-review-feedback.yaml +117 -0
  556. package/examples/oss-issue-contribution/oss-approve-contribution.yaml +181 -0
  557. package/examples/oss-issue-contribution/oss-approve-plan.yaml +111 -0
  558. package/examples/oss-issue-contribution/oss-explain-fix.yaml +108 -0
  559. package/examples/oss-issue-contribution/oss-explain-issue.yaml +114 -0
  560. package/examples/oss-issue-contribution/oss-implement-source-fix.yaml +171 -0
  561. package/examples/oss-issue-contribution/oss-investigate-area.yaml +116 -0
  562. package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +125 -0
  563. package/examples/oss-issue-contribution/oss-issue-intake.yaml +106 -0
  564. package/examples/oss-issue-contribution/oss-plan-investigation.yaml +112 -0
  565. package/examples/oss-issue-contribution/oss-plan-review.yaml +109 -0
  566. package/examples/oss-issue-contribution/oss-reproduce-issue.yaml +140 -0
  567. package/examples/oss-issue-contribution/oss-review-change.yaml +107 -0
  568. package/examples/oss-issue-contribution/oss-verify-fix.yaml +130 -0
  569. package/examples/oss-issue-contribution/oss-write-regression-test.yaml +135 -0
  570. package/examples/oss-issue-contribution/pi-7629.task.yaml +79 -0
  571. package/examples/oss-issue-contribution/pi-8919.task.yaml +75 -0
  572. package/examples/oss-issue-contribution/pydantic-ai-7971.task.yaml +53 -0
  573. package/examples/oss-quick-fix/README.md +65 -0
  574. package/examples/oss-quick-fix/implement-fix.yaml +84 -0
  575. package/examples/oss-quick-fix/oss-quick-fix.pipeline.yaml +35 -0
  576. package/examples/oss-quick-fix/oss-quick-fix.task.yaml +19 -0
  577. package/examples/oss-quick-fix/ship-fix.yaml +81 -0
  578. package/examples/oss-quick-fix/understand-issue.yaml +67 -0
  579. package/examples/oss-quick-fix/verify-fix.yaml +73 -0
  580. package/examples/plan-review/README.md +37 -0
  581. package/examples/plan-review/plan-review-followup.yaml +13 -0
  582. package/examples/plan-review/plan-review.pipeline.yaml +9 -0
  583. package/examples/plan-review/plan-review.task.yaml +9 -0
  584. package/examples/plan-review/plan-review.yaml +25 -0
  585. package/examples/playwright-mcp/README.md +39 -0
  586. package/examples/playwright-mcp/playwright-mcp.pipeline.yaml +5 -0
  587. package/examples/playwright-mcp/playwright-mcp.task.yaml +4 -0
  588. package/examples/playwright-mcp/screenshot.yaml +40 -0
  589. package/examples/retry-tour/README.md +75 -0
  590. package/examples/retry-tour/retry-tour.pipeline.yaml +122 -0
  591. package/examples/retry-tour/retry-tour.task.yaml +9 -0
  592. package/examples/route-if-tour/README.md +202 -0
  593. package/examples/route-if-tour/route-if-tour.pipeline.yaml +950 -0
  594. package/examples/route-if-tour/route-if-tour.task.yaml +4 -0
  595. package/examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml +168 -0
  596. package/examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml +44 -0
  597. package/examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml +28 -0
  598. package/examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml +27 -0
  599. package/examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml +110 -0
  600. package/examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml +82 -0
  601. package/examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml +82 -0
  602. package/examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml +77 -0
  603. package/examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml +102 -0
  604. package/examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml +23 -0
  605. package/examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml +37 -0
  606. package/examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml +138 -0
  607. package/examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml +84 -0
  608. package/examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml +50 -0
  609. package/examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml +37 -0
  610. package/examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml +65 -0
  611. package/examples/route-wiring-smoke-test/17-if-join.pipeline.yaml +80 -0
  612. package/examples/route-wiring-smoke-test/README.md +377 -0
  613. package/examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml +26 -0
  614. package/examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml +25 -0
  615. package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml +30 -0
  616. package/examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml +24 -0
  617. package/examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml +35 -0
  618. package/examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml +37 -0
  619. package/examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml +27 -0
  620. package/examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml +42 -0
  621. package/examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml +26 -0
  622. package/examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml +55 -0
  623. package/examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml +51 -0
  624. package/examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml +35 -0
  625. package/examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml +15 -0
  626. package/examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml +15 -0
  627. package/examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml +33 -0
  628. package/examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml +51 -0
  629. package/examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml +55 -0
  630. package/examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml +36 -0
  631. package/examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml +42 -0
  632. package/examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml +33 -0
  633. package/examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml +32 -0
  634. package/examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml +31 -0
  635. package/examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml +33 -0
  636. package/examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml +36 -0
  637. package/examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml +63 -0
  638. package/examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml +46 -0
  639. package/examples/route-wiring-smoke-test/smoke-test.task.yaml +4 -0
  640. package/examples/route-wiring-smoke-test/stages/branch-a.yaml +12 -0
  641. package/examples/route-wiring-smoke-test/stages/branch-b.yaml +12 -0
  642. package/examples/route-wiring-smoke-test/stages/decide.yaml +12 -0
  643. package/examples/route-wiring-smoke-test/stages/finish.yaml +12 -0
  644. package/examples/ship-feature/README.md +190 -0
  645. package/examples/ship-feature/feat-address-feedback.yaml +119 -0
  646. package/examples/ship-feature/feat-implement.yaml +180 -0
  647. package/examples/ship-feature/feat-plan.yaml +120 -0
  648. package/examples/ship-feature/feat-review.yaml +109 -0
  649. package/examples/ship-feature/feat-ship.yaml +203 -0
  650. package/examples/ship-feature/ship-feature.pipeline.yaml +44 -0
  651. package/examples/ship-feature/ship-feature.task.yaml +78 -0
  652. package/examples/stage-mcp/README.md +145 -0
  653. package/examples/stage-mcp/echo-mcp.mjs +20 -0
  654. package/examples/stage-mcp/stage-mcp-dead.pipeline.yaml +5 -0
  655. package/examples/stage-mcp/stage-mcp-dead.task.yaml +3 -0
  656. package/examples/stage-mcp/stage-mcp-missing-var.pipeline.yaml +5 -0
  657. package/examples/stage-mcp/stage-mcp-missing-var.task.yaml +3 -0
  658. package/examples/stage-mcp/stage-mcp.pipeline.yaml +5 -0
  659. package/examples/stage-mcp/stage-mcp.task.yaml +4 -0
  660. package/examples/stage-mcp/use-echo.yaml +20 -0
  661. package/examples/stageflow.yaml +51 -0
  662. package/examples/verify-tour/README.md +80 -0
  663. package/examples/verify-tour/verify-tour.pipeline.yaml +162 -0
  664. package/examples/verify-tour/verify-tour.task.yaml +11 -0
  665. package/package.json +9 -1
  666. package/skills/stageflow/SKILL.md +6 -6
  667. package/skills/stageflow/references/control-surface.md +13 -5
  668. package/skills/stageflow/scripts/detect-host.mjs +14 -1
  669. package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
  670. package/skills/stageflow-author/SKILL.md +4 -3
  671. package/skills/stageflow-author/references/catalog-mapping.md +16 -0
  672. package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
  673. package/skills/stageflow-author/references/stage-prompt-template.md +4 -4
  674. package/skills/stageflow-run/SKILL.md +22 -12
  675. package/skills/stageflow-run/references/mcp-call.md +9 -1
  676. package/skills/stageflow-run/references/task-and-pipeline-selection.md +19 -6
  677. package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
  678. package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
  679. package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
  680. package/skills/stageflow-setup/SKILL.md +51 -8
  681. package/dist/ui/assets/index-Da5EHU6M.js +0 -119
@@ -17,6 +17,10 @@ Talking jobs cite [`../stageflow/references/control-surface.md`](../stageflow/re
17
17
 
18
18
  MCP tool shapes: [`docs/mcp.md`](../../docs/mcp.md). CLI flags and exit codes: [`docs/cli-reference.md`](../../docs/cli-reference.md). Direct tool calls: [`references/mcp-call.md`](references/mcp-call.md). Selection: [`references/task-and-pipeline-selection.md`](references/task-and-pipeline-selection.md). Gate presentation: [`references/native-question-ui.md`](references/native-question-ui.md).
19
19
 
20
+ Runs live under **`$STAGEFLOW_HOME`** (default `~/.stageflow/`), not the project tree. Project `.stageflow/settings.json` is settings only.
21
+
22
+ `STAGEFLOW_OPERATOR_CWD` (skills resolution) is **not** catalog `project_root` / registration — see [MCP — Skills cwd vs catalog project_root](../../docs/mcp.md#skills-cwd-vs-catalog-project_root).
23
+
20
24
  ## Preconditions
21
25
 
22
26
  Run `sf --version`. **Done when** it prints a version. If `sf` is missing, stop and name `stageflow-setup`.
@@ -30,9 +34,11 @@ node ../stageflow/scripts/detect-host.mjs --base-url http://127.0.0.1:3847
30
34
 
31
35
  | stdout | path |
32
36
  |---|---|
33
- | `up <baseUrl>` | [MCP path](#mcp-path) |
37
+ | `up <baseUrl>` … | [MCP path](#mcp-path) |
34
38
  | `down <baseUrl>` | [CLI path](#cli-path) |
35
39
 
40
+ Optional trailing `bearer` means `STAGEFLOW_CONTROL_TOKEN` (or `_FILE`) is set in this environment — send it on MCP via [`mcp-call.md`](references/mcp-call.md) (Compose / non-loopback Hosts require a token). `/api/health` stays unauthenticated; the probe does not break loopback.
41
+
36
42
  **Done when** you have `up` or `down` and the base URL.
37
43
 
38
44
  ## Select
@@ -47,21 +53,23 @@ If this chat already has a `runId` and the request is check, answer, or continue
47
53
 
48
54
  Prefer this harness's native Stageflow MCP tools when their names are already in the tool list. When they are not, call [`scripts/mcp-call.mjs`](scripts/mcp-call.mjs) — see [`references/mcp-call.md`](references/mcp-call.md). Use `--stateless` only when the **user** started the host with `--mcp-stateless`. Do not start `sf mcp` from this skill.
49
55
 
50
- Call only these Stageflow MCP tools: `list_pipelines`, `list_tasks`, `start_run`, `get_run`, `wait_run`, `list_waiting`, `list_runs`, `answer_gate`, `decide_feedback_loop`, `read_artifact`, `describe_pipeline`, `validate`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`, `get_health`. Host question tools already in this harness's tool list (`AskQuestion`, `AskUserQuestion`, `ask_user`) are for [Gate](#gate) presentation, not Stageflow MCP.
56
+ Call only these Stageflow MCP tools: `list_pipelines`, `list_tasks`, `start_run`, `run_stage`, `get_run`, `wait_run`, `list_waiting`, `list_runs`, `answer_gate`, `decide_feedback_loop`, `get_envelope`, `read_artifact`, `list_checkout_changes`, `get_run_diff`, `read_checkout_file`, `describe_pipeline`, `validate`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`, `get_health`. Host question tools already in this harness's tool list (`AskQuestion`, `AskUserQuestion`, `ask_user`) are for [Gate](#gate) presentation, not Stageflow MCP.
51
57
 
52
58
  ## MCP path
53
59
 
54
60
  ### Start
55
61
 
56
- `start_run` with `pipeline` plus exactly one of `task_path` or inline `task`.
62
+ `start_run` with `pipeline` plus exactly one of `task_path` or inline `task`. Binding: task `repository`+`ref` XOR `checkout` (see selection). Repository-bound runs get a Host worktree under `$STAGEFLOW_HOME/worktrees/<runId>/`.
57
63
 
58
64
  | result | next |
59
65
  |---|---|
60
66
  | `{ "runId" }` | [Wait](#wait) |
61
- | `busy_capacity` / `busy_checkout` | [Report](#report) the included fields. Stop. Do not retry. |
67
+ | `{ "runId", "queued": true }` (optional `queuePosition`) | Same as `{ "runId" }` — queued is still success, just slower. [Wait](#wait) |
68
+ | `busy_capacity` / `busy_checkout` | [Report](#report) the included fields. Stop. Do not retry. `busy_capacity` means the **admission queue is full** (active-slot exhaustion queues instead). `busy_checkout` is a **path-bound checkout lease** only (never queued); repository-bound runs may parallelize on the same repo. |
69
+ | `insufficient_disk` | [Report](#report) `freeBytes` / `minFreeBytes`. Stop. Do not retry. Distinct from busy — the run was not queued. |
62
70
  | other `isError` | [Report](#report) the payload. Stop. |
63
71
 
64
- **Done when** you have a `runId`, or a busy/error report is printed.
72
+ **Done when** you have a `runId`, or a busy/disk/error report is printed.
65
73
 
66
74
  ### Wait
67
75
 
@@ -120,7 +128,7 @@ Discovery without a host: read `stageflow.yaml` catalog roots as in [`references
120
128
  sf run --task <path> --pipeline <path> --json
121
129
  ```
122
130
 
123
- Add `--checkout`, `--git-sha`, `--ci-pr-url`, `--ci-job-url`, `--operator-cwd`, or `--operator-agent-dir` only when the human supplied them. Always pass `--json`. Omit `--include stages` unless the human asked for a stage projection — and then only together with `--json`.
131
+ Add `--checkout`, `--repository` / `--ref`, `--git-sha`, `--ci-pr-url`, or `--ci-job-url` only when the human supplied them (binding: `repository`+`ref` XOR `checkout`). Do **not** pass `--operator-cwd` / `--operator-agent-dir` — they are no-ops on `sf run`; set `STAGEFLOW_OPERATOR_CWD` / `STAGEFLOW_OPERATOR_AGENT_DIR` before the Host first starts. Always pass `--json`. Omit `--include stages` unless the human asked for a stage projection — and then only together with `--json`.
124
132
 
125
133
  Parse the single JSON document.
126
134
 
@@ -128,7 +136,9 @@ Parse the single JSON document.
128
136
  |---|---|
129
137
  | `0` | `succeeded` | [Report](#report) |
130
138
  | `1` | `failed` | [Report](#report) `reason` verbatim |
139
+ | `1` | `cancelled` | [Report](#report) `reason` verbatim |
131
140
  | `1` | `busy` | [Report](#report) `busy_capacity` / `busy_checkout` and the included fields. Stop. |
141
+ | `1` | `failed` with `code: "insufficient_disk"` | [Report](#report) `freeBytes` / `minFreeBytes`. Stop. |
132
142
  | `2` | `waiting` | [CLI wait](#cli-wait) with this `runId` / `runDir` |
133
143
 
134
144
  **Done when** the outcome is reported, or a waiting exit has handed `runId` to CLI wait.
@@ -138,7 +148,7 @@ Parse the single JSON document.
138
148
  Host down after `sf run` exit `2`, or when this chat already has a `runId` and the host is down. Do not start `sf mcp`. HITL presentation follows [`references/native-question-ui.md`](references/native-question-ui.md). Submit HITL with `sf runs answer --json`. If `waiting_kind` is `feedback_loop_decision`, present extend / continue / abandon and submit with `sf runs feedback-decide --json` — not `sf runs answer`.
139
149
 
140
150
  1. Probe again with [`../stageflow/scripts/detect-host.mjs`](../stageflow/scripts/detect-host.mjs) (the host may have appeared). Probe before each `sf runs answer` or `sf runs feedback-decide`.
141
- 2. **Up:** use that host — native tools if present, otherwise `mcp-call.mjs` (omit `--stateless` unless the user started the host with `--mcp-stateless`). Continue at [Gate](#gate).
151
+ 2. **Up:** use that host — native tools if present, otherwise `mcp-call.mjs` (omit `--stateless` unless the user started the host with `--mcp-stateless`; send bearer when the probe notes `bearer` or `STAGEFLOW_CONTROL_TOKEN` is set). Continue at [Gate](#gate).
142
152
  3. **Down:**
143
153
 
144
154
  ```
@@ -177,7 +187,7 @@ Wait abort (exit `130`, `{ "error", "code": "aborted" }`) → [Report](#report):
177
187
 
178
188
  4. If `sf runs answer` or `sf runs feedback-decide` refuses because the host came up, continue that gate via MCP [Gate](#gate). Do not dual-write.
179
189
 
180
- If this chat ends before terminal, say the run stays in `.stageflow/` and to continue by re-invoking this skill (or starting a host and using MCP).
190
+ If this chat ends before terminal, say the run stays under `$STAGEFLOW_HOME` (default `~/.stageflow/`) and to continue by re-invoking this skill (or starting a host and using MCP).
181
191
 
182
192
  **Done when** the run is terminal, aborted, or a hard error is printed.
183
193
 
@@ -187,14 +197,14 @@ Print one shape on every path:
187
197
 
188
198
  1. Current or last-known stage (MCP live snapshot, or "start/finish only" on a CLI-only stretch).
189
199
  2. Waiting prompt text verbatim when the run is parked.
190
- 3. Outcome: `succeeded`, `failed`, `waiting`, or `busy`.
200
+ 3. Outcome: `succeeded`, `failed`, `cancelled`, `waiting`, `busy`, or `insufficient_disk`.
191
201
  4. Run id.
192
- 5. Run folder (`runDir` / `.stageflow/`).
202
+ 5. Run location under `$STAGEFLOW_HOME` (`runDir` / `runs/<runId>/`; default home `~/.stageflow/`). For repository-bound succeeded runs, the Host worktree under `worktrees/<runId>/` may already be reclaimed (`checkout_reclaimed` if the path is gone; `run_branch` is kept).
193
203
 
194
- MCP `get_run` / `wait_run` and `sf runs wait` / `sf runs show` `--json` carry live stage state. `sf run --json` reports start and finish only — say that in chat when the CLI path ran without a later wait/show. A succeeded report names id and folder and does not keep waiting language. A failure names `reason` in this same shape.
204
+ MCP `get_run` / `wait_run` and `sf runs wait` / `sf runs show` `--json` carry live stage state. `sf run --json` reports start and finish only — say that in chat when the CLI path ran without a later wait/show. A succeeded report names id and durable location and does not keep waiting language. A failure names `reason` in this same shape. Stop-and-report codes from Start include `busy_capacity`, `busy_checkout`, and `insufficient_disk`.
195
205
 
196
206
  **Done when** that five-part report is printed.
197
207
 
198
208
  ## Non-goals
199
209
 
200
- This job starts, watches, and answers runs. It does not require `sf ui`. The operator console is not the answer path. It does not register or invent an MCP tool. It does not start `sf mcp`. It does not retry, resume, abandon, recover, or rerun stages.
210
+ This job starts, watches, and answers runs. It does not require `sf ui`. The operator console is not the answer path. It does not register or invent an MCP tool. It does not start `sf mcp`. It does not retry, resume, abandon, recover, cancel, delete, gc, or rerun stages or runs.
@@ -8,10 +8,18 @@ node scripts/mcp-call.mjs --base-url <url> --tool <name> --args '<json>' [--stat
8
8
 
9
9
  Default `--base-url` is `http://127.0.0.1:3847`. `--args` defaults to `{}`.
10
10
 
11
+ ## Auth
12
+
13
+ When `STAGEFLOW_CONTROL_TOKEN` or `STAGEFLOW_CONTROL_TOKEN_FILE` is set, the script sends `Authorization: Bearer <token>` on every `/mcp` request (initialize, tools/call, session DELETE). Docker Compose and any non-loopback Host require a drive token — set the same env in the harness before calling. Loopback with no token stays unauthenticated. `/api/health` (detect-host) does not need a bearer.
14
+
15
+ ## Session
16
+
11
17
  `--stateless` sends one `tools/call` and no session header. Use it for hosts the **user** started with `sf mcp --mcp-stateless`, not a skill-started process.
12
18
 
13
19
  Without `--stateless`: `initialize`, capture `Mcp-Session-Id`, reuse it for `tools/call`.
14
20
 
15
21
  Stdout is the tool JSON. Exit `0` on success, including `wait_run` with `reason: "timeout"` (keep polling). Exit `1` on transport failure or `isError: true`. Exit `2` on usage or malformed `--args` — that parse error happens before any network call.
16
22
 
17
- Allowed `--tool` names (see [`docs/mcp.md`](../../../docs/mcp.md)): `list_pipelines`, `list_tasks`, `start_run`, `get_run`, `wait_run`, `list_waiting`, `list_runs`, `answer_gate`, `decide_feedback_loop`, `read_artifact`, `describe_pipeline`, `validate`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`, `get_health`.
23
+ Allowed `--tool` names (see [`docs/mcp.md`](../../../docs/mcp.md)): `list_pipelines`, `list_tasks`, `start_run`, `run_stage`, `get_run`, `wait_run`, `list_waiting`, `list_runs`, `answer_gate`, `decide_feedback_loop`, `get_envelope`, `read_artifact`, `list_checkout_changes`, `get_run_diff`, `read_checkout_file`, `describe_pipeline`, `validate`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`, `get_health`.
24
+
25
+ `start_run` may return `{ "runId", "queued": true }` — treat that like `{ "runId" }` (success, slower start). `busy_capacity` means the admission queue is full; `busy_checkout` is path-bound lease only; `insufficient_disk` is a hard stop (not queued). Do not call `cancel_run`, `delete_run`, or `gc_runs` from this skill.
@@ -12,7 +12,9 @@ Print a short pick list (id + path). Ask which.
12
12
 
13
13
  ## MCP catalog
14
14
 
15
- `list_pipelines` and `list_tasks` (native tools, or [`mcp-call.md`](mcp-call.md)). Listing objects carry `path` and `id`.
15
+ `list_pipelines` and `list_tasks` (native tools, or [`mcp-call.md`](mcp-call.md)). Listing objects carry `path` and `id`. The Host must already know the catalog root (seeded or registered via ensure / `POST /api/projects`) and that root needs a readable `stageflow.yaml`. Git is optional for listing — register + manifest is enough.
16
+
17
+ **Paths:** MCP requires catalog-relative paths under `project_root`. Absolute pipeline/task/checkout paths return `absolute_path_not_allowed` (with `registered_roots`). Local CLI may pass absolute paths and auto-register.
16
18
 
17
19
  ## CLI catalog
18
20
 
@@ -20,6 +22,17 @@ There is no CLI list command. Read `stageflow.yaml` at the project root (git top
20
22
 
21
23
  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
24
 
25
+ ## Repository binding
26
+
27
+ Task binding is **`repository` + `ref` XOR `checkout`** (code `task.binding_conflict` if both). Do not set both.
28
+
29
+ | Binding | Meaning |
30
+ |---|---|
31
+ | `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. |
32
+ | `checkout` | Path-bound working tree. `busy_checkout` is this path lease only — conflicting path-bound starts fail and never queue. |
33
+
34
+ CLI parity with MCP inline: `sf run --repository owner/repo --ref <ref>` (or `--checkout <path>`), and the same fields on throwaway scratch YAML.
35
+
23
36
  ## Task input
24
37
 
25
38
  ### MCP
@@ -27,14 +40,14 @@ Walk each `catalog.pipelines` / `catalog.tasks` root. Match `catalog.patterns.pi
27
40
  An existing `task_path` from `list_tasks`, or an inline `task` object built from the stated goal:
28
41
 
29
42
  ```json
30
- { "id": "<slug>", "goal": "<goal>", "context": "optional", "constraints": "optional", "checkout": "optional" }
43
+ { "id": "<slug>", "goal": "<goal>", "context": "optional", "constraints": "optional", "checkout": "optional", "repository": "optional", "ref": "optional" }
31
44
  ```
32
45
 
33
- `start_run` accepts that object. Do not write a scratch file on the MCP path.
46
+ 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
47
 
35
48
  ### CLI
36
49
 
37
- `sf run` accepts `--task <path>` only. Reuse a catalog `*.task.yaml`, or write a throwaway file at the project root:
50
+ `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
51
 
39
52
  ```
40
53
  .scratch/stageflow-run/<id>.task.yaml
@@ -45,8 +58,8 @@ id: <slug>
45
58
  goal: <human goal>
46
59
  ```
47
60
 
48
- Add `context`, `constraints`, or `checkout` only when the human gave them. Pass that path as `--task`.
61
+ 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
62
 
50
63
  ## Optional run flags
51
64
 
52
- `--checkout`, `--git-sha`, `--ci-pr-url`, `--ci-job-url` only when the human supplied them.
65
+ `--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,40 @@ 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.
143
+
144
+ ## MCP checklist (optional standing Host)
145
+
146
+ Do **not** auto-start `sf ui` / `sf mcp` from this job unless the operator already chose Compose or asked to start a Host. When a Host is up:
147
+
148
+ 1. Host up — probe [`../stageflow/scripts/detect-host.mjs`](../stageflow/scripts/detect-host.mjs) or `curl -fsS http://127.0.0.1:3847/livez`
149
+ 2. Register/ensure the catalog folder (`POST /api/projects` on trusted loopback, or a prior local `sf run`) — or use seeded `project_root: "examples"`
150
+ 3. Use **catalog-relative** paths only on MCP (absolute → `absolute_path_not_allowed`); CLI may pass abs and auto-register
151
+ 4. `list_pipelines` → `start_run` → `wait_run` (see Stageflow docs: MCP; Quickstart — MCP smoke path)
152
+
153
+ `STAGEFLOW_OPERATOR_CWD` (skills) ≠ catalog `project_root` — see Stageflow docs: MCP — Skills cwd vs catalog project_root.