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
package/dist/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from "node:child_process";
3
+ import { A2A_USAGE, runA2aCommand } from "./cli/a2aCommand.js";
3
4
  import { realpathSync } from "node:fs";
4
5
  import path from "node:path";
5
6
  import { fileURLToPath } from "node:url";
@@ -7,32 +8,49 @@ import { globalAgentBackendFromManifest, resolveAgentPort } from "./agent/resolv
7
8
  import { ARTIFACT_USAGE, runArtifactCommand } from "./cli/artifactCommand.js";
8
9
  import { ENVELOPE_USAGE, runEnvelopeCommand, } from "./cli/envelopeCommand.js";
9
10
  import { EXPORT_RUN_USAGE, runExportRunCommand, } from "./cli/exportRunCommand.js";
11
+ import { DEBUG_RUN_USAGE, runDebugRunCommand, } from "./cli/debugRunCommand.js";
12
+ import { BACKUP_USAGE, runBackupCommand, } from "./cli/backupCommand.js";
13
+ import { RESTORE_USAGE, runRestoreCommand, } from "./cli/restoreCommand.js";
14
+ import { EXPORT_ALL_USAGE, runExportAllCommand, } from "./cli/exportAllCommand.js";
10
15
  import { INIT_USAGE, runInitCommand } from "./cli/initCommand.js";
11
16
  import { PROVIDERS_USAGE, runProvidersCommand } from "./cli/providersCommand.js";
12
17
  import { RUN_USAGE, runRunCommand } from "./cli/runCommand.js";
18
+ import { RUN_STAGE_USAGE, runRunStageCommand } from "./cli/runStageCommand.js";
13
19
  import { RUNS_USAGE, runRunsCommand } from "./cli/runsCommand.js";
14
20
  import { resolveOperatorCatalog } from "./cli/operatorCatalog.js";
15
21
  import { SKILLS_USAGE, runSkillsCommand } from "./cli/skillsCommand.js";
16
22
  import { VALIDATE_USAGE, runValidateCommand } from "./cli/validateCommand.js";
17
23
  import { GRAPH_USAGE, runGraphCommand } from "./cli/graphCommand.js";
18
24
  import { MIGRATE_YAML_USAGE, runMigrateYamlCommand } from "./cli/migrateYamlCommand.js";
19
- import { createRunStore } from "./runstore/createStore.js";
25
+ import { DOCTOR_USAGE, runDoctorCommand } from "./cli/doctorCommand.js";
20
26
  import { resolveStageflowContext } from "./project/resolveStageflowContext.js";
21
27
  import { exitForOutcome, runStageWorker } from "./runtime/stageWorker.js";
28
+ import { scheduleExitWithDrain } from "./runtime/stageWorkerProtocol.js";
22
29
  import { SF_STAGE_WORKER } from "./runtime/stageWorkerProtocol.js";
23
30
  import { DEFAULT_PORT, startUiServer } from "./server/http.js";
24
31
  import { startMcpServer } from "./server/mcpHost.js";
32
+ import { resolveListenHost } from "./server/listenHost.js";
33
+ import { assertBindAllowed, BindRefusedError, loadControlTokens, } from "./server/controlToken.js";
25
34
  import { resolveMcpStateless } from "./mcp/server.js";
