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
|
@@ -12,6 +12,7 @@ import { recoveryRequiresCompletionIssue } from "./parseCompletionContract.js";
|
|
|
12
12
|
import { validateCompletionContractForStage } from "./validateCompletionContract.js";
|
|
13
13
|
import { applyCloneChains } from "./cloneChain.js";
|
|
14
14
|
import { collectRouteIfSchemaIssues, collectRouteIfIllegalCombos, collectRouteAllGatedWarnings, } from "./routeIf.js";
|
|
15
|
+
import { mergeToolRequires } from "./toolRequires.js";
|
|
15
16
|
function schemaCompileIssue(stageId, field, err, pipelineId) {
|
|
16
17
|
const message = err instanceof Error ? err.message : String(err);
|
|
17
18
|
if (err instanceof UnresolvedSchemaRefError) {
|
|
@@ -128,7 +129,7 @@ export async function loadPipelineFromObject(raw, options = {}) {
|
|
|
128
129
|
}
|
|
129
130
|
async function buildLoadedPipelineFromMerge(merge, options) {
|
|
130
131
|
const { projectRoot, requireIo, pipelinePath } = options;
|
|
131
|
-
const { entries: rawEntries, pipelineId, agent: pipelineAgent, model: pipelineModel, schemas: pipelineSchemas, warnings: mergeWarnings, } = merge;
|
|
132
|
+
const { entries: rawEntries, pipelineId, agent: pipelineAgent, model: pipelineModel, schemas: pipelineSchemas, requires: pipelineRequires, warnings: mergeWarnings, } = merge;
|
|
132
133
|
const ctx = { pipelineId, path: pipelinePath };
|
|
133
134
|
const warnings = [...mergeWarnings];
|
|
134
135
|
const normalizeOutcome = normalizePipelineStageEntries(rawEntries, ctx);
|
|
@@ -181,7 +182,14 @@ async function buildLoadedPipelineFromMerge(merge, options) {
|
|
|
181
182
|
if (!inlineOutcome.ok) {
|
|
182
183
|
return loadFailure(inlineOutcome.issues);
|
|
183
184
|
}
|
|
184
|
-
|
|
185
|
+
let stage = inlineOutcome.value;
|
|
186
|
+
if (entry.requires !== undefined) {
|
|
187
|
+
const merged = mergeToolRequires([stage.requires, entry.requires], { pipelineId, label: `stage "${entry.id}"` });
|
|
188
|
+
if (!merged.ok)
|
|
189
|
+
return loadFailure(merged.issues);
|
|
190
|
+
stage = { ...stage, requires: merged.value };
|
|
191
|
+
}
|
|
192
|
+
stages.push(stage);
|
|
185
193
|
stageSources[stageId] = { kind: "inline" };
|
|
186
194
|
continue;
|
|
187
195
|
}
|
|
@@ -229,10 +237,19 @@ async function buildLoadedPipelineFromMerge(merge, options) {
|
|
|
229
237
|
},
|
|
230
238
|
]);
|
|
231
239
|
}
|
|
240
|
+
let stageRequires = stageOutcome.value.requires;
|
|
241
|
+
if (entry.requires !== undefined) {
|
|
242
|
+
const merged = mergeToolRequires([stageRequires, entry.requires], { pipelineId, label: `stage "${entry.id}"` });
|
|
243
|
+
if (!merged.ok)
|
|
244
|
+
return loadFailure(merged.issues);
|
|
245
|
+
stageRequires = merged.value;
|
|
246
|
+
}
|
|
232
247
|
const stage = {
|
|
233
248
|
...stageOutcome.value,
|
|
234
249
|
...(entry.skill !== undefined ? { skill: entry.skill } : {}),
|
|
235
250
|
...(entry.mcp !== undefined ? { mcp: entry.mcp } : {}),
|
|
251
|
+
...(entry.secrets !== undefined ? { secrets: entry.secrets } : {}),
|
|
252
|
+
...(stageRequires !== undefined ? { requires: stageRequires } : {}),
|
|
236
253
|
};
|
|
237
254
|
stages.push(stage);
|
|
238
255
|
stageSources[stageId] = { kind: "file", path: entry.body.absolutePath };
|
|
@@ -282,7 +299,11 @@ async function buildLoadedPipelineFromMerge(merge, options) {
|
|
|
282
299
|
...(pipelineAgent !== undefined ? { agent: pipelineAgent } : {}),
|
|
283
300
|
...(pipelineModel !== undefined ? { model: pipelineModel } : {}),
|
|
284
301
|
...(pipelineSchemas !== undefined ? { schemas: pipelineSchemas } : {}),
|
|
302
|
+
...(pipelineRequires !== undefined ? { requires: pipelineRequires } : {}),
|
|
285
303
|
};
|
|
304
|
+
const effectiveRequires = mergeToolRequires([pipelineRequires, ...loadedStages.map((s) => s.requires)], { pipelineId });
|
|
305
|
+
if (!effectiveRequires.ok)
|
|
306
|
+
return loadFailure(effectiveRequires.issues);
|
|
286
307
|
const nodeById = new Map(dag.nodes.map((node) => [node.id, node]));
|
|
287
308
|
for (const [stageId, after] of fileAfterById) {
|
|
288
309
|
const node = nodeById.get(stageId);
|
package/dist/config/loadStage.js
CHANGED
|
@@ -7,6 +7,8 @@ import { parseModelField } from "./modelField.js";
|
|
|
7
7
|
import { allowLegacyYamlAuthoring, dialectWarningForDocument, legacyAuthoringRejected, presentLegacyKeys, } from "./legacyYaml.js";
|
|
8
8
|
import { parsePreEmitChecks } from "./parsePreEmitChecks.js";
|
|
9
9
|
import { readYamlObject } from "./readYamlObject.js";
|
|
10
|
+
import { parseStageSecrets } from "../runtime/stageSecretDecl.js";
|
|
11
|
+
import { parseToolRequires } from "./toolRequires.js";
|
|
10
12
|
import { classifyYamlDocument, compileTargetContract, dialectFromKeys, mixedDialectIssue, STAGE_FILE_WIRING_KEYS, } from "./yamlDialect.js";
|
|
11
13
|
const afterCompletionByStage = new WeakMap();
|
|
12
14
|
/** After-phase IR from target `verify` (`when` includes after). Stamped onto DAG `completion`. */
|
|
@@ -348,6 +350,22 @@ function parseStageFields(raw, label, entryId, deferSchemaRefs, requireIo, compi
|
|
|
348
350
|
if (mcpOutcome.value !== undefined) {
|
|
349
351
|
stage.mcp = mcpOutcome.value;
|
|
350
352
|
}
|
|
353
|
+
const secretsOutcome = parseStageSecrets(raw.secrets, label, entryId);
|
|
354
|
+
if (!secretsOutcome.ok)
|
|
355
|
+
return secretsOutcome;
|
|
356
|
+
if (secretsOutcome.value !== undefined) {
|
|
357
|
+
stage.secrets = secretsOutcome.value;
|
|
358
|
+
}
|
|
359
|
+
const requiresOutcome = parseToolRequires(raw.requires, `stage ${label}`, {
|
|
360
|
+
code: "stage.invalid_requires",
|
|
361
|
+
category: "stage",
|
|
362
|
+
stageId: entryId,
|
|
363
|
+
});
|
|
364
|
+
if (!requiresOutcome.ok)
|
|
365
|
+
return requiresOutcome;
|
|
366
|
+
if (requiresOutcome.value !== undefined) {
|
|
367
|
+
stage.requires = requiresOutcome.value;
|
|
368
|
+
}
|
|
351
369
|
const agentField = parseAgentField(raw.agent);
|
|
352
370
|
if (!agentField.ok) {
|
|
353
371
|
return loadFailure([
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { TaskFile } from "../types/task.js";
|
|
2
2
|
import { type LoadOutcome } from "./loadOutcome.js";
|
|
3
|
+
/** Structural TaskFile shape only — does not enforce workspace binding XOR. */
|
|
4
|
+
export declare function coerceTaskFile(raw: unknown): TaskFile | undefined;
|
|
3
5
|
export declare function parseTaskFile(raw: unknown, source?: string): LoadOutcome<TaskFile>;
|
|
4
6
|
export declare function loadTaskFromYamlOutcome(yamlText: string, source?: string): LoadOutcome<TaskFile>;
|
|
5
7
|
export declare function loadTaskOutcome(filePath: string): Promise<LoadOutcome<TaskFile>>;
|
package/dist/config/loadTask.js
CHANGED
|
@@ -1,12 +1,60 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { parse as parseYaml } from "yaml";
|
|
3
|
+
import { resolveWorkspaceBinding } from "../runtime/workspaceBinding.js";
|
|
3
4
|
import { loadFailure, loadSuccess } from "./loadOutcome.js";
|
|
4
5
|
function isPlainObject(value) {
|
|
5
6
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
7
|
}
|
|
7
|
-
|
|
8
|
+
function parseGitIdentity(raw) {
|
|
9
|
+
if (!isPlainObject(raw))
|
|
10
|
+
return undefined;
|
|
11
|
+
const identity = {};
|
|
12
|
+
if (typeof raw.name === "string")
|
|
13
|
+
identity.name = raw.name;
|
|
14
|
+
if (typeof raw.email === "string")
|
|
15
|
+
identity.email = raw.email;
|
|
16
|
+
return identity;
|
|
17
|
+
}
|
|
18
|
+
/** Structural TaskFile shape only — does not enforce workspace binding XOR. */
|
|
19
|
+
export function coerceTaskFile(raw) {
|
|
8
20
|
const record = raw;
|
|
9
21
|
if (typeof record?.id !== "string" || typeof record?.goal !== "string") {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
if (record.input !== undefined && !isPlainObject(record.input)) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
id: record.id,
|
|
29
|
+
goal: record.goal,
|
|
30
|
+
context: typeof record.context === "string" ? record.context : undefined,
|
|
31
|
+
constraints: typeof record.constraints === "string" ? record.constraints : undefined,
|
|
32
|
+
checkout: typeof record.checkout === "string" ? record.checkout : undefined,
|
|
33
|
+
...(typeof record.repository === "string" ? { repository: record.repository } : {}),
|
|
34
|
+
...(typeof record.ref === "string" ? { ref: record.ref } : {}),
|
|
35
|
+
...(typeof record.run_branch_template === "string"
|
|
36
|
+
? { run_branch_template: record.run_branch_template }
|
|
37
|
+
: {}),
|
|
38
|
+
...(isPlainObject(record.git_identity)
|
|
39
|
+
? { git_identity: parseGitIdentity(record.git_identity) }
|
|
40
|
+
: {}),
|
|
41
|
+
...(record.input !== undefined ? { input: record.input } : {}),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function parseTaskFile(raw, source = "task") {
|
|
45
|
+
const record = raw;
|
|
46
|
+
const task = coerceTaskFile(raw);
|
|
47
|
+
if (task === undefined) {
|
|
48
|
+
if (typeof record?.id === "string" && typeof record?.goal === "string") {
|
|
49
|
+
return loadFailure([
|
|
50
|
+
{
|
|
51
|
+
code: "task.invalid_shape",
|
|
52
|
+
message: `Invalid ${source}: input must be an object`,
|
|
53
|
+
category: "task",
|
|
54
|
+
taskId: record.id,
|
|
55
|
+
},
|
|
56
|
+
]);
|
|
57
|
+
}
|
|
10
58
|
return loadFailure([
|
|
11
59
|
{
|
|
12
60
|
code: "task.invalid_shape",
|
|
@@ -16,24 +64,15 @@ export function parseTaskFile(raw, source = "task") {
|
|
|
16
64
|
},
|
|
17
65
|
]);
|
|
18
66
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
]);
|
|
67
|
+
const binding = resolveWorkspaceBinding(task);
|
|
68
|
+
if (!binding.ok) {
|
|
69
|
+
return loadFailure(binding.issues.map((issue) => {
|
|
70
|
+
if (issue.category !== "task")
|
|
71
|
+
return issue;
|
|
72
|
+
return { ...issue, taskId: task.id };
|
|
73
|
+
}));
|
|
28
74
|
}
|
|
29
|
-
return loadSuccess(
|
|
30
|
-
id: record.id,
|
|
31
|
-
goal: record.goal,
|
|
32
|
-
context: typeof record.context === "string" ? record.context : undefined,
|
|
33
|
-
constraints: typeof record.constraints === "string" ? record.constraints : undefined,
|
|
34
|
-
checkout: typeof record.checkout === "string" ? record.checkout : undefined,
|
|
35
|
-
...(record.input !== undefined ? { input: record.input } : {}),
|
|
36
|
-
});
|
|
75
|
+
return loadSuccess(task);
|
|
37
76
|
}
|
|
38
77
|
export function loadTaskFromYamlOutcome(yamlText, source = "task yaml") {
|
|
39
78
|
let raw;
|
|
@@ -29,7 +29,11 @@ export async function materializeStageModels(stages, options) {
|
|
|
29
29
|
if (!modelOutcome.ok) {
|
|
30
30
|
return loadFailure(modelOutcome.issues);
|
|
31
31
|
}
|
|
32
|
-
materialized.push({
|
|
32
|
+
materialized.push({
|
|
33
|
+
...stage,
|
|
34
|
+
model: modelOutcome.value.model,
|
|
35
|
+
model_tier: modelOutcome.value.tier,
|
|
36
|
+
});
|
|
33
37
|
}
|
|
34
38
|
return loadSuccess(materialized);
|
|
35
39
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { PayloadSchemaMap } from "../envelope/payloadSchema.js";
|
|
2
2
|
import type { InlinePipelineDefinition } from "../types/pipeline.js";
|
|
3
3
|
import { type LoadIssue, type LoadOutcome } from "./loadOutcome.js";
|
|
4
|
+
import { type ToolRequirement } from "./toolRequires.js";
|
|
4
5
|
export type RawMergedEntry = {
|
|
5
6
|
raw: unknown;
|
|
6
7
|
declaringPath: string;
|
|
@@ -11,6 +12,7 @@ export declare function mergePipelineStages(rootPath: string): Promise<LoadOutco
|
|
|
11
12
|
agent?: string;
|
|
12
13
|
model?: string;
|
|
13
14
|
schemas?: PayloadSchemaMap;
|
|
15
|
+
requires?: ToolRequirement[];
|
|
14
16
|
warnings: LoadIssue[];
|
|
15
17
|
}>>;
|
|
16
18
|
/** Synthetic `declaringPath` for stage entries with no backing file. */
|
|
@@ -21,5 +23,6 @@ export declare function mergeInlinePipelineStages(raw: InlinePipelineDefinition)
|
|
|
21
23
|
agent?: string;
|
|
22
24
|
model?: string;
|
|
23
25
|
schemas?: PayloadSchemaMap;
|
|
26
|
+
requires?: ToolRequirement[];
|
|
24
27
|
warnings: LoadIssue[];
|
|
25
28
|
}>>;
|
|
@@ -4,6 +4,7 @@ import { loadFailure, loadSuccess } from "./loadOutcome.js";
|
|
|
4
4
|
import { allowLegacyYamlAuthoring, dialectWarningForDocument, legacyAuthoringRejected, presentLegacyKeys, } from "./legacyYaml.js";
|
|
5
5
|
import { parseModelField } from "./modelField.js";
|
|
6
6
|
import { readYamlObject } from "./readYamlObject.js";
|
|
7
|
+
import { parseToolRequires } from "./toolRequires.js";
|
|
7
8
|
import { classifyYamlDocument, collectDocumentKeys, mixedDialectIssue, } from "./yamlDialect.js";
|
|
8
9
|
function isPlainObject(value) {
|
|
9
10
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -177,6 +178,14 @@ export async function mergePipelineStages(rootPath) {
|
|
|
177
178
|
if (!schemasOutcome.ok)
|
|
178
179
|
return schemasOutcome;
|
|
179
180
|
const schemas = schemasOutcome.value;
|
|
181
|
+
const requiresOutcome = parseToolRequires(raw.requires, `pipeline ${absRoot}`, {
|
|
182
|
+
code: "pipeline.invalid_requires",
|
|
183
|
+
category: "pipeline",
|
|
184
|
+
pipelineId,
|
|
185
|
+
});
|
|
186
|
+
if (!requiresOutcome.ok)
|
|
187
|
+
return requiresOutcome;
|
|
188
|
+
const requires = requiresOutcome.value;
|
|
180
189
|
const idLocations = new Map();
|
|
181
190
|
const entries = [];
|
|
182
191
|
const warnings = [];
|
|
@@ -198,6 +207,7 @@ export async function mergePipelineStages(rootPath) {
|
|
|
198
207
|
...(agent !== undefined ? { agent } : {}),
|
|
199
208
|
...(model !== undefined ? { model } : {}),
|
|
200
209
|
...(schemas !== undefined ? { schemas } : {}),
|
|
210
|
+
...(requires !== undefined ? { requires } : {}),
|
|
201
211
|
warnings,
|
|
202
212
|
});
|
|
203
213
|
}
|
|
@@ -252,6 +262,14 @@ export async function mergeInlinePipelineStages(raw) {
|
|
|
252
262
|
if (!schemasOutcome.ok)
|
|
253
263
|
return schemasOutcome;
|
|
254
264
|
const schemas = schemasOutcome.value;
|
|
265
|
+
const requiresOutcome = parseToolRequires(raw.requires, `inline pipeline ${pipelineId}`, {
|
|
266
|
+
code: "pipeline.invalid_requires",
|
|
267
|
+
category: "pipeline",
|
|
268
|
+
pipelineId,
|
|
269
|
+
});
|
|
270
|
+
if (!requiresOutcome.ok)
|
|
271
|
+
return requiresOutcome;
|
|
272
|
+
const requires = requiresOutcome.value;
|
|
255
273
|
const entries = [];
|
|
256
274
|
for (let index = 0; index < raw.stages.length; index++) {
|
|
257
275
|
const entry = raw.stages[index];
|
|
@@ -273,6 +291,7 @@ export async function mergeInlinePipelineStages(raw) {
|
|
|
273
291
|
...(agent !== undefined ? { agent } : {}),
|
|
274
292
|
...(model !== undefined ? { model } : {}),
|
|
275
293
|
...(schemas !== undefined ? { schemas } : {}),
|
|
294
|
+
...(requires !== undefined ? { requires } : {}),
|
|
276
295
|
warnings: [],
|
|
277
296
|
});
|
|
278
297
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { execFileSync } from "node:child_process";
|
|
2
1
|
import { randomBytes } from "node:crypto";
|
|
3
2
|
import { readdir, readFile, rename, stat, unlink, writeFile } from "node:fs/promises";
|
|
4
3
|
import path from "node:path";
|
|
4
|
+
import { runGitSync } from "../git/exec.js";
|
|
5
|
+
import { statusPorcelain } from "../git/operations.js";
|
|
5
6
|
import { loadPipelineOutcome } from "./loadPipeline.js";
|
|
6
7
|
import { afterCompletionForStage, loadStageOutcome } from "./loadStage.js";
|
|
7
8
|
import { withLegacyYamlAllowedAsync } from "./legacyYaml.js";
|
|
@@ -104,11 +105,10 @@ function verifyFingerprint(items) {
|
|
|
104
105
|
}
|
|
105
106
|
function gitToplevel(cwd) {
|
|
106
107
|
try {
|
|
107
|
-
return
|
|
108
|
+
return runGitSync({
|
|
108
109
|
cwd,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}).trim();
|
|
110
|
+
args: ["rev-parse", "--show-toplevel"],
|
|
111
|
+
}).stdout.trim();
|
|
112
112
|
}
|
|
113
113
|
catch {
|
|
114
114
|
return null;
|
|
@@ -119,12 +119,7 @@ export function fileDirtyVsHead(absPath) {
|
|
|
119
119
|
if (top === null)
|
|
120
120
|
return true;
|
|
121
121
|
try {
|
|
122
|
-
|
|
123
|
-
cwd: top,
|
|
124
|
-
encoding: "utf8",
|
|
125
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
126
|
-
});
|
|
127
|
-
return status.trim().length > 0;
|
|
122
|
+
return statusPorcelain(top, absPath).trim().length > 0;
|
|
128
123
|
}
|
|
129
124
|
catch {
|
|
130
125
|
return true;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type PipelineListing, type TaskListing } from "./browseCatalog.js";
|
|
2
|
+
import { type CatalogRoot, type ResolveCatalogRootsOptions } from "./resolveCatalogRoots.js";
|
|
3
|
+
export type CatalogRootError = {
|
|
4
|
+
project_root: string;
|
|
5
|
+
code: "catalog_root_unreadable" | "unknown_project_root";
|
|
6
|
+
message: string;
|
|
7
|
+
};
|
|
8
|
+
export type MultiProjectListResult<T> = {
|
|
9
|
+
items: T[];
|
|
10
|
+
root_errors: CatalogRootError[];
|
|
11
|
+
roots: CatalogRoot[];
|
|
12
|
+
};
|
|
13
|
+
export declare function listPipelinesMultiProject(options: ResolveCatalogRootsOptions & {
|
|
14
|
+
projectRootFilter?: string;
|
|
15
|
+
}): Promise<MultiProjectListResult<PipelineListing & {
|
|
16
|
+
project_root: string;
|
|
17
|
+
}>>;
|
|
18
|
+
export declare function listTasksMultiProject(options: ResolveCatalogRootsOptions & {
|
|
19
|
+
projectRootFilter?: string;
|
|
20
|
+
}): Promise<MultiProjectListResult<TaskListing & {
|
|
21
|
+
project_root: string;
|
|
22
|
+
}>>;
|
|
23
|
+
export declare function listModelsMultiProject(options: ResolveCatalogRootsOptions & {
|
|
24
|
+
projectRootFilter?: string;
|
|
25
|
+
}): Promise<MultiProjectListResult<{
|
|
26
|
+
id: string;
|
|
27
|
+
project_root: string;
|
|
28
|
+
}> & {
|
|
29
|
+
models: string[];
|
|
30
|
+
}>;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { listModelsForContext, listPipelinesForContext, listTasksForContext, } from "./browseCatalog.js";
|
|
2
|
+
import { loadStageflowManifestOutcome, } from "./loadStageflowManifest.js";
|
|
3
|
+
import { findCatalogRoot, isRootReadable, resolveCatalogRoots, } from "./resolveCatalogRoots.js";
|
|
4
|
+
import { catalogContextFromStageflow } from "./resolveCatalogContext.js";
|
|
5
|
+
import { resolveStageflowContext } from "../project/resolveStageflowContext.js";
|
|
6
|
+
async function catalogContextForRoot(root) {
|
|
7
|
+
if (root.kind === "seeded") {
|
|
8
|
+
const outcome = await loadStageflowManifestOutcome(root.path);
|
|
9
|
+
if (!outcome.ok) {
|
|
10
|
+
return {
|
|
11
|
+
projectRoot: root.path,
|
|
12
|
+
manifest: null,
|
|
13
|
+
manifestStatus: "invalid",
|
|
14
|
+
issues: outcome.issues,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
projectRoot: root.path,
|
|
19
|
+
manifest: outcome.value,
|
|
20
|
+
manifestStatus: "ok",
|
|
21
|
+
issues: [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return catalogContextFromStageflow(await resolveStageflowContext(root.path));
|
|
25
|
+
}
|
|
26
|
+
async function selectRoots(options) {
|
|
27
|
+
const roots = await resolveCatalogRoots(options);
|
|
28
|
+
const root_errors = [];
|
|
29
|
+
if (options.projectRootFilter !== undefined) {
|
|
30
|
+
const match = findCatalogRoot(roots, options.projectRootFilter);
|
|
31
|
+
if (match === undefined) {
|
|
32
|
+
return {
|
|
33
|
+
roots,
|
|
34
|
+
selected: [],
|
|
35
|
+
root_errors: [
|
|
36
|
+
{
|
|
37
|
+
project_root: options.projectRootFilter,
|
|
38
|
+
code: "unknown_project_root",
|
|
39
|
+
message: `Unknown project_root: ${options.projectRootFilter}`,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (!(await isRootReadable(match.path))) {
|
|
45
|
+
return {
|
|
46
|
+
roots,
|
|
47
|
+
selected: [],
|
|
48
|
+
root_errors: [
|
|
49
|
+
{
|
|
50
|
+
project_root: match.project_root,
|
|
51
|
+
code: "catalog_root_unreadable",
|
|
52
|
+
message: `Catalog root is unreadable: ${match.project_root}`,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return { roots, selected: [match], root_errors };
|
|
58
|
+
}
|
|
59
|
+
const selected = [];
|
|
60
|
+
for (const root of roots) {
|
|
61
|
+
if (!(await isRootReadable(root.path))) {
|
|
62
|
+
root_errors.push({
|
|
63
|
+
project_root: root.project_root,
|
|
64
|
+
code: "catalog_root_unreadable",
|
|
65
|
+
message: `Catalog root is unreadable: ${root.project_root}`,
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
selected.push(root);
|
|
70
|
+
}
|
|
71
|
+
return { roots, selected, root_errors };
|
|
72
|
+
}
|
|
73
|
+
export async function listPipelinesMultiProject(options) {
|
|
74
|
+
const { roots, selected, root_errors } = await selectRoots(options);
|
|
75
|
+
const items = [];
|
|
76
|
+
for (const root of selected) {
|
|
77
|
+
try {
|
|
78
|
+
const ctx = await catalogContextForRoot(root);
|
|
79
|
+
const pipelines = await listPipelinesForContext(ctx);
|
|
80
|
+
for (const p of pipelines) {
|
|
81
|
+
items.push({ ...p, project_root: root.project_root });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
root_errors.push({
|
|
86
|
+
project_root: root.project_root,
|
|
87
|
+
code: "catalog_root_unreadable",
|
|
88
|
+
message: err instanceof Error ? err.message : String(err),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { items, root_errors, roots };
|
|
93
|
+
}
|
|
94
|
+
export async function listTasksMultiProject(options) {
|
|
95
|
+
const { roots, selected, root_errors } = await selectRoots(options);
|
|
96
|
+
const items = [];
|
|
97
|
+
for (const root of selected) {
|
|
98
|
+
try {
|
|
99
|
+
const ctx = await catalogContextForRoot(root);
|
|
100
|
+
const tasks = await listTasksForContext(ctx);
|
|
101
|
+
for (const t of tasks) {
|
|
102
|
+
items.push({ ...t, project_root: root.project_root });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
root_errors.push({
|
|
107
|
+
project_root: root.project_root,
|
|
108
|
+
code: "catalog_root_unreadable",
|
|
109
|
+
message: err instanceof Error ? err.message : String(err),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return { items, root_errors, roots };
|
|
114
|
+
}
|
|
115
|
+
export async function listModelsMultiProject(options) {
|
|
116
|
+
const { roots, selected, root_errors } = await selectRoots(options);
|
|
117
|
+
const items = [];
|
|
118
|
+
const modelSet = new Set();
|
|
119
|
+
for (const root of selected) {
|
|
120
|
+
try {
|
|
121
|
+
const ctx = await catalogContextForRoot(root);
|
|
122
|
+
const models = await listModelsForContext(ctx);
|
|
123
|
+
for (const id of models) {
|
|
124
|
+
modelSet.add(id);
|
|
125
|
+
items.push({ id, project_root: root.project_root });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
root_errors.push({
|
|
130
|
+
project_root: root.project_root,
|
|
131
|
+
code: "catalog_root_unreadable",
|
|
132
|
+
message: err instanceof Error ? err.message : String(err),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
items,
|
|
138
|
+
models: [...modelSet].sort((a, b) => a.localeCompare(b)),
|
|
139
|
+
root_errors,
|
|
140
|
+
roots,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { loadFailure, loadSuccess } from "./loadOutcome.js";
|
|
9
9
|
import { parseStageMcp } from "./loadStage.js";
|
|
10
|
+
import { parseStageSecrets } from "../runtime/stageSecretDecl.js";
|
|
11
|
+
import { parseToolRequires } from "./toolRequires.js";
|
|
10
12
|
import { legacyAuthoringRejected, presentLegacyKeys } from "./legacyYaml.js";
|
|
11
13
|
import { compileTargetContract, dialectFromKeys, mixedDialectIssue, } from "./yamlDialect.js";
|
|
12
14
|
import { BODY_KEYS, isAllowedPipelineStageEntryKey, } from "./pipelineStageKeys.js";
|
|
@@ -39,7 +41,11 @@ function extractBodyRaw(raw) {
|
|
|
39
41
|
return body;
|
|
40
42
|
}
|
|
41
43
|
function hasBodyKey(raw) {
|
|
42
|
-
return Object.keys(raw).some((key) => BODY_KEYS.has(key) &&
|
|
44
|
+
return Object.keys(raw).some((key) => BODY_KEYS.has(key) &&
|
|
45
|
+
key !== "skill" &&
|
|
46
|
+
key !== "mcp" &&
|
|
47
|
+
key !== "secrets" &&
|
|
48
|
+
key !== "requires");
|
|
43
49
|
}
|
|
44
50
|
function readSkill(raw) {
|
|
45
51
|
if (raw.skill === undefined)
|
|
@@ -112,6 +118,17 @@ export function normalizePipelineStageEntries(rawEntries, ctx) {
|
|
|
112
118
|
if (!mcpOutcome.ok)
|
|
113
119
|
return mcpOutcome;
|
|
114
120
|
const mcp = mcpOutcome.value;
|
|
121
|
+
const secretsOutcome = parseStageSecrets(raw.secrets, `entry at index ${index} in ${declaringPath}`);
|
|
122
|
+
if (!secretsOutcome.ok)
|
|
123
|
+
return secretsOutcome;
|
|
124
|
+
const secrets = secretsOutcome.value;
|
|
125
|
+
const requiresOutcome = parseToolRequires(raw.requires, `stage entry at index ${index} in ${declaringPath}`, {
|
|
126
|
+
code: "stage.invalid_requires",
|
|
127
|
+
category: "stage",
|
|
128
|
+
});
|
|
129
|
+
if (!requiresOutcome.ok)
|
|
130
|
+
return requiresOutcome;
|
|
131
|
+
const requires = requiresOutcome.value;
|
|
115
132
|
if (uses && hasBody) {
|
|
116
133
|
return loadFailure([
|
|
117
134
|
{
|
|
@@ -339,6 +356,8 @@ export function normalizePipelineStageEntries(rawEntries, ctx) {
|
|
|
339
356
|
...(entryFlag !== undefined ? { entry: entryFlag } : {}),
|
|
340
357
|
...(skill !== undefined ? { skill } : {}),
|
|
341
358
|
...(mcp !== undefined ? { mcp } : {}),
|
|
359
|
+
...(secrets !== undefined ? { secrets } : {}),
|
|
360
|
+
...(requires !== undefined ? { requires } : {}),
|
|
342
361
|
...(cloneCap !== undefined ? { clone_cap: cloneCap } : {}),
|
|
343
362
|
...(cloneMode !== undefined ? { clone_mode: cloneMode } : {}),
|
|
344
363
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { RunStore } from "../runstore/port.js";
|
|
2
|
+
export type CatalogRootKind = "registered" | "seeded";
|
|
3
|
+
export type CatalogRoot = {
|
|
4
|
+
/** Wire id: absolute path for registered; symbolic id for seeded (e.g. "examples"). */
|
|
5
|
+
project_root: string;
|
|
6
|
+
/** Absolute filesystem path used for browsing. */
|
|
7
|
+
path: string;
|
|
8
|
+
kind: CatalogRootKind;
|
|
9
|
+
read_only: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type ResolveCatalogRootsOptions = {
|
|
12
|
+
store: RunStore;
|
|
13
|
+
/** Unused for catalog membership; retained so call sites may still pass Host cwd. */
|
|
14
|
+
bootCwd?: string;
|
|
15
|
+
/** Optional seeded roots (U10); default none. */
|
|
16
|
+
seededRoots?: Array<{
|
|
17
|
+
id: string;
|
|
18
|
+
path: string;
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Root set = registered store roots ∪ seeded roots.
|
|
23
|
+
* Wire project_root for seeded is the symbolic id; store/capacity use absolute paths.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveCatalogRoots(options: ResolveCatalogRootsOptions): Promise<CatalogRoot[]>;
|
|
26
|
+
export declare function isRootReadable(rootPath: string): Promise<boolean>;
|
|
27
|
+
export declare function findCatalogRoot(roots: CatalogRoot[], projectRoot: string): CatalogRoot | undefined;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { realpathSync, constants } from "node:fs";
|
|
3
|
+
import { access } from "node:fs/promises";
|
|
4
|
+
function realOrResolve(p) {
|
|
5
|
+
const resolved = path.resolve(p);
|
|
6
|
+
try {
|
|
7
|
+
return realpathSync(resolved);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return resolved;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Root set = registered store roots ∪ seeded roots.
|
|
15
|
+
* Wire project_root for seeded is the symbolic id; store/capacity use absolute paths.
|
|
16
|
+
*/
|
|
17
|
+
export async function resolveCatalogRoots(options) {
|
|
18
|
+
const roots = [];
|
|
19
|
+
const seenPaths = new Set();
|
|
20
|
+
const seededRoots = options.seededRoots ??
|
|
21
|
+
(await import("./seededCatalog.js")).defaultSeededRoots();
|
|
22
|
+
let registered = [];
|
|
23
|
+
try {
|
|
24
|
+
registered = await options.store.listRegisteredProjects();
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
registered = [];
|
|
28
|
+
}
|
|
29
|
+
for (const root of registered) {
|
|
30
|
+
const abs = realOrResolve(root);
|
|
31
|
+
if (seenPaths.has(abs))
|
|
32
|
+
continue;
|
|
33
|
+
seenPaths.add(abs);
|
|
34
|
+
roots.push({
|
|
35
|
+
project_root: abs,
|
|
36
|
+
path: abs,
|
|
37
|
+
kind: "registered",
|
|
38
|
+
read_only: false,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
for (const seeded of seededRoots) {
|
|
42
|
+
const abs = realOrResolve(seeded.path);
|
|
43
|
+
if (seenPaths.has(abs))
|
|
44
|
+
continue;
|
|
45
|
+
seenPaths.add(abs);
|
|
46
|
+
roots.push({
|
|
47
|
+
project_root: seeded.id,
|
|
48
|
+
path: abs,
|
|
49
|
+
kind: "seeded",
|
|
50
|
+
read_only: true,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return roots;
|
|
54
|
+
}
|
|
55
|
+
export async function isRootReadable(rootPath) {
|
|
56
|
+
try {
|
|
57
|
+
await access(rootPath, constants.R_OK);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function findCatalogRoot(roots, projectRoot) {
|
|
65
|
+
if (!path.isAbsolute(projectRoot)) {
|
|
66
|
+
return roots.find((r) => r.project_root === projectRoot);
|
|
67
|
+
}
|
|
68
|
+
const normalized = realOrResolve(projectRoot);
|
|
69
|
+
const resolved = path.resolve(projectRoot);
|
|
70
|
+
return roots.find((r) => r.project_root === projectRoot ||
|
|
71
|
+
r.path === projectRoot ||
|
|
72
|
+
r.project_root === resolved ||
|
|
73
|
+
r.path === resolved ||
|
|
74
|
+
r.project_root === normalized ||
|
|
75
|
+
r.path === normalized);
|
|
76
|
+
}
|