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
|
@@ -1,16 +1,36 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bindingKindForOrigin, catalogOrSeededOrigin, decideWorkspaceConfigTrust, } from "../config/configOrigin.js";
|
|
2
|
+
import { resolveSkillByName, } from "../config/listSkills.js";
|
|
3
|
+
import { loadHostConfig } from "../config/hostConfig.js";
|
|
4
|
+
import { defaultSeededRoots } from "../config/seededCatalog.js";
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
2
6
|
import { mkdir } from "node:fs/promises";
|
|
3
|
-
import {
|
|
7
|
+
import { runSkillsDir } from "./runSkills.js";
|
|
8
|
+
import { MCP_CATALOG_FILENAME, STAGEFLOW_STAGE_ARTIFACTS_DIR_ENV, StageMcpError, mcpCatalogExists, mcpCatalogPath, resolveStageMcpServers, stampStagePromptArtifactsDir, } from "../config/resolveStageMcpServers.js";
|
|
4
9
|
import { attemptArtifactsDir, attemptStreamLogPath } from "../runstore/workspaceLayout.js";
|
|
5
10
|
import { createStageStreamLogWriter, } from "./stageStreamLog.js";
|
|
6
11
|
import { resolveCloneEmitContext, resolveForkEmitContext } from "../config/resolveForkEmitContext.js";
|
|
7
12
|
import { createAttemptQaTrailReader } from "../hitl/qaTrail.js";
|
|
13
|
+
import { collectMcpEnvNamedSecrets, patchRunManifest, redactMcpServers, sha256Digest, withSkillEntry, withStageMcpServers, withStageResolvedModel, } from "../runstore/runManifest.js";
|
|
14
|
+
import { getNamedSecrets, registerNamedSecrets, } from "../logging/namedSecrets.js";
|
|
8
15
|
import { assertPriorInputPayload, payloadInstanceMismatch, } from "../envelope/payloadSchema.js";
|
|
9
16
|
import { buildCompletedEnvelopesFromRun, resolvePriorEnvelope, } from "./envelopeRouting.js";
|
|
10
17
|
import { assignment } from "./cloneSchedule.js";
|
|
11
18
|
import { resumeSessionFilePath } from "./stageAttemptContext.js";
|
|
12
|
-
import { buildStageRoots, rootsForStageWorker, withResolvedAuthPath, } from "./stageRoots.js";
|
|
13
|
-
|
|
19
|
+
import { bindingKindFromMeta, buildStageRoots, rootsForStageWorker, withResolvedAuthPath, } from "./stageRoots.js";
|
|
20
|
+
function resolveTrustWorkspaceConfig(explicit) {
|
|
21
|
+
if (explicit !== undefined)
|
|
22
|
+
return explicit;
|
|
23
|
+
try {
|
|
24
|
+
return loadHostConfig().trustWorkspaceConfig;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function seededRootPaths() {
|
|
31
|
+
return defaultSeededRoots().map((root) => root.path);
|
|
32
|
+
}
|
|
33
|
+
async function resolveStageSkillForRun(stage, catalog, options) {
|
|
14
34
|
const name = stage.skill;
|
|
15
35
|
if (name === undefined)
|
|
16
36
|
return { ok: true };
|
|
@@ -20,44 +40,173 @@ async function resolveStageSkillForRun(stage, catalog) {
|
|
|
20
40
|
const resolved = await resolveSkillByName(name, {
|
|
21
41
|
cwd: catalog.cwd ?? process.cwd(),
|
|
22
42
|
agentDir: catalog.agentDir,
|
|
43
|
+
runSkillsDir: runSkillsDir(options.workspaceDir),
|
|
44
|
+
...(options.checkoutRoot !== undefined
|
|
45
|
+
? { checkoutRoot: options.checkoutRoot }
|
|
46
|
+
: {}),
|
|
23
47
|
});
|
|
24
48
|
if (!resolved) {
|
|
25
49
|
return { ok: false, reason: `Skill "${name}" is not installed` };
|
|
26
50
|
}
|
|
27
|
-
|
|
51
|
+
if (resolved.origin === "checkout") {
|
|
52
|
+
const decision = decideWorkspaceConfigTrust({
|
|
53
|
+
bindingKind: bindingKindForOrigin(options.bindingKind),
|
|
54
|
+
projectRoot: options.factoryCwd ?? options.checkoutRoot ?? "",
|
|
55
|
+
trustWorkspaceConfig: options.trustWorkspaceConfig,
|
|
56
|
+
source: "workspace",
|
|
57
|
+
});
|
|
58
|
+
if (!decision.allow) {
|
|
59
|
+
return {
|
|
60
|
+
ok: false,
|
|
61
|
+
reason: decision.code ?? "untrusted_config_origin",
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
ok: true,
|
|
67
|
+
skillFilePath: resolved.filePath,
|
|
68
|
+
skillOrigin: resolved.origin,
|
|
69
|
+
};
|
|
28
70
|
}
|
|
29
|
-
async function resolveAttemptMcpServers(allowlist, factoryCwd, artifactsDir) {
|
|
71
|
+
async function resolveAttemptMcpServers(allowlist, factoryCwd, artifactsDir, options) {
|
|
30
72
|
const names = allowlist ?? [];
|
|
31
73
|
if (names.length === 0)
|
|
32
|
-
return undefined;
|
|
33
|
-
|
|
34
|
-
|
|
74
|
+
return { servers: undefined, origins: [] };
|
|
75
|
+
const env = {
|
|
76
|
+
...(options.stageEnv ?? {}),
|
|
77
|
+
[STAGEFLOW_STAGE_ARTIFACTS_DIR_ENV]: artifactsDir,
|
|
78
|
+
};
|
|
79
|
+
const stageIdOpt = options.stageId !== undefined ? { stageId: options.stageId } : {};
|
|
80
|
+
const bindingKind = bindingKindForOrigin(options.bindingKind);
|
|
81
|
+
if (factoryCwd !== undefined && (await mcpCatalogExists(factoryCwd))) {
|
|
82
|
+
await mkdir(artifactsDir, { recursive: true });
|
|
83
|
+
const resolved = await resolveStageMcpServers({
|
|
84
|
+
projectRoot: factoryCwd,
|
|
85
|
+
allowlist: names,
|
|
86
|
+
env,
|
|
87
|
+
bindingKind,
|
|
88
|
+
trustWorkspaceConfig: options.trustWorkspaceConfig,
|
|
89
|
+
...stageIdOpt,
|
|
90
|
+
});
|
|
91
|
+
const origin = catalogOrSeededOrigin(factoryCwd, seededRootPaths());
|
|
92
|
+
const catalogPath = mcpCatalogPath(factoryCwd);
|
|
93
|
+
return {
|
|
94
|
+
servers: Object.keys(resolved).length > 0 ? resolved : undefined,
|
|
95
|
+
origins: names.map((name) => ({
|
|
96
|
+
name,
|
|
97
|
+
origin,
|
|
98
|
+
path: catalogPath,
|
|
99
|
+
})),
|
|
100
|
+
};
|
|
35
101
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
102
|
+
const checkoutRoot = options.checkoutRoot;
|
|
103
|
+
if (checkoutRoot !== undefined &&
|
|
104
|
+
checkoutRoot !== factoryCwd &&
|
|
105
|
+
(await mcpCatalogExists(checkoutRoot))) {
|
|
106
|
+
await mkdir(artifactsDir, { recursive: true });
|
|
107
|
+
const resolved = await resolveStageMcpServers({
|
|
108
|
+
projectRoot: checkoutRoot,
|
|
109
|
+
allowlist: names,
|
|
110
|
+
env,
|
|
111
|
+
bindingKind,
|
|
112
|
+
trustWorkspaceConfig: options.trustWorkspaceConfig,
|
|
113
|
+
trustProjectRoot: factoryCwd ?? checkoutRoot,
|
|
114
|
+
workspaceSourced: true,
|
|
115
|
+
...stageIdOpt,
|
|
116
|
+
});
|
|
117
|
+
const catalogPath = mcpCatalogPath(checkoutRoot);
|
|
118
|
+
return {
|
|
119
|
+
servers: Object.keys(resolved).length > 0 ? resolved : undefined,
|
|
120
|
+
origins: names.map((name) => ({
|
|
121
|
+
name,
|
|
122
|
+
origin: "workspace",
|
|
123
|
+
path: catalogPath,
|
|
124
|
+
})),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
throw new StageMcpError(`MCP catalog "${MCP_CATALOG_FILENAME}" is missing`, "missing_catalog");
|
|
46
128
|
}
|
|
47
|
-
|
|
48
|
-
const
|
|
129
|
+
function verifyCommandOrigins(dag, stageId, pipelinePath, factoryCwd) {
|
|
130
|
+
const completion = dag.nodes.find((node) => node.id === stageId)?.completion;
|
|
131
|
+
const origin = catalogOrSeededOrigin(factoryCwd, seededRootPaths());
|
|
132
|
+
const records = [];
|
|
133
|
+
for (const check of completion?.checks ?? []) {
|
|
134
|
+
if (check.type !== "command")
|
|
135
|
+
continue;
|
|
136
|
+
records.push({
|
|
137
|
+
name: check.id,
|
|
138
|
+
origin,
|
|
139
|
+
...(pipelinePath !== undefined ? { path: pipelinePath } : {}),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return records;
|
|
143
|
+
}
|
|
144
|
+
async function openStageWithOperatorCatalog(agent, input, catalog, factoryCwd, artifactsDir, resolveOptions) {
|
|
145
|
+
const skill = await resolveStageSkillForRun(input.stage, catalog, {
|
|
146
|
+
bindingKind: resolveOptions.bindingKind,
|
|
147
|
+
checkoutRoot: resolveOptions.checkoutRoot,
|
|
148
|
+
factoryCwd,
|
|
149
|
+
trustWorkspaceConfig: resolveOptions.trustWorkspaceConfig,
|
|
150
|
+
workspaceDir: resolveOptions.workspaceDir,
|
|
151
|
+
});
|
|
49
152
|
if (!skill.ok)
|
|
50
153
|
return skill;
|
|
51
154
|
let resolvedMcpServers;
|
|
155
|
+
const origins = [];
|
|
52
156
|
try {
|
|
53
|
-
|
|
157
|
+
const mcp = await resolveAttemptMcpServers(input.stage.mcp, factoryCwd, artifactsDir, {
|
|
158
|
+
checkoutRoot: resolveOptions.checkoutRoot,
|
|
159
|
+
bindingKind: resolveOptions.bindingKind,
|
|
160
|
+
trustWorkspaceConfig: resolveOptions.trustWorkspaceConfig,
|
|
161
|
+
stageEnv: resolveOptions.stageEnv,
|
|
162
|
+
stageId: input.stageId,
|
|
163
|
+
});
|
|
164
|
+
resolvedMcpServers = mcp.servers;
|
|
165
|
+
origins.push(...mcp.origins);
|
|
54
166
|
}
|
|
55
167
|
catch (err) {
|
|
56
168
|
if (err instanceof StageMcpError) {
|
|
57
|
-
return {
|
|
169
|
+
return {
|
|
170
|
+
ok: false,
|
|
171
|
+
reason: err.code === "untrusted_config_origin" ? err.code : err.message,
|
|
172
|
+
};
|
|
58
173
|
}
|
|
59
174
|
throw err;
|
|
60
175
|
}
|
|
176
|
+
origins.push(...verifyCommandOrigins(resolveOptions.dag, input.stageId ?? input.stage.id, resolveOptions.pipelinePath, factoryCwd));
|
|
177
|
+
if (origins.length > 0) {
|
|
178
|
+
await resolveOptions.store.appendConfigOrigins(resolveOptions.runId, origins);
|
|
179
|
+
}
|
|
180
|
+
const stageIdForManifest = input.stageId ?? input.stage.id;
|
|
181
|
+
if (resolvedMcpServers !== undefined) {
|
|
182
|
+
const mcpSecrets = collectMcpEnvNamedSecrets(resolvedMcpServers);
|
|
183
|
+
if (mcpSecrets.length > 0) {
|
|
184
|
+
registerNamedSecrets(mcpSecrets);
|
|
185
|
+
}
|
|
186
|
+
const originMap = new Map(origins
|
|
187
|
+
.filter((o) => o.name.length > 0)
|
|
188
|
+
.map((o) => [o.name, o.origin]));
|
|
189
|
+
const mcpServers = redactMcpServers(resolvedMcpServers, [...getNamedSecrets(), ...mcpSecrets], originMap);
|
|
190
|
+
await patchRunManifest(resolveOptions.store, resolveOptions.runId, (m) => withStageMcpServers(m, stageIdForManifest, mcpServers), [...getNamedSecrets(), ...mcpSecrets]).catch(() => null);
|
|
191
|
+
}
|
|
192
|
+
if (skill.skillOrigin !== undefined && skill.skillFilePath !== undefined) {
|
|
193
|
+
const skillName = input.stage.skill;
|
|
194
|
+
if (skillName !== undefined) {
|
|
195
|
+
let digest;
|
|
196
|
+
try {
|
|
197
|
+
digest = sha256Digest(readFileSync(skill.skillFilePath));
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
digest = sha256Digest(skill.skillFilePath);
|
|
201
|
+
}
|
|
202
|
+
await patchRunManifest(resolveOptions.store, resolveOptions.runId, (m) => withSkillEntry(m, {
|
|
203
|
+
name: skillName,
|
|
204
|
+
origin: skill.skillOrigin,
|
|
205
|
+
digest,
|
|
206
|
+
files: ["SKILL.md"],
|
|
207
|
+
})).catch(() => null);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
61
210
|
try {
|
|
62
211
|
const handle = agent.openStage({
|
|
63
212
|
...input,
|
|
@@ -69,6 +218,14 @@ async function openStageWithOperatorCatalog(agent, input, catalog, factoryCwd, a
|
|
|
69
218
|
? { skillFilePath: skill.skillFilePath }
|
|
70
219
|
: {}),
|
|
71
220
|
...(resolvedMcpServers !== undefined ? { resolvedMcpServers } : {}),
|
|
221
|
+
onResolvedModel: async (info) => {
|
|
222
|
+
await patchRunManifest(resolveOptions.store, resolveOptions.runId, (m) => withStageResolvedModel(m, info.stageId, {
|
|
223
|
+
model: info.model,
|
|
224
|
+
...(info.thinkingLevel !== undefined
|
|
225
|
+
? { thinkingLevel: info.thinkingLevel }
|
|
226
|
+
: {}),
|
|
227
|
+
})).catch(() => null);
|
|
228
|
+
},
|
|
72
229
|
});
|
|
73
230
|
return { ok: true, handle };
|
|
74
231
|
}
|
|
@@ -219,6 +376,9 @@ export async function openStageAttempt(input) {
|
|
|
219
376
|
: runtimeNode?.feedback_loop;
|
|
220
377
|
const repairContext = await repairContextForAttempt(input, stageId, attempt);
|
|
221
378
|
const readQaTrail = createAttemptQaTrailReader(input.store, input.runId, stageId, attempt);
|
|
379
|
+
const meta = await input.store.readRunMeta(input.runId);
|
|
380
|
+
const bindingKind = input.bindingKind ?? bindingKindFromMeta(meta);
|
|
381
|
+
const trustWorkspaceConfig = resolveTrustWorkspaceConfig(input.trustWorkspaceConfig);
|
|
222
382
|
const opened = await openStageWithOperatorCatalog(input.agent, {
|
|
223
383
|
roots,
|
|
224
384
|
stage: input.stage,
|
|
@@ -250,7 +410,17 @@ export async function openStageAttempt(input) {
|
|
|
250
410
|
...(input.stage.timeout_ms !== undefined
|
|
251
411
|
? { timeoutMs: input.stage.timeout_ms }
|
|
252
412
|
: {}),
|
|
253
|
-
}, input.operatorCatalog, input.factoryCwd, attemptArtifactsDir(input.workspaceDir, stageId, attempt)
|
|
413
|
+
}, input.operatorCatalog, input.factoryCwd, attemptArtifactsDir(input.workspaceDir, stageId, attempt), {
|
|
414
|
+
checkoutRoot: input.checkoutRoot ?? meta.checkout_root,
|
|
415
|
+
bindingKind,
|
|
416
|
+
trustWorkspaceConfig,
|
|
417
|
+
stageEnv: input.stageEnv,
|
|
418
|
+
store: input.store,
|
|
419
|
+
runId: input.runId,
|
|
420
|
+
pipelinePath: meta.pipeline_path,
|
|
421
|
+
dag: input.dag,
|
|
422
|
+
workspaceDir: input.workspaceDir,
|
|
423
|
+
});
|
|
254
424
|
if (!opened.ok)
|
|
255
425
|
return opened;
|
|
256
426
|
return {
|
|
@@ -258,5 +428,6 @@ export async function openStageAttempt(input) {
|
|
|
258
428
|
handle: opened.handle,
|
|
259
429
|
roots,
|
|
260
430
|
prior: priorResult.prior,
|
|
431
|
+
...(input.stageEnv !== undefined ? { stageEnv: input.stageEnv } : {}),
|
|
261
432
|
};
|
|
262
433
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function stageflowCacheRoot(home?: string): string;
|
|
2
|
+
/** Compute cache env vars without creating directories (lazy create is separate). */
|
|
3
|
+
export declare function computeCacheEnvVars(home?: string): Record<string, string>;
|
|
4
|
+
/** Lazily create shared cache directories at first stage launch. */
|
|
5
|
+
export declare function ensureStageCacheDirs(home?: string): Record<string, string>;
|
|
6
|
+
export declare function resetStageCacheDirsForTests(): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { mkdirSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { globalStageflowHome } from "../project/globalHome.js";
|
|
4
|
+
export function stageflowCacheRoot(home = globalStageflowHome()) {
|
|
5
|
+
return path.join(home, "cache");
|
|
6
|
+
}
|
|
7
|
+
/** Compute cache env vars without creating directories (lazy create is separate). */
|
|
8
|
+
export function computeCacheEnvVars(home = globalStageflowHome()) {
|
|
9
|
+
const cache = stageflowCacheRoot(home);
|
|
10
|
+
return {
|
|
11
|
+
STAGEFLOW_CACHE: cache,
|
|
12
|
+
npm_config_cache: path.join(cache, "npm"),
|
|
13
|
+
PNPM_STORE_DIR: path.join(cache, "pnpm"),
|
|
14
|
+
YARN_CACHE_FOLDER: path.join(cache, "yarn"),
|
|
15
|
+
UV_CACHE_DIR: path.join(cache, "uv"),
|
|
16
|
+
GOMODCACHE: path.join(cache, "go", "mod"),
|
|
17
|
+
CARGO_HOME: path.join(cache, "cargo"),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
let cacheEnsured = false;
|
|
21
|
+
/** Lazily create shared cache directories at first stage launch. */
|
|
22
|
+
export function ensureStageCacheDirs(home = globalStageflowHome()) {
|
|
23
|
+
const vars = computeCacheEnvVars(home);
|
|
24
|
+
if (!cacheEnsured) {
|
|
25
|
+
for (const value of Object.values(vars)) {
|
|
26
|
+
mkdirSync(value, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
cacheEnsured = true;
|
|
29
|
+
}
|
|
30
|
+
return vars;
|
|
31
|
+
}
|
|
32
|
+
export function resetStageCacheDirsForTests() {
|
|
33
|
+
cacheEnsured = false;
|
|
34
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export declare const UNLIMITED_CONCURRENCY: number;
|
|
2
2
|
export declare const DEFAULT_MAX_ACTIVE_STAGES_PER_RUN: number;
|
|
3
3
|
export declare const MAX_ACTIVE_STAGES_PER_RUN_ENV = "STAGEFLOW_MAX_ACTIVE_STAGES_PER_RUN";
|
|
4
|
-
|
|
4
|
+
/** Fallback when cgroup is absent; finite so waitForCapacity is exercised. */
|
|
5
|
+
export declare const DEFAULT_MAX_ACTIVE_STAGE_PROCESSES = 4;
|
|
5
6
|
export declare const MAX_ACTIVE_STAGE_PROCESSES_ENV = "STAGEFLOW_MAX_ACTIVE_STAGE_PROCESSES";
|
|
6
7
|
export declare const STAGE_EXECUTION_ENV = "STAGEFLOW_STAGE_EXECUTION";
|
|
7
8
|
export type StageExecutionMode = "process" | "inprocess";
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { getContainerLimits } from "./containerLimits.js";
|
|
1
2
|
export const UNLIMITED_CONCURRENCY = Number.POSITIVE_INFINITY;
|
|
2
3
|
export const DEFAULT_MAX_ACTIVE_STAGES_PER_RUN = UNLIMITED_CONCURRENCY;
|
|
3
4
|
export const MAX_ACTIVE_STAGES_PER_RUN_ENV = "STAGEFLOW_MAX_ACTIVE_STAGES_PER_RUN";
|
|
4
|
-
|
|
5
|
+
/** Fallback when cgroup is absent; finite so waitForCapacity is exercised. */
|
|
6
|
+
export const DEFAULT_MAX_ACTIVE_STAGE_PROCESSES = 4;
|
|
5
7
|
export const MAX_ACTIVE_STAGE_PROCESSES_ENV = "STAGEFLOW_MAX_ACTIVE_STAGE_PROCESSES";
|
|
6
8
|
export const STAGE_EXECUTION_ENV = "STAGEFLOW_STAGE_EXECUTION";
|
|
7
9
|
export function readStageExecutionMode(env = process.env, override) {
|
|
@@ -41,7 +43,7 @@ export function readMaxActiveStageProcesses(env = process.env, override) {
|
|
|
41
43
|
}
|
|
42
44
|
const raw = env[MAX_ACTIVE_STAGE_PROCESSES_ENV];
|
|
43
45
|
if (raw === undefined || raw.trim() === "") {
|
|
44
|
-
return
|
|
46
|
+
return getContainerLimits().maxActiveStageProcesses;
|
|
45
47
|
}
|
|
46
48
|
const n = Number.parseInt(raw, 10);
|
|
47
49
|
if (!Number.isFinite(n) || n < 1) {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const STAGE_ENV_PASSTHROUGH = "STAGEFLOW_STAGE_ENV_PASSTHROUGH";
|
|
2
|
+
export declare const STAGE_ENV_ALLOW = "STAGEFLOW_STAGE_ENV_ALLOW";
|
|
3
|
+
/** Names copied from Host when present (exact-name allowlist; no prefix wildcards). */
|
|
4
|
+
export declare const STAGE_ENV_ALLOWLIST: readonly string[];
|
|
5
|
+
/** Never grantable — even via secrets `as: env`. */
|
|
6
|
+
export declare const FOREVER_DENIED_SECRET_NAMES: ReadonlySet<string>;
|
|
7
|
+
/** Blocked from ambient / ALLOW / PASSTHROUGH; `as: env` grants may still inject. */
|
|
8
|
+
export declare const AMBIENT_BLOCKED_ENV_NAMES: ReadonlySet<string>;
|
|
9
|
+
/** Full denylist surface for docs and health (union of forever + ambient-blocked). */
|
|
10
|
+
export declare const STAGE_ENV_DENYLIST: readonly string[];
|
|
11
|
+
export type ResolvedStageGrants = {
|
|
12
|
+
env: Record<string, string>;
|
|
13
|
+
registeredSecretNames: readonly string[];
|
|
14
|
+
declaredSecretNames: readonly string[];
|
|
15
|
+
};
|
|
16
|
+
export type BuildStageEnvironmentInput = {
|
|
17
|
+
hostEnv: NodeJS.ProcessEnv;
|
|
18
|
+
runVars?: Record<string, string>;
|
|
19
|
+
cacheVars?: Record<string, string>;
|
|
20
|
+
grants?: ResolvedStageGrants;
|
|
21
|
+
/** Per-attempt empty HOME (KTD7). When set, overrides Host HOME. */
|
|
22
|
+
attemptHome?: string;
|
|
23
|
+
/** Package version for PASSTHROUGH deprecation text. */
|
|
24
|
+
packageVersion?: string;
|
|
25
|
+
};
|
|
26
|
+
export type BuildStageEnvironmentResult = {
|
|
27
|
+
env: Record<string, string>;
|
|
28
|
+
warnings: string[];
|
|
29
|
+
passthroughActive: boolean;
|
|
30
|
+
};
|
|
31
|
+
export declare function isForeverDeniedSecret(name: string): boolean;
|
|
32
|
+
export declare function isAmbientBlockedEnv(name: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Construct the stage child environment. Exact-name allowlist only — never a
|
|
35
|
+
* raw spread of Host env, and never a STAGEFLOW_* prefix passthrough.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildStageEnvironment(input: BuildStageEnvironmentInput): BuildStageEnvironmentResult;
|
|
38
|
+
export declare function envNameSet(env: Record<string, string>): Set<string>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { SF_STAGE_WORKER } from "./stageWorkerProtocol.js";
|
|
2
|
+
export const STAGE_ENV_PASSTHROUGH = "STAGEFLOW_STAGE_ENV_PASSTHROUGH";
|
|
3
|
+
export const STAGE_ENV_ALLOW = "STAGEFLOW_STAGE_ENV_ALLOW";
|
|
4
|
+
/** Names copied from Host when present (exact-name allowlist; no prefix wildcards). */
|
|
5
|
+
export const STAGE_ENV_ALLOWLIST = [
|
|
6
|
+
"PATH",
|
|
7
|
+
"USER",
|
|
8
|
+
"LOGNAME",
|
|
9
|
+
"SHELL",
|
|
10
|
+
"LANG",
|
|
11
|
+
"LC_ALL",
|
|
12
|
+
"LC_CTYPE",
|
|
13
|
+
"TZ",
|
|
14
|
+
"TERM",
|
|
15
|
+
"TMPDIR",
|
|
16
|
+
"TMP",
|
|
17
|
+
"TEMP",
|
|
18
|
+
"NODE_EXTRA_CA_CERTS",
|
|
19
|
+
"SSL_CERT_FILE",
|
|
20
|
+
"SSL_CERT_DIR",
|
|
21
|
+
"HTTP_PROXY",
|
|
22
|
+
"HTTPS_PROXY",
|
|
23
|
+
"NO_PROXY",
|
|
24
|
+
"http_proxy",
|
|
25
|
+
"https_proxy",
|
|
26
|
+
"no_proxy",
|
|
27
|
+
"STAGEFLOW_HOME",
|
|
28
|
+
];
|
|
29
|
+
const PROVIDER_AND_CLOUD_NAMES = [
|
|
30
|
+
"ANTHROPIC_API_KEY",
|
|
31
|
+
"OPENAI_API_KEY",
|
|
32
|
+
"OPENAI_API_KEY_FILE",
|
|
33
|
+
"GOOGLE_API_KEY",
|
|
34
|
+
"GEMINI_API_KEY",
|
|
35
|
+
"GROQ_API_KEY",
|
|
36
|
+
"MISTRAL_API_KEY",
|
|
37
|
+
"DEEPSEEK_API_KEY",
|
|
38
|
+
"TOGETHER_API_KEY",
|
|
39
|
+
"FIREWORKS_API_KEY",
|
|
40
|
+
"PERPLEXITY_API_KEY",
|
|
41
|
+
"XAI_API_KEY",
|
|
42
|
+
"COHERE_API_KEY",
|
|
43
|
+
"OPENROUTER_API_KEY",
|
|
44
|
+
"AZURE_OPENAI_API_KEY",
|
|
45
|
+
"AWS_ACCESS_KEY_ID",
|
|
46
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
47
|
+
"AWS_SESSION_TOKEN",
|
|
48
|
+
"AWS_SECURITY_TOKEN",
|
|
49
|
+
"AWS_PROFILE",
|
|
50
|
+
"AWS_DEFAULT_REGION",
|
|
51
|
+
"AWS_REGION",
|
|
52
|
+
"GOOGLE_APPLICATION_CREDENTIALS",
|
|
53
|
+
"GCLOUD_PROJECT",
|
|
54
|
+
"AZURE_CLIENT_SECRET",
|
|
55
|
+
"AZURE_TENANT_ID",
|
|
56
|
+
"AZURE_CLIENT_ID",
|
|
57
|
+
"NPM_TOKEN",
|
|
58
|
+
"NODE_AUTH_TOKEN",
|
|
59
|
+
"SSH_AUTH_SOCK",
|
|
60
|
+
"SSH_AGENT_PID",
|
|
61
|
+
"GITHUB_TOKEN",
|
|
62
|
+
"GH_TOKEN",
|
|
63
|
+
"GITHUB_TOKEN_FILE",
|
|
64
|
+
"GH_TOKEN_FILE",
|
|
65
|
+
];
|
|
66
|
+
/** Never grantable — even via secrets `as: env`. */
|
|
67
|
+
export const FOREVER_DENIED_SECRET_NAMES = new Set([
|
|
68
|
+
"STAGEFLOW_CONTROL_TOKEN",
|
|
69
|
+
"STAGEFLOW_CONTROL_TOKEN_FILE",
|
|
70
|
+
"STAGEFLOW_READ_TOKEN",
|
|
71
|
+
"STAGEFLOW_READ_TOKEN_FILE",
|
|
72
|
+
]);
|
|
73
|
+
/** Blocked from ambient / ALLOW / PASSTHROUGH; `as: env` grants may still inject. */
|
|
74
|
+
export const AMBIENT_BLOCKED_ENV_NAMES = new Set([
|
|
75
|
+
...FOREVER_DENIED_SECRET_NAMES,
|
|
76
|
+
...PROVIDER_AND_CLOUD_NAMES,
|
|
77
|
+
]);
|
|
78
|
+
/** Full denylist surface for docs and health (union of forever + ambient-blocked). */
|
|
79
|
+
export const STAGE_ENV_DENYLIST = [
|
|
80
|
+
...FOREVER_DENIED_SECRET_NAMES,
|
|
81
|
+
...PROVIDER_AND_CLOUD_NAMES,
|
|
82
|
+
];
|
|
83
|
+
function copyDefined(out, hostEnv, names) {
|
|
84
|
+
for (const name of names) {
|
|
85
|
+
const value = hostEnv[name];
|
|
86
|
+
if (value !== undefined && value !== "") {
|
|
87
|
+
out[name] = value;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export function isForeverDeniedSecret(name) {
|
|
92
|
+
if (FOREVER_DENIED_SECRET_NAMES.has(name))
|
|
93
|
+
return true;
|
|
94
|
+
return name.startsWith("STAGEFLOW_CONTROL_TOKEN_");
|
|
95
|
+
}
|
|
96
|
+
export function isAmbientBlockedEnv(name) {
|
|
97
|
+
return isForeverDeniedSecret(name) || AMBIENT_BLOCKED_ENV_NAMES.has(name);
|
|
98
|
+
}
|
|
99
|
+
function stripForeverDenied(env) {
|
|
100
|
+
const out = {};
|
|
101
|
+
for (const [key, value] of Object.entries(env)) {
|
|
102
|
+
if (value === undefined)
|
|
103
|
+
continue;
|
|
104
|
+
if (isForeverDeniedSecret(key))
|
|
105
|
+
continue;
|
|
106
|
+
out[key] = value;
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
function parseAllowList(raw) {
|
|
111
|
+
if (raw === undefined || raw.trim() === "")
|
|
112
|
+
return [];
|
|
113
|
+
return raw
|
|
114
|
+
.split(",")
|
|
115
|
+
.map((s) => s.trim())
|
|
116
|
+
.filter((s) => s.length > 0);
|
|
117
|
+
}
|
|
118
|
+
function passthroughDeprecationTarget(version) {
|
|
119
|
+
const parts = version.split(".").map((p) => Number.parseInt(p, 10));
|
|
120
|
+
const major = Number.isFinite(parts[0]) ? parts[0] : 0;
|
|
121
|
+
const minor = Number.isFinite(parts[1]) ? parts[1] : 0;
|
|
122
|
+
return `${major}.${minor + 2}.0`;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Construct the stage child environment. Exact-name allowlist only — never a
|
|
126
|
+
* raw spread of Host env, and never a STAGEFLOW_* prefix passthrough.
|
|
127
|
+
*/
|
|
128
|
+
export function buildStageEnvironment(input) {
|
|
129
|
+
const hostEnv = input.hostEnv;
|
|
130
|
+
const warnings = [];
|
|
131
|
+
const grants = input.grants ?? {
|
|
132
|
+
env: {},
|
|
133
|
+
registeredSecretNames: [],
|
|
134
|
+
declaredSecretNames: [],
|
|
135
|
+
};
|
|
136
|
+
const declared = new Set(grants.declaredSecretNames);
|
|
137
|
+
const registered = new Set(grants.registeredSecretNames);
|
|
138
|
+
const env = {};
|
|
139
|
+
copyDefined(env, hostEnv, STAGE_ENV_ALLOWLIST);
|
|
140
|
+
if (input.cacheVars) {
|
|
141
|
+
Object.assign(env, input.cacheVars);
|
|
142
|
+
}
|
|
143
|
+
if (input.runVars) {
|
|
144
|
+
Object.assign(env, input.runVars);
|
|
145
|
+
}
|
|
146
|
+
const allowNames = parseAllowList(hostEnv[STAGE_ENV_ALLOW]);
|
|
147
|
+
for (const name of allowNames) {
|
|
148
|
+
if (AMBIENT_BLOCKED_ENV_NAMES.has(name))
|
|
149
|
+
continue;
|
|
150
|
+
const value = hostEnv[name];
|
|
151
|
+
if (value !== undefined) {
|
|
152
|
+
env[name] = value;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const passthroughRaw = hostEnv[STAGE_ENV_PASSTHROUGH]?.trim();
|
|
156
|
+
const passthroughActive = passthroughRaw === "all";
|
|
157
|
+
if (passthroughActive) {
|
|
158
|
+
const version = input.packageVersion ?? "0.24.0";
|
|
159
|
+
const removeBy = passthroughDeprecationTarget(version);
|
|
160
|
+
warnings.push(`${STAGE_ENV_PASSTHROUGH}=all is deprecated and will be removed in ${removeBy}; prefer ${STAGE_ENV_ALLOW} or stage secrets:`);
|
|
161
|
+
for (const [key, value] of Object.entries(hostEnv)) {
|
|
162
|
+
if (value === undefined)
|
|
163
|
+
continue;
|
|
164
|
+
if (AMBIENT_BLOCKED_ENV_NAMES.has(key))
|
|
165
|
+
continue;
|
|
166
|
+
if (registered.has(key) && !declared.has(key))
|
|
167
|
+
continue;
|
|
168
|
+
if (key.endsWith("_FILE") &&
|
|
169
|
+
registered.has(key.slice(0, -"_FILE".length)) &&
|
|
170
|
+
!declared.has(key.slice(0, -"_FILE".length))) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (Object.hasOwn(env, key))
|
|
174
|
+
continue;
|
|
175
|
+
env[key] = value;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Grants after ambient so explicit `as: env` can inject ambient-blocked names
|
|
179
|
+
// (e.g. GITHUB_TOKEN). Forever-denied names are stripped below.
|
|
180
|
+
Object.assign(env, grants.env);
|
|
181
|
+
if (input.attemptHome !== undefined) {
|
|
182
|
+
env.HOME = input.attemptHome;
|
|
183
|
+
}
|
|
184
|
+
env[SF_STAGE_WORKER] = "1";
|
|
185
|
+
return {
|
|
186
|
+
env: stripForeverDenied(env),
|
|
187
|
+
warnings,
|
|
188
|
+
passthroughActive,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
export function envNameSet(env) {
|
|
192
|
+
return new Set(Object.keys(env));
|
|
193
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import * as childProcess from "node:child_process";
|
|
2
|
+
import { type Logger } from "../logging/logger.js";
|
|
3
|
+
import { type ResolvedStageGrants } from "./stageEnvironment.js";
|
|
1
4
|
import type { OperatorCatalog } from "./stageAttemptBootstrap.js";
|
|
5
|
+
import { type DerivedBindingKind } from "./stageRoots.js";
|
|
2
6
|
export type StageLaunchInput = {
|
|
3
7
|
runId: string;
|
|
4
8
|
stageId: string;
|
|
@@ -9,6 +13,10 @@ export type StageLaunchInput = {
|
|
|
9
13
|
sessionFilePath?: string;
|
|
10
14
|
operatorCatalog?: OperatorCatalog;
|
|
11
15
|
skipGates?: boolean;
|
|
16
|
+
env?: Record<string, string>;
|
|
17
|
+
bindingKind?: DerivedBindingKind;
|
|
18
|
+
grants?: ResolvedStageGrants;
|
|
19
|
+
attemptHome?: string;
|
|
12
20
|
};
|
|
13
21
|
export type StageLaunchResult = {
|
|
14
22
|
type: "succeeded";
|
|
@@ -27,17 +35,27 @@ export type StageProcessLauncherOptions = {
|
|
|
27
35
|
maxActiveStageProcesses?: number;
|
|
28
36
|
env?: Record<string, string | undefined>;
|
|
29
37
|
cliEntry?: string;
|
|
38
|
+
logger?: Logger;
|
|
39
|
+
/** Test seam: override child_process.fork. */
|
|
40
|
+
forkFn?: typeof childProcess.fork;
|
|
30
41
|
};
|
|
42
|
+
export declare function signalProcessGroup(pid: number | undefined, signal: NodeJS.Signals): void;
|
|
31
43
|
export declare class StageProcessLauncher {
|
|
32
44
|
private readonly maxActive;
|
|
33
45
|
private readonly env;
|
|
46
|
+
private readonly explicitChildExtras;
|
|
34
47
|
private readonly cliEntry;
|
|
48
|
+
private readonly logger;
|
|
49
|
+
private readonly forkFn;
|
|
35
50
|
private readonly active;
|
|
36
51
|
private readonly waitQueue;
|
|
52
|
+
private readonly cancelledRuns;
|
|
37
53
|
private slotsHeld;
|
|
54
|
+
private readonly heapMb;
|
|
38
55
|
constructor(options?: StageProcessLauncherOptions);
|
|
39
56
|
activeCount(): number;
|
|
40
57
|
getActiveStageProcesses(): ActiveStageProcess[];
|
|
58
|
+
signalAllActive(signal: NodeJS.Signals): void;
|
|
41
59
|
launch(input: StageLaunchInput): Promise<StageLaunchResult>;
|
|
42
60
|
cancelRun(runId: string, killAfterMs?: number): Promise<void>;
|
|
43
61
|
private waitForCapacity;
|