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,56 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
2
|
+
const DEFAULT_BIND = "127.0.0.1";
|
|
3
|
+
export function resolveListenHost(options) {
|
|
4
|
+
const env = options.env ?? process.env;
|
|
5
|
+
let raw;
|
|
6
|
+
if (options.flag !== undefined) {
|
|
7
|
+
raw = options.flag;
|
|
8
|
+
}
|
|
9
|
+
else if (env.STAGEFLOW_BIND !== undefined) {
|
|
10
|
+
raw = env.STAGEFLOW_BIND;
|
|
11
|
+
}
|
|
12
|
+
if (raw === undefined) {
|
|
13
|
+
return DEFAULT_BIND;
|
|
14
|
+
}
|
|
15
|
+
const value = raw.trim();
|
|
16
|
+
if (value.length === 0) {
|
|
17
|
+
throw new Error(`Invalid --host / STAGEFLOW_BIND value: ${JSON.stringify(raw)}. Use an IPv4 or IPv6 literal, 0.0.0.0, or ::.`);
|
|
18
|
+
}
|
|
19
|
+
const normalized = unwrapIpv6Brackets(value);
|
|
20
|
+
if (value.includes("://") ||
|
|
21
|
+
value.includes("/") ||
|
|
22
|
+
looksLikeHostPort(value) ||
|
|
23
|
+
isIP(normalized) === 0) {
|
|
24
|
+
throw new Error(`Invalid --host / STAGEFLOW_BIND value: ${JSON.stringify(value)}. Use an IPv4 or IPv6 literal, 0.0.0.0, or ::.`);
|
|
25
|
+
}
|
|
26
|
+
return normalized;
|
|
27
|
+
}
|
|
28
|
+
export function advertisedHost(bind) {
|
|
29
|
+
if (bind === "0.0.0.0")
|
|
30
|
+
return "127.0.0.1";
|
|
31
|
+
if (bind === "::")
|
|
32
|
+
return "[::1]";
|
|
33
|
+
if (isIP(bind) === 6)
|
|
34
|
+
return `[${bind}]`;
|
|
35
|
+
return bind;
|
|
36
|
+
}
|
|
37
|
+
function unwrapIpv6Brackets(value) {
|
|
38
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
39
|
+
return value.slice(1, -1);
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
function looksLikeHostPort(value) {
|
|
44
|
+
if (value.startsWith("[")) {
|
|
45
|
+
const end = value.indexOf("]");
|
|
46
|
+
if (end === -1)
|
|
47
|
+
return false;
|
|
48
|
+
const rest = value.slice(end + 1);
|
|
49
|
+
return rest.startsWith(":") && rest.length > 1;
|
|
50
|
+
}
|
|
51
|
+
const colon = value.lastIndexOf(":");
|
|
52
|
+
if (colon <= 0)
|
|
53
|
+
return false;
|
|
54
|
+
const maybePort = value.slice(colon + 1);
|
|
55
|
+
return /^\d+$/.test(maybePort) && isIP(value.slice(0, colon)) !== 0;
|
|
56
|
+
}
|
package/dist/server/mcpHost.d.ts
CHANGED
|
@@ -3,7 +3,10 @@ import type { ProviderAuthContext } from "../agent/providerAuth.js";
|
|
|
3
3
|
import type { RunStoreKind } from "../runstore/createStore.js";
|
|
4
4
|
import type { RunStore } from "../runstore/port.js";
|
|
5
5
|
import type { RunChangeBus } from "../runtime/runChangeBus.js";
|
|
6
|
+
import type { AllowedHosts } from "./allowedHosts.js";
|
|
7
|
+
import type { ControlTokens } from "./controlToken.js";
|
|
6
8
|
import { DEFAULT_PORT, type HttpHostEnvelope } from "./createHttpHost.js";
|
|
9
|
+
import { type ShutdownController } from "./shutdown.js";
|
|
7
10
|
export type McpServerOptions = {
|
|
8
11
|
agent: AgentPort;
|
|
9
12
|
cwd?: string;
|
|
@@ -17,6 +20,12 @@ export type McpServerOptions = {
|
|
|
17
20
|
providerAuthContext?: ProviderAuthContext;
|
|
18
21
|
mcpStateless?: boolean;
|
|
19
22
|
runChangeBus?: RunChangeBus;
|
|
23
|
+
allowedHosts?: AllowedHosts;
|
|
24
|
+
controlTokens?: ControlTokens;
|
|
25
|
+
requestTimeoutMs?: number;
|
|
26
|
+
maxConnections?: number;
|
|
20
27
|
};
|
|
21
|
-
export declare function startMcpServer(options: McpServerOptions): Promise<HttpHostEnvelope
|
|
28
|
+
export declare function startMcpServer(options: McpServerOptions): Promise<HttpHostEnvelope & {
|
|
29
|
+
shutdown: ShutdownController;
|
|
30
|
+
}>;
|
|
22
31
|
export { DEFAULT_PORT };
|
package/dist/server/mcpHost.js
CHANGED
|
@@ -1,20 +1,50 @@
|
|
|
1
1
|
import { bootstrapStageflowHost, } from "./bootstrap.js";
|
|
2
|
+
import { resolveAllowedHosts } from "./allowedHosts.js";
|
|
3
|
+
import { loadControlTokens } from "./controlToken.js";
|
|
2
4
|
import { createHttpHost, DEFAULT_PORT, } from "./createHttpHost.js";
|
|
3
5
|
import { createOperatorRoutes } from "./http.js";
|
|
6
|
+
import { installShutdownController, makeDrainableHostFromOptional, } from "./shutdown.js";
|
|
4
7
|
export async function startMcpServer(options) {
|
|
5
8
|
const host = options.host ?? "127.0.0.1";
|
|
6
9
|
const port = options.port ?? DEFAULT_PORT;
|
|
7
10
|
const boot = await bootstrapStageflowHost(options);
|
|
8
|
-
const {
|
|
11
|
+
const { cwd, agentDir, rootDir } = boot;
|
|
9
12
|
const providerAuthContext = boot.providerAuthContext;
|
|
10
|
-
|
|
13
|
+
const allowedHosts = options.allowedHosts ?? resolveAllowedHosts();
|
|
14
|
+
const controlTokens = options.controlTokens ?? loadControlTokens();
|
|
15
|
+
let shutdown;
|
|
16
|
+
const routes = boot.serveBlocked !== undefined ||
|
|
17
|
+
boot.manager === undefined ||
|
|
18
|
+
boot.store === undefined
|
|
19
|
+
? async () => false
|
|
20
|
+
: createOperatorRoutes({
|
|
21
|
+
manager: boot.manager,
|
|
22
|
+
store: boot.store,
|
|
23
|
+
cwd,
|
|
24
|
+
agentDir,
|
|
25
|
+
rootDir,
|
|
26
|
+
providerAuthContext,
|
|
27
|
+
allowedHosts,
|
|
28
|
+
controlTokens,
|
|
29
|
+
getShutdown: () => shutdown,
|
|
30
|
+
});
|
|
31
|
+
const envelope = await createHttpHost({
|
|
11
32
|
boot,
|
|
12
33
|
host,
|
|
13
34
|
port,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
35
|
+
allowedHosts,
|
|
36
|
+
controlTokens,
|
|
37
|
+
requestTimeoutMs: options.requestTimeoutMs,
|
|
38
|
+
maxConnections: options.maxConnections,
|
|
39
|
+
routes,
|
|
18
40
|
});
|
|
41
|
+
shutdown = installShutdownController({
|
|
42
|
+
server: envelope.server,
|
|
43
|
+
host: makeDrainableHostFromOptional(envelope.manager, envelope.store),
|
|
44
|
+
});
|
|
45
|
+
envelope.server.on("close", () => {
|
|
46
|
+
shutdown?.uninstall();
|
|
47
|
+
});
|
|
48
|
+
return { ...envelope, shutdown };
|
|
19
49
|
}
|
|
20
50
|
export { DEFAULT_PORT };
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { RetryStageResult, StartRunResult } from "../runtime/runManager.js";
|
|
2
|
-
export declare function inferRetryStageErrorCode(reason: string): string | undefined;
|
|
3
2
|
export declare function mapRetryStageFailure(result: Extract<RetryStageResult, {
|
|
4
3
|
ok: false;
|
|
5
4
|
}>): {
|
|
6
5
|
error: string;
|
|
7
|
-
code
|
|
6
|
+
code: string;
|
|
8
7
|
} & Record<string, unknown>;
|
|
9
8
|
export declare function mapStartFailure(result: Extract<StartRunResult, {
|
|
10
9
|
ok: false;
|
|
@@ -17,6 +16,7 @@ export type StoreLookupMapped = {
|
|
|
17
16
|
error: string;
|
|
18
17
|
status: number;
|
|
19
18
|
kind: StoreLookupKind;
|
|
19
|
+
code: string;
|
|
20
20
|
};
|
|
21
21
|
export declare function mapStoreLookupError(err: unknown, opts: {
|
|
22
22
|
policy: StoreLookupPolicy;
|
|
@@ -1,48 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
if (/retry already in progress/i.test(reason))
|
|
3
|
-
return "retry_in_progress";
|
|
4
|
-
if (/waiting for input/i.test(reason))
|
|
5
|
-
return "hitl_not_retriable";
|
|
6
|
-
if (/already has active orchestration/i.test(reason))
|
|
7
|
-
return "run_not_retryable";
|
|
8
|
-
if (/run is not failed/i.test(reason))
|
|
9
|
-
return "run_not_retryable";
|
|
10
|
-
if (/stage is not failed/i.test(reason))
|
|
11
|
-
return "stage_not_failed";
|
|
12
|
-
if (/manual recovery/i.test(reason))
|
|
13
|
-
return "manual_recovery_required";
|
|
14
|
-
return undefined;
|
|
15
|
-
}
|
|
1
|
+
import { codeOrInternal } from "../errors/codes.js";
|
|
16
2
|
export function mapRetryStageFailure(result) {
|
|
17
|
-
const { ok: _ok, status: _status, reason, ...rest } = result;
|
|
18
|
-
|
|
19
|
-
return { error: reason, ...(code ? { code } : {}), ...rest };
|
|
3
|
+
const { ok: _ok, status: _status, reason, code, ...rest } = result;
|
|
4
|
+
return { error: reason, code: codeOrInternal(code), ...rest };
|
|
20
5
|
}
|
|
21
6
|
export function mapStartFailure(result) {
|
|
22
7
|
const { ok: _ok, status: _status, reason, ...rest } = result;
|
|
23
8
|
return { error: reason, ...rest };
|
|
24
9
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
10
|
+
function storeLookupCode(kind, policy) {
|
|
11
|
+
if (kind === "denied")
|
|
12
|
+
return "artifact_path_denied";
|
|
13
|
+
if (kind === "not_found") {
|
|
14
|
+
if (policy === "artifact")
|
|
15
|
+
return "artifact_not_found";
|
|
16
|
+
if (policy === "envelope")
|
|
17
|
+
return "envelope_not_found";
|
|
18
|
+
return "run_not_found";
|
|
19
|
+
}
|
|
20
|
+
return "internal_error";
|
|
21
|
+
}
|
|
22
|
+
function classifyStoreMessage(error, policy) {
|
|
23
|
+
if (policy === "artifact") {
|
|
28
24
|
if (error === "Artifact path denied") {
|
|
29
|
-
return {
|
|
25
|
+
return { kind: "denied", status: 400 };
|
|
30
26
|
}
|
|
31
27
|
const notFound = error.startsWith("Run not found") ||
|
|
32
28
|
error.startsWith("Artifact not found") ||
|
|
33
|
-
|
|
29
|
+
error.startsWith("Checkout file not found");
|
|
34
30
|
return {
|
|
35
|
-
error,
|
|
31
|
+
kind: notFound ? "not_found" : "error",
|
|
36
32
|
status: notFound ? 404 : 400,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (policy === "envelope") {
|
|
36
|
+
const notFound = error.startsWith("Envelope not found") ||
|
|
37
|
+
error.startsWith("Run not found") ||
|
|
38
|
+
error.startsWith("Stage execution not found");
|
|
39
|
+
return {
|
|
37
40
|
kind: notFound ? "not_found" : "error",
|
|
41
|
+
status: notFound ? 404 : 500,
|
|
38
42
|
};
|
|
39
43
|
}
|
|
40
|
-
const notFound =
|
|
41
|
-
? /not found|no such|envelope/i.test(error)
|
|
42
|
-
: /not found|no such|unknown run/i.test(error);
|
|
44
|
+
const notFound = error.startsWith("Run not found") || error.startsWith("unknown run");
|
|
43
45
|
return {
|
|
44
|
-
error,
|
|
45
|
-
status: notFound ? 404 : 500,
|
|
46
46
|
kind: notFound ? "not_found" : "error",
|
|
47
|
+
status: notFound ? 404 : 500,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export function mapStoreLookupError(err, opts) {
|
|
51
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
52
|
+
const classified = classifyStoreMessage(error, opts.policy);
|
|
53
|
+
return {
|
|
54
|
+
error,
|
|
55
|
+
status: classified.status,
|
|
56
|
+
kind: classified.kind,
|
|
57
|
+
code: storeLookupCode(classified.kind, opts.policy),
|
|
47
58
|
};
|
|
48
59
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BearerAuth, ControlScope } from "./controlToken.js";
|
|
2
|
+
export type CallerSurface = "mcp" | "rest" | "cli" | "a2a";
|
|
3
|
+
export type RequestAuthContext = {
|
|
4
|
+
scope: ControlScope;
|
|
5
|
+
caller_id: string;
|
|
6
|
+
surface: CallerSurface;
|
|
7
|
+
};
|
|
8
|
+
export declare function runWithRequestAuth<T>(auth: RequestAuthContext | null, fn: () => T): T;
|
|
9
|
+
export declare function getRequestAuth(): RequestAuthContext | null;
|
|
10
|
+
export declare function requestAuthFromBearer(bearer: BearerAuth | undefined, surface: CallerSurface): RequestAuthContext | null;
|
|
11
|
+
/** Attribution for createRun: auth caller only; CLI / open loopback → null. */
|
|
12
|
+
export declare function callerIdFromRequestAuth(): string | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
const storage = new AsyncLocalStorage();
|
|
3
|
+
export function runWithRequestAuth(auth, fn) {
|
|
4
|
+
return storage.run(auth, fn);
|
|
5
|
+
}
|
|
6
|
+
export function getRequestAuth() {
|
|
7
|
+
return storage.getStore() ?? null;
|
|
8
|
+
}
|
|
9
|
+
export function requestAuthFromBearer(bearer, surface) {
|
|
10
|
+
if (bearer === undefined)
|
|
11
|
+
return null;
|
|
12
|
+
return {
|
|
13
|
+
scope: bearer.scope,
|
|
14
|
+
caller_id: bearer.caller_id,
|
|
15
|
+
surface,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Attribution for createRun: auth caller only; CLI / open loopback → null. */
|
|
19
|
+
export function callerIdFromRequestAuth() {
|
|
20
|
+
return getRequestAuth()?.caller_id ?? null;
|
|
21
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Server } from "node:http";
|
|
2
|
+
import { type Logger } from "../logging/logger.js";
|
|
3
|
+
import type { RunStore } from "../runstore/port.js";
|
|
4
|
+
import type { RunManager } from "../runtime/runManager.js";
|
|
5
|
+
export interface DrainableHost {
|
|
6
|
+
stopAcceptingWork(): void;
|
|
7
|
+
drainActiveStages(opts: {
|
|
8
|
+
deadlineMs: number;
|
|
9
|
+
isEscalated?: () => boolean;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
forced: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
closeStore(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export declare function makeDrainableHost(manager: RunManager, store: RunStore): DrainableHost;
|
|
16
|
+
export declare function makeDrainableHostFromOptional(manager: RunManager | undefined, store: RunStore | undefined): DrainableHost;
|
|
17
|
+
export declare const SHUTDOWN_GRACE_MS_ENV = "STAGEFLOW_SHUTDOWN_GRACE_MS";
|
|
18
|
+
export declare const DEFAULT_SHUTDOWN_GRACE_MS = 8000;
|
|
19
|
+
export declare const CHECKPOINT_RESERVE_MS = 2000;
|
|
20
|
+
export declare const ESCALATION_CHECKPOINT_MS = 1000;
|
|
21
|
+
export declare const HOST_EXIT: {
|
|
22
|
+
readonly CLEAN: 0;
|
|
23
|
+
readonly CRASH: 1;
|
|
24
|
+
readonly RESERVED: 2;
|
|
25
|
+
readonly BAD_CONFIG: 3;
|
|
26
|
+
readonly STORE_NEWER: 4;
|
|
27
|
+
readonly FORCED: 5;
|
|
28
|
+
readonly ESCALATED: 6;
|
|
29
|
+
};
|
|
30
|
+
export type HostExitCode = (typeof HOST_EXIT)[keyof typeof HOST_EXIT];
|
|
31
|
+
export type HostDrainResult = {
|
|
32
|
+
exitCode: typeof HOST_EXIT.CLEAN | typeof HOST_EXIT.FORCED | typeof HOST_EXIT.ESCALATED;
|
|
33
|
+
forced: boolean;
|
|
34
|
+
escalated: boolean;
|
|
35
|
+
};
|
|
36
|
+
export type ShutdownControllerOptions = {
|
|
37
|
+
server: Server;
|
|
38
|
+
host: DrainableHost;
|
|
39
|
+
graceMs?: number;
|
|
40
|
+
env?: NodeJS.ProcessEnv;
|
|
41
|
+
logger?: Logger;
|
|
42
|
+
/** When false, callers drive drain via `beginDrain()` (tests). Default true. */
|
|
43
|
+
installSignals?: boolean;
|
|
44
|
+
};
|
|
45
|
+
export declare function parseShutdownGraceMs(env?: NodeJS.ProcessEnv): number;
|
|
46
|
+
export declare function workerBudgetMs(graceMs: number): number;
|
|
47
|
+
export declare class ShutdownController {
|
|
48
|
+
private readonly server;
|
|
49
|
+
private readonly host;
|
|
50
|
+
private readonly graceMs;
|
|
51
|
+
private readonly log;
|
|
52
|
+
private readonly installSignals;
|
|
53
|
+
private drainPromise;
|
|
54
|
+
private escalated;
|
|
55
|
+
private readonly escalateWaiters;
|
|
56
|
+
private installed;
|
|
57
|
+
private drainStarted;
|
|
58
|
+
constructor(options: ShutdownControllerOptions);
|
|
59
|
+
install(): void;
|
|
60
|
+
uninstall(): void;
|
|
61
|
+
/** Deliver a SIGTERM/SIGINT-equivalent (tests and supervisors). */
|
|
62
|
+
notifySignal(): void;
|
|
63
|
+
whenDrained(): Promise<HostDrainResult>;
|
|
64
|
+
beginDrain(): Promise<HostDrainResult>;
|
|
65
|
+
private readonly onSignal;
|
|
66
|
+
private waitUntil;
|
|
67
|
+
private runDrain;
|
|
68
|
+
}
|
|
69
|
+
export declare function installShutdownController(options: ShutdownControllerOptions): ShutdownController;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { logger as rootLogger, } from "../logging/logger.js";
|
|
2
|
+
export function makeDrainableHost(manager, store) {
|
|
3
|
+
return {
|
|
4
|
+
stopAcceptingWork: () => manager.stopAcceptingWork(),
|
|
5
|
+
drainActiveStages: (opts) => manager.drainActiveStages(opts),
|
|
6
|
+
closeStore: () => store.close(),
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
const noopDrainableHost = {
|
|
10
|
+
stopAcceptingWork: () => { },
|
|
11
|
+
drainActiveStages: async () => ({ forced: false }),
|
|
12
|
+
closeStore: async () => { },
|
|
13
|
+
};
|
|
14
|
+
export function makeDrainableHostFromOptional(manager, store) {
|
|
15
|
+
if (manager !== undefined && store !== undefined) {
|
|
16
|
+
return makeDrainableHost(manager, store);
|
|
17
|
+
}
|
|
18
|
+
return noopDrainableHost;
|
|
19
|
+
}
|
|
20
|
+
export const SHUTDOWN_GRACE_MS_ENV = "STAGEFLOW_SHUTDOWN_GRACE_MS";
|
|
21
|
+
export const DEFAULT_SHUTDOWN_GRACE_MS = 8000;
|
|
22
|
+
export const CHECKPOINT_RESERVE_MS = 2000;
|
|
23
|
+
export const ESCALATION_CHECKPOINT_MS = 1000;
|
|
24
|
+
export const HOST_EXIT = {
|
|
25
|
+
CLEAN: 0,
|
|
26
|
+
CRASH: 1,
|
|
27
|
+
RESERVED: 2,
|
|
28
|
+
BAD_CONFIG: 3,
|
|
29
|
+
STORE_NEWER: 4,
|
|
30
|
+
FORCED: 5,
|
|
31
|
+
ESCALATED: 6,
|
|
32
|
+
};
|
|
33
|
+
export function parseShutdownGraceMs(env = process.env) {
|
|
34
|
+
const raw = env[SHUTDOWN_GRACE_MS_ENV]?.trim();
|
|
35
|
+
if (raw === undefined || raw === "") {
|
|
36
|
+
return DEFAULT_SHUTDOWN_GRACE_MS;
|
|
37
|
+
}
|
|
38
|
+
const parsed = Number(raw);
|
|
39
|
+
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
40
|
+
return DEFAULT_SHUTDOWN_GRACE_MS;
|
|
41
|
+
}
|
|
42
|
+
return Math.floor(parsed);
|
|
43
|
+
}
|
|
44
|
+
export function workerBudgetMs(graceMs) {
|
|
45
|
+
return Math.max(0, graceMs - CHECKPOINT_RESERVE_MS);
|
|
46
|
+
}
|
|
47
|
+
export class ShutdownController {
|
|
48
|
+
server;
|
|
49
|
+
host;
|
|
50
|
+
graceMs;
|
|
51
|
+
log;
|
|
52
|
+
installSignals;
|
|
53
|
+
drainPromise;
|
|
54
|
+
escalated = false;
|
|
55
|
+
escalateWaiters = new Set();
|
|
56
|
+
installed = false;
|
|
57
|
+
drainStarted;
|
|
58
|
+
constructor(options) {
|
|
59
|
+
this.server = options.server;
|
|
60
|
+
this.host = options.host;
|
|
61
|
+
this.graceMs =
|
|
62
|
+
options.graceMs ?? parseShutdownGraceMs(options.env ?? process.env);
|
|
63
|
+
this.log =
|
|
64
|
+
options.logger ?? rootLogger.child({ component: "shutdown" });
|
|
65
|
+
this.installSignals = options.installSignals !== false;
|
|
66
|
+
}
|
|
67
|
+
install() {
|
|
68
|
+
if (!this.installSignals || this.installed)
|
|
69
|
+
return;
|
|
70
|
+
this.installed = true;
|
|
71
|
+
process.on("SIGTERM", this.onSignal);
|
|
72
|
+
process.on("SIGINT", this.onSignal);
|
|
73
|
+
}
|
|
74
|
+
uninstall() {
|
|
75
|
+
if (!this.installed)
|
|
76
|
+
return;
|
|
77
|
+
this.installed = false;
|
|
78
|
+
process.off("SIGTERM", this.onSignal);
|
|
79
|
+
process.off("SIGINT", this.onSignal);
|
|
80
|
+
}
|
|
81
|
+
/** Deliver a SIGTERM/SIGINT-equivalent (tests and supervisors). */
|
|
82
|
+
notifySignal() {
|
|
83
|
+
this.onSignal();
|
|
84
|
+
}
|
|
85
|
+
whenDrained() {
|
|
86
|
+
if (this.drainPromise !== undefined) {
|
|
87
|
+
return this.drainPromise;
|
|
88
|
+
}
|
|
89
|
+
if (this.drainStarted === undefined) {
|
|
90
|
+
let resolve;
|
|
91
|
+
const promise = new Promise((r) => {
|
|
92
|
+
resolve = r;
|
|
93
|
+
});
|
|
94
|
+
this.drainStarted = { resolve, promise };
|
|
95
|
+
}
|
|
96
|
+
return this.drainStarted.promise.then((p) => p);
|
|
97
|
+
}
|
|
98
|
+
beginDrain() {
|
|
99
|
+
if (this.drainPromise !== undefined) {
|
|
100
|
+
return this.drainPromise;
|
|
101
|
+
}
|
|
102
|
+
this.drainPromise = this.runDrain();
|
|
103
|
+
if (this.drainStarted === undefined) {
|
|
104
|
+
let resolve;
|
|
105
|
+
const promise = new Promise((r) => {
|
|
106
|
+
resolve = r;
|
|
107
|
+
});
|
|
108
|
+
this.drainStarted = { resolve, promise };
|
|
109
|
+
}
|
|
110
|
+
this.drainStarted.resolve(this.drainPromise);
|
|
111
|
+
return this.drainPromise;
|
|
112
|
+
}
|
|
113
|
+
onSignal = () => {
|
|
114
|
+
if (this.drainPromise === undefined) {
|
|
115
|
+
this.log.info("host.shutdown.signal", "shutdown signal received", {
|
|
116
|
+
grace_ms: this.graceMs,
|
|
117
|
+
});
|
|
118
|
+
void this.beginDrain();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (this.escalated)
|
|
122
|
+
return;
|
|
123
|
+
this.escalated = true;
|
|
124
|
+
this.log.warn("host.shutdown.escalated", "second shutdown signal; escalating", { grace_ms: this.graceMs });
|
|
125
|
+
for (const wake of this.escalateWaiters) {
|
|
126
|
+
wake();
|
|
127
|
+
}
|
|
128
|
+
this.escalateWaiters.clear();
|
|
129
|
+
};
|
|
130
|
+
waitUntil(deadlineMs) {
|
|
131
|
+
return new Promise((resolve) => {
|
|
132
|
+
const finish = () => {
|
|
133
|
+
clearInterval(timer);
|
|
134
|
+
this.escalateWaiters.delete(finish);
|
|
135
|
+
resolve();
|
|
136
|
+
};
|
|
137
|
+
const timer = setInterval(() => {
|
|
138
|
+
if (this.escalated || Date.now() >= deadlineMs) {
|
|
139
|
+
finish();
|
|
140
|
+
}
|
|
141
|
+
}, 25);
|
|
142
|
+
this.escalateWaiters.add(finish);
|
|
143
|
+
if (this.escalated || Date.now() >= deadlineMs) {
|
|
144
|
+
finish();
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
async runDrain() {
|
|
149
|
+
const startedAt = Date.now();
|
|
150
|
+
const hardDeadline = startedAt + this.graceMs;
|
|
151
|
+
const workerDeadline = startedAt + workerBudgetMs(this.graceMs);
|
|
152
|
+
this.log.info("host.shutdown.drain_start", "beginning host drain", {
|
|
153
|
+
grace_ms: this.graceMs,
|
|
154
|
+
worker_budget_ms: workerBudgetMs(this.graceMs),
|
|
155
|
+
});
|
|
156
|
+
this.host.stopAcceptingWork();
|
|
157
|
+
try {
|
|
158
|
+
this.server.closeIdleConnections();
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// older Node or already closing
|
|
162
|
+
}
|
|
163
|
+
const serverClosed = new Promise((resolve) => {
|
|
164
|
+
this.server.close(() => resolve());
|
|
165
|
+
});
|
|
166
|
+
const stageResult = await this.host.drainActiveStages({
|
|
167
|
+
deadlineMs: workerDeadline,
|
|
168
|
+
isEscalated: () => this.escalated,
|
|
169
|
+
});
|
|
170
|
+
const checkpointDeadline = this.escalated
|
|
171
|
+
? Date.now() + ESCALATION_CHECKPOINT_MS
|
|
172
|
+
: hardDeadline;
|
|
173
|
+
let storeCloseFailed = false;
|
|
174
|
+
try {
|
|
175
|
+
await this.host.closeStore();
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
storeCloseFailed = true;
|
|
179
|
+
this.log.error("host.shutdown.store_close_failed", err instanceof Error ? err.message : String(err));
|
|
180
|
+
}
|
|
181
|
+
await Promise.race([
|
|
182
|
+
serverClosed,
|
|
183
|
+
this.waitUntil(checkpointDeadline),
|
|
184
|
+
]);
|
|
185
|
+
try {
|
|
186
|
+
this.server.closeAllConnections();
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// ignore
|
|
190
|
+
}
|
|
191
|
+
await Promise.race([
|
|
192
|
+
serverClosed,
|
|
193
|
+
this.waitUntil(Date.now() + 100),
|
|
194
|
+
]);
|
|
195
|
+
this.uninstall();
|
|
196
|
+
const forced = stageResult.forced || storeCloseFailed;
|
|
197
|
+
const exitCode = this.escalated
|
|
198
|
+
? HOST_EXIT.ESCALATED
|
|
199
|
+
: forced
|
|
200
|
+
? HOST_EXIT.FORCED
|
|
201
|
+
: HOST_EXIT.CLEAN;
|
|
202
|
+
this.log.info("host.shutdown.drain_complete", "host drain complete", {
|
|
203
|
+
exit_code: exitCode,
|
|
204
|
+
forced,
|
|
205
|
+
escalated: this.escalated,
|
|
206
|
+
elapsed_ms: Date.now() - startedAt,
|
|
207
|
+
});
|
|
208
|
+
return {
|
|
209
|
+
exitCode,
|
|
210
|
+
forced,
|
|
211
|
+
escalated: this.escalated,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
export function installShutdownController(options) {
|
|
216
|
+
const controller = new ShutdownController(options);
|
|
217
|
+
controller.install();
|
|
218
|
+
return controller;
|
|
219
|
+
}
|
package/dist/types/pipeline.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { LoadedStageConfig, StageGateKind, StageIoYaml } from "./stage.js";
|
|
2
2
|
import type { CompletionContract, RecoveryPolicy } from "./completion.js";
|
|
3
|
+
import type { StageSecretDecl } from "../runtime/stageSecretDecl.js";
|
|
4
|
+
import type { ToolRequirement } from "../config/toolRequires.js";
|
|
3
5
|
export type PipelineConfig = {
|
|
4
6
|
id: string;
|
|
5
7
|
stages: string[];
|
|
@@ -9,6 +11,8 @@ export type PipelineConfig = {
|
|
|
9
11
|
model?: string;
|
|
10
12
|
/** Pipeline-file `$ref` root (`#/schemas/<name>`). */
|
|
11
13
|
schemas?: Record<string, unknown>;
|
|
14
|
+
/** Declared toolchain binaries this pipeline needs (Slot 9). */
|
|
15
|
+
requires?: ToolRequirement[];
|
|
12
16
|
};
|
|
13
17
|
/** An inline pipeline definition authored directly in a `start_run` call, with no backing file. */
|
|
14
18
|
export type InlinePipelineDefinition = {
|
|
@@ -17,6 +21,7 @@ export type InlinePipelineDefinition = {
|
|
|
17
21
|
agent?: unknown;
|
|
18
22
|
model?: unknown;
|
|
19
23
|
schemas?: unknown;
|
|
24
|
+
requires?: unknown;
|
|
20
25
|
};
|
|
21
26
|
export type PipelineForkConfig = {
|
|
22
27
|
select: "one" | "subset";
|
|
@@ -155,6 +160,8 @@ export type NormalizedPipelineStageEntry = {
|
|
|
155
160
|
entry?: boolean;
|
|
156
161
|
skill?: string;
|
|
157
162
|
mcp?: string[];
|
|
163
|
+
secrets?: StageSecretDecl[];
|
|
164
|
+
requires?: ToolRequirement[];
|
|
158
165
|
clone_cap?: number;
|
|
159
166
|
clone_mode?: CloneMode;
|
|
160
167
|
body: {
|
package/dist/types/stage.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { PreEmitCheck } from "./preEmitCheck.js";
|
|
2
|
+
import type { StageSecretDecl } from "../runtime/stageSecretDecl.js";
|
|
3
|
+
import type { ToolRequirement } from "../config/toolRequires.js";
|
|
2
4
|
/** Typed emit/schema fields from `compileTargetContract`. Not catalog YAML keys. */
|
|
3
5
|
export type CompiledStageEmitBody = {
|
|
4
6
|
payload_schema?: unknown;
|
|
@@ -38,6 +40,10 @@ export type StageConfig = {
|
|
|
38
40
|
timeout_ms?: number;
|
|
39
41
|
skill?: string;
|
|
40
42
|
mcp?: string[];
|
|
43
|
+
/** Declared Host secret names this stage may receive (Slot 6). */
|
|
44
|
+
secrets?: StageSecretDecl[];
|
|
45
|
+
/** Declared toolchain binaries this stage needs (Slot 9). */
|
|
46
|
+
requires?: ToolRequirement[];
|
|
41
47
|
/**
|
|
42
48
|
* Selects the AgentPort backend for this stage, overriding pipeline/global.
|
|
43
49
|
* Parsed but not yet consulted — see STAGE_LEVEL_AGENT_OVERRIDE_ENABLED.
|
|
@@ -46,4 +52,6 @@ export type StageConfig = {
|
|
|
46
52
|
};
|
|
47
53
|
export type LoadedStageConfig = StageConfig & {
|
|
48
54
|
model: string;
|
|
55
|
+
/** Which catalog tier supplied `model` (stage > pipeline > global). */
|
|
56
|
+
model_tier?: "stage" | "pipeline" | "global";
|
|
49
57
|
};
|
package/dist/types/task.d.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
export type TaskGitIdentity = {
|
|
2
|
+
name?: string;
|
|
3
|
+
email?: string;
|
|
4
|
+
};
|
|
1
5
|
export type TaskFile = {
|
|
2
6
|
id: string;
|
|
3
7
|
goal: string;
|
|
4
8
|
context?: string;
|
|
5
9
|
constraints?: string;
|
|
6
10
|
checkout?: string;
|
|
11
|
+
repository?: string;
|
|
12
|
+
ref?: string;
|
|
13
|
+
run_branch_template?: string;
|
|
14
|
+
git_identity?: TaskGitIdentity;
|
|
7
15
|
input?: Record<string, unknown>;
|
|
8
16
|
};
|