stageflow 0.25.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (501) hide show
  1. package/README.md +10 -3
  2. package/dist/a2a/contracts.d.ts +1 -0
  3. package/dist/a2a/contracts.js +1 -0
  4. package/dist/a2a/registry.d.ts +2 -0
  5. package/dist/a2a/registry.js +20 -1
  6. package/dist/a2a/server.d.ts +7 -0
  7. package/dist/a2a/server.js +5 -2
  8. package/dist/a2a/service.d.ts +1 -1
  9. package/dist/a2a/service.js +57 -8
  10. package/dist/a2a/store.d.ts +8 -5
  11. package/dist/a2a/store.js +24 -67
  12. package/dist/agent/activity.d.ts +3 -0
  13. package/dist/agent/bootProviderConfig.d.ts +21 -0
  14. package/dist/agent/bootProviderConfig.js +74 -0
  15. package/dist/agent/piAdapter.d.ts +9 -1
  16. package/dist/agent/piAdapter.js +58 -3
  17. package/dist/agent/piIsolatedMcp.d.ts +2 -0
  18. package/dist/agent/piIsolatedMcp.js +10 -2
  19. package/dist/agent/port.d.ts +6 -0
  20. package/dist/agent/streamLogRedact.d.ts +1 -1
  21. package/dist/agent/streamLogRedact.js +4 -11
  22. package/dist/cli/artifactCommand.js +9 -16
  23. package/dist/cli/backupCommand.d.ts +9 -0
  24. package/dist/cli/backupCommand.js +111 -0
  25. package/dist/cli/debugRunCommand.d.ts +10 -0
  26. package/dist/cli/debugRunCommand.js +109 -0
  27. package/dist/cli/doctorCommand.d.ts +32 -0
  28. package/dist/cli/doctorCommand.js +453 -0
  29. package/dist/cli/envelopeCommand.js +9 -2
  30. package/dist/cli/exportAllCommand.d.ts +55 -0
  31. package/dist/cli/exportAllCommand.js +218 -0
  32. package/dist/cli/exportRunCommand.js +23 -21
  33. package/dist/cli/hostClient.d.ts +21 -3
  34. package/dist/cli/hostClient.js +93 -12
  35. package/dist/cli/initTemplates.d.ts +1 -1
  36. package/dist/cli/initTemplates.js +8 -1
  37. package/dist/cli/resolveSafeOutPath.d.ts +2 -0
  38. package/dist/cli/resolveSafeOutPath.js +40 -0
  39. package/dist/cli/restoreCommand.d.ts +10 -0
  40. package/dist/cli/restoreCommand.js +90 -0
  41. package/dist/cli/runCommand.d.ts +3 -2
  42. package/dist/cli/runCommand.js +93 -11
  43. package/dist/cli/runOutput.d.ts +4 -0
  44. package/dist/cli/runOutput.js +33 -7
  45. package/dist/cli/runStageCommand.d.ts +1 -0
  46. package/dist/cli/runStageCommand.js +44 -25
  47. package/dist/cli/runsCommand.d.ts +1 -1
  48. package/dist/cli/runsCommand.js +162 -8
  49. package/dist/cli.js +171 -30
  50. package/dist/config/catalogRelativePath.d.ts +62 -0
  51. package/dist/config/catalogRelativePath.js +118 -0
  52. package/dist/config/configOrigin.d.ts +27 -0
  53. package/dist/config/configOrigin.js +59 -0
  54. package/dist/config/hostConfig.d.ts +55 -0
  55. package/dist/config/hostConfig.js +333 -0
  56. package/dist/config/listSkills.d.ts +26 -0
  57. package/dist/config/listSkills.js +190 -3
  58. package/dist/config/loadOutcome.d.ts +1 -1
  59. package/dist/config/loadPipeline.js +23 -2
  60. package/dist/config/loadStage.js +18 -0
  61. package/dist/config/loadTask.d.ts +2 -0
  62. package/dist/config/loadTask.js +57 -18
  63. package/dist/config/materializeStageModels.js +5 -1
  64. package/dist/config/mergePipelineIncludes.d.ts +3 -0
  65. package/dist/config/mergePipelineIncludes.js +19 -0
  66. package/dist/config/migrateYaml.js +6 -11
  67. package/dist/config/multiProjectCatalog.d.ts +30 -0
  68. package/dist/config/multiProjectCatalog.js +142 -0
  69. package/dist/config/normalizePipelineStageEntry.js +20 -1
  70. package/dist/config/pipelineStageKeys.js +2 -0
  71. package/dist/config/resolveCatalogRoots.d.ts +27 -0
  72. package/dist/config/resolveCatalogRoots.js +76 -0
  73. package/dist/config/resolveModel.d.ts +7 -1
  74. package/dist/config/resolveModel.js +11 -1
  75. package/dist/config/resolveStageMcpServers.d.ts +9 -1
  76. package/dist/config/resolveStageMcpServers.js +36 -9
  77. package/dist/config/secretFromEnvOrFile.d.ts +9 -0
  78. package/dist/config/secretFromEnvOrFile.js +34 -0
  79. package/dist/config/seededCatalog.d.ts +11 -0
  80. package/dist/config/seededCatalog.js +29 -0
  81. package/dist/config/toolRequires.d.ts +24 -0
  82. package/dist/config/toolRequires.js +115 -0
  83. package/dist/config/validateCatalog.d.ts +5 -1
  84. package/dist/config/validateCatalog.js +140 -1
  85. package/dist/diagnostics/checks.d.ts +39 -0
  86. package/dist/diagnostics/checks.js +135 -0
  87. package/dist/errors/codes.d.ts +14 -0
  88. package/dist/errors/codes.js +59 -0
  89. package/dist/git/cache.d.ts +14 -0
  90. package/dist/git/cache.js +150 -0
  91. package/dist/git/credentials.d.ts +9 -0
  92. package/dist/git/credentials.js +88 -0
  93. package/dist/git/errors.d.ts +20 -0
  94. package/dist/git/errors.js +94 -0
  95. package/dist/git/exec.d.ts +16 -0
  96. package/dist/git/exec.js +135 -0
  97. package/dist/git/operations.d.ts +29 -0
  98. package/dist/git/operations.js +153 -0
  99. package/dist/git/version.d.ts +1 -0
  100. package/dist/git/version.js +10 -0
  101. package/dist/logging/audit.d.ts +16 -0
  102. package/dist/logging/audit.js +19 -0
  103. package/dist/logging/commonWords.d.ts +2 -0
  104. package/dist/logging/commonWords.js +13 -0
  105. package/dist/logging/logger.d.ts +49 -0
  106. package/dist/logging/logger.js +193 -0
  107. package/dist/logging/namedSecrets.d.ts +6 -0
  108. package/dist/logging/namedSecrets.js +58 -0
  109. package/dist/logging/redact.d.ts +13 -0
  110. package/dist/logging/redact.js +88 -0
  111. package/dist/mcp/catalogTools.js +456 -80
  112. package/dist/mcp/checkoutTools.d.ts +52 -0
  113. package/dist/mcp/checkoutTools.js +332 -0
  114. package/dist/mcp/controlTools.js +179 -5
  115. package/dist/mcp/deps.d.ts +1 -0
  116. package/dist/mcp/getStartedTool.d.ts +3 -0
  117. package/dist/mcp/getStartedTool.js +62 -0
  118. package/dist/mcp/readArtifact.d.ts +11 -0
  119. package/dist/mcp/readArtifact.js +46 -30
  120. package/dist/mcp/server.js +1 -0
  121. package/dist/mcp/tools.js +4 -0
  122. package/dist/net/proxy.d.ts +14 -0
  123. package/dist/net/proxy.js +78 -0
  124. package/dist/package-meta.d.ts +2 -1
  125. package/dist/package-meta.js +2 -1
  126. package/dist/preflight/bash.d.ts +8 -0
  127. package/dist/preflight/bash.js +34 -0
  128. package/dist/preflight/claudeRoot.d.ts +11 -0
  129. package/dist/preflight/claudeRoot.js +23 -0
  130. package/dist/preflight/mcpCommands.d.ts +8 -0
  131. package/dist/preflight/mcpCommands.js +36 -0
  132. package/dist/preflight/pipelinePreflight.d.ts +40 -0
  133. package/dist/preflight/pipelinePreflight.js +192 -0
  134. package/dist/preflight/tls.d.ts +6 -0
  135. package/dist/preflight/tls.js +18 -0
  136. package/dist/preflight/toolchain.d.ts +45 -0
  137. package/dist/preflight/toolchain.js +219 -0
  138. package/dist/project/findProjectRoot.js +3 -4
  139. package/dist/project/globalHome.d.ts +7 -0
  140. package/dist/project/globalHome.js +63 -2
  141. package/dist/project/resolveProjectContext.js +2 -2
  142. package/dist/project/resolveStageflowContext.js +2 -2
  143. package/dist/projection/projectRun.d.ts +2 -1
  144. package/dist/projection/projectRun.js +1 -0
  145. package/dist/runstore/assertTmpdir.d.ts +1 -0
  146. package/dist/runstore/assertTmpdir.js +21 -0
  147. package/dist/runstore/backup.d.ts +52 -0
  148. package/dist/runstore/backup.js +292 -0
  149. package/dist/runstore/createStore.d.ts +18 -1
  150. package/dist/runstore/createStore.js +64 -5
  151. package/dist/runstore/debugBundle.d.ts +60 -0
  152. package/dist/runstore/debugBundle.js +143 -0
  153. package/dist/runstore/diskUsage.d.ts +50 -0
  154. package/dist/runstore/diskUsage.js +214 -0
  155. package/dist/runstore/exportRunPayload.d.ts +8 -0
  156. package/dist/runstore/exportRunPayload.js +23 -0
  157. package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
  158. package/dist/runstore/normalizeCatalogPath.js +10 -0
  159. package/dist/runstore/paths.d.ts +5 -0
  160. package/dist/runstore/paths.js +145 -1
  161. package/dist/runstore/port.d.ts +111 -13
  162. package/dist/runstore/port.js +8 -1
  163. package/dist/runstore/restore.d.ts +81 -0
  164. package/dist/runstore/restore.js +355 -0
  165. package/dist/runstore/retention.d.ts +27 -0
  166. package/dist/runstore/retention.js +74 -0
  167. package/dist/runstore/runManifest.d.ts +146 -0
  168. package/dist/runstore/runManifest.js +288 -0
  169. package/dist/runstore/runProjection.d.ts +3 -1
  170. package/dist/runstore/runProjection.js +63 -1
  171. package/dist/runstore/sqlite/SqliteRunStore.d.ts +28 -3
  172. package/dist/runstore/sqlite/SqliteRunStore.js +352 -219
  173. package/dist/runstore/sqlite/applyStorePragmas.d.ts +39 -0
  174. package/dist/runstore/sqlite/applyStorePragmas.js +145 -0
  175. package/dist/runstore/sqlite/migrations/001-baseline.d.ts +7 -0
  176. package/dist/runstore/sqlite/migrations/001-baseline.js +10 -0
  177. package/dist/runstore/sqlite/migrations/002-repository-binding.d.ts +7 -0
  178. package/dist/runstore/sqlite/migrations/002-repository-binding.js +29 -0
  179. package/dist/runstore/sqlite/migrations/003-run-lifecycle.d.ts +7 -0
  180. package/dist/runstore/sqlite/migrations/003-run-lifecycle.js +28 -0
  181. package/dist/runstore/sqlite/migrations/004-auto-resume-count.d.ts +7 -0
  182. package/dist/runstore/sqlite/migrations/004-auto-resume-count.js +19 -0
  183. package/dist/runstore/sqlite/migrations/005-config-origins.d.ts +7 -0
  184. package/dist/runstore/sqlite/migrations/005-config-origins.js +19 -0
  185. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.d.ts +7 -0
  186. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.js +28 -0
  187. package/dist/runstore/sqlite/migrations/007-projects-registry.d.ts +7 -0
  188. package/dist/runstore/sqlite/migrations/007-projects-registry.js +31 -0
  189. package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
  190. package/dist/runstore/sqlite/migrations/index.js +72 -0
  191. package/dist/runstore/sqlite/schema.d.ts +20 -1
  192. package/dist/runstore/sqlite/schema.js +277 -1
  193. package/dist/runstore/sqlite/storeOpenError.d.ts +6 -0
  194. package/dist/runstore/sqlite/storeOpenError.js +11 -0
  195. package/dist/runstore/sqlite/storeSchemaError.d.ts +5 -0
  196. package/dist/runstore/sqlite/storeSchemaError.js +8 -0
  197. package/dist/runstore/stageExecution.js +3 -0
  198. package/dist/runstore/storeFilesystem.d.ts +32 -0
  199. package/dist/runstore/storeFilesystem.js +148 -0
  200. package/dist/runstore/trackProjection.js +2 -0
  201. package/dist/runstore/workspaceLayout.d.ts +13 -0
  202. package/dist/runstore/workspaceLayout.js +76 -0
  203. package/dist/runtime/completionCheckRunner.d.ts +3 -0
  204. package/dist/runtime/completionCheckRunner.js +45 -7
  205. package/dist/runtime/containerLimits.d.ts +16 -0
  206. package/dist/runtime/containerLimits.js +84 -0
  207. package/dist/runtime/credentialMaterialisation.d.ts +28 -0
  208. package/dist/runtime/credentialMaterialisation.js +128 -0
  209. package/dist/runtime/gitCheckoutCapability.js +7 -13
  210. package/dist/runtime/pipelineRunner.d.ts +36 -1
  211. package/dist/runtime/pipelineRunner.js +178 -17
  212. package/dist/runtime/pipelineScheduler.d.ts +15 -0
  213. package/dist/runtime/pipelineScheduler.js +135 -27
  214. package/dist/runtime/reloadRunCatalog.js +6 -1
  215. package/dist/runtime/repositoryMaterialize.d.ts +47 -0
  216. package/dist/runtime/repositoryMaterialize.js +235 -0
  217. package/dist/runtime/resumeTimedOut.d.ts +1 -1
  218. package/dist/runtime/resumeTimedOut.js +5 -2
  219. package/dist/runtime/runChangeBus.js +9 -0
  220. package/dist/runtime/runDeletion.d.ts +7 -0
  221. package/dist/runtime/runDeletion.js +37 -0
  222. package/dist/runtime/runManager.d.ts +158 -4
  223. package/dist/runtime/runManager.js +1596 -79
  224. package/dist/runtime/runRetentionSweep.d.ts +31 -0
  225. package/dist/runtime/runRetentionSweep.js +328 -0
  226. package/dist/runtime/runRetryCoordinator.d.ts +2 -0
  227. package/dist/runtime/runRetryCoordinator.js +19 -2
  228. package/dist/runtime/runSkills.d.ts +40 -0
  229. package/dist/runtime/runSkills.js +173 -0
  230. package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
  231. package/dist/runtime/stageAttemptBootstrap.js +195 -24
  232. package/dist/runtime/stageCacheEnv.d.ts +6 -0
  233. package/dist/runtime/stageCacheEnv.js +34 -0
  234. package/dist/runtime/stageConcurrency.d.ts +2 -1
  235. package/dist/runtime/stageConcurrency.js +4 -2
  236. package/dist/runtime/stageEnvironment.d.ts +38 -0
  237. package/dist/runtime/stageEnvironment.js +193 -0
  238. package/dist/runtime/stageProcessLauncher.d.ts +18 -0
  239. package/dist/runtime/stageProcessLauncher.js +194 -38
  240. package/dist/runtime/stageRecovery.d.ts +3 -1
  241. package/dist/runtime/stageRecovery.js +19 -4
  242. package/dist/runtime/stageRoots.d.ts +38 -1
  243. package/dist/runtime/stageRoots.js +118 -0
  244. package/dist/runtime/stageRunner.d.ts +1 -0
  245. package/dist/runtime/stageRunner.js +3 -1
  246. package/dist/runtime/stageSecretDecl.d.ts +9 -0
  247. package/dist/runtime/stageSecretDecl.js +102 -0
  248. package/dist/runtime/stageSecrets.d.ts +40 -0
  249. package/dist/runtime/stageSecrets.js +181 -0
  250. package/dist/runtime/stageWorker.d.ts +3 -2
  251. package/dist/runtime/stageWorker.js +58 -10
  252. package/dist/runtime/stageWorkerProtocol.d.ts +5 -0
  253. package/dist/runtime/stageWorkerProtocol.js +8 -0
  254. package/dist/runtime/startPayload.d.ts +32 -0
  255. package/dist/runtime/startPayload.js +59 -0
  256. package/dist/runtime/taskInput.js +14 -5
  257. package/dist/runtime/verifiedStageExecution.d.ts +1 -0
  258. package/dist/runtime/verifiedStageExecution.js +2 -1
  259. package/dist/runtime/workspaceBinding.d.ts +20 -0
  260. package/dist/runtime/workspaceBinding.js +60 -0
  261. package/dist/server/allowedHosts.d.ts +19 -0
  262. package/dist/server/allowedHosts.js +179 -0
  263. package/dist/server/bootstrap.d.ts +36 -2
  264. package/dist/server/bootstrap.js +209 -5
  265. package/dist/server/controlToken.d.ts +47 -0
  266. package/dist/server/controlToken.js +241 -0
  267. package/dist/server/createHttpHost.d.ts +11 -2
  268. package/dist/server/createHttpHost.js +103 -10
  269. package/dist/server/ensureGlobalService.d.ts +5 -1
  270. package/dist/server/ensureGlobalService.js +35 -1
  271. package/dist/server/healthSurfaces.d.ts +6 -0
  272. package/dist/server/healthSurfaces.js +98 -0
  273. package/dist/server/http.d.ts +12 -1
  274. package/dist/server/http.js +1085 -485
  275. package/dist/server/listenHost.d.ts +5 -0
  276. package/dist/server/listenHost.js +56 -0
  277. package/dist/server/mcpHost.d.ts +10 -1
  278. package/dist/server/mcpHost.js +36 -6
  279. package/dist/server/operatorResults.d.ts +2 -2
  280. package/dist/server/operatorResults.js +40 -29
  281. package/dist/server/requestAuthContext.d.ts +12 -0
  282. package/dist/server/requestAuthContext.js +21 -0
  283. package/dist/server/shutdown.d.ts +69 -0
  284. package/dist/server/shutdown.js +219 -0
  285. package/dist/types/pipeline.d.ts +7 -0
  286. package/dist/types/stage.d.ts +8 -0
  287. package/dist/types/task.d.ts +8 -0
  288. package/dist/ui/assets/index-B6hlSXXn.js +120 -0
  289. package/dist/ui/index.html +1 -1
  290. package/examples/README.md +98 -0
  291. package/examples/archify-on-pr/README.md +213 -0
  292. package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +19 -0
  293. package/examples/archify-on-pr/archify-on-pr.task.yaml +19 -0
  294. package/examples/archify-on-pr/author-diagrams.yaml +106 -0
  295. package/examples/archify-on-pr/detect-changes.yaml +89 -0
  296. package/examples/ci-validate/README.md +35 -0
  297. package/examples/ci-validate/check.yaml +13 -0
  298. package/examples/ci-validate/ci-demo.pipeline.yaml +4 -0
  299. package/examples/ci-validate/validate.sh +5 -0
  300. package/examples/compliance-review-demo/README.md +125 -0
  301. package/examples/compliance-review-demo/compliance-review-demo.pipeline.yaml +29 -0
  302. package/examples/compliance-review-demo/connect-account.yaml +47 -0
  303. package/examples/compliance-review-demo/map-to-control.yaml +123 -0
  304. package/examples/compliance-review-demo/poll-bucket-config.yaml +103 -0
  305. package/examples/compliance-review-demo/publish-report.yaml +79 -0
  306. package/examples/compliance-review-demo/review-verdict.yaml +122 -0
  307. package/examples/compliance-review-demo/run-compliance-check.yaml +96 -0
  308. package/examples/compliance-review-demo/store-evidence.yaml +143 -0
  309. package/examples/conditional-fork/README.md +89 -0
  310. package/examples/conditional-fork/branch-a.yaml +13 -0
  311. package/examples/conditional-fork/branch-b.yaml +13 -0
  312. package/examples/conditional-fork/decide.yaml +35 -0
  313. package/examples/conditional-fork/fork-demo.pipeline.yaml +20 -0
  314. package/examples/conditional-fork/fork-demo.task.yaml +8 -0
  315. package/examples/context7-mcp/README.md +42 -0
  316. package/examples/context7-mcp/context7-mcp.pipeline.yaml +15 -0
  317. package/examples/context7-mcp/context7-mcp.task.yaml +4 -0
  318. package/examples/context7-mcp/fetch-docs.yaml +52 -0
  319. package/examples/context7-mcp/resolve-library.yaml +31 -0
  320. package/examples/context7-mcp/write-brief.yaml +52 -0
  321. package/examples/feature-loop/README.md +104 -0
  322. package/examples/feature-loop/address-feedback.yaml +148 -0
  323. package/examples/feature-loop/align.yaml +116 -0
  324. package/examples/feature-loop/decompose.yaml +86 -0
  325. package/examples/feature-loop/default-model-hierarchy.task.yaml +58 -0
  326. package/examples/feature-loop/feature-loop.pipeline.yaml +140 -0
  327. package/examples/feature-loop/feature-loop.task.yaml +25 -0
  328. package/examples/feature-loop/implement.yaml +128 -0
  329. package/examples/feature-loop/plan.yaml +111 -0
  330. package/examples/feature-loop/publish.yaml +167 -0
  331. package/examples/feature-loop/review.yaml +146 -0
  332. package/examples/feature-loop/verify.yaml +106 -0
  333. package/examples/feedback-loop/README.md +72 -0
  334. package/examples/feedback-loop/VERIFY.md +208 -0
  335. package/examples/feedback-loop/continue-only.task.yaml +4 -0
  336. package/examples/feedback-loop/exhaust-require-continue.task.yaml +6 -0
  337. package/examples/feedback-loop/exhaust-wait-human.task.yaml +11 -0
  338. package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +23 -0
  339. package/examples/feedback-loop/feedback-loop.pipeline.yaml +23 -0
  340. package/examples/feedback-loop/feedback-loop.task.yaml +4 -0
  341. package/examples/feedback-loop/implement.yaml +14 -0
  342. package/examples/feedback-loop/plan.yaml +14 -0
  343. package/examples/feedback-loop/review.yaml +15 -0
  344. package/examples/feedback-loop/send-back-once.task.yaml +6 -0
  345. package/examples/feedback-loop/submit.yaml +12 -0
  346. package/examples/generic-fan-in/README.md +151 -0
  347. package/examples/generic-fan-in/clarify.yaml +18 -0
  348. package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +19 -0
  349. package/examples/generic-fan-in/generic-fan-in-accepted.task.yaml +8 -0
  350. package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +18 -0
  351. package/examples/generic-fan-in/generic-fan-in.task.yaml +9 -0
  352. package/examples/generic-fan-in/research.yaml +45 -0
  353. package/examples/generic-fan-in/synthesize.yaml +66 -0
  354. package/examples/generic-fan-in/validation.yaml +45 -0
  355. package/examples/github-release/README.md +78 -0
  356. package/examples/github-release/draft-release-notes.yaml +64 -0
  357. package/examples/github-release/github-release.pipeline.yaml +11 -0
  358. package/examples/github-release/github-release.task.yaml +13 -0
  359. package/examples/github-release/publish-github-release.yaml +64 -0
  360. package/examples/hello-world/README.md +28 -0
  361. package/examples/hello-world/hello.pipeline.yaml +4 -0
  362. package/examples/hello-world/my-task.task.yaml +6 -0
  363. package/examples/hello-world/research.yaml +18 -0
  364. package/examples/mcp-hitl-tour/README.md +113 -0
  365. package/examples/mcp-hitl-tour/draft-angle.yaml +33 -0
  366. package/examples/mcp-hitl-tour/draft-short.yaml +32 -0
  367. package/examples/mcp-hitl-tour/emit-angles.yaml +45 -0
  368. package/examples/mcp-hitl-tour/gather.yaml +31 -0
  369. package/examples/mcp-hitl-tour/intake.yaml +62 -0
  370. package/examples/mcp-hitl-tour/mcp-hitl-tour-exhaust.task.yaml +13 -0
  371. package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +54 -0
  372. package/examples/mcp-hitl-tour/mcp-hitl-tour.task.yaml +16 -0
  373. package/examples/mcp-hitl-tour/polish.yaml +33 -0
  374. package/examples/mcp-hitl-tour/review.yaml +17 -0
  375. package/examples/mcp-hitl-tour/ship.yaml +25 -0
  376. package/examples/oss-issue-contribution/README.md +218 -0
  377. package/examples/oss-issue-contribution/oss-address-review-feedback.yaml +117 -0
  378. package/examples/oss-issue-contribution/oss-approve-contribution.yaml +181 -0
  379. package/examples/oss-issue-contribution/oss-approve-plan.yaml +111 -0
  380. package/examples/oss-issue-contribution/oss-explain-fix.yaml +108 -0
  381. package/examples/oss-issue-contribution/oss-explain-issue.yaml +114 -0
  382. package/examples/oss-issue-contribution/oss-implement-source-fix.yaml +171 -0
  383. package/examples/oss-issue-contribution/oss-investigate-area.yaml +116 -0
  384. package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +125 -0
  385. package/examples/oss-issue-contribution/oss-issue-intake.yaml +106 -0
  386. package/examples/oss-issue-contribution/oss-plan-investigation.yaml +112 -0
  387. package/examples/oss-issue-contribution/oss-plan-review.yaml +109 -0
  388. package/examples/oss-issue-contribution/oss-reproduce-issue.yaml +140 -0
  389. package/examples/oss-issue-contribution/oss-review-change.yaml +107 -0
  390. package/examples/oss-issue-contribution/oss-verify-fix.yaml +130 -0
  391. package/examples/oss-issue-contribution/oss-write-regression-test.yaml +135 -0
  392. package/examples/oss-issue-contribution/pi-7629.task.yaml +79 -0
  393. package/examples/oss-issue-contribution/pi-8919.task.yaml +75 -0
  394. package/examples/oss-issue-contribution/pydantic-ai-7971.task.yaml +53 -0
  395. package/examples/oss-quick-fix/README.md +65 -0
  396. package/examples/oss-quick-fix/implement-fix.yaml +84 -0
  397. package/examples/oss-quick-fix/oss-quick-fix.pipeline.yaml +35 -0
  398. package/examples/oss-quick-fix/oss-quick-fix.task.yaml +19 -0
  399. package/examples/oss-quick-fix/ship-fix.yaml +81 -0
  400. package/examples/oss-quick-fix/understand-issue.yaml +67 -0
  401. package/examples/oss-quick-fix/verify-fix.yaml +73 -0
  402. package/examples/plan-review/README.md +37 -0
  403. package/examples/plan-review/plan-review-followup.yaml +13 -0
  404. package/examples/plan-review/plan-review.pipeline.yaml +9 -0
  405. package/examples/plan-review/plan-review.task.yaml +9 -0
  406. package/examples/plan-review/plan-review.yaml +25 -0
  407. package/examples/playwright-mcp/README.md +39 -0
  408. package/examples/playwright-mcp/playwright-mcp.pipeline.yaml +5 -0
  409. package/examples/playwright-mcp/playwright-mcp.task.yaml +4 -0
  410. package/examples/playwright-mcp/screenshot.yaml +40 -0
  411. package/examples/retry-tour/README.md +75 -0
  412. package/examples/retry-tour/retry-tour.pipeline.yaml +122 -0
  413. package/examples/retry-tour/retry-tour.task.yaml +9 -0
  414. package/examples/route-if-tour/README.md +202 -0
  415. package/examples/route-if-tour/route-if-tour.pipeline.yaml +950 -0
  416. package/examples/route-if-tour/route-if-tour.task.yaml +4 -0
  417. package/examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml +168 -0
  418. package/examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml +44 -0
  419. package/examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml +28 -0
  420. package/examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml +27 -0
  421. package/examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml +110 -0
  422. package/examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml +82 -0
  423. package/examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml +82 -0
  424. package/examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml +77 -0
  425. package/examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml +102 -0
  426. package/examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml +23 -0
  427. package/examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml +37 -0
  428. package/examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml +138 -0
  429. package/examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml +84 -0
  430. package/examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml +50 -0
  431. package/examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml +37 -0
  432. package/examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml +65 -0
  433. package/examples/route-wiring-smoke-test/17-if-join.pipeline.yaml +80 -0
  434. package/examples/route-wiring-smoke-test/README.md +377 -0
  435. package/examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml +26 -0
  436. package/examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml +25 -0
  437. package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml +30 -0
  438. package/examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml +24 -0
  439. package/examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml +35 -0
  440. package/examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml +37 -0
  441. package/examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml +27 -0
  442. package/examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml +42 -0
  443. package/examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml +26 -0
  444. package/examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml +55 -0
  445. package/examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml +51 -0
  446. package/examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml +35 -0
  447. package/examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml +15 -0
  448. package/examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml +15 -0
  449. package/examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml +33 -0
  450. package/examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml +51 -0
  451. package/examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml +55 -0
  452. package/examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml +36 -0
  453. package/examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml +42 -0
  454. package/examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml +33 -0
  455. package/examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml +32 -0
  456. package/examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml +31 -0
  457. package/examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml +33 -0
  458. package/examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml +36 -0
  459. package/examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml +63 -0
  460. package/examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml +46 -0
  461. package/examples/route-wiring-smoke-test/smoke-test.task.yaml +4 -0
  462. package/examples/route-wiring-smoke-test/stages/branch-a.yaml +12 -0
  463. package/examples/route-wiring-smoke-test/stages/branch-b.yaml +12 -0
  464. package/examples/route-wiring-smoke-test/stages/decide.yaml +12 -0
  465. package/examples/route-wiring-smoke-test/stages/finish.yaml +12 -0
  466. package/examples/ship-feature/README.md +190 -0
  467. package/examples/ship-feature/feat-address-feedback.yaml +119 -0
  468. package/examples/ship-feature/feat-implement.yaml +180 -0
  469. package/examples/ship-feature/feat-plan.yaml +120 -0
  470. package/examples/ship-feature/feat-review.yaml +109 -0
  471. package/examples/ship-feature/feat-ship.yaml +203 -0
  472. package/examples/ship-feature/ship-feature.pipeline.yaml +44 -0
  473. package/examples/ship-feature/ship-feature.task.yaml +78 -0
  474. package/examples/stage-mcp/README.md +144 -0
  475. package/examples/stage-mcp/echo-mcp.mjs +20 -0
  476. package/examples/stage-mcp/stage-mcp-dead.pipeline.yaml +5 -0
  477. package/examples/stage-mcp/stage-mcp-dead.task.yaml +3 -0
  478. package/examples/stage-mcp/stage-mcp-missing-var.pipeline.yaml +5 -0
  479. package/examples/stage-mcp/stage-mcp-missing-var.task.yaml +3 -0
  480. package/examples/stage-mcp/stage-mcp.pipeline.yaml +5 -0
  481. package/examples/stage-mcp/stage-mcp.task.yaml +4 -0
  482. package/examples/stage-mcp/use-echo.yaml +20 -0
  483. package/examples/verify-tour/README.md +80 -0
  484. package/examples/verify-tour/verify-tour.pipeline.yaml +162 -0
  485. package/examples/verify-tour/verify-tour.task.yaml +11 -0
  486. package/package.json +5 -1
  487. package/skills/stageflow/SKILL.md +6 -6
  488. package/skills/stageflow/references/control-surface.md +11 -5
  489. package/skills/stageflow/scripts/detect-host.mjs +14 -1
  490. package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
  491. package/skills/stageflow-author/SKILL.md +4 -3
  492. package/skills/stageflow-author/references/catalog-mapping.md +16 -0
  493. package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
  494. package/skills/stageflow-run/SKILL.md +20 -12
  495. package/skills/stageflow-run/references/mcp-call.md +9 -1
  496. package/skills/stageflow-run/references/task-and-pipeline-selection.md +16 -5
  497. package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
  498. package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
  499. package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
  500. package/skills/stageflow-setup/SKILL.md +40 -8
  501. package/dist/ui/assets/index-Da5EHU6M.js +0 -119