26
- import { PACKAGE_VERSION } from "./package-meta.js";
35
+ import { PACKAGE_VERSION, BUILD_SHA } from "./package-meta.js";
36
+ import { installProxyDispatcher } from "./net/proxy.js";
37
+ import { warnMissingCaPaths } from "./preflight/tls.js";
38
+ import { logger as cliLogger } from "./logging/logger.js";
27
39
  const USAGE = `Usage:
28
40
  sf init
29
- sf run --task <path> --pipeline <path> [--checkout <path>] [--json] [--include stages] [--skip-gates] [--git-sha <sha>] [--ci-pr-url <url>] [--ci-job-url <url>] [--operator-cwd <path>] [--operator-agent-dir <path>]
41
+ sf run --task <path> --pipeline <path> [--checkout <path>] [--repository <owner/repo>] [--ref <ref>] [--json] [--include stages] [--skip-gates] [--git-sha <sha>] [--ci-pr-url <url>] [--ci-job-url <url>] [--operator-cwd <path>] [--operator-agent-dir <path>]
42
+ sf run-stage (--stage <path> | --stage-inline '<json>') (--task <path> | --task-inline '<json>' | --envelope-ref <runId>:<stageId>[:<attempt>]) [--checkout <path>] [--model <id>] [--blocking] [--timeout-ms <n>] [--json]
30
43
  sf validate [--pipeline <path>] [--task <path>] [--strict] [--json]
44
+ sf doctor [--json] [--pipeline <path>] [--strict]
31
45
  sf graph --pipeline <path> [--json]
32
46
  sf migrate-yaml [path] [--root <path>] [--write] [--json] [--force]
33
47
  sf artifact read --run <runId> --path <relPath> [--out <file>]
34
48
  sf envelope get --run <runId> --stage <stageId> [--json] [--from <sf-run.json>] [--detect-stage <id>] [--format envelope|handoff]
35
49
  sf export-run --run <runId> [--from <sf-run.json>] [--out <file>]
50
+ sf debug-run <runId> [--out <file>]
51
+ sf backup [--out <file>] [--db-only] [--no-credentials] [--include-a2a-artifacts] [--json]
52
+ sf restore <file> [--force] [--json]
53
+ sf export --all [--status <status>] [--since <iso>] [--pipeline <id-or-path>] [--out <file>]
36
54
  sf runs list [--status created|running|succeeded|failed] [--since <iso>] [--pipeline <id-or-path>] [--json]
37
55
  sf runs show --run <runId> [--from <sf-run.json>] [--json]
38
56
  sf runs verify --run <runId> --stage <stageId> [--json]
@@ -43,9 +61,9 @@ const USAGE = `Usage:
43
61
  sf runs retry --run <runId> --stage <stageId> [--json]
44
62
  sf runs resume --run <runId> --stage <stageId> [--json]
45
63
  sf runs abandon --run <runId> --stage <stageId> [--json]
46
- sf runs rerun --run <runId> [--json]
47
- sf ui [--port ${DEFAULT_PORT}] [--mcp-stateless]
48
- sf mcp [--port ${DEFAULT_PORT}] [--mcp-stateless]
64
+ sf runs rerun --run <runId> [--pinned] [--json]
65
+ sf ui [--host <addr>] [--port ${DEFAULT_PORT}] [--no-open] [--mcp-stateless]
66
+ sf mcp [--host <addr>] [--port ${DEFAULT_PORT}] [--mcp-stateless]
49
67
  sf providers list
50
68
  sf providers status [--provider <id>]
51
69
  sf providers detect
