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.
- package/README.md +10 -3
- package/dist/a2a/contracts.d.ts +1 -0
- package/dist/a2a/contracts.js +1 -0
- package/dist/a2a/registry.d.ts +2 -0
- package/dist/a2a/registry.js +20 -1
- package/dist/a2a/server.d.ts +7 -0
- package/dist/a2a/server.js +5 -2
- package/dist/a2a/service.d.ts +1 -1
- package/dist/a2a/service.js +57 -8
- package/dist/a2a/store.d.ts +8 -5
- package/dist/a2a/store.js +24 -67
- package/dist/agent/activity.d.ts +3 -0
- package/dist/agent/bootProviderConfig.d.ts +21 -0
- package/dist/agent/bootProviderConfig.js +74 -0
- package/dist/agent/piAdapter.d.ts +9 -1
- package/dist/agent/piAdapter.js +58 -3
- package/dist/agent/piIsolatedMcp.d.ts +2 -0
- package/dist/agent/piIsolatedMcp.js +10 -2
- package/dist/agent/port.d.ts +6 -0
- package/dist/agent/streamLogRedact.d.ts +1 -1
- package/dist/agent/streamLogRedact.js +4 -11
- package/dist/cli/artifactCommand.js +9 -16
- package/dist/cli/backupCommand.d.ts +9 -0
- package/dist/cli/backupCommand.js +111 -0
- package/dist/cli/debugRunCommand.d.ts +10 -0
- package/dist/cli/debugRunCommand.js +109 -0
- package/dist/cli/doctorCommand.d.ts +32 -0
- package/dist/cli/doctorCommand.js +453 -0
- package/dist/cli/envelopeCommand.js +9 -2
- package/dist/cli/exportAllCommand.d.ts +55 -0
- package/dist/cli/exportAllCommand.js +218 -0
- package/dist/cli/exportRunCommand.js +23 -21
- package/dist/cli/hostClient.d.ts +21 -3
- package/dist/cli/hostClient.js +93 -12
- package/dist/cli/initTemplates.d.ts +1 -1
- package/dist/cli/initTemplates.js +8 -1
- package/dist/cli/resolveSafeOutPath.d.ts +2 -0
- package/dist/cli/resolveSafeOutPath.js +40 -0
- package/dist/cli/restoreCommand.d.ts +10 -0
- package/dist/cli/restoreCommand.js +90 -0
- package/dist/cli/runCommand.d.ts +3 -2
- package/dist/cli/runCommand.js +93 -11
- package/dist/cli/runOutput.d.ts +4 -0
- package/dist/cli/runOutput.js +33 -7
- package/dist/cli/runStageCommand.d.ts +1 -0
- package/dist/cli/runStageCommand.js +44 -25
- package/dist/cli/runsCommand.d.ts +1 -1
- package/dist/cli/runsCommand.js +162 -8
- package/dist/cli.js +171 -30
- package/dist/config/catalogRelativePath.d.ts +62 -0
- package/dist/config/catalogRelativePath.js +118 -0
- package/dist/config/configOrigin.d.ts +27 -0
- package/dist/config/configOrigin.js +59 -0
- package/dist/config/hostConfig.d.ts +55 -0
- package/dist/config/hostConfig.js +333 -0
- package/dist/config/listSkills.d.ts +26 -0
- package/dist/config/listSkills.js +190 -3
- package/dist/config/loadOutcome.d.ts +1 -1
- package/dist/config/loadPipeline.js +23 -2
- package/dist/config/loadStage.js +18 -0
- package/dist/config/loadTask.d.ts +2 -0
- package/dist/config/loadTask.js +57 -18
- package/dist/config/materializeStageModels.js +5 -1
- package/dist/config/mergePipelineIncludes.d.ts +3 -0
- package/dist/config/mergePipelineIncludes.js +19 -0
- package/dist/config/migrateYaml.js +6 -11
- package/dist/config/multiProjectCatalog.d.ts +30 -0
- package/dist/config/multiProjectCatalog.js +142 -0
- package/dist/config/normalizePipelineStageEntry.js +20 -1
- package/dist/config/pipelineStageKeys.js +2 -0
- package/dist/config/resolveCatalogRoots.d.ts +27 -0
- package/dist/config/resolveCatalogRoots.js +76 -0
- package/dist/config/resolveModel.d.ts +7 -1
- package/dist/config/resolveModel.js +11 -1
- package/dist/config/resolveStageMcpServers.d.ts +9 -1
- package/dist/config/resolveStageMcpServers.js +36 -9
- package/dist/config/secretFromEnvOrFile.d.ts +9 -0
- package/dist/config/secretFromEnvOrFile.js +34 -0
- package/dist/config/seededCatalog.d.ts +11 -0
- package/dist/config/seededCatalog.js +29 -0
- package/dist/config/toolRequires.d.ts +24 -0
- package/dist/config/toolRequires.js +115 -0
- package/dist/config/validateCatalog.d.ts +5 -1
- package/dist/config/validateCatalog.js +140 -1
- package/dist/diagnostics/checks.d.ts +39 -0
- package/dist/diagnostics/checks.js +135 -0
- package/dist/errors/codes.d.ts +14 -0
- package/dist/errors/codes.js +59 -0
- package/dist/git/cache.d.ts +14 -0
- package/dist/git/cache.js +150 -0
- package/dist/git/credentials.d.ts +9 -0
- package/dist/git/credentials.js +88 -0
- package/dist/git/errors.d.ts +20 -0
- package/dist/git/errors.js +94 -0
- package/dist/git/exec.d.ts +16 -0
- package/dist/git/exec.js +135 -0
- package/dist/git/operations.d.ts +29 -0
- package/dist/git/operations.js +153 -0
- package/dist/git/version.d.ts +1 -0
- package/dist/git/version.js +10 -0
- package/dist/logging/audit.d.ts +16 -0
- package/dist/logging/audit.js +19 -0
- package/dist/logging/commonWords.d.ts +2 -0
- package/dist/logging/commonWords.js +13 -0
- package/dist/logging/logger.d.ts +49 -0
- package/dist/logging/logger.js +193 -0
- package/dist/logging/namedSecrets.d.ts +6 -0
- package/dist/logging/namedSecrets.js +58 -0
- package/dist/logging/redact.d.ts +13 -0
- package/dist/logging/redact.js +88 -0
- package/dist/mcp/catalogTools.js +456 -80
- package/dist/mcp/checkoutTools.d.ts +52 -0
- package/dist/mcp/checkoutTools.js +332 -0
- package/dist/mcp/controlTools.js +179 -5
- package/dist/mcp/deps.d.ts +1 -0
- package/dist/mcp/getStartedTool.d.ts +3 -0
- package/dist/mcp/getStartedTool.js +62 -0
- package/dist/mcp/readArtifact.d.ts +11 -0
- package/dist/mcp/readArtifact.js +46 -30
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.js +4 -0
- package/dist/net/proxy.d.ts +14 -0
- package/dist/net/proxy.js +78 -0
- package/dist/package-meta.d.ts +2 -1
- package/dist/package-meta.js +2 -1
- package/dist/preflight/bash.d.ts +8 -0
- package/dist/preflight/bash.js +34 -0
- package/dist/preflight/claudeRoot.d.ts +11 -0
- package/dist/preflight/claudeRoot.js +23 -0
- package/dist/preflight/mcpCommands.d.ts +8 -0
- package/dist/preflight/mcpCommands.js +36 -0
- package/dist/preflight/pipelinePreflight.d.ts +40 -0
- package/dist/preflight/pipelinePreflight.js +192 -0
- package/dist/preflight/tls.d.ts +6 -0
- package/dist/preflight/tls.js +18 -0
- package/dist/preflight/toolchain.d.ts +45 -0
- package/dist/preflight/toolchain.js +219 -0
- package/dist/project/findProjectRoot.js +3 -4
- package/dist/project/globalHome.d.ts +7 -0
- package/dist/project/globalHome.js +63 -2
- package/dist/project/resolveProjectContext.js +2 -2
- package/dist/project/resolveStageflowContext.js +2 -2
- package/dist/projection/projectRun.d.ts +2 -1
- package/dist/projection/projectRun.js +1 -0
- package/dist/runstore/assertTmpdir.d.ts +1 -0
- package/dist/runstore/assertTmpdir.js +21 -0
- package/dist/runstore/backup.d.ts +52 -0
- package/dist/runstore/backup.js +292 -0
- package/dist/runstore/createStore.d.ts +18 -1
- package/dist/runstore/createStore.js +64 -5
- package/dist/runstore/debugBundle.d.ts +60 -0
- package/dist/runstore/debugBundle.js +143 -0
- package/dist/runstore/diskUsage.d.ts +50 -0
- package/dist/runstore/diskUsage.js +214 -0
- package/dist/runstore/exportRunPayload.d.ts +8 -0
- package/dist/runstore/exportRunPayload.js +23 -0
- package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
- package/dist/runstore/normalizeCatalogPath.js +10 -0
- package/dist/runstore/paths.d.ts +5 -0
- package/dist/runstore/paths.js +145 -1
- package/dist/runstore/port.d.ts +111 -13
- package/dist/runstore/port.js +8 -1
- package/dist/runstore/restore.d.ts +81 -0
- package/dist/runstore/restore.js +355 -0
- package/dist/runstore/retention.d.ts +27 -0
- package/dist/runstore/retention.js +74 -0
- package/dist/runstore/runManifest.d.ts +146 -0
- package/dist/runstore/runManifest.js +288 -0
- package/dist/runstore/runProjection.d.ts +3 -1
- package/dist/runstore/runProjection.js +63 -1
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +28 -3
- package/dist/runstore/sqlite/SqliteRunStore.js +352 -219
- package/dist/runstore/sqlite/applyStorePragmas.d.ts +39 -0
- package/dist/runstore/sqlite/applyStorePragmas.js +145 -0
- package/dist/runstore/sqlite/migrations/001-baseline.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/001-baseline.js +10 -0
- package/dist/runstore/sqlite/migrations/002-repository-binding.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/002-repository-binding.js +29 -0
- package/dist/runstore/sqlite/migrations/003-run-lifecycle.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/003-run-lifecycle.js +28 -0
- package/dist/runstore/sqlite/migrations/004-auto-resume-count.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/004-auto-resume-count.js +19 -0
- package/dist/runstore/sqlite/migrations/005-config-origins.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/005-config-origins.js +19 -0
- package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.js +28 -0
- package/dist/runstore/sqlite/migrations/007-projects-registry.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/007-projects-registry.js +31 -0
- package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
- package/dist/runstore/sqlite/migrations/index.js +72 -0
- package/dist/runstore/sqlite/schema.d.ts +20 -1
- package/dist/runstore/sqlite/schema.js +277 -1
- package/dist/runstore/sqlite/storeOpenError.d.ts +6 -0
- package/dist/runstore/sqlite/storeOpenError.js +11 -0
- package/dist/runstore/sqlite/storeSchemaError.d.ts +5 -0
- package/dist/runstore/sqlite/storeSchemaError.js +8 -0
- package/dist/runstore/stageExecution.js +3 -0
- package/dist/runstore/storeFilesystem.d.ts +32 -0
- package/dist/runstore/storeFilesystem.js +148 -0
- package/dist/runstore/trackProjection.js +2 -0
- package/dist/runstore/workspaceLayout.d.ts +13 -0
- package/dist/runstore/workspaceLayout.js +76 -0
- package/dist/runtime/completionCheckRunner.d.ts +3 -0
- package/dist/runtime/completionCheckRunner.js +45 -7
- package/dist/runtime/containerLimits.d.ts +16 -0
- package/dist/runtime/containerLimits.js +84 -0
- package/dist/runtime/credentialMaterialisation.d.ts +28 -0
- package/dist/runtime/credentialMaterialisation.js +128 -0
- package/dist/runtime/gitCheckoutCapability.js +7 -13
- package/dist/runtime/pipelineRunner.d.ts +36 -1
- package/dist/runtime/pipelineRunner.js +178 -17
- package/dist/runtime/pipelineScheduler.d.ts +15 -0
- package/dist/runtime/pipelineScheduler.js +135 -27
- package/dist/runtime/reloadRunCatalog.js +6 -1
- package/dist/runtime/repositoryMaterialize.d.ts +47 -0
- package/dist/runtime/repositoryMaterialize.js +235 -0
- package/dist/runtime/resumeTimedOut.d.ts +1 -1
- package/dist/runtime/resumeTimedOut.js +5 -2
- package/dist/runtime/runChangeBus.js +9 -0
- package/dist/runtime/runDeletion.d.ts +7 -0
- package/dist/runtime/runDeletion.js +37 -0
- package/dist/runtime/runManager.d.ts +158 -4
- package/dist/runtime/runManager.js +1596 -79
- package/dist/runtime/runRetentionSweep.d.ts +31 -0
- package/dist/runtime/runRetentionSweep.js +328 -0
- package/dist/runtime/runRetryCoordinator.d.ts +2 -0
- package/dist/runtime/runRetryCoordinator.js +19 -2
- package/dist/runtime/runSkills.d.ts +40 -0
- package/dist/runtime/runSkills.js +173 -0
- package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
- package/dist/runtime/stageAttemptBootstrap.js +195 -24
- package/dist/runtime/stageCacheEnv.d.ts +6 -0
- package/dist/runtime/stageCacheEnv.js +34 -0
- package/dist/runtime/stageConcurrency.d.ts +2 -1
- package/dist/runtime/stageConcurrency.js +4 -2
- package/dist/runtime/stageEnvironment.d.ts +38 -0
- package/dist/runtime/stageEnvironment.js +193 -0
- package/dist/runtime/stageProcessLauncher.d.ts +18 -0
- package/dist/runtime/stageProcessLauncher.js +194 -38
- package/dist/runtime/stageRecovery.d.ts +3 -1
- package/dist/runtime/stageRecovery.js +19 -4
- package/dist/runtime/stageRoots.d.ts +38 -1
- package/dist/runtime/stageRoots.js +118 -0
- package/dist/runtime/stageRunner.d.ts +1 -0
- package/dist/runtime/stageRunner.js +3 -1
- package/dist/runtime/stageSecretDecl.d.ts +9 -0
- package/dist/runtime/stageSecretDecl.js +102 -0
- package/dist/runtime/stageSecrets.d.ts +40 -0
- package/dist/runtime/stageSecrets.js +181 -0
- package/dist/runtime/stageWorker.d.ts +3 -2
- package/dist/runtime/stageWorker.js +58 -10
- package/dist/runtime/stageWorkerProtocol.d.ts +5 -0
- package/dist/runtime/stageWorkerProtocol.js +8 -0
- package/dist/runtime/startPayload.d.ts +32 -0
- package/dist/runtime/startPayload.js +59 -0
- package/dist/runtime/taskInput.js +14 -5
- package/dist/runtime/verifiedStageExecution.d.ts +1 -0
- package/dist/runtime/verifiedStageExecution.js +2 -1
- package/dist/runtime/workspaceBinding.d.ts +20 -0
- package/dist/runtime/workspaceBinding.js +60 -0
- package/dist/server/allowedHosts.d.ts +19 -0
- package/dist/server/allowedHosts.js +179 -0
- package/dist/server/bootstrap.d.ts +36 -2
- package/dist/server/bootstrap.js +209 -5
- package/dist/server/controlToken.d.ts +47 -0
- package/dist/server/controlToken.js +241 -0
- package/dist/server/createHttpHost.d.ts +11 -2
- package/dist/server/createHttpHost.js +103 -10
- package/dist/server/ensureGlobalService.d.ts +5 -1
- package/dist/server/ensureGlobalService.js +35 -1
- package/dist/server/healthSurfaces.d.ts +6 -0
- package/dist/server/healthSurfaces.js +98 -0
- package/dist/server/http.d.ts +12 -1
- package/dist/server/http.js +1085 -485
- package/dist/server/listenHost.d.ts +5 -0
- package/dist/server/listenHost.js +56 -0
- package/dist/server/mcpHost.d.ts +10 -1
- package/dist/server/mcpHost.js +36 -6
- package/dist/server/operatorResults.d.ts +2 -2
- package/dist/server/operatorResults.js +40 -29
- package/dist/server/requestAuthContext.d.ts +12 -0
- package/dist/server/requestAuthContext.js +21 -0
- package/dist/server/shutdown.d.ts +69 -0
- package/dist/server/shutdown.js +219 -0
- package/dist/types/pipeline.d.ts +7 -0
- package/dist/types/stage.d.ts +8 -0
- package/dist/types/task.d.ts +8 -0
- package/dist/ui/assets/index-B6hlSXXn.js +120 -0
- package/dist/ui/index.html +1 -1
- package/examples/README.md +98 -0
- package/examples/archify-on-pr/README.md +213 -0
- package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +19 -0
- package/examples/archify-on-pr/archify-on-pr.task.yaml +19 -0
- package/examples/archify-on-pr/author-diagrams.yaml +106 -0
- package/examples/archify-on-pr/detect-changes.yaml +89 -0
- package/examples/ci-validate/README.md +35 -0
- package/examples/ci-validate/check.yaml +13 -0
- package/examples/ci-validate/ci-demo.pipeline.yaml +4 -0
- package/examples/ci-validate/validate.sh +5 -0
- package/examples/compliance-review-demo/README.md +125 -0
- package/examples/compliance-review-demo/compliance-review-demo.pipeline.yaml +29 -0
- package/examples/compliance-review-demo/connect-account.yaml +47 -0
- package/examples/compliance-review-demo/map-to-control.yaml +123 -0
- package/examples/compliance-review-demo/poll-bucket-config.yaml +103 -0
- package/examples/compliance-review-demo/publish-report.yaml +79 -0
- package/examples/compliance-review-demo/review-verdict.yaml +122 -0
- package/examples/compliance-review-demo/run-compliance-check.yaml +96 -0
- package/examples/compliance-review-demo/store-evidence.yaml +143 -0
- package/examples/conditional-fork/README.md +89 -0
- package/examples/conditional-fork/branch-a.yaml +13 -0
- package/examples/conditional-fork/branch-b.yaml +13 -0
- package/examples/conditional-fork/decide.yaml +35 -0
- package/examples/conditional-fork/fork-demo.pipeline.yaml +20 -0
- package/examples/conditional-fork/fork-demo.task.yaml +8 -0
- package/examples/context7-mcp/README.md +42 -0
- package/examples/context7-mcp/context7-mcp.pipeline.yaml +15 -0
- package/examples/context7-mcp/context7-mcp.task.yaml +4 -0
- package/examples/context7-mcp/fetch-docs.yaml +52 -0
- package/examples/context7-mcp/resolve-library.yaml +31 -0
- package/examples/context7-mcp/write-brief.yaml +52 -0
- package/examples/feature-loop/README.md +104 -0
- package/examples/feature-loop/address-feedback.yaml +148 -0
- package/examples/feature-loop/align.yaml +116 -0
- package/examples/feature-loop/decompose.yaml +86 -0
- package/examples/feature-loop/default-model-hierarchy.task.yaml +58 -0
- package/examples/feature-loop/feature-loop.pipeline.yaml +140 -0
- package/examples/feature-loop/feature-loop.task.yaml +25 -0
- package/examples/feature-loop/implement.yaml +128 -0
- package/examples/feature-loop/plan.yaml +111 -0
- package/examples/feature-loop/publish.yaml +167 -0
- package/examples/feature-loop/review.yaml +146 -0
- package/examples/feature-loop/verify.yaml +106 -0
- package/examples/feedback-loop/README.md +72 -0
- package/examples/feedback-loop/VERIFY.md +208 -0
- package/examples/feedback-loop/continue-only.task.yaml +4 -0
- package/examples/feedback-loop/exhaust-require-continue.task.yaml +6 -0
- package/examples/feedback-loop/exhaust-wait-human.task.yaml +11 -0
- package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +23 -0
- package/examples/feedback-loop/feedback-loop.pipeline.yaml +23 -0
- package/examples/feedback-loop/feedback-loop.task.yaml +4 -0
- package/examples/feedback-loop/implement.yaml +14 -0
- package/examples/feedback-loop/plan.yaml +14 -0
- package/examples/feedback-loop/review.yaml +15 -0
- package/examples/feedback-loop/send-back-once.task.yaml +6 -0
- package/examples/feedback-loop/submit.yaml +12 -0
- package/examples/generic-fan-in/README.md +151 -0
- package/examples/generic-fan-in/clarify.yaml +18 -0
- package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +19 -0
- package/examples/generic-fan-in/generic-fan-in-accepted.task.yaml +8 -0
- package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +18 -0
- package/examples/generic-fan-in/generic-fan-in.task.yaml +9 -0
- package/examples/generic-fan-in/research.yaml +45 -0
- package/examples/generic-fan-in/synthesize.yaml +66 -0
- package/examples/generic-fan-in/validation.yaml +45 -0
- package/examples/github-release/README.md +78 -0
- package/examples/github-release/draft-release-notes.yaml +64 -0
- package/examples/github-release/github-release.pipeline.yaml +11 -0
- package/examples/github-release/github-release.task.yaml +13 -0
- package/examples/github-release/publish-github-release.yaml +64 -0
- package/examples/hello-world/README.md +28 -0
- package/examples/hello-world/hello.pipeline.yaml +4 -0
- package/examples/hello-world/my-task.task.yaml +6 -0
- package/examples/hello-world/research.yaml +18 -0
- package/examples/mcp-hitl-tour/README.md +113 -0
- package/examples/mcp-hitl-tour/draft-angle.yaml +33 -0
- package/examples/mcp-hitl-tour/draft-short.yaml +32 -0
- package/examples/mcp-hitl-tour/emit-angles.yaml +45 -0
- package/examples/mcp-hitl-tour/gather.yaml +31 -0
- package/examples/mcp-hitl-tour/intake.yaml +62 -0
- package/examples/mcp-hitl-tour/mcp-hitl-tour-exhaust.task.yaml +13 -0
- package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +54 -0
- package/examples/mcp-hitl-tour/mcp-hitl-tour.task.yaml +16 -0
- package/examples/mcp-hitl-tour/polish.yaml +33 -0
- package/examples/mcp-hitl-tour/review.yaml +17 -0
- package/examples/mcp-hitl-tour/ship.yaml +25 -0
- package/examples/oss-issue-contribution/README.md +218 -0
- package/examples/oss-issue-contribution/oss-address-review-feedback.yaml +117 -0
- package/examples/oss-issue-contribution/oss-approve-contribution.yaml +181 -0
- package/examples/oss-issue-contribution/oss-approve-plan.yaml +111 -0
- package/examples/oss-issue-contribution/oss-explain-fix.yaml +108 -0
- package/examples/oss-issue-contribution/oss-explain-issue.yaml +114 -0
- package/examples/oss-issue-contribution/oss-implement-source-fix.yaml +171 -0
- package/examples/oss-issue-contribution/oss-investigate-area.yaml +116 -0
- package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +125 -0
- package/examples/oss-issue-contribution/oss-issue-intake.yaml +106 -0
- package/examples/oss-issue-contribution/oss-plan-investigation.yaml +112 -0
- package/examples/oss-issue-contribution/oss-plan-review.yaml +109 -0
- package/examples/oss-issue-contribution/oss-reproduce-issue.yaml +140 -0
- package/examples/oss-issue-contribution/oss-review-change.yaml +107 -0
- package/examples/oss-issue-contribution/oss-verify-fix.yaml +130 -0
- package/examples/oss-issue-contribution/oss-write-regression-test.yaml +135 -0
- package/examples/oss-issue-contribution/pi-7629.task.yaml +79 -0
- package/examples/oss-issue-contribution/pi-8919.task.yaml +75 -0
- package/examples/oss-issue-contribution/pydantic-ai-7971.task.yaml +53 -0
- package/examples/oss-quick-fix/README.md +65 -0
- package/examples/oss-quick-fix/implement-fix.yaml +84 -0
- package/examples/oss-quick-fix/oss-quick-fix.pipeline.yaml +35 -0
- package/examples/oss-quick-fix/oss-quick-fix.task.yaml +19 -0
- package/examples/oss-quick-fix/ship-fix.yaml +81 -0
- package/examples/oss-quick-fix/understand-issue.yaml +67 -0
- package/examples/oss-quick-fix/verify-fix.yaml +73 -0
- package/examples/plan-review/README.md +37 -0
- package/examples/plan-review/plan-review-followup.yaml +13 -0
- package/examples/plan-review/plan-review.pipeline.yaml +9 -0
- package/examples/plan-review/plan-review.task.yaml +9 -0
- package/examples/plan-review/plan-review.yaml +25 -0
- package/examples/playwright-mcp/README.md +39 -0
- package/examples/playwright-mcp/playwright-mcp.pipeline.yaml +5 -0
- package/examples/playwright-mcp/playwright-mcp.task.yaml +4 -0
- package/examples/playwright-mcp/screenshot.yaml +40 -0
- package/examples/retry-tour/README.md +75 -0
- package/examples/retry-tour/retry-tour.pipeline.yaml +122 -0
- package/examples/retry-tour/retry-tour.task.yaml +9 -0
- package/examples/route-if-tour/README.md +202 -0
- package/examples/route-if-tour/route-if-tour.pipeline.yaml +950 -0
- package/examples/route-if-tour/route-if-tour.task.yaml +4 -0
- package/examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml +168 -0
- package/examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml +44 -0
- package/examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml +28 -0
- package/examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml +27 -0
- package/examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml +110 -0
- package/examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml +82 -0
- package/examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml +82 -0
- package/examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml +77 -0
- package/examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml +102 -0
- package/examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml +23 -0
- package/examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml +37 -0
- package/examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml +138 -0
- package/examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml +84 -0
- package/examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml +50 -0
- package/examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml +37 -0
- package/examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml +65 -0
- package/examples/route-wiring-smoke-test/17-if-join.pipeline.yaml +80 -0
- package/examples/route-wiring-smoke-test/README.md +377 -0
- package/examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml +26 -0
- package/examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml +25 -0
- package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml +30 -0
- package/examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml +24 -0
- package/examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml +35 -0
- package/examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml +37 -0
- package/examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml +27 -0
- package/examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml +42 -0
- package/examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml +26 -0
- package/examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml +55 -0
- package/examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml +51 -0
- package/examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml +35 -0
- package/examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml +15 -0
- package/examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml +15 -0
- package/examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml +33 -0
- package/examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml +51 -0
- package/examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml +55 -0
- package/examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml +36 -0
- package/examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml +42 -0
- package/examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml +33 -0
- package/examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml +32 -0
- package/examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml +31 -0
- package/examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml +33 -0
- package/examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml +36 -0
- package/examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml +63 -0
- package/examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml +46 -0
- package/examples/route-wiring-smoke-test/smoke-test.task.yaml +4 -0
- package/examples/route-wiring-smoke-test/stages/branch-a.yaml +12 -0
- package/examples/route-wiring-smoke-test/stages/branch-b.yaml +12 -0
- package/examples/route-wiring-smoke-test/stages/decide.yaml +12 -0
- package/examples/route-wiring-smoke-test/stages/finish.yaml +12 -0
- package/examples/ship-feature/README.md +190 -0
- package/examples/ship-feature/feat-address-feedback.yaml +119 -0
- package/examples/ship-feature/feat-implement.yaml +180 -0
- package/examples/ship-feature/feat-plan.yaml +120 -0
- package/examples/ship-feature/feat-review.yaml +109 -0
- package/examples/ship-feature/feat-ship.yaml +203 -0
- package/examples/ship-feature/ship-feature.pipeline.yaml +44 -0
- package/examples/ship-feature/ship-feature.task.yaml +78 -0
- package/examples/stage-mcp/README.md +144 -0
- package/examples/stage-mcp/echo-mcp.mjs +20 -0
- package/examples/stage-mcp/stage-mcp-dead.pipeline.yaml +5 -0
- package/examples/stage-mcp/stage-mcp-dead.task.yaml +3 -0
- package/examples/stage-mcp/stage-mcp-missing-var.pipeline.yaml +5 -0
- package/examples/stage-mcp/stage-mcp-missing-var.task.yaml +3 -0
- package/examples/stage-mcp/stage-mcp.pipeline.yaml +5 -0
- package/examples/stage-mcp/stage-mcp.task.yaml +4 -0
- package/examples/stage-mcp/use-echo.yaml +20 -0
- package/examples/verify-tour/README.md +80 -0
- package/examples/verify-tour/verify-tour.pipeline.yaml +162 -0
- package/examples/verify-tour/verify-tour.task.yaml +11 -0
- package/package.json +5 -1
- package/skills/stageflow/SKILL.md +6 -6
- package/skills/stageflow/references/control-surface.md +11 -5
- package/skills/stageflow/scripts/detect-host.mjs +14 -1
- package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
- package/skills/stageflow-author/SKILL.md +4 -3
- package/skills/stageflow-author/references/catalog-mapping.md +16 -0
- package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
- package/skills/stageflow-run/SKILL.md +20 -12
- package/skills/stageflow-run/references/mcp-call.md +9 -1
- package/skills/stageflow-run/references/task-and-pipeline-selection.md +16 -5
- package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
- package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
- package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
- package/skills/stageflow-setup/SKILL.md +40 -8
- package/dist/ui/assets/index-Da5EHU6M.js +0 -119
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Verify tour
|
|
2
|
+
|
|
3
|
+
One short spine that walks every **verify check type** in a single successful run. Each stage does one type. Prompts spell the tool calls so the checks we claim actually pass.
|
|
4
|
+
|
|
5
|
+
This catalog is a **deep spine**: ungated `to:` is the next stop. Open the stage in the operator console and inspect that attempt’s verify evidence.
|
|
6
|
+
|
|
7
|
+
Illegal catalogs (emit-only `command`, artifact without `when`, `if` on a loop, …) cannot live here — validate would reject the whole pipeline.
|
|
8
|
+
|
|
9
|
+
## Run
|
|
10
|
+
|
|
11
|
+
From the repo git root, after `sf ui` is up, pick pipeline `verify-tour` and task `verify-tour`.
|
|
12
|
+
|
|
13
|
+
The task binds `checkout: .` (this git tree, resolved from the factory cwd). `checkout-check` writes `verify-tour-marker.txt` at that checkout root. Delete the file when you are done; do not commit it.
|
|
14
|
+
|
|
15
|
+
Or:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx tsx src/cli.ts validate --pipeline examples/verify-tour/verify-tour.pipeline.yaml
|
|
19
|
+
npx tsx src/cli.ts run \
|
|
20
|
+
--pipeline examples/verify-tour/verify-tour.pipeline.yaml \
|
|
21
|
+
--task examples/verify-tour/verify-tour.task.yaml
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Validate should succeed (`ok: true`). You may see `pipeline.model_applies` because `model` is set on the pipeline, not on each stage.
|
|
25
|
+
|
|
26
|
+
The run should **succeed**. Every stage should **succeed**. `gate-check` pauses for a **confirm** accept in the operator console (or `--skip-gates` on the CLI).
|
|
27
|
+
|
|
28
|
+
## Walk (follow-along order)
|
|
29
|
+
|
|
30
|
+
| Level | Stage | Verify type | What the agent does | What Stageflow checks |
|
|
31
|
+
|-------|-------|-------------|---------------------|------------------------|
|
|
32
|
+
| 1 | `kickoff` | none | Emit empty success | — |
|
|
33
|
+
| 2 | `artifact-check` | `artifact` emit + after | `write_stage_artifact` `note.md`, list it on emit | Basename on `artifacts`; file exists nonempty under the attempt artifacts dir |
|
|
34
|
+
| 3 | `command-check` | `command` after | Emit empty success | Stageflow runs `echo verify-tour-ok` (exit 0) |
|
|
35
|
+
| 4 | `checklist-check` | `checklist` after | Emit `checklist_attestations` for `self-review` | Items match the declared list exactly |
|
|
36
|
+
| 5 | `payload-check` | `payload_schema` after | Emit `{"ok": true}` | Re-check captured payload against `io.output.schema` |
|
|
37
|
+
| 6 | `gate-check` | `gate` confirm emit + after | `ask_operator` confirm, then emit | Last confirm this attempt is accept |
|
|
38
|
+
| 7 | `checkout-check` | `checkout_changes` after | Write `verify-tour-marker.txt` in the checkout | Diff vs pre-attempt snapshot; `changed_files` matches exactly |
|
|
39
|
+
|
|
40
|
+
## Scenario table
|
|
41
|
+
|
|
42
|
+
| Scenario | How this pipeline covers it | Evidence |
|
|
43
|
+
|----------|------------------------------|----------|
|
|
44
|
+
| `type: artifact` emit | `note-declared` `when: [emit]` | Emit lists `note.md` (basename / suffix match, no disk I/O) |
|
|
45
|
+
| `type: artifact` after | `note-on-disk` `when: [after]` `nonempty: true` | File on disk under attempt artifacts |
|
|
46
|
+
| `type: command` | `echo-ok` `run: echo verify-tour-ok` | After-phase exit 0; stdout in verify evidence |
|
|
47
|
+
| `type: checklist` | `self-review` two items | Envelope `checklist_attestations` match |
|
|
48
|
+
| `type: payload_schema` | `payload-ok` after `{"ok": true}` | After-phase re-check of `io.output.schema` |
|
|
49
|
+
| `type: gate` emit | `operator-ok` `kind: confirm` `when` includes `emit` | Soft reject until confirm accept |
|
|
50
|
+
| `type: gate` after | same check `when` includes `after` | After-phase sees the accepted confirm on this attempt |
|
|
51
|
+
| `type: checkout_changes` | `repo-touched` `path_fields: [changed_files]` | Marker file appears in the attempt diff and payload |
|
|
52
|
+
| Bound checkout required | task `checkout: .` | Without a git checkout this last stage errors |
|
|
53
|
+
| No `on_verify_fail` | omitted | A failed after-check fails the stage (no silent repair) |
|
|
54
|
+
|
|
55
|
+
## Expected stage status
|
|
56
|
+
|
|
57
|
+
| Stage | Status | Why |
|
|
58
|
+
|-------|--------|-----|
|
|
59
|
+
| `kickoff` | succeeded | entry |
|
|
60
|
+
| `artifact-check` | succeeded | both artifact checks passed |
|
|
61
|
+
| `command-check` | succeeded | command exited 0 |
|
|
62
|
+
| `checklist-check` | succeeded | attestation matched |
|
|
63
|
+
| `payload-check` | succeeded | payload matched schema |
|
|
64
|
+
| `gate-check` | succeeded | confirm accepted |
|
|
65
|
+
| `checkout-check` | succeeded | marker file changed the checkout |
|
|
66
|
+
|
|
67
|
+
## Not in this pipeline
|
|
68
|
+
|
|
69
|
+
These are real cases, but putting them here would fail validate or fail the run.
|
|
70
|
+
|
|
71
|
+
| Scenario | Why it is absent | Where to see it |
|
|
72
|
+
|---------|------------------|-----------------|
|
|
73
|
+
| Failing after-phase verify | would fail the stage / run | [Verified Stage Execution](../../docs/verified-stage-execution.md) |
|
|
74
|
+
| `on_verify_fail.mode: repair` | recovery policy, not a check type | `tests/fixtures/target-dialect/demo.pipeline.yaml` |
|
|
75
|
+
| `on_verify_fail.mode: manual` | needs an operator recover decision after a failed check | [Verified Stage Execution — Manual recovery](../../docs/verified-stage-execution.md#manual-recovery) |
|
|
76
|
+
| Other gate kinds (`free_text`, `multi_question`, `artifact_backed`) | `type: gate` is covered; kinds are HITL widgets | `examples/plan-review/`, `tests/fixtures/stages/hitl-four-kinds.yaml` |
|
|
77
|
+
| `command` / `checklist` / `payload_schema` / `checkout_changes` with `when: [emit]` | illegal | yaml-catalog Verify |
|
|
78
|
+
| Artifact without `when` | illegal | yaml-catalog Verify |
|
|
79
|
+
| Gitignored marker file | `--exclude-standard` hides it; the check would fail | git checkout capability |
|
|
80
|
+
| Unbound checkout | `checkout_changes` errors without `task.checkout` | [Verified Stage Execution](../../docs/verified-stage-execution.md) |
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
id: verify-tour
|
|
2
|
+
model: cursor/auto
|
|
3
|
+
schemas:
|
|
4
|
+
empty:
|
|
5
|
+
type: object
|
|
6
|
+
ok-flag:
|
|
7
|
+
type: object
|
|
8
|
+
required: [ok]
|
|
9
|
+
properties:
|
|
10
|
+
ok:
|
|
11
|
+
type: boolean
|
|
12
|
+
changed:
|
|
13
|
+
type: object
|
|
14
|
+
required: [changed_files]
|
|
15
|
+
properties:
|
|
16
|
+
changed_files:
|
|
17
|
+
type: array
|
|
18
|
+
items:
|
|
19
|
+
type: string
|
|
20
|
+
stages:
|
|
21
|
+
- id: kickoff
|
|
22
|
+
entry: true
|
|
23
|
+
route:
|
|
24
|
+
- to: artifact-check
|
|
25
|
+
system_prompt: |
|
|
26
|
+
Start the verify tour in one sentence.
|
|
27
|
+
Then emit a success envelope via emit_stage_envelope with status: success, a short summary, artifacts: [], and payload: {}.
|
|
28
|
+
io:
|
|
29
|
+
input:
|
|
30
|
+
schema:
|
|
31
|
+
$ref: "#/schemas/empty"
|
|
32
|
+
output:
|
|
33
|
+
schema:
|
|
34
|
+
$ref: "#/schemas/empty"
|
|
35
|
+
|
|
36
|
+
- id: artifact-check
|
|
37
|
+
route:
|
|
38
|
+
- to: command-check
|
|
39
|
+
system_prompt: |
|
|
40
|
+
Cover type: artifact (emit list check and after on-disk check).
|
|
41
|
+
1. Call write_stage_artifact with path note.md and a short nonempty markdown body.
|
|
42
|
+
2. Call emit_stage_envelope with status: success, a one-sentence summary, artifacts listing the path returned by write_stage_artifact, and payload: {}.
|
|
43
|
+
Do not call ask_operator. Do not edit the project checkout.
|
|
44
|
+
io:
|
|
45
|
+
input:
|
|
46
|
+
schema:
|
|
47
|
+
$ref: "#/schemas/empty"
|
|
48
|
+
output:
|
|
49
|
+
schema:
|
|
50
|
+
$ref: "#/schemas/empty"
|
|
51
|
+
verify:
|
|
52
|
+
- id: note-declared
|
|
53
|
+
type: artifact
|
|
54
|
+
basename: note.md
|
|
55
|
+
when: [emit]
|
|
56
|
+
- id: note-on-disk
|
|
57
|
+
type: artifact
|
|
58
|
+
path: note.md
|
|
59
|
+
nonempty: true
|
|
60
|
+
when: [after]
|
|
61
|
+
|
|
62
|
+
- id: command-check
|
|
63
|
+
route:
|
|
64
|
+
- to: checklist-check
|
|
65
|
+
system_prompt: |
|
|
66
|
+
Cover type: command. Stageflow runs the declared command after you emit. Do not run it yourself.
|
|
67
|
+
Call emit_stage_envelope with status: success, a one-sentence summary, artifacts: [], and payload: {}.
|
|
68
|
+
Do not call ask_operator. Do not edit the project checkout.
|
|
69
|
+
io:
|
|
70
|
+
input:
|
|
71
|
+
schema:
|
|
72
|
+
$ref: "#/schemas/empty"
|
|
73
|
+
output:
|
|
74
|
+
schema:
|
|
75
|
+
$ref: "#/schemas/empty"
|
|
76
|
+
verify:
|
|
77
|
+
- id: echo-ok
|
|
78
|
+
type: command
|
|
79
|
+
run: echo verify-tour-ok
|
|
80
|
+
|
|
81
|
+
- id: checklist-check
|
|
82
|
+
route:
|
|
83
|
+
- to: payload-check
|
|
84
|
+
system_prompt: |
|
|
85
|
+
Cover type: checklist. The attestation must match the declared items exactly.
|
|
86
|
+
Call emit_stage_envelope with status: success, a one-sentence summary, artifacts: [], payload: {}, and checklist_attestations:
|
|
87
|
+
- check_id: self-review
|
|
88
|
+
items:
|
|
89
|
+
- Tour steps completed
|
|
90
|
+
- No extra checkout edits
|
|
91
|
+
Do not call ask_operator. Do not edit the project checkout.
|
|
92
|
+
io:
|
|
93
|
+
input:
|
|
94
|
+
schema:
|
|
95
|
+
$ref: "#/schemas/empty"
|
|
96
|
+
output:
|
|
97
|
+
schema:
|
|
98
|
+
$ref: "#/schemas/empty"
|
|
99
|
+
verify:
|
|
100
|
+
- id: self-review
|
|
101
|
+
type: checklist
|
|
102
|
+
items:
|
|
103
|
+
- Tour steps completed
|
|
104
|
+
- No extra checkout edits
|
|
105
|
+
|
|
106
|
+
- id: payload-check
|
|
107
|
+
route:
|
|
108
|
+
- to: gate-check
|
|
109
|
+
system_prompt: |
|
|
110
|
+
Cover type: payload_schema. Emit a payload that matches io.output.schema.
|
|
111
|
+
Call emit_stage_envelope with status: success, a one-sentence summary, artifacts: [], and payload: { "ok": true }.
|
|
112
|
+
Do not call ask_operator. Do not edit the project checkout.
|
|
113
|
+
io:
|
|
114
|
+
input:
|
|
115
|
+
schema:
|
|
116
|
+
$ref: "#/schemas/empty"
|
|
117
|
+
output:
|
|
118
|
+
schema:
|
|
119
|
+
$ref: "#/schemas/ok-flag"
|
|
120
|
+
verify:
|
|
121
|
+
- id: payload-ok
|
|
122
|
+
type: payload_schema
|
|
123
|
+
|
|
124
|
+
- id: gate-check
|
|
125
|
+
route:
|
|
126
|
+
- to: checkout-check
|
|
127
|
+
gate_kinds: [confirm]
|
|
128
|
+
system_prompt: |
|
|
129
|
+
Cover type: gate kind confirm (emit and after).
|
|
130
|
+
1. Call ask_operator with kind: confirm and message: "Accept to continue the verify tour."
|
|
131
|
+
2. Wait for the operator to accept. If they reject, ask again. Do not emit until accepted.
|
|
132
|
+
3. After accept, call emit_stage_envelope with status: success, a one-sentence summary, artifacts: [], and payload: {}.
|
|
133
|
+
io:
|
|
134
|
+
input:
|
|
135
|
+
schema:
|
|
136
|
+
$ref: "#/schemas/empty"
|
|
137
|
+
output:
|
|
138
|
+
schema:
|
|
139
|
+
$ref: "#/schemas/empty"
|
|
140
|
+
verify:
|
|
141
|
+
- id: operator-ok
|
|
142
|
+
type: gate
|
|
143
|
+
kind: confirm
|
|
144
|
+
when: [emit, after]
|
|
145
|
+
|
|
146
|
+
- id: checkout-check
|
|
147
|
+
system_prompt: |
|
|
148
|
+
Cover type: checkout_changes. Edit the project checkout, not a stage artifact.
|
|
149
|
+
1. Create or overwrite verify-tour-marker.txt at the checkout root (the Project checkout path in this prompt) with one unique line (include a timestamp or random token).
|
|
150
|
+
2. Call emit_stage_envelope with status: success, a one-sentence summary, artifacts: [], and payload: { "changed_files": ["verify-tour-marker.txt"] }.
|
|
151
|
+
Do not gitignore that file. Do not commit, push, or delete other files. Do not call ask_operator.
|
|
152
|
+
io:
|
|
153
|
+
input:
|
|
154
|
+
schema:
|
|
155
|
+
$ref: "#/schemas/empty"
|
|
156
|
+
output:
|
|
157
|
+
schema:
|
|
158
|
+
$ref: "#/schemas/changed"
|
|
159
|
+
verify:
|
|
160
|
+
- id: repo-touched
|
|
161
|
+
type: checkout_changes
|
|
162
|
+
path_fields: [changed_files]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
id: verify-tour
|
|
2
|
+
goal: Walk each verify type and leave a checkout marker file.
|
|
3
|
+
context: |
|
|
4
|
+
Verify tour — each stage covers one check type. Payloads and tool calls
|
|
5
|
+
are spelled in the stage prompts. checkout_changes needs this bound git
|
|
6
|
+
checkout; Stageflow compares it before and after checkout-check.
|
|
7
|
+
constraints: |
|
|
8
|
+
Docs and one marker file only. Do not commit or push.
|
|
9
|
+
One-sentence summaries. Use each prompt's payload and attestations verbatim.
|
|
10
|
+
Never emit fork_choice. On gate-check, wait for confirm accept before emit.
|
|
11
|
+
checkout: .
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stageflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "Stageflow — CLI pipeline runtime for configurable stages on Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
12
|
"skills",
|
|
13
|
+
"examples",
|
|
13
14
|
"README.md",
|
|
14
15
|
"LICENSE"
|
|
15
16
|
],
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/better-sqlite3": "^9.6.0",
|
|
58
59
|
"@types/node": "^26.2.0",
|
|
60
|
+
"@types/semver": "^7.8.0",
|
|
59
61
|
"tsx": "^4.23.11",
|
|
60
62
|
"typescript": "^7.0.2",
|
|
61
63
|
"vitest": "^4.1.10"
|
|
@@ -71,7 +73,9 @@
|
|
|
71
73
|
"better-sqlite3": "^13.0.3",
|
|
72
74
|
"jiti": "^2.7.0",
|
|
73
75
|
"pi-mcp-adapter": "^2.32.1",
|
|
76
|
+
"semver": "^7.8.5",
|
|
74
77
|
"typebox": "^1.3.7",
|
|
78
|
+
"undici": "^7.29.1",
|
|
75
79
|
"yaml": "^2.9.0",
|
|
76
80
|
"zod": "^4.4.3"
|
|
77
81
|
},
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stageflow
|
|
3
3
|
description: >-
|
|
4
|
-
Routes Stageflow work to one job: setup (install, catalog,
|
|
5
|
-
session-capture (reuse this chat or a past
|
|
6
|
-
can explain), run (start, watch, or answer
|
|
7
|
-
repeating pattern). Use when the user mentions
|
|
8
|
-
HITL, or a repeating Stageflow workflow.
|
|
4
|
+
Routes Stageflow work to one job: setup (install, catalog, provider, or
|
|
5
|
+
optional Docker Compose local try), session-capture (reuse this chat or a past
|
|
6
|
+
session), author (a loop the human can explain), run (start, watch, or answer
|
|
7
|
+
a pipeline), or delegate (a repeating pattern). Use when the user mentions
|
|
8
|
+
Stageflow, sf, a pipeline, HITL, or a repeating Stageflow workflow.
|
|
9
9
|
compatibility: Requires the Stageflow CLI (sf). An MCP host (sf ui or sf mcp) is optional.
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -17,7 +17,7 @@ Read the matching job `SKILL.md` and follow it. Do not invent job behavior in th
|
|
|
17
17
|
|
|
18
18
|
| Reach this job when | Read |
|
|
19
19
|
|---|---|
|
|
20
|
-
| Install is missing, there is no catalog,
|
|
20
|
+
| Install is missing, there is no catalog, a provider is not logged in, or the operator wants Docker Compose local try | [../stageflow-setup/SKILL.md](../stageflow-setup/SKILL.md) |
|
|
21
21
|
| The request should reuse a past session or this chat | [../stageflow-session-capture/SKILL.md](../stageflow-session-capture/SKILL.md) |
|
|
22
22
|
| The request describes a loop the human can explain | [../stageflow-author/SKILL.md](../stageflow-author/SKILL.md) |
|
|
23
23
|
| The request needs to start, watch, or answer a run | [../stageflow-run/SKILL.md](../stageflow-run/SKILL.md) |
|
|
@@ -11,18 +11,24 @@ node ../scripts/detect-host.mjs
|
|
|
11
11
|
node ../scripts/detect-host.mjs --base-url http://127.0.0.1:3847
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
The script `GET`s `{baseUrl}/api/health` (default `http://127.0.0.1:3847`, 1500 ms timeout). **up** means HTTP 200 and parseable JSON. Non-200, non-JSON, or timeout is **down**. This probe is Stageflow host up/down only — it does not detect a coding-agent question UI. Gate presentation lives in [`../../stageflow-run/references/native-question-ui.md`](../../stageflow-run/references/native-question-ui.md).
|
|
14
|
+
The script `GET`s `{baseUrl}/api/health` (default `http://127.0.0.1:3847`, 1500 ms timeout). **up** means HTTP 200 and parseable JSON. Non-200, non-JSON, or timeout is **down**. Health stays Host/Origin-only (no bearer), so loopback probes keep working when a control token is configured. This probe is Stageflow host up/down only — it does not detect a coding-agent question UI. Gate presentation lives in [`../../stageflow-run/references/native-question-ui.md`](../../stageflow-run/references/native-question-ui.md).
|
|
15
15
|
|
|
16
|
-
Stdout is one line: `up <baseUrl>` or `down <baseUrl
|
|
16
|
+
Stdout is one line: `up <baseUrl>` or `down <baseUrl>`, with an optional trailing `bearer` when `STAGEFLOW_CONTROL_TOKEN` or `STAGEFLOW_CONTROL_TOKEN_FILE` is set in this environment (MCP/Compose need `Authorization: Bearer` — see [`../../stageflow-run/references/mcp-call.md`](../../stageflow-run/references/mcp-call.md)). Exit `0` when up, `1` when down, `2` on usage error.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
**Health is not auth.** `GET /api/health` is ungated (Host/Origin only — no bearer). Do **not** treat a health 200 as authenticated MCP. Non-loopback and Compose Hosts require a drive bearer (`STAGEFLOW_CONTROL_TOKEN`); MCP and protected API calls need `Authorization: Bearer <drive-token>` when a control token is set. See Stageflow docs: MCP (Access control); Docker and self-hosting — Local try.
|
|
19
|
+
|
|
20
|
+
Start a host with `sf ui` or `sf mcp` when the user wants MCP. Do not auto-start one. Compose local try is the standing-Host path — see `stageflow-setup` and Stageflow docs: Docker and self-hosting.
|
|
19
21
|
|
|
20
22
|
## When the host is up
|
|
21
23
|
|
|
22
|
-
Use MCP tools over the Streamable HTTP endpoint at `{baseUrl}/mcp`. Tool names and payloads live in [docs/mcp.md](../../../docs/mcp.md). Typical talking-job tools: `list_pipelines`, `list_tasks`, `start_run`, `get_run`, `wait_run`, `list_waiting`, `answer_gate`, `decide_feedback_loop`, `get_envelope`, `read_artifact`, `validate`, `describe_pipeline`, `get_health`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`.
|
|
24
|
+
Use MCP tools over the Streamable HTTP endpoint at `{baseUrl}/mcp`. Send `Authorization: Bearer <drive-token>` when `STAGEFLOW_CONTROL_TOKEN` (or a named drive token) is configured. Tool names and payloads live in Stageflow docs: MCP (checkout: [docs/mcp.md](../../../docs/mcp.md)). Typical talking-job tools: `list_pipelines`, `list_tasks`, `start_run`, `run_stage`, `get_run`, `wait_run`, `list_waiting`, `answer_gate`, `decide_feedback_loop`, `get_envelope`, `read_artifact`, `list_checkout_changes`, `get_run_diff`, `read_checkout_file`, `validate`, `describe_pipeline`, `get_health`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`, `export_run`, `list_skills`, `list_stage_events`, `get_stage_verification`.
|
|
25
|
+
|
|
26
|
+
`get_health` returns capacity fields plus an on-demand `disk` breakdown (`runs_bytes`, `worktrees_bytes`, `repos_bytes`, `state_db_bytes`, `a2a_artifacts_bytes`, `free_bytes`) for the durable root. When `slotsAvailable` is `0`, starts may still succeed as queued until `STAGEFLOW_MAX_QUEUED` is full — see `start_run` in the MCP docs.
|
|
27
|
+
|
|
28
|
+
Some capabilities stay **CLI-only** (or `docker exec` on a container Host): `sf graph`, `sf migrate-yaml`, `sf skills install` (durable host install; prefer `start_run.skills` for harnesses), A2A config mutate/validate, and provider OAuth login. Provider API keys for Host boot use `STAGEFLOW_PROVIDER_<ID>_API_KEY(_FILE)`, not an MCP login tool. Use the MCP **CLI-only capabilities** decision table (Stageflow docs: MCP) instead of inventing MCP substitutes.
|
|
23
29
|
|
|
24
30
|
## When the host is down
|
|
25
31
|
|
|
26
|
-
Use the `sf` CLI. Command names and flags live in [docs/cli-reference.md](../../../docs/cli-reference.md). Typical talking-job commands: `sf run`, `sf runs waiting`, `sf runs answer`, `sf runs feedback-decide`, `sf runs wait`, `sf validate`, `sf envelope get`, `sf artifact read`, `sf providers`.
|
|
32
|
+
Use the `sf` CLI. Command names and flags live in Stageflow docs: CLI reference (checkout: [docs/cli-reference.md](../../../docs/cli-reference.md)). Typical talking-job commands: `sf run`, `sf runs waiting`, `sf runs answer`, `sf runs feedback-decide`, `sf runs wait`, `sf validate`, `sf envelope get`, `sf artifact read`, `sf providers`.
|
|
27
33
|
|
|
28
34
|
Probe before each mutating `sf runs` verb. If the probe is **up** or the command refuses because a host is up, continue that gate via MCP — do not start a second mutating writer, and do not start `sf mcp` as a disposable bridge.
|
|
@@ -33,6 +33,15 @@ function parseArgs(argv) {
|
|
|
33
33
|
return { baseUrl };
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
function clientHasControlToken(env = process.env) {
|
|
37
|
+
const plain = env.STAGEFLOW_CONTROL_TOKEN;
|
|
38
|
+
const filePath = env.STAGEFLOW_CONTROL_TOKEN_FILE;
|
|
39
|
+
return (
|
|
40
|
+
(plain !== undefined && plain.length > 0) ||
|
|
41
|
+
(filePath !== undefined && filePath.length > 0)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
36
45
|
async function probe(baseUrl) {
|
|
37
46
|
const ac = new AbortController();
|
|
38
47
|
const timer = setTimeout(() => ac.abort(), TIMEOUT_MS);
|
|
@@ -50,5 +59,9 @@ async function probe(baseUrl) {
|
|
|
50
59
|
|
|
51
60
|
const { baseUrl } = parseArgs(process.argv.slice(2));
|
|
52
61
|
const status = await probe(baseUrl);
|
|
53
|
-
|
|
62
|
+
const parts = [status, baseUrl];
|
|
63
|
+
if (clientHasControlToken()) {
|
|
64
|
+
parts.push("bearer");
|
|
65
|
+
}
|
|
66
|
+
console.log(parts.join(" "));
|
|
54
67
|
process.exit(status === "up" ? 0 : 1);
|
|
@@ -7,10 +7,18 @@ import { test } from "node:test";
|
|
|
7
7
|
|
|
8
8
|
const script = path.join(path.dirname(fileURLToPath(import.meta.url)), "detect-host.mjs");
|
|
9
9
|
|
|
10
|
-
function
|
|
10
|
+
function cleanEnv(extra = {}) {
|
|
11
|
+
const env = { ...process.env };
|
|
12
|
+
delete env.STAGEFLOW_CONTROL_TOKEN;
|
|
13
|
+
delete env.STAGEFLOW_CONTROL_TOKEN_FILE;
|
|
14
|
+
return { ...env, ...extra };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function run(baseUrl, opts = {}) {
|
|
11
18
|
return new Promise((resolve) => {
|
|
12
19
|
const child = spawn(process.execPath, [script, "--base-url", baseUrl], {
|
|
13
20
|
stdio: ["ignore", "pipe", "pipe"],
|
|
21
|
+
env: opts.env ?? cleanEnv(),
|
|
14
22
|
});
|
|
15
23
|
let stdout = "";
|
|
16
24
|
let stderr = "";
|
|
@@ -95,3 +103,23 @@ test("classifies a hung /api/health as down", async () => {
|
|
|
95
103
|
server.close();
|
|
96
104
|
}
|
|
97
105
|
});
|
|
106
|
+
|
|
107
|
+
test("notes bearer when STAGEFLOW_CONTROL_TOKEN is set without changing health probe", async () => {
|
|
108
|
+
const { server, baseUrl } = await listen((req, res) => {
|
|
109
|
+
assert.equal(req.url, "/api/health");
|
|
110
|
+
assert.equal(req.headers.authorization, undefined);
|
|
111
|
+
res.writeHead(200, { "content-type": "application/json" });
|
|
112
|
+
res.end(JSON.stringify({ ok: true }));
|
|
113
|
+
});
|
|
114
|
+
try {
|
|
115
|
+
const result = await run(baseUrl, {
|
|
116
|
+
env: cleanEnv({
|
|
117
|
+
STAGEFLOW_CONTROL_TOKEN: "b".repeat(32),
|
|
118
|
+
}),
|
|
119
|
+
});
|
|
120
|
+
assert.equal(result.status, 0);
|
|
121
|
+
assert.equal(result.stdout.trim(), `up ${baseUrl} bearer`);
|
|
122
|
+
} finally {
|
|
123
|
+
server.close();
|
|
124
|
+
}
|
|
125
|
+
});
|
|
@@ -35,9 +35,9 @@ Ask until you can name every step, how they sequence, any decision point, and an
|
|
|
35
35
|
|
|
36
36
|
## Map
|
|
37
37
|
|
|
38
|
-
Read [`references/catalog-mapping.md`](references/catalog-mapping.md). Apply those rules to the confirmed structure. Read [`references/stage-prompt-template.md`](references/stage-prompt-template.md) for each stage's `system_prompt`, optional `model`, `io`, `verify`, and `gate_kinds`. Apply the Anti-patterns section below while mapping. When the human needs hard advance gates, plan body `verify` and wiring `on_verify_fail`. When a review can demand changes, include an address-feedback stage before approve/ship.
|
|
38
|
+
Read [`references/catalog-mapping.md`](references/catalog-mapping.md). Apply those rules to the confirmed structure. Read [`references/stage-prompt-template.md`](references/stage-prompt-template.md) for each stage's `system_prompt`, optional `model`, `io`, `verify`, and `gate_kinds`. Apply the Anti-patterns section below while mapping. When the human needs hard advance gates, plan body `verify` and wiring `on_verify_fail`. When a stage needs git/`gh`/registry credentials, plan `secrets:` (do not assume ambient Host env). When a review can demand changes, include an address-feedback stage before approve/ship.
|
|
39
39
|
|
|
40
|
-
**Done when** you have a pipeline id, one stage id per step, `route` / `entry` wiring (optional `if`, `{ type: loop }`, sealed Clone Chain when the human wants one run per list item), a prompt plan per stage, and any `verify` / `on_verify_fail` / remediation stages the structure requires.
|
|
40
|
+
**Done when** you have a pipeline id, one stage id per step, `route` / `entry` wiring (optional `if`, `{ type: loop }`, sealed Clone Chain when the human wants one run per list item), a prompt plan per stage, and any `verify` / `on_verify_fail` / remediation stages / `secrets` the structure requires.
|
|
41
41
|
|
|
42
42
|
## Anti-patterns
|
|
43
43
|
|
|
@@ -52,7 +52,8 @@ Author these contracts explicitly. They come from long runs that failed after ho
|
|
|
52
52
|
| Give review blockers a place to land | Wire `review → address-feedback → approve/ship`. Put `verdict` / `blocking_findings` (or equivalent) in the review `io.output.schema`. |
|
|
53
53
|
| Bind success to the full checklist | If a plan lists N commands, success requires all of them in `commands_run` with exit 0. Cheap checks first; slow suites last or in a verify stage. Size `timeout_ms` to the work. |
|
|
54
54
|
| Use configured models on every sibling | Same configured `model` family after fan-out unless the human asks otherwise. Reliable model on publish/PR stages. |
|
|
55
|
-
| Finish publish in the accept attempt | After `artifact_backed` accept: side effects (commit/push/PR) → final artifact → emit in the same attempt. Fix emit/schema errors by re-emitting. |
|
|
55
|
+
| Finish publish in the accept attempt | After `artifact_backed` accept: side effects (commit/push/PR) → final artifact → emit in the same attempt. Declare `secrets:` for those side effects; do not assume ambient `GITHUB_TOKEN`. Fix emit/schema errors by re-emitting. |
|
|
56
|
+
| Declare credentials the stage needs | Stages get a curated env — not Host `process.env`. Put `secrets:` on the stage body or pipeline entry. Never put `STAGEFLOW_CONTROL_TOKEN` / read tokens in `secrets:`. See [`catalog-mapping.md`](references/catalog-mapping.md#stage-secrets). |
|
|
56
57
|
| Author a sealed Clone Chain | One run per list item is emitter → clone child → Join. Never write `clonable`, `clone_forks`, or emit-time `skip` / `once` / `fanout`. See [YAML catalog — Clone Chain](../../docs/yaml-catalog.md#clone-chain). |
|
|
57
58
|
|
|
58
59
|
Throwaway checkout deliverables (HTML spike, scratch file): prompt builtin `write` at a checkout-relative path, `artifacts: []` on emit, path in `payload`.
|
|
@@ -114,6 +114,22 @@ See [YAML catalog — Clone Chain](../../../docs/yaml-catalog.md#clone-chain) an
|
|
|
114
114
|
|
|
115
115
|
Do not author `clonable`, `clone_actions`, or envelope `clone_forks`. Do not put `clone_cap` / `clone_mode` on a stage that is not a Clone Chain emitter.
|
|
116
116
|
|
|
117
|
+
## Stage secrets
|
|
118
|
+
|
|
119
|
+
Stages receive a **curated** environment — not Host `process.env`. Credentials reach a stage only via `secrets:` on the stage body or the pipeline `uses:` entry. Do not assume ambient `GITHUB_TOKEN` in the stage.
|
|
120
|
+
|
|
121
|
+
```yaml
|
|
122
|
+
secrets:
|
|
123
|
+
- GITHUB_TOKEN # GIT_ASKPASS + materialised token file (no raw env)
|
|
124
|
+
- { name: GITHUB_TOKEN, as: env } # when gh/MCP need the env var (askpass still set)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`GITHUB_TOKEN` / `GH_TOKEN` default to askpass (no raw env). Prefer `{ name: GITHUB_TOKEN, as: env }` when `gh` or MCP needs the env var — askpass remains set for plain HTTPS `git`. Never put `STAGEFLOW_CONTROL_TOKEN` or read tokens in `secrets:` (never grantable). The Host still needs `GITHUB_TOKEN` / `GH_TOKEN` for clone/fetch materialize even for public repos; that Host token is separate from stage grants.
|
|
128
|
+
|
|
129
|
+
When a publish stage calls `gh`, add `requires: [{ tool: gh }]`. The base Docker image has no `gh` — operators derive an image. Stageflow never installs tools from `requires:`.
|
|
130
|
+
|
|
131
|
+
Full reference: [YAML catalog — Stage secrets](../../../docs/yaml-catalog.md#stage-secrets), [migration-stage-environment.md](../../../docs/migration-stage-environment.md). Legacy contract-key catalogs → `sf migrate-yaml` (laptop / `docker exec`, not MCP).
|
|
132
|
+
|
|
117
133
|
## Models
|
|
118
134
|
|
|
119
135
|
Confirm providers before writing. After fan-out, give every sibling the same configured `model` unless the human asks for different ones. Prefer a reliable configured model on side-effecting final stages.
|
|
@@ -20,7 +20,7 @@ One directory (or the project root) holds:
|
|
|
20
20
|
| `<pipeline-id>.pipeline.yaml` | `id` matching the filename stem; `stages:` array of object entries |
|
|
21
21
|
| `<stage-id>.yaml` | `id`, `system_prompt`; `model` when not inherited; required `io.input.schema` and `io.output.schema`; `verify` / `gate_kinds` when the step needs them |
|
|
22
22
|
|
|
23
|
-
Each pipeline stage entry has `id` and `uses: ./<id>.yaml` (path relative to the pipeline file). At least one root marks `entry: true`. Sources list forward `route: [{ to: <id> }, …]`. Optional `on:` is skip-cascade policy (default succeeded-only); it does not launch from skipped/failed. Optional `if` gates a successor after the source succeeds (predicate on required `io.output.schema` fields). A review that can send work back adds `{ type: loop, to, max_replays, on_max_replays, replay_session }` inside `route`. A Clone Chain emitter puts `clone_cap` and `clone_mode` on that **pipeline entry**, never on the reusable stage body. Put `on_verify_fail` on the pipeline entry when after-phase `verify` should repair or wait for an operator. Filename stem matches `id`. Optional pipeline-root `model` fills stages that omit `model`. Sequencing rules: [`catalog-mapping.md`](catalog-mapping.md). Catalog load rejects `needs`, `fork`, and `feedback_loop` as YAML keys.
|
|
23
|
+
Each pipeline stage entry has `id` and `uses: ./<id>.yaml` (path relative to the pipeline file). At least one root marks `entry: true`. Sources list forward `route: [{ to: <id> }, …]`. Optional `on:` is skip-cascade policy (default succeeded-only); it does not launch from skipped/failed. Optional `if` gates a successor after the source succeeds (predicate on required `io.output.schema` fields). A review that can send work back adds `{ type: loop, to, max_replays, on_max_replays, replay_session }` inside `route`. A Clone Chain emitter puts `clone_cap` and `clone_mode` on that **pipeline entry**, never on the reusable stage body. Put `on_verify_fail` on the pipeline entry when after-phase `verify` should repair or wait for an operator. `secrets` and `requires` may sit on the stage body or the `uses:` wrapper — stages get a curated env, not Host ambient credentials; see [`catalog-mapping.md`](catalog-mapping.md#stage-secrets). Filename stem matches `id`. Optional pipeline-root `model` fills stages that omit `model`. Sequencing rules: [`catalog-mapping.md`](catalog-mapping.md). Catalog load rejects `needs`, `fork`, and `feedback_loop` as YAML keys.
|
|
24
24
|
|
|
25
25
|
## Collisions
|
|
26
26
|
|
|
@@ -17,6 +17,8 @@ Talking jobs cite [`../stageflow/references/control-surface.md`](../stageflow/re
|
|
|
17
17
|
|
|
18
18
|
MCP tool shapes: [`docs/mcp.md`](../../docs/mcp.md). CLI flags and exit codes: [`docs/cli-reference.md`](../../docs/cli-reference.md). Direct tool calls: [`references/mcp-call.md`](references/mcp-call.md). Selection: [`references/task-and-pipeline-selection.md`](references/task-and-pipeline-selection.md). Gate presentation: [`references/native-question-ui.md`](references/native-question-ui.md).
|
|
19
19
|
|
|
20
|
+
Runs live under **`$STAGEFLOW_HOME`** (default `~/.stageflow/`), not the project tree. Project `.stageflow/settings.json` is settings only.
|
|
21
|
+
|
|
20
22
|
## Preconditions
|
|
21
23
|
|
|
22
24
|
Run `sf --version`. **Done when** it prints a version. If `sf` is missing, stop and name `stageflow-setup`.
|
|
@@ -30,9 +32,11 @@ node ../stageflow/scripts/detect-host.mjs --base-url http://127.0.0.1:3847
|
|
|
30
32
|
|
|
31
33
|
| stdout | path |
|
|
32
34
|
|---|---|
|
|
33
|
-
| `up <baseUrl>` | [MCP path](#mcp-path) |
|
|
35
|
+
| `up <baseUrl>` … | [MCP path](#mcp-path) |
|
|
34
36
|
| `down <baseUrl>` | [CLI path](#cli-path) |
|
|
35
37
|
|
|
38
|
+
Optional trailing `bearer` means `STAGEFLOW_CONTROL_TOKEN` (or `_FILE`) is set in this environment — send it on MCP via [`mcp-call.md`](references/mcp-call.md) (Compose / non-loopback Hosts require a token). `/api/health` stays unauthenticated; the probe does not break loopback.
|
|
39
|
+
|
|
36
40
|
**Done when** you have `up` or `down` and the base URL.
|
|
37
41
|
|
|
38
42
|
## Select
|
|
@@ -47,21 +51,23 @@ If this chat already has a `runId` and the request is check, answer, or continue
|
|
|
47
51
|
|
|
48
52
|
Prefer this harness's native Stageflow MCP tools when their names are already in the tool list. When they are not, call [`scripts/mcp-call.mjs`](scripts/mcp-call.mjs) — see [`references/mcp-call.md`](references/mcp-call.md). Use `--stateless` only when the **user** started the host with `--mcp-stateless`. Do not start `sf mcp` from this skill.
|
|
49
53
|
|
|
50
|
-
Call only these Stageflow MCP tools: `list_pipelines`, `list_tasks`, `start_run`, `get_run`, `wait_run`, `list_waiting`, `list_runs`, `answer_gate`, `decide_feedback_loop`, `read_artifact`, `describe_pipeline`, `validate`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`, `get_health`. Host question tools already in this harness's tool list (`AskQuestion`, `AskUserQuestion`, `ask_user`) are for [Gate](#gate) presentation, not Stageflow MCP.
|
|
54
|
+
Call only these Stageflow MCP tools: `list_pipelines`, `list_tasks`, `start_run`, `run_stage`, `get_run`, `wait_run`, `list_waiting`, `list_runs`, `answer_gate`, `decide_feedback_loop`, `get_envelope`, `read_artifact`, `list_checkout_changes`, `get_run_diff`, `read_checkout_file`, `describe_pipeline`, `validate`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`, `get_health`. Host question tools already in this harness's tool list (`AskQuestion`, `AskUserQuestion`, `ask_user`) are for [Gate](#gate) presentation, not Stageflow MCP.
|
|
51
55
|
|
|
52
56
|
## MCP path
|
|
53
57
|
|
|
54
58
|
### Start
|
|
55
59
|
|
|
56
|
-
`start_run` with `pipeline` plus exactly one of `task_path` or inline `task`.
|
|
60
|
+
`start_run` with `pipeline` plus exactly one of `task_path` or inline `task`. Binding: task `repository`+`ref` XOR `checkout` (see selection). Repository-bound runs get a Host worktree under `$STAGEFLOW_HOME/worktrees/<runId>/`.
|
|
57
61
|
|
|
58
62
|
| result | next |
|
|
59
63
|
|---|---|
|
|
60
64
|
| `{ "runId" }` | [Wait](#wait) |
|
|
61
|
-
| `
|
|
65
|
+
| `{ "runId", "queued": true }` (optional `queuePosition`) | Same as `{ "runId" }` — queued is still success, just slower. [Wait](#wait) |
|
|
66
|
+
| `busy_capacity` / `busy_checkout` | [Report](#report) the included fields. Stop. Do not retry. `busy_capacity` means the **admission queue is full** (active-slot exhaustion queues instead). `busy_checkout` is a **path-bound checkout lease** only (never queued); repository-bound runs may parallelize on the same repo. |
|
|
67
|
+
| `insufficient_disk` | [Report](#report) `freeBytes` / `minFreeBytes`. Stop. Do not retry. Distinct from busy — the run was not queued. |
|
|
62
68
|
| other `isError` | [Report](#report) the payload. Stop. |
|
|
63
69
|
|
|
64
|
-
**Done when** you have a `runId`, or a busy/error report is printed.
|
|
70
|
+
**Done when** you have a `runId`, or a busy/disk/error report is printed.
|
|
65
71
|
|
|
66
72
|
### Wait
|
|
67
73
|
|
|
@@ -120,7 +126,7 @@ Discovery without a host: read `stageflow.yaml` catalog roots as in [`references
|
|
|
120
126
|
sf run --task <path> --pipeline <path> --json
|
|
121
127
|
```
|
|
122
128
|
|
|
123
|
-
Add `--checkout`, `--git-sha`, `--ci-pr-url`, `--ci-job-url
|
|
129
|
+
Add `--checkout`, `--repository` / `--ref`, `--git-sha`, `--ci-pr-url`, or `--ci-job-url` only when the human supplied them (binding: `repository`+`ref` XOR `checkout`). Do **not** pass `--operator-cwd` / `--operator-agent-dir` — they are no-ops on `sf run`; set `STAGEFLOW_OPERATOR_CWD` / `STAGEFLOW_OPERATOR_AGENT_DIR` before the Host first starts. Always pass `--json`. Omit `--include stages` unless the human asked for a stage projection — and then only together with `--json`.
|
|
124
130
|
|
|
125
131
|
Parse the single JSON document.
|
|
126
132
|
|
|
@@ -128,7 +134,9 @@ Parse the single JSON document.
|
|
|
128
134
|
|---|---|
|
|
129
135
|
| `0` | `succeeded` | [Report](#report) |
|
|
130
136
|
| `1` | `failed` | [Report](#report) `reason` verbatim |
|
|
137
|
+
| `1` | `cancelled` | [Report](#report) `reason` verbatim |
|
|
131
138
|
| `1` | `busy` | [Report](#report) `busy_capacity` / `busy_checkout` and the included fields. Stop. |
|
|
139
|
+
| `1` | `failed` with `code: "insufficient_disk"` | [Report](#report) `freeBytes` / `minFreeBytes`. Stop. |
|
|
132
140
|
| `2` | `waiting` | [CLI wait](#cli-wait) with this `runId` / `runDir` |
|
|
133
141
|
|
|
134
142
|
**Done when** the outcome is reported, or a waiting exit has handed `runId` to CLI wait.
|
|
@@ -138,7 +146,7 @@ Parse the single JSON document.
|
|
|
138
146
|
Host down after `sf run` exit `2`, or when this chat already has a `runId` and the host is down. Do not start `sf mcp`. HITL presentation follows [`references/native-question-ui.md`](references/native-question-ui.md). Submit HITL with `sf runs answer --json`. If `waiting_kind` is `feedback_loop_decision`, present extend / continue / abandon and submit with `sf runs feedback-decide --json` — not `sf runs answer`.
|
|
139
147
|
|
|
140
148
|
1. Probe again with [`../stageflow/scripts/detect-host.mjs`](../stageflow/scripts/detect-host.mjs) (the host may have appeared). Probe before each `sf runs answer` or `sf runs feedback-decide`.
|
|
141
|
-
2. **Up:** use that host — native tools if present, otherwise `mcp-call.mjs` (omit `--stateless` unless the user started the host with `--mcp-stateless`). Continue at [Gate](#gate).
|
|
149
|
+
2. **Up:** use that host — native tools if present, otherwise `mcp-call.mjs` (omit `--stateless` unless the user started the host with `--mcp-stateless`; send bearer when the probe notes `bearer` or `STAGEFLOW_CONTROL_TOKEN` is set). Continue at [Gate](#gate).
|
|
142
150
|
3. **Down:**
|
|
143
151
|
|
|
144
152
|
```
|
|
@@ -177,7 +185,7 @@ Wait abort (exit `130`, `{ "error", "code": "aborted" }`) → [Report](#report):
|
|
|
177
185
|
|
|
178
186
|
4. If `sf runs answer` or `sf runs feedback-decide` refuses because the host came up, continue that gate via MCP [Gate](#gate). Do not dual-write.
|
|
179
187
|
|
|
180
|
-
If this chat ends before terminal, say the run stays
|
|
188
|
+
If this chat ends before terminal, say the run stays under `$STAGEFLOW_HOME` (default `~/.stageflow/`) and to continue by re-invoking this skill (or starting a host and using MCP).
|
|
181
189
|
|
|
182
190
|
**Done when** the run is terminal, aborted, or a hard error is printed.
|
|
183
191
|
|
|
@@ -187,14 +195,14 @@ Print one shape on every path:
|
|
|
187
195
|
|
|
188
196
|
1. Current or last-known stage (MCP live snapshot, or "start/finish only" on a CLI-only stretch).
|
|
189
197
|
2. Waiting prompt text verbatim when the run is parked.
|
|
190
|
-
3. Outcome: `succeeded`, `failed`, `waiting`, or `
|
|
198
|
+
3. Outcome: `succeeded`, `failed`, `cancelled`, `waiting`, `busy`, or `insufficient_disk`.
|
|
191
199
|
4. Run id.
|
|
192
|
-
5. Run
|
|
200
|
+
5. Run location under `$STAGEFLOW_HOME` (`runDir` / `runs/<runId>/`; default home `~/.stageflow/`). For repository-bound succeeded runs, the Host worktree under `worktrees/<runId>/` may already be reclaimed (`checkout_reclaimed` if the path is gone; `run_branch` is kept).
|
|
193
201
|
|
|
194
|
-
MCP `get_run` / `wait_run` and `sf runs wait` / `sf runs show` `--json` carry live stage state. `sf run --json` reports start and finish only — say that in chat when the CLI path ran without a later wait/show. A succeeded report names id and
|
|
202
|
+
MCP `get_run` / `wait_run` and `sf runs wait` / `sf runs show` `--json` carry live stage state. `sf run --json` reports start and finish only — say that in chat when the CLI path ran without a later wait/show. A succeeded report names id and durable location and does not keep waiting language. A failure names `reason` in this same shape. Stop-and-report codes from Start include `busy_capacity`, `busy_checkout`, and `insufficient_disk`.
|
|
195
203
|
|
|
196
204
|
**Done when** that five-part report is printed.
|
|
197
205
|
|
|
198
206
|
## Non-goals
|
|
199
207
|
|
|
200
|
-
This job starts, watches, and answers runs. It does not require `sf ui`. The operator console is not the answer path. It does not register or invent an MCP tool. It does not start `sf mcp`. It does not retry, resume, abandon, recover, or rerun stages.
|
|
208
|
+
This job starts, watches, and answers runs. It does not require `sf ui`. The operator console is not the answer path. It does not register or invent an MCP tool. It does not start `sf mcp`. It does not retry, resume, abandon, recover, cancel, delete, gc, or rerun stages or runs.
|
|
@@ -8,10 +8,18 @@ node scripts/mcp-call.mjs --base-url <url> --tool <name> --args '<json>' [--stat
|
|
|
8
8
|
|
|
9
9
|
Default `--base-url` is `http://127.0.0.1:3847`. `--args` defaults to `{}`.
|
|
10
10
|
|
|
11
|
+
## Auth
|
|
12
|
+
|
|
13
|
+
When `STAGEFLOW_CONTROL_TOKEN` or `STAGEFLOW_CONTROL_TOKEN_FILE` is set, the script sends `Authorization: Bearer <token>` on every `/mcp` request (initialize, tools/call, session DELETE). Docker Compose and any non-loopback Host require a drive token — set the same env in the harness before calling. Loopback with no token stays unauthenticated. `/api/health` (detect-host) does not need a bearer.
|
|
14
|
+
|
|
15
|
+
## Session
|
|
16
|
+
|
|
11
17
|
`--stateless` sends one `tools/call` and no session header. Use it for hosts the **user** started with `sf mcp --mcp-stateless`, not a skill-started process.
|
|
12
18
|
|
|
13
19
|
Without `--stateless`: `initialize`, capture `Mcp-Session-Id`, reuse it for `tools/call`.
|
|
14
20
|
|
|
15
21
|
Stdout is the tool JSON. Exit `0` on success, including `wait_run` with `reason: "timeout"` (keep polling). Exit `1` on transport failure or `isError: true`. Exit `2` on usage or malformed `--args` — that parse error happens before any network call.
|
|
16
22
|
|
|
17
|
-
Allowed `--tool` names (see [`docs/mcp.md`](../../../docs/mcp.md)): `list_pipelines`, `list_tasks`, `start_run`, `get_run`, `wait_run`, `list_waiting`, `list_runs`, `answer_gate`, `decide_feedback_loop`, `read_artifact`, `describe_pipeline`, `validate`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`, `get_health`.
|
|
23
|
+
Allowed `--tool` names (see [`docs/mcp.md`](../../../docs/mcp.md)): `list_pipelines`, `list_tasks`, `start_run`, `run_stage`, `get_run`, `wait_run`, `list_waiting`, `list_runs`, `answer_gate`, `decide_feedback_loop`, `get_envelope`, `read_artifact`, `list_checkout_changes`, `get_run_diff`, `read_checkout_file`, `describe_pipeline`, `validate`, `list_providers`, `list_models`, `list_project_mcp`, `probe_project_mcp`, `get_health`.
|
|
24
|
+
|
|
25
|
+
`start_run` may return `{ "runId", "queued": true }` — treat that like `{ "runId" }` (success, slower start). `busy_capacity` means the admission queue is full; `busy_checkout` is path-bound lease only; `insufficient_disk` is a hard stop (not queued). Do not call `cancel_run`, `delete_run`, or `gc_runs` from this skill.
|