@@ -1,11 +1,12 @@
1
1
  import type { RunStore } from "../runstore/port.js";
2
2
  import type { StartRunResult } from "../runtime/runManager.js";
3
+ import type { TaskFile } from "../types/task.js";
3
4
  import { type EnsureGlobalServiceResult } from "../server/ensureGlobalService.js";
4
5
  import { type CliRunReportIo } from "./runOutput.js";
5
- export declare const RUN_USAGE = "Usage:\n 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>]";
6
+ export declare const RUN_USAGE = "Usage:\n 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>]";
6
7
  export type RunCommandIo = CliRunReportIo;
7
8
  export type StartRunFn = (input: {
8
- task: string;
9
+ task: string | TaskFile;
9
10
  pipeline: string;
10
11
  checkoutOverride?: string;
11
12
  skipGates?: boolean;
@@ -1,11 +1,16 @@
1
- import { PipelineValidationError } from "../runtime/pipelineRunner.js";
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { coerceTaskFile } from "../config/loadTask.js";
5
+ import { relativizeLocalPathForNetwork } from "../config/catalogRelativePath.js";
6
+ import { PipelinePreflightError, PipelineValidationError } from "../runtime/pipelineRunner.js";
2
7
  import { ensureGlobalService, hostBaseUrl, } from "../server/ensureGlobalService.js";
3
- import { httpStartRun, httpStoreReader, resolveAbsolute } from "./hostClient.js";
4
- import { reportCliRun, } from "./runOutput.js";
8
+ import { httpEnsureProject, httpStartRun, httpStoreReader } from "./hostClient.js";
9
+ import { reportCliRun, writeQueuedAdmissionLine, } from "./runOutput.js";
5
10
  import { resolveCiIdentity } from "./ciIdentity.js";
6
11
  import { exitCodeForValidation, formatValidationHuman, formatValidationJson, } from "./validateOutput.js";
7
12
  export const RUN_USAGE = `Usage:
8
- 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>]`;
13
+ 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>]`;
9
14
  const defaultIo = {
10
15
  log: (line) => console.log(line),
11
16
  error: (line) => console.error(line),
@@ -20,6 +25,8 @@ function parseRunArgs(args) {
20
25
  let task;
21
26
  let pipeline;
22
27
  let checkout;
28
+ let repository;
29
+ let ref;
23
30
  let gitSha;
24
31
  let ciPrUrl;
25
32
  let ciJobUrl;
@@ -55,6 +62,20 @@ function parseRunArgs(args) {
55
62
  }
56
63
  checkout = value;
57
64
  }
65
+ else if (arg === "--repository") {
66
+ const value = args[++i];
67
+ if (value === undefined || value.length === 0) {
68
+ throw new Error("Missing value for --repository");
69
+ }
70
+ repository = value;
71
+ }
72
+ else if (arg === "--ref") {
73
+ const value = args[++i];
74
+ if (value === undefined || value.length === 0) {
75
+ throw new Error("Missing value for --ref");
76
+ }
77
+ ref = value;
78
+ }
58
79
  else if (arg === "--git-sha") {
59
80
  const value = args[++i];
60
81
  if (value === undefined || value.length === 0) {
@@ -123,6 +144,8 @@ function parseRunArgs(args) {
123
144
  task,
124
145
  pipeline,
125
146
  checkout,
147
+ repository,
148
+ ref,
126
149
  gitSha,
127
150
  ciPrUrl,
128
151
  ciJobUrl,
@@ -130,18 +153,60 @@ function parseRunArgs(args) {
130
153
  operatorAgentDir,
131
154
  };
132
155
  }
156
+ async function loadTaskWithBindingOverrides(taskPath, cwd, overrides) {
157
+ const absolute = path.resolve(cwd, taskPath);
158
+ const yamlText = await readFile(absolute, "utf8");
159
+ const raw = parseYaml(yamlText);
160
+ const task = coerceTaskFile(raw);
161
+ if (task === undefined) {
162
+ throw new Error(`Invalid task file ${absolute}: id and goal are required strings`);
163
+ }
164
+ if (overrides.repository !== undefined)
165
+ task.repository = overrides.repository;
166
+ if (overrides.ref !== undefined)
167
+ task.ref = overrides.ref;
168
+ return task;
169
+ }
133
170
  function defaultStartRun(cwd, base, ensureService) {
134
171
  return async (input) => {
135
172
  const ensured = await ensureService();
136
173
  if (!ensured.ok) {
137
- return { ok: false, reason: ensured.message, status: 503 };
174
+ return {
175
+ ok: false,
176
+ reason: ensured.message,
177
+ status: 503,
178
+ ...(ensured.reason === "autostart_disabled"
179
+ ? { code: "autostart_disabled" }
180
+ : {}),
181
+ };
138
182
  }
183
+ const pipelineRef = relativizeLocalPathForNetwork(cwd, input.pipeline);
184
+ let task = input.task;
185
+ let projectRoot = pipelineRef.project_root;
186
+ if (typeof input.task === "string") {
187
+ const absTask = path.resolve(cwd, input.task);
188
+ const cwdAbs = path.resolve(cwd);
189
+ const relTask = path.relative(cwdAbs, absTask);
190
+ if (relTask.startsWith("..") || path.isAbsolute(relTask)) {
191
+ task = await loadTaskWithBindingOverrides(input.task, cwd, {});
192
+ }
193
+ else {
194
+ const taskRef = relativizeLocalPathForNetwork(cwd, input.task);
195
+ task = taskRef.path;
196
+ projectRoot = taskRef.project_root;
197
+ }
198
+ }
199
+ const ensuredProject = await httpEnsureProject(base, projectRoot);
200
+ if (!ensuredProject.ok)
201
+ return ensuredProject;
202
+ const checkoutOverride = input.checkoutOverride !== undefined
203
+ ? relativizeLocalPathForNetwork(cwd, input.checkoutOverride).path
204
+ : undefined;
139
205
  return httpStartRun(base, {
140
- pipeline: resolveAbsolute(cwd, input.pipeline),
141
- task: resolveAbsolute(cwd, input.task),
142
- ...(input.checkoutOverride !== undefined
143
- ? { checkoutOverride: resolveAbsolute(cwd, input.checkoutOverride) }
144
- : {}),
206
+ pipeline: pipelineRef.path,
207
+ task,
208
+ project_root: ensuredProject.project_root,
209
+ ...(checkoutOverride !== undefined ? { checkoutOverride } : {}),
145
210
  ...(input.skipGates !== undefined ? { skipGates: input.skipGates } : {}),
146
211
  ...(input.gitSha !== undefined ? { gitSha: input.gitSha } : {}),
147
212
  ...(input.ciPrUrl !== undefined ? { ciPrUrl: input.ciPrUrl } : {}),
@@ -200,8 +265,15 @@ export async function runRunCommand(args, options = {}) {
200
265
  });
201
266
  const store = options.store ?? (parsed.includeStages ? httpStoreReader(base) : undefined);
202
267
  try {
268
+ const hasBindingOverride = parsed.repository !== undefined || parsed.ref !== undefined;
269
+ const taskInput = hasBindingOverride
270
+ ? await loadTaskWithBindingOverrides(parsed.task, cwd, {
271
+ repository: parsed.repository,
272
+ ref: parsed.ref,
273
+ })
274
+ : parsed.task;
203
275
  const started = await startRun({
204
- task: parsed.task,
276
+ task: taskInput,
205
277
  pipeline: parsed.pipeline,
206
278
  checkoutOverride: parsed.checkout,
207
279
  ...(parsed.skipGates ? { skipGates: true } : {}),
@@ -210,6 +282,7 @@ export async function runRunCommand(args, options = {}) {
210
282
  if (!started.ok) {
211
283
  return reportCliRun({ kind: "start-failure", started }, { json: parsed.json, io: out });
212
284
  }
285
+ writeQueuedAdmissionLine(started, out);
213
286
  return completeCliRun(started, out, {
214
287
  json: parsed.json,
215
288
  includeStages: parsed.includeStages,
@@ -226,6 +299,15 @@ export async function runRunCommand(args, options = {}) {
226
299
  }
227
300
  return exitCodeForValidation(err.result);
228
301
  }
302
+ if (err instanceof PipelinePreflightError) {
303
+ if (parsed.json) {
304
+ out.log(JSON.stringify(err.toNetworkBody(), null, 2));
305
+ }
306
+ else {
307
+ out.error(err.message);
308
+ }
309
+ return 1;
310
+ }
229
311
  out.error(err instanceof Error ? err.message : String(err));
230
312
  return 1;
231
313
  }
@@ -14,6 +14,10 @@ export type CliRunReportEvent = {
14
14
  kind: "completion";
15
15
  result: PipelineRunResult;
16
16
  };
17
+ /** Stderr line when start_run was admitted to the queue (origin transparency rule). */
18
+ export declare function writeQueuedAdmissionLine(started: Extract<StartRunResult, {
19
+ ok: true;
20
+ }>, io: Pick<CliRunReportIo, "error">): void;
17
21
  export declare function reportCliRun(event: CliRunReportEvent, options: {
18
22
  json?: boolean;
19
23
  io: CliRunReportIo;
@@ -20,6 +20,12 @@ async function tryReadTotalCostUsd(store, runId) {
20
20
  function isBusyCode(code) {
21
21
  return code === "busy_capacity" || code === "busy_checkout";
22
22
  }
23
+ /** Stderr line when start_run was admitted to the queue (origin transparency rule). */
24
+ export function writeQueuedAdmissionLine(started, io) {
25
+ if (started.queued === true && started.queuePosition !== undefined) {
26
+ io.error(`queued at position ${started.queuePosition}`);
27
+ }
28
+ }
23
29
  function formatRunBusyJson(started) {
24
30
  const payload = {
25
31
  ok: false,
@@ -52,6 +58,13 @@ function formatRunStartFailedJson(started) {
52
58
  };
53
59
  if (started.code !== undefined)
54
60
  payload.code = started.code;
61
+ if (started.freeBytes !== undefined)
62
+ payload.freeBytes = started.freeBytes;
63
+ if (started.minFreeBytes !== undefined) {
64
+ payload.minFreeBytes = started.minFreeBytes;
65
+ }
66
+ if (started.stderr !== undefined)
67
+ payload.stderr = started.stderr;
55
68
  return stringify(payload);
56
69
  }
57
70
  function formatStartFailureJson(started) {
@@ -75,13 +88,21 @@ function baseRunCompletionPayload(result) {
75
88
  runId: result.runId,
76
89
  runDir: result.runDir,
77
90
  }
78
- : {
79
- ok: false,
80
- outcome: "failed",
81
- runId: result.runId,
82
- runDir: result.runDir,
83
- };
84
- if (result.outcome === "failed" && result.reason !== undefined) {
91
+ : result.outcome === "cancelled"
92
+ ? {
93
+ ok: false,
94
+ outcome: "cancelled",
95
+ runId: result.runId,
96
+ runDir: result.runDir,
97
+ }
98
+ : {
99
+ ok: false,
100
+ outcome: "failed",
101
+ runId: result.runId,
102
+ runDir: result.runDir,
103
+ };
104
+ if ((result.outcome === "failed" || result.outcome === "cancelled") &&
105
+ result.reason !== undefined) {
85
106
  payload.reason = result.reason;
86
107
  }
87
108
  if (Array.isArray(result.findings) && result.findings.length > 0) {
@@ -130,6 +151,10 @@ function writeCompletionHuman(result, io, totalCostUsd) {
130
151
  io.error(`Pipeline failed: ${result.reason}`);
131
152
  io.error(`Run folder: ${result.runDir}`);
132
153
  break;
154
+ case "cancelled":
155
+ io.error(`Pipeline cancelled${result.reason ? `: ${result.reason}` : ""}`);
156
+ io.error(`Run folder: ${result.runDir}`);
157
+ break;
133
158
  case "succeeded":
134
159
  io.log(`Pipeline succeeded. Run folder: ${result.runDir}`);
135
160
  break;
@@ -145,6 +170,7 @@ function exitCodeForRunOutcome(outcome) {
145
170
  case "waiting":
146
171
  return 2;
147
172
  case "failed":
173
+ case "cancelled":
148
174
  return 1;
149
175
  }
150
176
  }
@@ -7,6 +7,7 @@ export type RunStageEnvelopeRef = {
7
7
  };
8
8
  export type RunStageToolArgs = {
9
9
  stage: string | Record<string, unknown>;
10
+ project_root?: string;
10
11
  task_path?: string;
11
12
  task?: Record<string, unknown>;
12
13
  envelope_ref?: RunStageEnvelopeRef | RunStageEnvelopeRef[];
@@ -1,6 +1,7 @@
1
+ import { relativizeLocalPathForNetwork } from "../config/catalogRelativePath.js";
1
2
  import { PACKAGE_VERSION } from "../package-meta.js";
2
3
  import { ensureGlobalService, hostBaseUrl, } from "../server/ensureGlobalService.js";
3
- import { resolveAbsolute } from "./hostClient.js";
4
+ import { httpEnsureProject } from "./hostClient.js";
4
5
  export const RUN_STAGE_USAGE = `Usage:
5
6
  sf run-stage (--stage <path> | --stage-inline '<json>') (--task <path> | --task-inline '<json>' | --envelope-ref <runId>:<stageId>[:<attempt>] [--envelope-ref ...]) [--checkout <path>] [--model <id>] [--blocking] [--timeout-ms <n>] [--json]
6
7
 
@@ -247,9 +248,17 @@ function defaultCallTool(base, ensureService) {
247
248
  if (!ensured.ok) {
248
249
  throw new Error(ensured.message);
249
250
  }
251
+ let toolArgs = args;
252
+ if (args.project_root !== undefined) {
253
+ const ensuredProject = await httpEnsureProject(base, args.project_root);
254
+ if (!ensuredProject.ok) {
255
+ throw new Error(ensuredProject.reason);
256
+ }
257
+ toolArgs = { ...args, project_root: ensuredProject.project_root };
258
+ }
250
259
  const sessionId = await mcpInitializeSession(base);
251
260
  try {
252
- return await mcpToolCall(base, sessionId, "run_stage", args);
261
+ return await mcpToolCall(base, sessionId, "run_stage", toolArgs);
253
262
  }
254
263
  finally {
255
264
  await mcpCloseSession(base, sessionId);
@@ -338,37 +347,48 @@ export async function runRunStageCommand(args, options = {}) {
338
347
  return 1;
339
348
  }
340
349
  let stage;
341
- if (parsed.stage !== undefined) {
342
- stage = resolveAbsolute(cwd, parsed.stage);
343
- }
344
- else {
345
- try {
346
- stage = parseJsonFlag(parsed.stageInline, "--stage-inline");
350
+ let projectRoot;
351
+ try {
352
+ if (parsed.stage !== undefined) {
353
+ const stageRef = relativizeLocalPathForNetwork(cwd, parsed.stage);
354
+ stage = stageRef.path;
355
+ projectRoot = stageRef.project_root;
347
356
  }
348
- catch (err) {
349
- out.error(err instanceof Error ? err.message : String(err));
350
- return 1;
357
+ else {
358
+ stage = parseJsonFlag(parsed.stageInline, "--stage-inline");
351
359
  }
352
360
  }
361
+ catch (err) {
362
+ out.error(err instanceof Error ? err.message : String(err));
363
+ return 1;
364
+ }
353
365
  let taskPath;
354
366
  let task;
355
367
  let envelopeRef;
356
- if (parsed.task !== undefined) {
357
- taskPath = resolveAbsolute(cwd, parsed.task);
358
- }
359
- else if (parsed.taskInline !== undefined) {
360
- try {
368
+ try {
369
+ if (parsed.task !== undefined) {
370
+ const taskRef = relativizeLocalPathForNetwork(cwd, parsed.task);
371
+ taskPath = taskRef.path;
372
+ projectRoot = taskRef.project_root;
373
+ }
374
+ else if (parsed.taskInline !== undefined) {
361
375
  task = parseJsonFlag(parsed.taskInline, "--task-inline");
362
376
  }
363
- catch (err) {
364
- out.error(err instanceof Error ? err.message : String(err));
365
- return 1;
377
+ else {
378
+ const refs = parsed.envelopeRef.map(parseEnvelopeRefFlag);
379
+ envelopeRef = refs.length === 1 ? refs[0] : refs;
366
380
  }
367
381
  }
368
- else {
382
+ catch (err) {
383
+ out.error(err instanceof Error ? err.message : String(err));
384
+ return 1;
385
+ }
386
+ let checkout;
387
+ if (parsed.checkout !== undefined) {
369
388
  try {
370
- const refs = parsed.envelopeRef.map(parseEnvelopeRefFlag);
371
- envelopeRef = refs.length === 1 ? refs[0] : refs;
389
+ const checkoutRef = relativizeLocalPathForNetwork(cwd, parsed.checkout);
390
+ checkout = checkoutRef.path;
391
+ projectRoot = projectRoot ?? checkoutRef.project_root;
372
392
  }
373
393
  catch (err) {
374
394
  out.error(err instanceof Error ? err.message : String(err));
@@ -377,12 +397,11 @@ export async function runRunStageCommand(args, options = {}) {
377
397
  }
378
398
  const toolArgs = {
379
399
  stage,
400
+ ...(projectRoot !== undefined ? { project_root: projectRoot } : {}),
380
401
  ...(taskPath !== undefined ? { task_path: taskPath } : {}),
381
402
  ...(task !== undefined ? { task } : {}),
382
403
  ...(envelopeRef !== undefined ? { envelope_ref: envelopeRef } : {}),
383
- ...(parsed.checkout !== undefined
384
- ? { checkout: resolveAbsolute(cwd, parsed.checkout) }
385
- : {}),
404
+ ...(checkout !== undefined ? { checkout } : {}),
386
405
  ...(parsed.model !== undefined ? { model: parsed.model } : {}),
387
406
  ...(parsed.blocking ? { blocking: true } : {}),
388
407
  ...(parsed.timeoutMs !== undefined ? { timeout_ms: parsed.timeoutMs } : {}),
@@ -1,6 +1,6 @@
1
1
  import type { RunStore } from "../runstore/port.js";
2
2
  import { type EnsureGlobalServiceResult } from "../server/ensureGlobalService.js";
3
- export declare const RUNS_USAGE = "Usage:\n sf runs list [--status created|running|succeeded|failed] [--since <iso>] [--pipeline <id-or-path>] [--json]\n sf runs show --run <runId> [--from <sf-run.json>] [--json]\n sf runs verify --run <runId> --stage <stageId> [--json]\n sf runs recover --run <runId> --stage <stageId> [--guidance <text>] [--stop] [--json]\n sf runs waiting [--run <runId>] [--json]\n sf runs wait --run <runId> [--from <sf-run.json>] [--until any|waiting|terminal] [--timeout-ms <n>] [--json]\n sf runs answer --run <runId> --stage <stageId> [--answer '<json>'] [--json]\n sf runs feedback-decide --run <runId> --stage <sourceStageId> [--loop <loopId>] --decision extend|continue|abandon [--reason <text>] [--json]\n sf runs retry --run <runId> --stage <stageId> [--json]\n sf runs resume --run <runId> --stage <stageId> [--json]\n sf runs abandon --run <runId> --stage <stageId> [--json]\n sf runs rerun --run <runId> [--json]";
3
+ export declare const RUNS_USAGE = "Usage:\n sf runs list [--status created|queued|running|succeeded|failed|cancelled] [--since <iso>] [--pipeline <id-or-path>] [--json]\n sf runs show --run <runId> [--from <sf-run.json>] [--json]\n sf runs verify --run <runId> --stage <stageId> [--json]\n sf runs recover --run <runId> --stage <stageId> [--guidance <text>] [--stop] [--json]\n sf runs waiting [--run <runId>] [--json]\n sf runs wait --run <runId> [--from <sf-run.json>] [--until any|waiting|terminal] [--timeout-ms <n>] [--json]\n sf runs answer --run <runId> --stage <stageId> [--answer '<json>'] [--json]\n sf runs feedback-decide --run <runId> --stage <sourceStageId> [--loop <loopId>] --decision extend|continue|abandon [--reason <text>] [--json]\n sf runs retry --run <runId> --stage <stageId> [--json]\n sf runs resume --run <runId> --stage <stageId> [--json]\n sf runs abandon --run <runId> --stage <stageId> [--json]\n sf runs cancel --run <runId> --reason <text> [--json]\n sf runs delete --run <runId> [--force] [--json]\n sf runs gc [--dry-run] [--json]\n sf runs rerun --run <runId> [--pinned] [--json]";
4
4
  export type RunsCommandIo = {
5
5
  log: (line: string) => void;
6
6
  error: (line: string) => void;
@@ -4,16 +4,16 @@ import { projectRun } from "../projection/projectRun.js";
4
4
  import { waitRun } from "../mcp/waitRun.js";
5
5
  import { projectWaitingGates } from "../mcp/waitingGates.js";
6
6
  import { completeCliRun } from "./runCommand.js";
7
- import { reportCliRun } from "./runOutput.js";
7
+ import { reportCliRun, writeQueuedAdmissionLine } from "./runOutput.js";
8
8
  import { globalStageflowHome } from "../project/globalHome.js";
9
- import { createRunStore } from "../runstore/createStore.js";
9
+ import { createRunStore, storeNeedsHostMigration, } from "../runstore/createStore.js";
10
10
  import { readStageVerificationHistory } from "../runstore/verificationHistory.js";
11
11
  import { ensureGlobalService, hostBaseUrl, } from "../server/ensureGlobalService.js";
12
12
  import { mapRetryStageFailure } from "../server/operatorResults.js";
13
- import { httpAbandonStage, httpDecideFeedbackLoop, httpDeliverAnswer, httpRecoverManualStageUntilStop, httpRerun, httpResumeTimedOutStage, httpRetryStageUntilStop, httpStopManualRecovery, } from "./hostClient.js";
13
+ import { httpAbandonStage, httpCancelRun, httpDecideFeedbackLoop, httpDeleteRun, httpDeliverAnswer, httpGcRuns, httpRecoverManualStageUntilStop, httpRerun, httpResumeTimedOutStage, httpRetryStageUntilStop, httpStopManualRecovery, } from "./hostClient.js";
14
14
  import { AskOperatorError, parseAskOperatorAnswer, } from "../tools/askOperator.js";
15
15
  export const RUNS_USAGE = `Usage:
16
- sf runs list [--status created|running|succeeded|failed] [--since <iso>] [--pipeline <id-or-path>] [--json]
16
+ sf runs list [--status created|queued|running|succeeded|failed|cancelled] [--since <iso>] [--pipeline <id-or-path>] [--json]
17
17
  sf runs show --run <runId> [--from <sf-run.json>] [--json]
18
18
  sf runs verify --run <runId> --stage <stageId> [--json]
19
19
  sf runs recover --run <runId> --stage <stageId> [--guidance <text>] [--stop] [--json]
@@ -24,16 +24,21 @@ export const RUNS_USAGE = `Usage:
24
24
  sf runs retry --run <runId> --stage <stageId> [--json]
25
25
  sf runs resume --run <runId> --stage <stageId> [--json]
26
26
  sf runs abandon --run <runId> --stage <stageId> [--json]
27
- sf runs rerun --run <runId> [--json]`;
27
+ sf runs cancel --run <runId> --reason <text> [--json]
28
+ sf runs delete --run <runId> [--force] [--json]
29
+ sf runs gc [--dry-run] [--json]
30
+ sf runs rerun --run <runId> [--pinned] [--json]`;
28
31
  const defaultIo = {
29
32
  log: (line) => console.log(line),
30
33
  error: (line) => console.error(line),
31
34
  };
32
35
  const RUN_STATUSES = [
33
36
  "created",
37
+ "queued",
34
38
  "running",
35
39
  "succeeded",
36
40
  "failed",
41
+ "cancelled",
37
42
  ];
38
43
  const LIST_FLAGS = new Set([
39
44
  "--status",
@@ -85,7 +90,10 @@ const FEEDBACK_DECIDE_FLAGS = new Set([
85
90
  ]);
86
91
  const RETRY_FLAGS = new Set(["--run", "--stage", "--json", "--help", "-h"]);
87
92
  const ABANDON_FLAGS = new Set(["--run", "--stage", "--json", "--help", "-h"]);
88
- const RERUN_FLAGS = new Set(["--run", "--json", "--help", "-h"]);
93
+ const CANCEL_FLAGS = new Set(["--run", "--reason", "--json", "--help", "-h"]);
94
+ const DELETE_FLAGS = new Set(["--run", "--force", "--json", "--help", "-h"]);
95
+ const GC_FLAGS = new Set(["--dry-run", "--json", "--help", "-h"]);
96
+ const RERUN_FLAGS = new Set(["--run", "--pinned", "--json", "--help", "-h"]);
89
97
  const VALUE_FLAGS = new Set([
90
98
  "--status",
91
99
  "--since",
@@ -125,6 +133,12 @@ function flagsFor(subcommand) {
125
133
  return RETRY_FLAGS;
126
134
  case "abandon":
127
135
  return ABANDON_FLAGS;
136
+ case "cancel":
137
+ return CANCEL_FLAGS;
138
+ case "delete":
139
+ return DELETE_FLAGS;
140
+ case "gc":
141
+ return GC_FLAGS;
128
142
  case "rerun":
129
143
  return RERUN_FLAGS;
130
144
  default:
@@ -156,6 +170,9 @@ function parseRunsArgs(args) {
156
170
  let answer;
157
171
  let guidance;
158
172
  let stop = false;
173
+ let pinned = false;
174
+ let force = false;
175
+ let dryRun = false;
159
176
  let loopId;
160
177
  let decision;
161
178
  let reason;
@@ -172,6 +189,21 @@ function parseRunsArgs(args) {
172
189
  throw new Error(`Unknown flag: ${arg}`);
173
190
  stop = true;
174
191
  }
192
+ else if (arg === "--pinned") {
193
+ if (!allowed.has(arg))
194
+ throw new Error(`Unknown flag: ${arg}`);
195
+ pinned = true;
196
+ }
197
+ else if (arg === "--force") {
198
+ if (!allowed.has(arg))
199
+ throw new Error(`Unknown flag: ${arg}`);
200
+ force = true;
201
+ }
202
+ else if (arg === "--dry-run") {
203
+ if (!allowed.has(arg))
204
+ throw new Error(`Unknown flag: ${arg}`);
205
+ dryRun = true;
206
+ }
175
207
  else if (VALUE_FLAGS.has(arg)) {
176
208
  if (!allowed.has(arg)) {
177
209
  throw new Error(`Unknown flag: ${arg}`);
@@ -229,6 +261,9 @@ function parseRunsArgs(args) {
229
261
  answer,
230
262
  guidance,
231
263
  stop,
264
+ pinned,
265
+ force,
266
+ dryRun,
232
267
  loopId,
233
268
  decision,
234
269
  reason,
@@ -287,8 +322,18 @@ const MUTATING_SUBCOMMANDS = new Set([
287
322
  "resume",
288
323
  "recover",
289
324
  "abandon",
325
+ "cancel",
326
+ "delete",
327
+ "gc",
290
328
  "rerun",
291
329
  ]);
330
+ const READ_ONLY_SUBCOMMANDS = new Set([
331
+ "list",
332
+ "show",
333
+ "verify",
334
+ "waiting",
335
+ "wait",
336
+ ]);
292
337
  export async function runRunsCommand(args, options = {}) {
293
338
  const cwd = options.cwd ?? process.cwd();
294
339
  const out = { ...defaultIo, ...options.io };
@@ -331,6 +376,21 @@ export async function runRunsCommand(args, options = {}) {
331
376
  return 1;
332
377
  }
333
378
  }
379
+ if (READ_ONLY_SUBCOMMANDS.has(parsed.subcommand) &&
380
+ resolvedStore === undefined) {
381
+ if (storeNeedsHostMigration(globalStageflowHome())) {
382
+ const ensured = await ensureService();
383
+ if (!ensured.ok) {
384
+ if (parsed.json) {
385
+ printJson(out, { error: ensured.message, reason: ensured.reason });
386
+ }
387
+ else {
388
+ out.error(ensured.message);
389
+ }
390
+ return 1;
391
+ }
392
+ }
393
+ }
334
394
  switch (parsed.subcommand) {
335
395
  case "list": {
336
396
  if (parsed.status === "waiting") {
@@ -338,7 +398,7 @@ export async function runRunsCommand(args, options = {}) {
338
398
  return 1;
339
399
  }
340
400
  if (parsed.status !== undefined && !isRunStatus(parsed.status)) {
341
- out.error("--status must be created, running, succeeded, or failed");
401
+ out.error("--status must be created, queued, running, succeeded, failed, or cancelled");
342
402
  return 1;
343
403
  }
344
404
  if (parsed.since !== undefined && !Number.isFinite(Date.parse(parsed.since))) {
@@ -730,14 +790,108 @@ export async function runRunsCommand(args, options = {}) {
730
790
  }
731
791
  return 0;
732
792
  }
793
+ case "cancel": {
794
+ if (!parsed.runId || !parsed.reason) {
795
+ return usageError(out, "Missing --run and/or --reason");
796
+ }
797
+ const result = await httpCancelRun(base, parsed.runId, parsed.reason);
798
+ if (!result.ok) {
799
+ const payload = { error: result.reason };
800
+ if (result.status !== undefined)
801
+ payload.status = result.status;
802
+ if (parsed.json) {
803
+ printJson(out, payload);
804
+ }
805
+ else {
806
+ out.error(result.reason);
807
+ }
808
+ return 1;
809
+ }
810
+ if (parsed.json) {
811
+ printJson(out, {
812
+ ok: true,
813
+ runId: result.runId,
814
+ });
815
+ }
816
+ else {
817
+ out.log(result.runId);
818
+ }
819
+ return 0;
820
+ }
821
+ case "delete": {
822
+ if (!parsed.runId) {
823
+ return usageError(out, "Missing --run");
824
+ }
825
+ const result = await httpDeleteRun(base, parsed.runId, {
826
+ force: parsed.force === true,
827
+ });
828
+ if (!result.ok) {
829
+ const payload = { error: result.reason };
830
+ if (result.status !== undefined)
831
+ payload.status = result.status;
832
+ if (parsed.json) {
833
+ printJson(out, payload);
834
+ }
835
+ else {
836
+ out.error(result.reason);
837
+ }
838
+ return 1;
839
+ }
840
+ if (parsed.json) {
841
+ printJson(out, {
842
+ ok: true,
843
+ runId: result.runId,
844
+ });
845
+ }
846
+ else {
847
+ out.log(result.runId);
848
+ }
849
+ return 0;
850
+ }
851
+ case "gc": {
852
+ const execute = parsed.dryRun !== true;
853
+ const result = await httpGcRuns(base, { execute });
854
+ if (!result.ok) {
855
+ const payload = { error: result.reason };
856
+ if (result.status !== undefined)
857
+ payload.status = result.status;
858
+ if (parsed.json) {
859
+ printJson(out, payload);
860
+ }
861
+ else {
862
+ out.error(result.reason);
863
+ }
864
+ return 1;
865
+ }
866
+ const report = {
867
+ slimmed: result.slimmed,
868
+ purged: result.purged,
869
+ bareCachesEvicted: result.bareCachesEvicted,
870
+ };
871
+ if (parsed.json) {
872
+ printJson(out, report);
873
+ }
874
+ else {
875
+ out.log([
876
+ `slimmed:\t${report.slimmed.length}`,
877
+ ...report.slimmed.map((id) => `\t${id}`),
878
+ `purged:\t${report.purged.length}`,
879
+ ...report.purged.map((id) => `\t${id}`),
880
+ `bareCachesEvicted:\t${report.bareCachesEvicted.length}`,
881
+ ...report.bareCachesEvicted.map((id) => `\t${id}`),
882
+ ].join("\n"));
883
+ }
884
+ return 0;
885
+ }
733
886
  case "rerun": {
734
887
  if (!parsed.runId) {
735
888
  return usageError(out, "Missing --run");
736
889
  }
737
- const started = await httpRerun(base, parsed.runId);
890
+ const started = await httpRerun(base, parsed.runId, parsed.pinned ? { pinned: true } : undefined);
738
891
  if (!started.ok) {
739
892
  return reportCliRun({ kind: "start-failure", started }, { json: parsed.json, io: mutatingIo });
740
893
  }
894
+ writeQueuedAdmissionLine(started, mutatingIo);
741
895
  return completeCliRun(started, mutatingIo, {
742
896
  json: parsed.json,
743
897
  store: getStore(),