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,377 @@
|
|
|
1
|
+
# route wiring smoke test
|
|
2
|
+
|
|
3
|
+
Seventeen small, self-contained pipelines that together cover the `route`-based pipeline wiring YAML surface, plus twenty-nine deliberately-invalid ones that each trigger one specific rejection error.
|
|
4
|
+
|
|
5
|
+
- The 17 **valid** ones live directly in this directory and are registered in the repo's `stageflow.yaml` catalog (the directory is listed once; new `*.pipeline.yaml` files dropped in here are picked up automatically), so they show up in `sf ui` / the pipeline picker and are runnable end-to-end with `smoke-test.task.yaml`.
|
|
6
|
+
- The 29 **rejected** ones live in `rejected/` and are excluded from the catalog via `stageflow.yaml`'s `exclude:` list — **they will not show up in the UI on purpose**, so they don't clutter the picker or fail a catalog-wide validate/CI run. Each demonstrates one distinct pipeline-level failure; since a whole pipeline fails to load on its first error, these can't usefully be merged into fewer files without hiding all but one message per file. They're CLI-only, via `sf validate --pipeline <path>`.
|
|
7
|
+
|
|
8
|
+
## Patterns covered — which pipeline for which feature
|
|
9
|
+
|
|
10
|
+
`route` is declarative wiring. Listed forward `to:` stay on the DAG. After a **succeeded** source, each forward entry is eligible (an entry without `if` fires; `if` match fires; `if` miss **skips** that target — the run can still succeed). Single-parent launch still requires succeeded. `on:` is skip-cascade policy, not launch-from-failed. `if` may be a leaf (`eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `not_in`) or nested `all` / `any` / `not`. There is no agent `fork_choice` for catalog pipelines, and `route_select` / `allow_none` are rejected.
|
|
11
|
+
|
|
12
|
+
A Join (two or more parents name the same child) waits for *every* parent to become terminal. A false inbound `if` (leaf or `all` / `any` / `not` composition) does **not** skip the child while another parent is still running. After every parent **succeeded**, the child runs only if every inbound edge fired (`if` true, or no `if`); it then opens with every parent's success envelope. If any inbound `if` missed, the child is **skipped** — not pending forever, not opened with a partial envelope set. A failed parent still blocks. Pipelines with **no** forward `if` keep today's Join: skipped sibling + succeeded sibling can still run; all-skipped still force-skip. Mixed skip + a succeeded arm’s `if` miss still runs — the all-fired check is only when every parent succeeded.
|
|
13
|
+
|
|
14
|
+
State-gated routing uses `on:` on the source stage (`succeeded` / `failed`) as skip-cascade policy.
|
|
15
|
+
|
|
16
|
+
| Pipeline ID | File | Demonstrates |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `route-demo-core` | `01-core-routing.pipeline.yaml` | The broadest single flow: entry, forward routing, loop (`require_continue`/`resume`), unconditional fan-out from `qa` and `ship`, fan-in join. After qa succeeds, both `ship` and `request-changes` run. After ship succeeds, all three notify stages run. `close` fans in those four parents. |
|
|
19
|
+
| `route-demo-on-gate` | `02-on-gating.pipeline.yaml` | `on: [succeeded]` / `on: [failed]` state-gated routing, declared on the source stage. |
|
|
20
|
+
| `route-demo-two-entries` | `03-two-entry-points.pipeline.yaml` | Multiple independent `entry: true` roots. |
|
|
21
|
+
| `route-demo-entry-false` | `04-entry-false-equivalent-to-omitted.pipeline.yaml` | `entry: false` behaves like omitting the key (code-review fix). |
|
|
22
|
+
| `route-demo-fork-choice` | `05-fork-choice.pipeline.yaml` | Larger unconditional fan-out: `triage` lists two follow-ups; `quick-fix` lists three. All listed `to:` targets run. Overlaps `06` on purpose — a bigger fan-out graph in one file. |
|
|
23
|
+
| `route-demo-fan-out-fan-in` | `06-fan-out-fan-in.pipeline.yaml` | Parallel fan-out (all 3 branches always run) into a join that waits for and combines all 3 real outputs. |
|
|
24
|
+
| `route-demo-loop-human-decision` | `07-loop-human-decision.pipeline.yaml` | The loop config variants `01` doesn't cover: `on_max_replays: wait_for_human` + `replay_session: new_session`. Reliably parks the run waiting for a human decision — exercises the HITL UI flow (`npx tsx src/cli.ts runs answer`), not a bug/stuck state. |
|
|
25
|
+
| `route-demo-skip-and-multi-on` | `08-skip-fallback-and-multi-on-gate.pipeline.yaml` | `decide` fans out to both `risky-step` and `safe-step`. `risky-step` is a leaf. `done` stays only on the safe-step arm (not a join across both). |
|
|
26
|
+
| `route-demo-multi-loop-targets` | `09-multi-loop-targets.pipeline.yaml` | Two *different* stages (`review`, `qa`) each declaring their own loop entry back to the *same* ancestor — `qa` loops to a stage two hops back, not its immediate parent. |
|
|
27
|
+
| `route-demo-uses-dialect-fork` | `10-uses-dialect-fork.pipeline.yaml` | `route`/`entry` combined with the `uses:` external-stage-file dialect — every other pipeline here uses inline `system_prompt`/`model` bodies instead. Both branches always run. |
|
|
28
|
+
| `route-demo-sequential-io` | `11-sequential-io-handoff.pipeline.yaml` | Sequential `io` handoff: parent `draft` `io.output.schema` and child `review` `io.input.schema` share the same object contract (`required: [title]`). `sf validate` is how users see this compatibility check. |
|
|
29
|
+
| `route-demo-complex-io` | `12-complex-io-schemas.pipeline.yaml` | Sequential `io` with pipeline `schemas:` (`finding`, `report`, `analyzed`): nested metadata, array of `$ref` items, enum/pattern/minLength/integer score. `draft → analyze → summarize`; summarize input is a subset (`title`/`summary`/`score` as number). Some `io` sides stay inline (`draft.in`, `summarize.in`/`out`). |
|
|
30
|
+
| `route-demo-ref-io` | `13-ref-io-handoff.pipeline.yaml` | Sequential `io` where **both** every `io.input.schema` and every `io.output.schema` is `$ref: "#/schemas/..."`. `draft.out` and `review.in` share `#/schemas/doc`; `ship.in` is `#/schemas/title-only` (subset of `analyzed`). Unlike `12`, no inline schema sides. |
|
|
31
|
+
| `route-demo-if-eq` | `14-if-eq-gating.pipeline.yaml` | Gated forward `if: { field: severity, op: eq, value: high }` to `page`, plus always-run `notify`. Default prompt emits `severity: low`, so `page` is skipped and the run succeeds. |
|
|
32
|
+
| `route-demo-if-all-gated` | `15-if-all-gated.pipeline.yaml` | Every forward `to:` has `if`. `sf validate` warns `pipeline.route_all_gated` with `ok: true`; `--strict` does not fail. |
|
|
33
|
+
| `route-demo-if-composition` | `16-if-composition.pipeline.yaml` | Nested `not` around `all`, dotted `customer.tier`, and `in`. Default prompt emits a miss, so `page` is skipped and always-run `notify` still runs. |
|
|
34
|
+
| `route-demo-if-join` | `17-if-join.pipeline.yaml` | Two-parent Join gated by inbound `if`s. `write` fires when `ready` is true; `draw` fires when `complete` is true. Default prompts emit both true, so `assemble` runs with both envelopes. Either miss skips `assemble`; the run still succeeds. |
|
|
35
|
+
|
|
36
|
+
## Important: use the local build, not your global `sf`
|
|
37
|
+
|
|
38
|
+
Your globally-installed `sf` (`/opt/homebrew/bin/sf`, `stageflow@0.1.0`) is a much older release and does not contain this branch's changes — running the bare `sf` command would test the wrong code entirely. Use one of these instead, from the **repository git root**:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# no build step, always current — what every command below uses
|
|
42
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml --strict
|
|
43
|
+
|
|
44
|
+
# or build once, then use the built CLI directly
|
|
45
|
+
npm run build
|
|
46
|
+
node dist/cli.js validate --pipeline examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml --strict
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If you want the bare `sf`/`stageflow` command itself to point at this worktree (e.g. so `sf ui` in a browser tab uses it too), run `npm link` from the repo root once — that swaps your global install for this working copy until you `npm unlink` or reinstall the real global package. That's a machine-wide change, so it's your call whether to do it; the commands below don't need it.
|
|
50
|
+
|
|
51
|
+
`sf validate` never calls a model — it only resolves the pipeline's DAG and runs this project's parsing/validation logic, so every command below is free and instant.
|
|
52
|
+
|
|
53
|
+
## Valid pipelines (should pass)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml --strict
|
|
57
|
+
```
|
|
58
|
+
Expect: **Validation passed.** One pipeline, most of the new surface in one realistic flow:
|
|
59
|
+
`plan -> implement -> review` (review's `route` mixes a normal forward entry to `qa` with a `type: loop` entry back to `implement`, `max_replays: 2`, `on_max_replays: require_continue`, `replay_session: resume`) `-> qa` (fans out to both `ship` and `request-changes`) `-> ship` (fans out to `notify-slack`/`notify-email`/`update-changelog`) `-> close` (fan-in of request-changes plus the three notify stages; all four run on the happy path. The Join waits until every parent is terminal. With no inbound `if`, it runs if at least one succeeded. It stays pending if a parent failed. It does not run if every parent skipped).
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml --strict
|
|
63
|
+
```
|
|
64
|
+
Expect: **Validation passed.** `run-tests` lists `ship` (default succeeded) and `hotfix` with `on: [failed]`. `on: [failed]` opts hotfix out of skip-cascade when tests fail; hotfix does not launch; launch still needs a succeeded parent. Deterministic branching after success uses `if`.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml --strict
|
|
68
|
+
```
|
|
69
|
+
Expect: **Validation passed.** Two independent `entry: true` stages, no wiring between them — a topology the core pipeline can't demonstrate (it only has one root).
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml --strict
|
|
73
|
+
```
|
|
74
|
+
Expect: **Validation passed.** `draft` explicitly writes `entry: false`; this must behave exactly like omitting the key. This is the code-review fix that closed a bug where `entry: false` used to incorrectly force the whole pipeline into strict entry-stage validation.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml --strict
|
|
78
|
+
```
|
|
79
|
+
Expect: **Validation passed.** Unconditional fan-out: `triage` lists `quick-fix` and `big-project` — both always run. `quick-fix` lists `notify-team`/`update-docs`/`schedule-followup` — all three always run. `close` fans in those three notify stages. `big-project` is a leaf.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml --strict
|
|
83
|
+
```
|
|
84
|
+
Expect: **Validation passed.** `kickoff`'s `route` list of three targets (`research`/`analysis`/`review-notes`) all fire unconditionally — parallel fan-out, no skipping. `synthesize` is the fan-in join: it waits for and combines all three, every run.
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml --strict
|
|
88
|
+
```
|
|
89
|
+
Expect: **Validation passed.** The loop config variants `01-core-routing` doesn't exercise: `on_max_replays: wait_for_human` (vs. `require_continue`) and `replay_session: new_session` (vs. `resume`). `review`'s prompt always sends work back to `implement`; with `max_replays: 1`, the second send-back exhausts the budget and parks the run for a human decision instead of failing or looping forever.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml --strict
|
|
93
|
+
```
|
|
94
|
+
Expect: **Validation passed.** `decide` lists both `risky-step` and `safe-step`, so both always run. `risky-step` is a leaf. `safe-step` routes to `notify-either-way` on success (the default `on:`), then `done`. `done` is only on that arm, not a join across both.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml --strict
|
|
98
|
+
```
|
|
99
|
+
Expect: **Validation passed.** `review` and `qa` each declare their own `type: loop` entry back to `implement`. `review`'s stays dormant (always continues); `qa`'s fires once (sends back on its first attempt, continues on its second) — demonstrating a loop target that isn't the looping stage's immediate parent (`implement` is two hops back from `qa`), and two independent loop points converging on the same ancestor.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml --strict
|
|
103
|
+
```
|
|
104
|
+
Expect: **Validation passed.** Same fan-out shape as `05-fork-choice`'s `triage` (both listed branches always run), but every stage body lives in an external file under `stages/` and is loaded via `uses:` instead of inline `system_prompt`/`model` — confirms `route`/`entry` work identically under both stage-body dialects.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml --strict
|
|
108
|
+
```
|
|
109
|
+
Expect: **Validation passed.** Parent `draft` `io.output` matches child `review` `io.input` — the same object contract (`required: [title]`). This is the check users see from `sf validate` on sequential (non-clone) edges.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml --strict
|
|
113
|
+
```
|
|
114
|
+
Expect: **Validation passed.** Three-stage `draft → analyze → summarize` with pipeline `schemas:` (`finding`, `report`, `analyzed`): nested metadata, array of `$ref` items, enum/pattern/minLength/integer score. `summarize` input is a subset (`title`/`summary`/`score` as number). Some `io` sides stay inline.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml --strict
|
|
118
|
+
```
|
|
119
|
+
Expect: **Validation passed.** Every `io.input.schema` and `io.output.schema` is `$ref: "#/schemas/..."`. `draft.out` and `review.in` share `#/schemas/doc`; `ship.in` is `#/schemas/title-only` (subset of `analyzed`). Unlike `12`, both sides of every stage are `$ref`.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml --strict
|
|
123
|
+
```
|
|
124
|
+
Expect: **Validation passed.** `triage` routes to `page` only when `severity` equals `high`, and always to `notify`. Mixed gated + always-run siblings do not warn `pipeline.route_all_gated`.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml --strict --json
|
|
128
|
+
```
|
|
129
|
+
Expect: **Validation passed** (`ok: true`) with warning `pipeline.route_all_gated`. `--strict` does not promote that warning to an error.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml --strict
|
|
133
|
+
```
|
|
134
|
+
Expect: **Validation passed.** `page` is gated by `not` / `all` over `severity` and `customer.tier` `in` `[bronze]`. `notify` always runs. Nested required object paths are legal.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/17-if-join.pipeline.yaml --strict
|
|
138
|
+
```
|
|
139
|
+
Expect: **Validation passed.** `write` and `draw` both route to `assemble` with inbound `if`. Default prompts emit `ready: true` and `complete: true`, so the Join child runs with both success envelopes. Change either payload so the predicate misses and `assemble` is skipped (run still succeeds). A false `if` on one parent does not skip `assemble` while the other parent is still running.
|
|
140
|
+
|
|
141
|
+
## Rejected pipelines (should fail with the given message)
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml --strict
|
|
145
|
+
```
|
|
146
|
+
Expect: `stage "review": "needs" is no longer supported — declare the wiring on the source stage's "route" instead`
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml --strict
|
|
150
|
+
```
|
|
151
|
+
Expect: `stage "decide": "fork" is no longer supported — use "route" instead; listed route targets always run`
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml --strict
|
|
155
|
+
```
|
|
156
|
+
Expect: `stage "review": "feedback_loop" is no longer supported — use a "type: loop" entry inside "route" instead`
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml --strict
|
|
160
|
+
```
|
|
161
|
+
Expect: `no stage is marked entry: true` — this pipeline uses `route` but nothing is marked as a start.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml --strict
|
|
165
|
+
```
|
|
166
|
+
Expect: `stage "orphan" is unreachable: not marked entry: true and not targeted by any route entry`
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml --strict
|
|
170
|
+
```
|
|
171
|
+
Expect: `stage "decide": "allow_none" is no longer supported — listed route targets always run`
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml --strict
|
|
175
|
+
```
|
|
176
|
+
Expect: `dependency cycle detected` — `a` routes to `b`, `b` routes back to `a`, as plain forward entries (not a loop).
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml --strict
|
|
180
|
+
```
|
|
181
|
+
Expect: `stage "b": feedback_loop target "c" must be an earlier ancestor` — `b`'s loop entry targets `c`, which is `a`'s other branch (a sibling), not an ancestor of `b`.
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml --strict
|
|
185
|
+
```
|
|
186
|
+
Expect: `stage "decide": "route_select" is no longer supported — listed route targets always run` — the field itself is unsupported, including on a leaf.
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml --strict
|
|
196
|
+
```
|
|
197
|
+
Expect: `stage "review": feedback_loop target "implement" replays replay_safe: false stage "middle"` — a stage sitting on the replay route (between target and source) is marked `replay_safe: false`.
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml --strict
|
|
201
|
+
```
|
|
202
|
+
Expect: `stage "review": route supports at most one loop entry, got 2` — two `type: loop` entries (with different, both-valid targets) on the same stage.
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml --strict
|
|
206
|
+
```
|
|
207
|
+
Expect: `Duplicate stage id "review" in ...` — two stage entries with the same `id` in one pipeline file. (Caught earlier, at the catalog/merge layer, before the route-specific checks even run.)
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml --strict
|
|
211
|
+
```
|
|
212
|
+
Expect: `stage "draft" has unknown route target "nonexistent-stage"`
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml --strict
|
|
216
|
+
```
|
|
217
|
+
Expect: `stage "draft": route item must have a non-empty "to" stage id` — a route entry with only `on:`, no `to:`.
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml --json
|
|
221
|
+
```
|
|
222
|
+
Expect: `io.input is not a structural subset` / `pipeline.io_incompatible` — `draft` outputs `verdict`, `review` requires `title`.
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml --json
|
|
226
|
+
```
|
|
227
|
+
Expect: `pipeline.io_incompatible` / `io.input is not a structural subset` — nested `metadata.owner.email` required on child, parent only has `metadata.source`.
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml --json
|
|
231
|
+
```
|
|
232
|
+
Expect: `pipeline.io_incompatible` / `io.input is not a structural subset` — array items `$ref` child requires `severity`, parent items only `id`.
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml --json
|
|
236
|
+
```
|
|
237
|
+
Expect: `pipeline.io_incompatible` / `io.input is not a structural subset` — child `additionalProperties: false` while parent has extra `extra`.
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml --json
|
|
241
|
+
```
|
|
242
|
+
Expect: `pipeline.io_incompatible` — `draft.out` `$ref` `#/schemas/produced` vs `review.in` `$ref` `#/schemas/consumed` (`consumed` requires extra field `extra`).
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml --json
|
|
246
|
+
```
|
|
247
|
+
Expect: `pipeline.route_if_invalid` — `if.field` is not a property of the source `io.output.schema`.
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml --json
|
|
251
|
+
```
|
|
252
|
+
Expect: `pipeline.route_if_invalid` — `if.field` is present on the output schema but not in `required`.
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml --json
|
|
256
|
+
```
|
|
257
|
+
Expect: `pipeline.route_if_invalid` — empty `all:` list.
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml --json
|
|
261
|
+
```
|
|
262
|
+
Expect: `pipeline.route_if_invalid` — numeric op `gt` on a string field.
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml --json
|
|
266
|
+
```
|
|
267
|
+
Expect: `pipeline.route_if_invalid` — nested path `customer.tier` is not required on the object schema.
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml --json
|
|
271
|
+
```
|
|
272
|
+
Expect: `pipeline.route_if_invalid` — `if` on a `{ type: loop }` Route Entry.
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
npx tsx src/cli.ts validate --pipeline examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml --json
|
|
279
|
+
```
|
|
280
|
+
Expect: `pipeline.route_if_invalid` — `if` combined with `on: [failed]`.
|
|
281
|
+
|
|
282
|
+
## Run from the UI / CLI
|
|
283
|
+
|
|
284
|
+
All 17 valid pipelines and `smoke-test.task.yaml` are registered in the repo-root `stageflow.yaml`. Point the UI at the local build (see "Important" above — either `npm link` first, or run the UI via `npx tsx src/cli.ts ui`):
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
npx tsx src/cli.ts ui
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Start a new run, pick any of the 17 pipeline IDs from the table above, `route-smoke-test` as the task. Requires a Pi-compatible provider connected (`npx tsx src/cli.ts providers login` or via the UI's own connect flow) — actually executing a stage calls a real model, unlike the validate command above.
|
|
291
|
+
|
|
292
|
+
From the repo git root, run a pipeline with this worktree's CLI (never global `sf`):
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
npx tsx src/cli.ts run \
|
|
296
|
+
--pipeline examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml \
|
|
297
|
+
--task examples/route-wiring-smoke-test/smoke-test.task.yaml
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
npx tsx src/cli.ts run \
|
|
302
|
+
--pipeline examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml \
|
|
303
|
+
--task examples/route-wiring-smoke-test/smoke-test.task.yaml
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
npx tsx src/cli.ts run \
|
|
308
|
+
--pipeline examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml \
|
|
309
|
+
--task examples/route-wiring-smoke-test/smoke-test.task.yaml
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Pipeline `07` *will* stop and wait for a human — that's expected (`on_max_replays: wait_for_human`). Unstick it:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
npx tsx src/cli.ts runs waiting
|
|
316
|
+
npx tsx src/cli.ts runs answer --run <runId> --stage review --answer '{"action":"continue"}'
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
(or the UI's own decide control).
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
npx tsx src/cli.ts run \
|
|
323
|
+
--pipeline examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml \
|
|
324
|
+
--task examples/route-wiring-smoke-test/smoke-test.task.yaml
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
npx tsx src/cli.ts run \
|
|
329
|
+
--pipeline examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml \
|
|
330
|
+
--task examples/route-wiring-smoke-test/smoke-test.task.yaml
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
npx tsx src/cli.ts run \
|
|
335
|
+
--pipeline examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml \
|
|
336
|
+
--task examples/route-wiring-smoke-test/smoke-test.task.yaml
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
npx tsx src/cli.ts run \
|
|
341
|
+
--pipeline examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml \
|
|
342
|
+
--task examples/route-wiring-smoke-test/smoke-test.task.yaml
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
npx tsx src/cli.ts run \
|
|
347
|
+
--pipeline examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml \
|
|
348
|
+
--task examples/route-wiring-smoke-test/smoke-test.task.yaml
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
npx tsx src/cli.ts run \
|
|
353
|
+
--pipeline examples/route-wiring-smoke-test/17-if-join.pipeline.yaml \
|
|
354
|
+
--task examples/route-wiring-smoke-test/smoke-test.task.yaml
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Pipelines **11–13** require the agent to emit the example payloads in each stage prompt (`11` draft: `{ "title": "<short string>" }`; `12` draft/analyze copy the `#/schemas/report` / `#/schemas/analyzed` examples; `13` draft/review copy the `#/schemas/doc` / `#/schemas/analyzed` examples). Review/summarize/ship may emit `payload: {}`.
|
|
358
|
+
|
|
359
|
+
- Want to watch a larger fan-out (triage plus three follow-ups from quick-fix)? Run `route-demo-fork-choice`.
|
|
360
|
+
- Want to watch true parallel fan-out/fan-in? Run `route-demo-fan-out-fan-in`.
|
|
361
|
+
- Want to practice the human-in-the-loop decision flow? Run `route-demo-loop-human-decision`.
|
|
362
|
+
- Want to see both arms of a fan-out run, with `done` only on the safe-step arm? Run `route-demo-skip-and-multi-on`.
|
|
363
|
+
- Want to see two loop points converging on one ancestor? Run `route-demo-multi-loop-targets` — it also parks briefly for a replay, same idea as `07`, but resolves itself (`require_continue`) rather than needing a human.
|
|
364
|
+
- Want to confirm the `uses:` dialect works the same as inline stage bodies? Run `route-demo-uses-dialect-fork`.
|
|
365
|
+
- Want to see a payload-gated `page` skip while `notify` still runs? Run `route-demo-if-eq`. The skipped stage is skipped, not a failed run.
|
|
366
|
+
- Want nested `all` / `not` and `customer.tier` `in`? Run `route-demo-if-composition`. Default payload misses, so `page` skips.
|
|
367
|
+
- Want to see a two-parent Join gated by inbound `if`s? Run `route-demo-if-join`. Default payloads match, so `assemble` runs with both envelopes.
|
|
368
|
+
- Want the broadest single flow, including notify stages that all run after ship? Run `route-demo-core`.
|
|
369
|
+
|
|
370
|
+
## What's still out of scope
|
|
371
|
+
|
|
372
|
+
A few things intentionally aren't in this catalog because they're orthogonal to the `route` migration (pre-existing features the migration didn't touch, not gaps in route coverage):
|
|
373
|
+
|
|
374
|
+
- **`gate_kinds`** / non-`feedback_loop` HITL gates — a stage-body concept, unrelated to wiring.
|
|
375
|
+
- **`verify`/`on_verify_fail`** completion contracts interacting with `route` — these fields pass through the migration completely unchanged; already covered by the existing (non-route) test suite.
|
|
376
|
+
- **`skill`/`mcp`** fields on a routed stage — capability wiring, unrelated to routing wiring.
|
|
377
|
+
- **The exact two-sequential-forks race timing** that caused the original "stuck-looking run" bug report — deliberately not turned into a hand-runnable example, since its whole point is a timing race that a live run can't reliably reproduce on demand. It lives only as an automated regression test: `tests/fixtures/pipelines/two-sequential-forks-join.pipeline.yaml` + `tests/runtime.genericFanIn.schedule.test.ts`.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
id: route-demo-reject-needs
|
|
2
|
+
stages:
|
|
3
|
+
- id: draft
|
|
4
|
+
entry: true
|
|
5
|
+
route:
|
|
6
|
+
- to: review
|
|
7
|
+
system_prompt: Draft.
|
|
8
|
+
model: cursor/auto
|
|
9
|
+
io:
|
|
10
|
+
input:
|
|
11
|
+
schema:
|
|
12
|
+
type: object
|
|
13
|
+
output:
|
|
14
|
+
schema:
|
|
15
|
+
type: object
|
|
16
|
+
- id: review
|
|
17
|
+
needs: draft
|
|
18
|
+
system_prompt: Review.
|
|
19
|
+
model: cursor/auto
|
|
20
|
+
io:
|
|
21
|
+
input:
|
|
22
|
+
schema:
|
|
23
|
+
type: object
|
|
24
|
+
output:
|
|
25
|
+
schema:
|
|
26
|
+
type: object
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
id: route-demo-reject-fork
|
|
2
|
+
stages:
|
|
3
|
+
- id: decide
|
|
4
|
+
entry: true
|
|
5
|
+
fork:
|
|
6
|
+
select: one
|
|
7
|
+
system_prompt: Decide.
|
|
8
|
+
model: cursor/auto
|
|
9
|
+
io:
|
|
10
|
+
input:
|
|
11
|
+
schema:
|
|
12
|
+
type: object
|
|
13
|
+
output:
|
|
14
|
+
schema:
|
|
15
|
+
type: object
|
|
16
|
+
- id: branch-a
|
|
17
|
+
system_prompt: Branch A.
|
|
18
|
+
model: cursor/auto
|
|
19
|
+
io:
|
|
20
|
+
input:
|
|
21
|
+
schema:
|
|
22
|
+
type: object
|
|
23
|
+
output:
|
|
24
|
+
schema:
|
|
25
|
+
type: object
|
package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
id: route-demo-reject-feedback-loop
|
|
2
|
+
stages:
|
|
3
|
+
- id: implement
|
|
4
|
+
entry: true
|
|
5
|
+
route:
|
|
6
|
+
- to: review
|
|
7
|
+
system_prompt: Implement.
|
|
8
|
+
model: cursor/auto
|
|
9
|
+
io:
|
|
10
|
+
input:
|
|
11
|
+
schema:
|
|
12
|
+
type: object
|
|
13
|
+
output:
|
|
14
|
+
schema:
|
|
15
|
+
type: object
|
|
16
|
+
- id: review
|
|
17
|
+
feedback_loop:
|
|
18
|
+
target: implement
|
|
19
|
+
max_replays: 2
|
|
20
|
+
on_max_replays: require_continue
|
|
21
|
+
replay_session: resume
|
|
22
|
+
system_prompt: Review.
|
|
23
|
+
model: cursor/auto
|
|
24
|
+
io:
|
|
25
|
+
input:
|
|
26
|
+
schema:
|
|
27
|
+
type: object
|
|
28
|
+
output:
|
|
29
|
+
schema:
|
|
30
|
+
type: object
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
id: route-demo-reject-missing-entry
|
|
2
|
+
stages:
|
|
3
|
+
- id: draft
|
|
4
|
+
route:
|
|
5
|
+
- to: review
|
|
6
|
+
system_prompt: Draft.
|
|
7
|
+
model: cursor/auto
|
|
8
|
+
io:
|
|
9
|
+
input:
|
|
10
|
+
schema:
|
|
11
|
+
type: object
|
|
12
|
+
output:
|
|
13
|
+
schema:
|
|
14
|
+
type: object
|
|
15
|
+
- id: review
|
|
16
|
+
system_prompt: Review.
|
|
17
|
+
model: cursor/auto
|
|
18
|
+
io:
|
|
19
|
+
input:
|
|
20
|
+
schema:
|
|
21
|
+
type: object
|
|
22
|
+
output:
|
|
23
|
+
schema:
|
|
24
|
+
type: object
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
id: route-demo-reject-unreachable
|
|
2
|
+
stages:
|
|
3
|
+
- id: draft
|
|
4
|
+
entry: true
|
|
5
|
+
route:
|
|
6
|
+
- to: review
|
|
7
|
+
system_prompt: Draft.
|
|
8
|
+
model: cursor/auto
|
|
9
|
+
io:
|
|
10
|
+
input:
|
|
11
|
+
schema:
|
|
12
|
+
type: object
|
|
13
|
+
output:
|
|
14
|
+
schema:
|
|
15
|
+
type: object
|
|
16
|
+
- id: review
|
|
17
|
+
system_prompt: Review.
|
|
18
|
+
model: cursor/auto
|
|
19
|
+
io:
|
|
20
|
+
input:
|
|
21
|
+
schema:
|
|
22
|
+
type: object
|
|
23
|
+
output:
|
|
24
|
+
schema:
|
|
25
|
+
type: object
|
|
26
|
+
- id: orphan
|
|
27
|
+
system_prompt: Nobody routes to me, and I'm not marked entry.
|
|
28
|
+
model: cursor/auto
|
|
29
|
+
io:
|
|
30
|
+
input:
|
|
31
|
+
schema:
|
|
32
|
+
type: object
|
|
33
|
+
output:
|
|
34
|
+
schema:
|
|
35
|
+
type: object
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
id: route-demo-reject-allow-none
|
|
2
|
+
stages:
|
|
3
|
+
- id: decide
|
|
4
|
+
entry: true
|
|
5
|
+
allow_none: true
|
|
6
|
+
route:
|
|
7
|
+
- to: path-a
|
|
8
|
+
- to: path-b
|
|
9
|
+
system_prompt: Decide.
|
|
10
|
+
model: cursor/auto
|
|
11
|
+
io:
|
|
12
|
+
input:
|
|
13
|
+
schema:
|
|
14
|
+
type: object
|
|
15
|
+
output:
|
|
16
|
+
schema:
|
|
17
|
+
type: object
|
|
18
|
+
- id: path-a
|
|
19
|
+
system_prompt: A.
|
|
20
|
+
model: cursor/auto
|
|
21
|
+
io:
|
|
22
|
+
input:
|
|
23
|
+
schema:
|
|
24
|
+
type: object
|
|
25
|
+
output:
|
|
26
|
+
schema:
|
|
27
|
+
type: object
|
|
28
|
+
- id: path-b
|
|
29
|
+
system_prompt: B.
|
|
30
|
+
model: cursor/auto
|
|
31
|
+
io:
|
|
32
|
+
input:
|
|
33
|
+
schema:
|
|
34
|
+
type: object
|
|
35
|
+
output:
|
|
36
|
+
schema:
|
|
37
|
+
type: object
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
id: route-demo-reject-cycle
|
|
2
|
+
stages:
|
|
3
|
+
- id: a
|
|
4
|
+
entry: true
|
|
5
|
+
route:
|
|
6
|
+
- to: b
|
|
7
|
+
system_prompt: A.
|
|
8
|
+
model: cursor/auto
|
|
9
|
+
io:
|
|
10
|
+
input:
|
|
11
|
+
schema:
|
|
12
|
+
type: object
|
|
13
|
+
output:
|
|
14
|
+
schema:
|
|
15
|
+
type: object
|
|
16
|
+
- id: b
|
|
17
|
+
route:
|
|
18
|
+
- to: a
|
|
19
|
+
system_prompt: B.
|
|
20
|
+
model: cursor/auto
|
|
21
|
+
io:
|
|
22
|
+
input:
|
|
23
|
+
schema:
|
|
24
|
+
type: object
|
|
25
|
+
output:
|
|
26
|
+
schema:
|
|
27
|
+
type: object
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
id: route-demo-reject-loop-non-ancestor
|
|
2
|
+
stages:
|
|
3
|
+
- id: a
|
|
4
|
+
entry: true
|
|
5
|
+
route:
|
|
6
|
+
- to: b
|
|
7
|
+
- to: c
|
|
8
|
+
system_prompt: A.
|
|
9
|
+
model: cursor/auto
|
|
10
|
+
io:
|
|
11
|
+
input:
|
|
12
|
+
schema:
|
|
13
|
+
type: object
|
|
14
|
+
output:
|
|
15
|
+
schema:
|
|
16
|
+
type: object
|
|
17
|
+
- id: b
|
|
18
|
+
route:
|
|
19
|
+
- type: loop
|
|
20
|
+
to: c
|
|
21
|
+
max_replays: 1
|
|
22
|
+
on_max_replays: require_continue
|
|
23
|
+
replay_session: resume
|
|
24
|
+
system_prompt: B.
|
|
25
|
+
model: cursor/auto
|
|
26
|
+
io:
|
|
27
|
+
input:
|
|
28
|
+
schema:
|
|
29
|
+
type: object
|
|
30
|
+
output:
|
|
31
|
+
schema:
|
|
32
|
+
type: object
|
|
33
|
+
- id: c
|
|
34
|
+
system_prompt: C.
|
|
35
|
+
model: cursor/auto
|
|
36
|
+
io:
|
|
37
|
+
input:
|
|
38
|
+
schema:
|
|
39
|
+
type: object
|
|
40
|
+
output:
|
|
41
|
+
schema:
|
|
42
|
+
type: object
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
id: route-demo-reject-route-select-leaf
|
|
2
|
+
stages:
|
|
3
|
+
- id: decide
|
|
4
|
+
entry: true
|
|
5
|
+
route_select: one
|
|
6
|
+
route:
|
|
7
|
+
- to: only-branch
|
|
8
|
+
system_prompt: Decide.
|
|
9
|
+
model: cursor/auto
|
|
10
|
+
io:
|
|
11
|
+
input:
|
|
12
|
+
schema:
|
|
13
|
+
type: object
|
|
14
|
+
output:
|
|
15
|
+
schema:
|
|
16
|
+
type: object
|
|
17
|
+
- id: only-branch
|
|
18
|
+
system_prompt: Only branch.
|
|
19
|
+
model: cursor/auto
|
|
20
|
+
io:
|
|
21
|
+
input:
|
|
22
|
+
schema:
|
|
23
|
+
type: object
|
|
24
|
+
output:
|
|
25
|
+
schema:
|
|
26
|
+
type: object
|