@@ -58,6 +76,8 @@ const USAGE = `Usage:
58
76
  sf --version
59
77
  sf -V
60
78
  sf --help
79
+ sf a2a validate|list [--config <path>]
80
+ sf a2a add-caller <id> [--config <path>] [--token-env <NAME>]
61
81
 
62
82
  Stageflow (sf) runs YAML-defined automatic stage pipelines.
63
83
 
@@ -67,10 +87,16 @@ ${INIT_USAGE}
67
87
 
68
88
  ${RUN_USAGE}
69
89
 
90
+ ${RUN_STAGE_USAGE}
91
+
70
92
  ${VALIDATE_USAGE}
71
93
 
94
+ ${DOCTOR_USAGE}
95
+
72
96
  ${GRAPH_USAGE}
73
97
 
98
+ ${A2A_USAGE}
99
+
74
100
  ${MIGRATE_YAML_USAGE}
75
101
 
76
102
  ${ARTIFACT_USAGE}
@@ -79,6 +105,14 @@ ${ENVELOPE_USAGE}
79
105
 
80
106
  ${EXPORT_RUN_USAGE}
81
107
 
108
+ ${DEBUG_RUN_USAGE}
109
+
110
+ ${BACKUP_USAGE}
111
+
112
+ ${RESTORE_USAGE}
113
+
114
+ ${EXPORT_ALL_USAGE}
115
+
82
116
  ${RUNS_USAGE}
83
117
 
84
118
  ${PROVIDERS_USAGE}
@@ -94,21 +128,30 @@ function parseArgs(argv) {
94
128
  return { help: true };
95
129
  }
96
130
  if (args[0] === "--version" || args[0] === "-V") {
97
- if (args.length > 1) {
98
- throw new Error(`Unexpected argument: ${args[1]}`);
131
+ const versionJson = args.includes("--json");
132
+ const rest = args.slice(1).filter((a) => a !== "--json");
133
+ if (rest.length > 0) {
134
+ throw new Error(`Unexpected argument: ${rest[0]}`);
99
135
  }
100
- return { help: false, version: true };
136
+ return { help: false, version: true, versionJson };
101
137
  }
102
138
  const command = args[0];
103
139
  if (command === "providers" ||
104
140
  command === "validate" ||
141
+ command === "doctor" ||
105
142
  command === "graph" ||
143
+ command === "a2a" ||
106
144
  command === "migrate-yaml" ||
107
145
  command === "run" ||
146
+ command === "run-stage" ||
108
147
  command === "init" ||
109
148
  command === "artifact" ||
110
149
  command === "envelope" ||
111
150
  command === "export-run" ||
151
+ command === "debug-run" ||
152
+ command === "backup" ||
153
+ command === "restore" ||
154
+ command === "export" ||
112
155
  command === "runs" ||
113
156
  command === "skills") {
114
157
  return { help: false, command };
@@ -119,7 +162,11 @@ function parseArgs(argv) {
119
162
  let task;
120
163
  let pipeline;
121
164
  let port;
165
+ let host;
166
+ let noOpen = false;
122
167
  let checkout;
168
+ let repository;
169
+ let ref;
123
170
  let mcpStateless = false;
124
171
  for (let i = 1; i < args.length; i++) {
125
172
  if (args[i] === "--task") {
@@ -135,6 +182,20 @@ function parseArgs(argv) {
135
182
  }
136
183
  checkout = raw;
137
184
  }
185
+ else if (args[i] === "--repository") {
186
+ const raw = args[++i];
187
+ if (raw === undefined || raw.length === 0) {
188
+ throw new Error("Missing value for --repository");
189
+ }
190
+ repository = raw;
191
+ }
192
+ else if (args[i] === "--ref") {
193
+ const raw = args[++i];
194
+ if (raw === undefined || raw.length === 0) {
195
+ throw new Error("Missing value for --ref");
196
+ }
197
+ ref = raw;
198
+ }
138
199
  else if (args[i] === "--port") {
139
200
  const raw = args[++i];
140
201
  port = Number(raw);
@@ -142,11 +203,33 @@ function parseArgs(argv) {
142
203
  throw new Error(`Invalid --port: ${raw}`);
143
204
  }
144
205
  }
206
+ else if (args[i] === "--host") {
207
+ const raw = args[++i];
208
+ if (raw === undefined || raw.length === 0) {
209
+ throw new Error("Missing value for --host");
210
+ }
211
+ host = raw;
212
+ }
213
+ else if (args[i] === "--no-open") {
214
+ noOpen = true;
215
+ }
145
216
  else if (args[i] === "--mcp-stateless") {
146
217
  mcpStateless = true;
147
218
  }
148
219
  }
149
- return { help: false, command, task, pipeline, port, checkout, mcpStateless };
220
+ return {
221
+ help: false,
222
+ command,
223
+ task,
224
+ pipeline,
225
+ port,
226
+ host,
227
+ noOpen,
228
+ checkout,
229
+ repository,
230
+ ref,
231
+ mcpStateless,
232
+ };
150
233
  }
151
234
  export function parseRunStageArgs(argv) {
152
235
  let runId;
@@ -243,6 +326,9 @@ async function handleInternalRunStage(argv) {
243
326
  if (process.env[SF_STAGE_WORKER] !== "1") {
244
327
  process.env[SF_STAGE_WORKER] = "1";
245
328
  }
329
+ installProxyDispatcher(process.env, {
330
+ log: (msg) => cliLogger.info("proxy.dispatcher", msg),
331
+ });
246
332
  const parsed = parseRunStageArgs(argv);
247
333
  const outcome = await runStageWorker({
248
334
  runId: parsed.runId,
@@ -256,32 +342,61 @@ async function handleInternalRunStage(argv) {
256
342
  operatorCatalog: parsed.operatorCatalog,
257
343
  skipGates: parsed.skipGates,
258
344
  });
259
- exitForOutcome(outcome);
345
+ return exitForOutcome(outcome);
260
346
  }
261
347
  function openBrowser(url) {
262
348
  const platform = process.platform;
349
+ let child;
263
350
  if (platform === "darwin") {
264
- spawn("open", [url], { detached: true, stdio: "ignore" }).unref();
351
+ child = spawn("open", [url], { detached: true, stdio: "ignore" });
265
352
  }
266
353
  else if (platform === "win32") {
267
- spawn("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore" }).unref();
354
+ child = spawn("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore" });
268
355
  }
269
356
  else {
270
- spawn("xdg-open", [url], { detached: true, stdio: "ignore" }).unref();
357
+ child = spawn("xdg-open", [url], { detached: true, stdio: "ignore" });
271
358
  }
359
+ child.on("error", () => { });
360
+ child.unref();
361
+ }
362
+ function isNoOpenEnabled(flag, env = process.env) {
363
+ if (flag)
364
+ return true;
365
+ const raw = env.STAGEFLOW_NO_OPEN;
366
+ if (raw === undefined || raw.trim() === "")
367
+ return false;
368
+ const normalized = raw.trim().toLowerCase();
369
+ return normalized !== "0" && normalized !== "false";
272
370
  }
273
371
  async function main(argv) {
274
372
  try {
373
+ installProxyDispatcher(process.env, {
374
+ log: (msg) => cliLogger.info("proxy.dispatcher", msg),
375
+ });
376
+ for (const warning of warnMissingCaPaths(process.env)) {
377
+ cliLogger.warn("tls.ca_missing", `${warning.name} points to missing path: ${warning.path}`);
378
+ }
275
379
  const parsed = parseArgs(argv);
276
380
  if (parsed.help) {
277
381
  console.log(USAGE);
278
382
  return argv.slice(2).length === 0 ? 1 : 0;
279
383
  }
280
384
  if (parsed.version) {
281
- console.log(PACKAGE_VERSION);
385
+ if (parsed.versionJson) {
386
+ console.log(JSON.stringify({
387
+ version: PACKAGE_VERSION,
388
+ build_sha: BUILD_SHA,
389
+ }));
390
+ }
391
+ else {
392
+ console.log(PACKAGE_VERSION);
393
+ }
282
394
  return 0;
283
395
  }
284
396
  const ctx = await resolveStageflowContext(process.cwd());
397
+ if (parsed.command === "a2a") {
398
+ return runA2aCommand(argv.slice(3), { cwd: ctx.invocationCwd, projectRoot: ctx.projectRoot });
399
+ }
285
400
  if (parsed.command === "init") {
286
401
  return runInitCommand(argv.slice(3), { cwd: ctx.invocationCwd });
287
402
  }
@@ -291,6 +406,9 @@ async function main(argv) {
291
406
  projectRoot: ctx.projectRoot,
292
407
  });
293
408
  }
409
+ if (parsed.command === "doctor") {
410
+ return runDoctorCommand(argv.slice(3), { cwd: ctx.invocationCwd });
411
+ }
294
412
  if (parsed.command === "graph") {
295
413
  return runGraphCommand(argv.slice(3), {
296
414
  cwd: ctx.invocationCwd,
@@ -308,6 +426,11 @@ async function main(argv) {
308
426
  cwd: ctx.invocationCwd,
309
427
  });
310
428
  }
429
+ if (parsed.command === "run-stage") {
430
+ return runRunStageCommand(argv.slice(3), {
431
+ cwd: ctx.invocationCwd,
432
+ });
433
+ }
311
434
  if (parsed.command === "artifact") {
312
435
  return runArtifactCommand(argv.slice(3), {
313
436
  cwd: ctx.invocationCwd,
@@ -326,6 +449,25 @@ async function main(argv) {
326
449
  projectRoot: ctx.projectRoot,
327
450
  });
328
451
  }
452
+ if (parsed.command === "debug-run") {
453
+ return runDebugRunCommand(argv.slice(3), {
454
+ cwd: ctx.invocationCwd,
455
+ projectRoot: ctx.projectRoot,
456
+ });
457
+ }
458
+ if (parsed.command === "backup") {
459
+ return runBackupCommand(argv.slice(3), {
460
+ cwd: ctx.invocationCwd,
461
+ });
462
+ }
463
+ if (parsed.command === "restore") {
464
+ return runRestoreCommand(argv.slice(3));
465
+ }
466
+ if (parsed.command === "export") {
467
+ return runExportAllCommand(argv.slice(3), {
468
+ cwd: ctx.invocationCwd,
469
+ });
470
+ }
329
471
  if (parsed.command === "runs") {
330
472
  return runRunsCommand(argv.slice(3), {
331
473
  cwd: ctx.invocationCwd,
@@ -340,41 +482,53 @@ async function main(argv) {
340
482
  projectRoot: ctx.projectRoot,
341
483
  });
342
484
  }
343
- const store = createRunStore({ rootDir: ctx.globalHome });
344
485
  const globalAgent = globalAgentBackendFromManifest(ctx.manifest);
345
486
  if (parsed.command === "ui") {
487
+ const listenHost = resolveListenHost({ flag: parsed.host });
488
+ const tokens = loadControlTokens();
489
+ assertBindAllowed(listenHost, tokens);
346
490
  const mcpStateless = resolveMcpStateless({
347
491
  mcpStateless: parsed.mcpStateless,
348
492
  });
349
- const { url, mcpUrl } = await startUiServer({
493
+ const host = await startUiServer({
350
494
  agent: resolveAgentPort({ global: globalAgent }),
351
- store,
352
495
  cwd: ctx.invocationCwd,
353
496
  rootDir: ctx.projectRoot,
354
497
  port: parsed.port,
498
+ host: listenHost,
355
499
  mcpStateless,
500
+ controlTokens: tokens,
356
501
  });
357
- console.log(`Operator console: ${url}`);
358
- console.log(`MCP endpoint: ${mcpUrl}`);
359
- openBrowser(url);
360
- await new Promise(() => undefined);
361
- return 0;
502
+ console.log(`Operator console: ${host.url}`);
503
+ console.log(`MCP endpoint: ${host.mcpUrl}`);
504
+ if (!isNoOpenEnabled(parsed.noOpen)) {
505
+ openBrowser(host.url);
506
+ }
507
+ const outcome = await host.shutdown.whenDrained();
508
+ return outcome.exitCode;
362
509
  }
363
510
  if (parsed.command === "mcp") {
511
+ if (parsed.noOpen) {
512
+ throw new Error("--no-open is only valid with sf ui");
513
+ }
514
+ const listenHost = resolveListenHost({ flag: parsed.host });
515
+ const tokens = loadControlTokens();
516
+ assertBindAllowed(listenHost, tokens);
364
517
  const mcpStateless = resolveMcpStateless({
365
518
  mcpStateless: parsed.mcpStateless,
366
519
  });
367
- const { mcpUrl } = await startMcpServer({
520
+ const host = await startMcpServer({
368
521
  agent: resolveAgentPort({ global: globalAgent }),
369
- store,
370
522
  cwd: ctx.invocationCwd,
371
523
  rootDir: ctx.projectRoot,
372
524
  port: parsed.port,
525
+ host: listenHost,
373
526
  mcpStateless,
527
+ controlTokens: tokens,
374
528
  });
375
- console.log(`MCP endpoint: ${mcpUrl}`);
376
- await new Promise(() => undefined);
377
- return 0;
529
+ console.log(`MCP endpoint: ${host.mcpUrl}`);
530
+ const outcome = await host.shutdown.whenDrained();
531
+ return outcome.exitCode;
378
532
  }
379
533
  if (parsed.command === "internal") {
380
534
  const subArgs = argv.slice(3);
@@ -390,6 +544,10 @@ async function main(argv) {
390
544
  return 1;
391
545
  }
392
546
  catch (err) {
547
+ if (err instanceof BindRefusedError) {
548
+ console.error(err.message);
549
+ return err.exitCode;
550
+ }
393
551
  console.error(err instanceof Error ? err.message : String(err));
394
552
  return 1;
395
553
  }
@@ -414,9 +572,11 @@ function isDirectCliInvocation() {
414
572
  }
415
573
  if (isDirectCliInvocation()) {
416
574
  main(process.argv)
417
- .then((code) => process.exit(code))
575
+ .then((code) => {
576
+ scheduleExitWithDrain(code);
577
+ })
418
578
  .catch((err) => {
419
579
  console.error(err instanceof Error ? err.message : String(err));
420
- process.exit(1);
580
+ scheduleExitWithDrain(1);
421
581
  });
422
582
  }
@@ -0,0 +1,62 @@
1
+ import type { CatalogRoot, ResolveCatalogRootsOptions } from "./resolveCatalogRoots.js";
2
+ export type CatalogPathErrorCode = "absolute_path_not_allowed" | "path_outside_project_root" | "unknown_project_root" | "catalog_root_read_only";
3
+ export declare class CatalogPathError extends Error {
4
+ readonly code: CatalogPathErrorCode;
5
+ readonly registered_roots: string[];
6
+ constructor(message: string, code: CatalogPathErrorCode, registered_roots: string[]);
7
+ }
8
+ export declare function isInsideProjectRoot(projectRoot: string, candidate: string): boolean;
9
+ export type ResolveCatalogRelativePathInput = {
10
+ /** Caller-supplied path (pipeline, task, etc.). */
11
+ inputPath: string;
12
+ /** Optional wire project_root (symbolic seeded id or absolute). */
13
+ projectRoot?: string;
14
+ roots: CatalogRoot[];
15
+ fieldName?: string;
16
+ };
17
+ export type ResolvedCatalogPath = {
18
+ absolutePath: string;
19
+ root: CatalogRoot;
20
+ relativePath: string;
21
+ };
22
+ /**
23
+ * Network-surface path contract: refuse absolute paths; resolve relative under
24
+ * a selected catalog root; refuse `..` escape via realpath containment.
25
+ */
26
+ export declare function resolveCatalogRelativePath(input: ResolveCatalogRelativePathInput): ResolvedCatalogPath;
27
+ export declare function catalogPathErrorBody(err: CatalogPathError): {
28
+ error: string;
29
+ code: CatalogPathErrorCode;
30
+ registered_roots: string[];
31
+ };
32
+ /**
33
+ * Pick the catalog root for start_run / POST /api/runs.
34
+ * Wire project_root (symbolic seeded id or absolute) maps to CatalogRoot.path
35
+ * (absolute store key). When omitted: sole root, or sole non-seeded root;
36
+ * otherwise require explicit — no invent.
37
+ */
38
+ export declare function selectCatalogRootForStart(roots: CatalogRoot[], projectRoot?: string): CatalogRoot;
39
+ /**
40
+ * Shared helper: resolveCatalogRoots → selectCatalogRootForStart.
41
+ * All network-surface start-input call sites use this to avoid the hand-copy sequence.
42
+ */
43
+ export declare function resolveCatalogStartInput(options: ResolveCatalogRootsOptions, projectRoot?: string): Promise<{
44
+ roots: CatalogRoot[];
45
+ wireRoot: CatalogRoot;
46
+ }>;
47
+ /**
48
+ * Like resolveCatalogStartInput but additionally refuses read-only roots.
49
+ * Used by write surfaces (POST /api/stages, POST /api/pipelines).
50
+ */
51
+ export declare function resolveWritableCatalogRoot(options: ResolveCatalogRootsOptions, projectRoot?: string): Promise<{
52
+ roots: CatalogRoot[];
53
+ wireRoot: CatalogRoot;
54
+ }>;
55
+ /**
56
+ * Local CLI control: turn a cwd-resolved filesystem path into a catalog-relative
57
+ * wire path + project_root so the network surface does not see an absolute path.
58
+ */
59
+ export declare function relativizeLocalPathForNetwork(cwd: string, inputPath: string): {
60
+ path: string;
61
+ project_root: string;
62
+ };
@@ -0,0 +1,118 @@
1
+ import path from "node:path";
2
+ import { realpathSync } from "node:fs";
3
+ import { findCatalogRoot, resolveCatalogRoots } from "./resolveCatalogRoots.js";
4
+ export class CatalogPathError extends Error {
5
+ code;
6
+ registered_roots;
7
+ constructor(message, code, registered_roots) {
8
+ super(message);
9
+ this.name = "CatalogPathError";
10
+ this.code = code;
11
+ this.registered_roots = registered_roots;
12
+ }
13
+ }
14
+ function realOrResolve(p) {
15
+ try {
16
+ return realpathSync(p);
17
+ }
18
+ catch {
19
+ return path.resolve(p);
20
+ }
21
+ }
22
+ export function isInsideProjectRoot(projectRoot, candidate) {
23
+ const rootReal = realOrResolve(projectRoot);
24
+ const candidateReal = realOrResolve(candidate);
25
+ const rel = path.relative(rootReal, candidateReal);
26
+ return rel === "" || (!rel.startsWith("..") && !path.isAbsolute(rel));
27
+ }
28
+ /**
29
+ * Network-surface path contract: refuse absolute paths; resolve relative under
30
+ * a selected catalog root; refuse `..` escape via realpath containment.
31
+ */
32
+ export function resolveCatalogRelativePath(input) {
33
+ const field = input.fieldName ?? "path";
34
+ const registered = input.roots.map((r) => r.project_root);
35
+ if (path.isAbsolute(input.inputPath)) {
36
+ throw new CatalogPathError(`Absolute ${field} is not allowed on network surfaces; use a catalog-relative path under a registered project_root, or an inline definition.`, "absolute_path_not_allowed", registered);
37
+ }
38
+ const root = selectCatalogRootForStart(input.roots, input.projectRoot);
39
+ const absolutePath = path.resolve(root.path, input.inputPath);
40
+ if (!isInsideProjectRoot(root.path, absolutePath)) {
41
+ throw new CatalogPathError(`${field} escapes project_root ${root.project_root}`, "path_outside_project_root", registered);
42
+ }
43
+ return {
44
+ absolutePath,
45
+ root,
46
+ relativePath: path.relative(root.path, absolutePath).replace(/\\/g, "/"),
47
+ };
48
+ }
49
+ export function catalogPathErrorBody(err) {
50
+ return {
51
+ error: err.message,
52
+ code: err.code,
53
+ registered_roots: err.registered_roots,
54
+ };
55
+ }
56
+ /**
57
+ * Pick the catalog root for start_run / POST /api/runs.
58
+ * Wire project_root (symbolic seeded id or absolute) maps to CatalogRoot.path
59
+ * (absolute store key). When omitted: sole root, or sole non-seeded root;
60
+ * otherwise require explicit — no invent.
61
+ */
62
+ export function selectCatalogRootForStart(roots, projectRoot) {
63
+ const registered = roots.map((r) => r.project_root);
64
+ if (projectRoot !== undefined) {
65
+ const found = findCatalogRoot(roots, projectRoot);
66
+ if (found === undefined) {
67
+ throw new CatalogPathError(`Unknown project_root: ${projectRoot}`, "unknown_project_root", registered);
68
+ }
69
+ return found;
70
+ }
71
+ if (roots.length === 0) {
72
+ throw new CatalogPathError("No catalog roots configured; ensure a project_root first", "unknown_project_root", registered);
73
+ }
74
+ if (roots.length === 1) {
75
+ return roots[0];
76
+ }
77
+ const writable = roots.filter((r) => r.kind !== "seeded");
78
+ if (writable.length === 1) {
79
+ return writable[0];
80
+ }
81
+ throw new CatalogPathError("project_root is required when multiple catalog roots are configured", "unknown_project_root", registered);
82
+ }
83
+ /**
84
+ * Shared helper: resolveCatalogRoots → selectCatalogRootForStart.
85
+ * All network-surface start-input call sites use this to avoid the hand-copy sequence.
86
+ */
87
+ export async function resolveCatalogStartInput(options, projectRoot) {
88
+ const roots = await resolveCatalogRoots(options);
89
+ const wireRoot = selectCatalogRootForStart(roots, projectRoot);
90
+ return { roots, wireRoot };
91
+ }
92
+ /**
93
+ * Like resolveCatalogStartInput but additionally refuses read-only roots.
94
+ * Used by write surfaces (POST /api/stages, POST /api/pipelines).
95
+ */
96
+ export async function resolveWritableCatalogRoot(options, projectRoot) {
97
+ const { roots, wireRoot } = await resolveCatalogStartInput(options, projectRoot);
98
+ if (wireRoot.read_only) {
99
+ throw new CatalogPathError(`Catalog root ${wireRoot.project_root} is read-only`, "catalog_root_read_only", roots.map((r) => r.project_root));
100
+ }
101
+ return { roots, wireRoot };
102
+ }
103
+ /**
104
+ * Local CLI control: turn a cwd-resolved filesystem path into a catalog-relative
105
+ * wire path + project_root so the network surface does not see an absolute path.
106
+ */
107
+ export function relativizeLocalPathForNetwork(cwd, inputPath) {
108
+ const abs = realOrResolve(path.resolve(cwd, inputPath));
109
+ const cwdAbs = realOrResolve(cwd);
110
+ const rel = path.relative(cwdAbs, abs);
111
+ if (rel.startsWith("..") || path.isAbsolute(rel)) {
112
+ throw new Error(`Path ${abs} is outside CLI cwd ${cwdAbs}; run from the project root, pass a path under cwd, or use an inline definition on the Host API`);
113
+ }
114
+ return {
115
+ path: rel === "" ? "." : rel.replace(/\\/g, "/"),
116
+ project_root: cwdAbs,
117
+ };
118
+ }
@@ -0,0 +1,27 @@
1
+ export type ConfigOriginKind = "catalog" | "inline" | "workspace" | "seeded";
2
+ export type ConfigOriginRecord = {
3
+ name: string;
4
+ origin: ConfigOriginKind;
5
+ path?: string;
6
+ };
7
+ export type BindingKindForOrigin = "repository" | "checkout" | "none";
8
+ export type TrustWorkspaceDecision = {
9
+ allow: boolean;
10
+ origin: ConfigOriginKind;
11
+ code?: "untrusted_config_origin";
12
+ message?: string;
13
+ };
14
+ export declare function bindingKindForOrigin(kind: "repository" | "checkout" | "unbound" | "none" | undefined): BindingKindForOrigin;
15
+ /**
16
+ * Decide whether workspace-sourced config (.mcp.json / skills under checkout)
17
+ * is permitted. Default: refuse for repository bindings; allow for checkout;
18
+ * host trust_workspace_config can allowlisted roots.
19
+ */
20
+ export declare function decideWorkspaceConfigTrust(options: {
21
+ bindingKind: BindingKindForOrigin;
22
+ projectRoot: string;
23
+ trustWorkspaceConfig?: string[];
24
+ source: "workspace" | "catalog" | "inline" | "seeded";
25
+ }): TrustWorkspaceDecision;
26
+ export declare function skillOriginKind(scope: "user" | "project" | "temporary", filePath: string, checkoutRoot: string | undefined): ConfigOriginKind;
27
+ export declare function catalogOrSeededOrigin(projectRoot: string | undefined, seededRoots: readonly string[]): ConfigOriginKind;