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
package/dist/mcp/catalogTools.js
CHANGED
|
@@ -1,39 +1,49 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import { z } from "zod";
|
|
3
|
-
import {
|
|
2
|
+
import { catalogPathErrorBody, CatalogPathError, resolveCatalogRelativePath, resolveCatalogStartInput, selectCatalogRootForStart, } from "../config/catalogRelativePath.js";
|
|
3
|
+
import { listModelsMultiProject, listPipelinesMultiProject, listTasksMultiProject, } from "../config/multiProjectCatalog.js";
|
|
4
|
+
import { resolveCatalogRoots } from "../config/resolveCatalogRoots.js";
|
|
4
5
|
import { describePipeline } from "../config/describePipeline.js";
|
|
5
6
|
import { loadPipeline } from "../config/loadPipeline.js";
|
|
6
7
|
import { readYamlObject } from "../config/readYamlObject.js";
|
|
7
8
|
import { validateCatalog } from "../config/validateCatalog.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
9
|
+
import { writeAudit } from "../logging/audit.js";
|
|
10
|
+
import { logger as rootLogger } from "../logging/logger.js";
|
|
11
|
+
import { PACKAGE_VERSION, BUILD_SHA } from "../package-meta.js";
|
|
10
12
|
import { PipelineValidationError } from "../runtime/pipelineValidationError.js";
|
|
13
|
+
import { PipelinePreflightError } from "../runtime/pipelineRunner.js";
|
|
11
14
|
import { EnvelopeRefError, resolveEnvelopeRefsToTask, } from "../runtime/resolveEnvelopeRef.js";
|
|
12
15
|
import { isTerminalProjection, isWaitingProjection, waitRun } from "./waitRun.js";
|
|
13
16
|
import { mapStoreLookupError } from "../server/operatorResults.js";
|
|
17
|
+
import { callerIdFromRequestAuth, getRequestAuth, } from "../server/requestAuthContext.js";
|
|
14
18
|
import { projectRunForMcp } from "./projectRun.js";
|
|
15
19
|
import { classifyArtifactContent, readRunArtifactBytes } from "./readArtifact.js";
|
|
16
20
|
import { imageResult, textResult } from "./toolResults.js";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
import { buildRunExportPayload } from "../runstore/exportRunPayload.js";
|
|
22
|
+
import { redactRunManifestForRead } from "../runstore/runManifest.js";
|
|
23
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
24
|
+
import { runSkillsDir } from "../runtime/runSkills.js";
|
|
25
|
+
import { listSkillsWithOrigin } from "../config/listSkills.js";
|
|
26
|
+
import { findTokenShapedField, pickCheckoutOverride, tokenRejectedPayload, } from "../runtime/startPayload.js";
|
|
27
|
+
import { loadPipelineFromObjectOutcome, loadPipelineOutcome, } from "../config/loadPipeline.js";
|
|
28
|
+
import { preflightFailureCode, runPipelinePreflight, } from "../preflight/pipelinePreflight.js";
|
|
29
|
+
import { toolchainHealthMap } from "../preflight/toolchain.js";
|
|
30
|
+
const auditLog = rootLogger.child({ component: "audit" });
|
|
31
|
+
const gitIdentitySchema = z
|
|
32
|
+
.object({
|
|
33
|
+
name: z.string().optional(),
|
|
34
|
+
email: z.string().optional(),
|
|
35
|
+
})
|
|
36
|
+
.strict();
|
|
31
37
|
const taskFileSchema = z.object({
|
|
32
38
|
id: z.string(),
|
|
33
39
|
goal: z.string(),
|
|
34
40
|
context: z.string().optional(),
|
|
35
41
|
constraints: z.string().optional(),
|
|
36
42
|
checkout: z.string().optional(),
|
|
43
|
+
repository: z.string().optional(),
|
|
44
|
+
ref: z.string().optional(),
|
|
45
|
+
run_branch_template: z.string().optional(),
|
|
46
|
+
git_identity: gitIdentitySchema.optional(),
|
|
37
47
|
input: z.record(z.string(), z.unknown()).optional(),
|
|
38
48
|
});
|
|
39
49
|
/**
|
|
@@ -50,16 +60,35 @@ const inlinePipelineSchema = z
|
|
|
50
60
|
agent: z.unknown().optional(),
|
|
51
61
|
model: z.unknown().optional(),
|
|
52
62
|
schemas: z.unknown().optional(),
|
|
63
|
+
requires: z.unknown().optional(),
|
|
53
64
|
})
|
|
54
65
|
.strict();
|
|
55
66
|
const startRunSchema = z
|
|
56
67
|
.object({
|
|
57
68
|
pipeline: z
|
|
58
69
|
.union([z.string(), inlinePipelineSchema])
|
|
59
|
-
.describe("
|
|
70
|
+
.describe("Catalog-relative pipeline path, or an inline pipeline definition object ({ id, stages: [...] }) authored directly in this call"),
|
|
60
71
|
task_path: z.string().optional(),
|
|
61
72
|
task: taskFileSchema.optional(),
|
|
73
|
+
project_root: z.string().optional(),
|
|
74
|
+
checkout: z
|
|
75
|
+
.string()
|
|
76
|
+
.optional()
|
|
77
|
+
.describe("Catalog-relative checkout path (maps to RunManager checkoutOverride); absolute paths are rejected with absolute_path_not_allowed"),
|
|
78
|
+
checkout_override: z
|
|
79
|
+
.string()
|
|
80
|
+
.optional()
|
|
81
|
+
.describe("Alias of checkout; prefer checkout"),
|
|
82
|
+
skip_gates: z.boolean().optional(),
|
|
83
|
+
git_sha: z.string().optional(),
|
|
84
|
+
ci_pr_url: z.string().optional(),
|
|
85
|
+
ci_job_url: z.string().optional(),
|
|
86
|
+
skills: z
|
|
87
|
+
.record(z.string(), z.record(z.string(), z.string()))
|
|
88
|
+
.optional()
|
|
89
|
+
.describe("Run-scoped skills: name → { relativePath: utf-8 contents }. Requires SKILL.md per name; materialised under the run workspace skills dir (never the worktree)"),
|
|
62
90
|
})
|
|
91
|
+
.passthrough()
|
|
63
92
|
.refine((data) => Boolean(data.task_path) !== Boolean(data.task), {
|
|
64
93
|
message: "Exactly one of task_path or task is required",
|
|
65
94
|
});
|
|
@@ -77,7 +106,11 @@ const runStageSchema = z
|
|
|
77
106
|
.object({
|
|
78
107
|
stage: z
|
|
79
108
|
.union([z.string(), z.record(z.string(), z.unknown())])
|
|
80
|
-
.describe("
|
|
109
|
+
.describe("Catalog-relative path to a stage YAML file (same path contract as start_run — absolute paths rejected, must be inside a registered project_root), or a bare inline stage body object ({ id, system_prompt, io, model?, gate_kinds?, mcp?, verify?, timeout_ms? } — no uses:/route/pipeline wrapper) authored directly in this call"),
|
|
110
|
+
project_root: z
|
|
111
|
+
.string()
|
|
112
|
+
.optional()
|
|
113
|
+
.describe("Catalog project root to resolve a string stage path against; required when multiple catalog roots are configured and no sole non-seeded root exists"),
|
|
81
114
|
task_path: z.string().optional(),
|
|
82
115
|
task: taskFileSchema.optional(),
|
|
83
116
|
envelope_ref: z
|
|
@@ -102,62 +135,132 @@ const runStageSchema = z
|
|
|
102
135
|
.describe("Wait budget in ms when blocking is true (same bounds as wait_run)"),
|
|
103
136
|
})
|
|
104
137
|
.refine((data) => [data.task_path, data.task, data.envelope_ref].filter(Boolean).length === 1, { message: "Exactly one of task_path, task, or envelope_ref is required" });
|
|
105
|
-
const runStatusSchema = z.enum([
|
|
138
|
+
const runStatusSchema = z.enum([
|
|
139
|
+
"created",
|
|
140
|
+
"queued",
|
|
141
|
+
"running",
|
|
142
|
+
"succeeded",
|
|
143
|
+
"failed",
|
|
144
|
+
"cancelled",
|
|
145
|
+
]);
|
|
106
146
|
export function registerCatalogTools(server, deps) {
|
|
107
147
|
const { manager, store, cwd } = deps;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
148
|
+
const agentDir = deps.agentDir ?? getAgentDir();
|
|
149
|
+
server.registerTool("list_skills", {
|
|
150
|
+
description: "List skills with name, description, and origin (run|checkout|host). Optional runId scopes to that run's resolution view (run-tier skills first, then checkout .pi/skills, then host).",
|
|
151
|
+
inputSchema: z.object({
|
|
152
|
+
runId: z.string().optional(),
|
|
153
|
+
}),
|
|
154
|
+
}, async ({ runId }) => {
|
|
155
|
+
try {
|
|
156
|
+
let runSkills;
|
|
157
|
+
let checkoutRoot;
|
|
158
|
+
if (runId !== undefined) {
|
|
159
|
+
const meta = await store.readRunMeta(runId);
|
|
160
|
+
runSkills = runSkillsDir(store.getWorkspaceDir(runId));
|
|
161
|
+
checkoutRoot = meta.checkout_root;
|
|
120
162
|
}
|
|
121
|
-
|
|
122
|
-
|
|
163
|
+
const catalog = await listSkillsWithOrigin({
|
|
164
|
+
cwd,
|
|
165
|
+
agentDir,
|
|
166
|
+
...(runSkills !== undefined ? { runSkillsDir: runSkills } : {}),
|
|
167
|
+
...(checkoutRoot !== undefined ? { checkoutRoot } : {}),
|
|
168
|
+
});
|
|
169
|
+
return textResult({
|
|
170
|
+
skills: catalog.skills,
|
|
171
|
+
diagnostics: catalog.diagnostics,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
if (runId !== undefined) {
|
|
176
|
+
const mapped = mapStoreLookupError(err, { policy: "run" });
|
|
177
|
+
return textResult({ error: mapped.error, status: mapped.status }, true);
|
|
123
178
|
}
|
|
179
|
+
throw err;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
server.registerTool("list_pipelines", {
|
|
183
|
+
description: "List manifest-declared pipeline paths across every project this host knows about (registered store roots and seeded roots). Each entry is tagged with project_root. Optional project_root filter narrows; unknown value returns unknown_project_root.",
|
|
184
|
+
inputSchema: z.object({
|
|
185
|
+
project_root: z.string().optional(),
|
|
186
|
+
}),
|
|
187
|
+
}, async ({ project_root }) => {
|
|
188
|
+
const result = await listPipelinesMultiProject({
|
|
189
|
+
store,
|
|
190
|
+
bootCwd: cwd,
|
|
191
|
+
projectRootFilter: project_root,
|
|
192
|
+
});
|
|
193
|
+
if (result.root_errors.some((e) => e.code === "unknown_project_root") &&
|
|
194
|
+
result.items.length === 0) {
|
|
195
|
+
return textResult({
|
|
196
|
+
error: result.root_errors[0].message,
|
|
197
|
+
code: "unknown_project_root",
|
|
198
|
+
root_errors: result.root_errors,
|
|
199
|
+
}, true);
|
|
124
200
|
}
|
|
125
|
-
return textResult({
|
|
201
|
+
return textResult({
|
|
202
|
+
pipelines: result.items,
|
|
203
|
+
root_errors: result.root_errors,
|
|
204
|
+
});
|
|
126
205
|
});
|
|
127
206
|
server.registerTool("list_tasks", {
|
|
128
|
-
description: "List manifest-declared task paths across every project this host knows about (
|
|
129
|
-
inputSchema: z.object({
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
207
|
+
description: "List manifest-declared task paths across every project this host knows about (registered store roots and seeded roots). Each entry is tagged with project_root. Optional project_root filter narrows; unknown value returns unknown_project_root.",
|
|
208
|
+
inputSchema: z.object({
|
|
209
|
+
project_root: z.string().optional(),
|
|
210
|
+
}),
|
|
211
|
+
}, async ({ project_root }) => {
|
|
212
|
+
const result = await listTasksMultiProject({
|
|
213
|
+
store,
|
|
214
|
+
bootCwd: cwd,
|
|
215
|
+
projectRootFilter: project_root,
|
|
216
|
+
});
|
|
217
|
+
if (result.root_errors.some((e) => e.code === "unknown_project_root") &&
|
|
218
|
+
result.items.length === 0) {
|
|
219
|
+
return textResult({
|
|
220
|
+
error: result.root_errors[0].message,
|
|
221
|
+
code: "unknown_project_root",
|
|
222
|
+
root_errors: result.root_errors,
|
|
223
|
+
}, true);
|
|
143
224
|
}
|
|
144
|
-
return textResult({
|
|
225
|
+
return textResult({
|
|
226
|
+
tasks: result.items,
|
|
227
|
+
root_errors: result.root_errors,
|
|
228
|
+
});
|
|
145
229
|
});
|
|
146
230
|
server.registerTool("list_models", {
|
|
147
|
-
description: "List catalog model ids
|
|
148
|
-
inputSchema: z.object({
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
231
|
+
description: "List catalog model ids across every project this host knows about (same multi-root source as GET /api/models). Optional project_root filter narrows.",
|
|
232
|
+
inputSchema: z.object({
|
|
233
|
+
project_root: z.string().optional(),
|
|
234
|
+
}),
|
|
235
|
+
}, async ({ project_root }) => {
|
|
236
|
+
const result = await listModelsMultiProject({
|
|
237
|
+
store,
|
|
238
|
+
bootCwd: cwd,
|
|
239
|
+
projectRootFilter: project_root,
|
|
240
|
+
});
|
|
241
|
+
if (result.root_errors.some((e) => e.code === "unknown_project_root") &&
|
|
242
|
+
result.items.length === 0) {
|
|
243
|
+
return textResult({
|
|
244
|
+
error: result.root_errors[0].message,
|
|
245
|
+
code: "unknown_project_root",
|
|
246
|
+
root_errors: result.root_errors,
|
|
247
|
+
}, true);
|
|
248
|
+
}
|
|
249
|
+
return textResult({
|
|
250
|
+
models: result.models,
|
|
251
|
+
entries: result.items,
|
|
252
|
+
root_errors: result.root_errors,
|
|
253
|
+
});
|
|
152
254
|
});
|
|
153
255
|
server.registerTool("list_runs", {
|
|
154
|
-
description: "List known pipeline runs. Optional filters: status, since (ISO created_at lower bound), pipeline (id or path).",
|
|
256
|
+
description: "List known pipeline runs. Optional filters: status, since (ISO created_at lower bound), pipeline (id or path), caller_id.",
|
|
155
257
|
inputSchema: z.object({
|
|
156
258
|
status: runStatusSchema.optional(),
|
|
157
259
|
since: z.string().optional(),
|
|
158
260
|
pipeline: z.string().optional(),
|
|
261
|
+
caller_id: z.string().optional(),
|
|
159
262
|
}),
|
|
160
|
-
}, async ({ status, since, pipeline }) => {
|
|
263
|
+
}, async ({ status, since, pipeline, caller_id }) => {
|
|
161
264
|
const filter = {};
|
|
162
265
|
if (status !== undefined)
|
|
163
266
|
filter.status = status;
|
|
@@ -169,17 +272,106 @@ export function registerCatalogTools(server, deps) {
|
|
|
169
272
|
}
|
|
170
273
|
if (pipeline !== undefined)
|
|
171
274
|
filter.pipeline = pipeline;
|
|
275
|
+
if (caller_id !== undefined)
|
|
276
|
+
filter.caller_id = caller_id;
|
|
172
277
|
const runs = await store.listRuns(Object.keys(filter).length > 0 ? filter : undefined);
|
|
173
278
|
return textResult({ runs });
|
|
174
279
|
});
|
|
175
280
|
server.registerTool("get_health", {
|
|
176
|
-
description: "Server health and soft-max run capacity: activeRunIds, activeCount, maxConcurrent, slotsAvailable, version. Start until slotsAvailable is 0; then wait for a run to finish or raise STAGEFLOW_MAX_CONCURRENT_RUNS.",
|
|
281
|
+
description: "Server health and soft-max run capacity: activeRunIds, activeCount, maxConcurrent, slotsAvailable, activeStageProcesses, version, plus disk breakdown (disk.runs_bytes, worktrees_bytes, repos_bytes, state_db_bytes, a2a_artifacts_bytes, free_bytes) for the durable root. Start until slotsAvailable is 0; then wait for a run to finish or raise STAGEFLOW_MAX_CONCURRENT_RUNS.",
|
|
177
282
|
inputSchema: z.object({}),
|
|
178
|
-
}, async () => textResult({
|
|
283
|
+
}, async () => textResult({
|
|
284
|
+
...(await manager.getHealthWithDisk()),
|
|
285
|
+
version: PACKAGE_VERSION,
|
|
286
|
+
build_sha: BUILD_SHA,
|
|
287
|
+
toolchain: toolchainHealthMap(),
|
|
288
|
+
}));
|
|
289
|
+
server.registerTool("preflight", {
|
|
290
|
+
description: "Check pipeline requires:/secrets:/mcp against the Host toolchain manifest and curated stage env before start_run. Accepts pipeline path or inline definition (same union as start_run). Returns { ok, checks } with status ok|missing_tool|tool_version_mismatch|unknown_version|secret_unavailable|unresolved_var. Does not create a Run. unknown_version is ok unless strict:true.",
|
|
291
|
+
inputSchema: z.object({
|
|
292
|
+
pipeline: z
|
|
293
|
+
.union([z.string(), inlinePipelineSchema])
|
|
294
|
+
.describe("Catalog-relative pipeline path, or an inline pipeline definition object"),
|
|
295
|
+
project_root: z.string().optional(),
|
|
296
|
+
strict: z
|
|
297
|
+
.boolean()
|
|
298
|
+
.optional()
|
|
299
|
+
.describe("When true, unknown_version fails (default false)"),
|
|
300
|
+
}),
|
|
301
|
+
}, async ({ pipeline, project_root, strict }) => {
|
|
302
|
+
const roots = await resolveCatalogRoots({
|
|
303
|
+
store: deps.store,
|
|
304
|
+
bootCwd: deps.cwd,
|
|
305
|
+
});
|
|
306
|
+
let loaded;
|
|
307
|
+
let projectRoot;
|
|
308
|
+
try {
|
|
309
|
+
const wireRoot = selectCatalogRootForStart(roots, project_root);
|
|
310
|
+
projectRoot = wireRoot.project_root;
|
|
311
|
+
if (typeof pipeline === "string") {
|
|
312
|
+
const resolved = resolveCatalogRelativePath({
|
|
313
|
+
inputPath: pipeline,
|
|
314
|
+
projectRoot: project_root,
|
|
315
|
+
roots,
|
|
316
|
+
fieldName: "pipeline",
|
|
317
|
+
});
|
|
318
|
+
projectRoot = resolved.root.project_root;
|
|
319
|
+
const outcome = await loadPipelineOutcome(resolved.absolutePath, {
|
|
320
|
+
cwd: deps.cwd,
|
|
321
|
+
projectRoot,
|
|
322
|
+
});
|
|
323
|
+
if (!outcome.ok) {
|
|
324
|
+
return textResult({
|
|
325
|
+
ok: false,
|
|
326
|
+
error: outcome.issues[0]?.message ?? "pipeline load failed",
|
|
327
|
+
code: outcome.issues[0]?.code ?? "config_invalid",
|
|
328
|
+
issues: outcome.issues,
|
|
329
|
+
}, true);
|
|
330
|
+
}
|
|
331
|
+
loaded = outcome.value;
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
const outcome = await loadPipelineFromObjectOutcome(pipeline, {
|
|
335
|
+
cwd: deps.cwd,
|
|
336
|
+
projectRoot,
|
|
337
|
+
});
|
|
338
|
+
if (!outcome.ok) {
|
|
339
|
+
return textResult({
|
|
340
|
+
ok: false,
|
|
341
|
+
error: outcome.issues[0]?.message ?? "pipeline load failed",
|
|
342
|
+
code: outcome.issues[0]?.code ?? "config_invalid",
|
|
343
|
+
issues: outcome.issues,
|
|
344
|
+
}, true);
|
|
345
|
+
}
|
|
346
|
+
loaded = outcome.value;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
catch (err) {
|
|
350
|
+
if (err instanceof CatalogPathError) {
|
|
351
|
+
return textResult(catalogPathErrorBody(err), true);
|
|
352
|
+
}
|
|
353
|
+
throw err;
|
|
354
|
+
}
|
|
355
|
+
const result = await runPipelinePreflight(loaded, {
|
|
356
|
+
projectRoot,
|
|
357
|
+
strict: strict === true,
|
|
358
|
+
});
|
|
359
|
+
const code = preflightFailureCode(result, { strict: strict === true });
|
|
360
|
+
return textResult({
|
|
361
|
+
ok: result.ok,
|
|
362
|
+
checks: result.checks,
|
|
363
|
+
...(code !== undefined ? { code } : {}),
|
|
364
|
+
});
|
|
365
|
+
});
|
|
179
366
|
server.registerTool("start_run", {
|
|
180
|
-
description: "Start a pipeline run
|
|
367
|
+
description: "Start a pipeline run. Accepted params: pipeline (catalog-relative path or inline { id, stages: [...] } — stages are YAML stage bodies, no uses: refs), task_path XOR task (inline task may include repository/ref or checkout; repository XOR checkout with code task.binding_conflict), project_root, checkout (catalog-relative; prefer this name; absolute → absolute_path_not_allowed), checkout_override (alias of checkout), skip_gates, git_sha, ci_pr_url, ci_job_url, skills (name → { relativePath: utf-8 contents }; requires SKILL.md; materialised under runs/<runId>/skills/, never the worktree). REST POST /api/runs accepts path pipelines only (no inline pipeline). Returns { runId } or { runId, queued: true, queuePosition }. Errors: busy_capacity, busy_checkout, insufficient_disk, start.token_rejected, skills_*, inline_pipeline_too_large, catalog path-contract codes.",
|
|
181
368
|
inputSchema: startRunSchema,
|
|
182
|
-
}, async (
|
|
369
|
+
}, async (args) => {
|
|
370
|
+
const tokenField = findTokenShapedField(args);
|
|
371
|
+
if (tokenField !== undefined) {
|
|
372
|
+
return textResult(tokenRejectedPayload(tokenField), true);
|
|
373
|
+
}
|
|
374
|
+
const { pipeline, task_path, task, project_root, checkout, checkout_override, skip_gates, git_sha, ci_pr_url, ci_job_url, skills, } = args;
|
|
183
375
|
if (typeof pipeline === "string" && !pipeline.trim()) {
|
|
184
376
|
return textResult({ error: "pipeline is required" }, true);
|
|
185
377
|
}
|
|
@@ -187,26 +379,130 @@ export function registerCatalogTools(server, deps) {
|
|
|
187
379
|
if (taskInput === undefined) {
|
|
188
380
|
return textResult({ error: "Exactly one of task_path or task is required" }, true);
|
|
189
381
|
}
|
|
382
|
+
let wireRoot;
|
|
383
|
+
let roots;
|
|
384
|
+
try {
|
|
385
|
+
({ wireRoot, roots } = await resolveCatalogStartInput({ store: deps.store, bootCwd: deps.cwd }, project_root));
|
|
386
|
+
}
|
|
387
|
+
catch (err) {
|
|
388
|
+
if (err instanceof CatalogPathError) {
|
|
389
|
+
return textResult(catalogPathErrorBody(err), true);
|
|
390
|
+
}
|
|
391
|
+
throw err;
|
|
392
|
+
}
|
|
393
|
+
const wireProjectRoot = wireRoot.project_root;
|
|
394
|
+
let resolvedPipeline = pipeline;
|
|
395
|
+
let resolvedTask = taskInput;
|
|
396
|
+
let resolvedCheckout;
|
|
397
|
+
try {
|
|
398
|
+
if (typeof pipeline === "string") {
|
|
399
|
+
resolvedPipeline = resolveCatalogRelativePath({
|
|
400
|
+
inputPath: pipeline,
|
|
401
|
+
projectRoot: wireProjectRoot,
|
|
402
|
+
roots,
|
|
403
|
+
fieldName: "pipeline",
|
|
404
|
+
}).absolutePath;
|
|
405
|
+
}
|
|
406
|
+
if (typeof task_path === "string") {
|
|
407
|
+
resolvedTask = resolveCatalogRelativePath({
|
|
408
|
+
inputPath: task_path,
|
|
409
|
+
projectRoot: wireProjectRoot,
|
|
410
|
+
roots,
|
|
411
|
+
fieldName: "task_path",
|
|
412
|
+
}).absolutePath;
|
|
413
|
+
}
|
|
414
|
+
const rawCheckout = pickCheckoutOverride({ checkout, checkout_override });
|
|
415
|
+
if (rawCheckout !== undefined) {
|
|
416
|
+
resolvedCheckout = resolveCatalogRelativePath({
|
|
417
|
+
inputPath: rawCheckout,
|
|
418
|
+
projectRoot: wireProjectRoot,
|
|
419
|
+
roots,
|
|
420
|
+
fieldName: "checkout",
|
|
421
|
+
}).absolutePath;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
catch (err) {
|
|
425
|
+
if (err instanceof CatalogPathError) {
|
|
426
|
+
return textResult(catalogPathErrorBody(err), true);
|
|
427
|
+
}
|
|
428
|
+
throw err;
|
|
429
|
+
}
|
|
430
|
+
const callerId = callerIdFromRequestAuth();
|
|
190
431
|
let result;
|
|
191
432
|
try {
|
|
192
|
-
result = await manager.startRun({
|
|
433
|
+
result = await manager.startRun({
|
|
434
|
+
pipeline: resolvedPipeline,
|
|
435
|
+
task: resolvedTask,
|
|
436
|
+
projectRoot: wireRoot.path,
|
|
437
|
+
...(resolvedCheckout !== undefined
|
|
438
|
+
? { checkoutOverride: resolvedCheckout }
|
|
439
|
+
: {}),
|
|
440
|
+
...(skip_gates !== undefined ? { skipGates: skip_gates } : {}),
|
|
441
|
+
...(git_sha !== undefined ? { gitSha: git_sha } : {}),
|
|
442
|
+
...(ci_pr_url !== undefined ? { ciPrUrl: ci_pr_url } : {}),
|
|
443
|
+
...(ci_job_url !== undefined ? { ciJobUrl: ci_job_url } : {}),
|
|
444
|
+
...(skills !== undefined ? { skills } : {}),
|
|
445
|
+
callerId,
|
|
446
|
+
});
|
|
193
447
|
}
|
|
194
448
|
catch (err) {
|
|
195
449
|
if (err instanceof PipelineValidationError) {
|
|
450
|
+
writeAudit(auditLog, {
|
|
451
|
+
caller_id: callerId,
|
|
452
|
+
surface: getRequestAuth()?.surface ?? "mcp",
|
|
453
|
+
action: "start_run",
|
|
454
|
+
outcome: "error",
|
|
455
|
+
error_code: "pipeline_validation",
|
|
456
|
+
});
|
|
196
457
|
return textResult({ error: "Pipeline validation failed", validation: err.result }, true);
|
|
197
458
|
}
|
|
459
|
+
if (err instanceof PipelinePreflightError) {
|
|
460
|
+
writeAudit(auditLog, {
|
|
461
|
+
caller_id: callerId,
|
|
462
|
+
surface: getRequestAuth()?.surface ?? "mcp",
|
|
463
|
+
action: "start_run",
|
|
464
|
+
outcome: "error",
|
|
465
|
+
error_code: err.code,
|
|
466
|
+
});
|
|
467
|
+
return textResult(err.toNetworkBody(), true);
|
|
468
|
+
}
|
|
198
469
|
throw err;
|
|
199
470
|
}
|
|
200
471
|
if (!result.ok) {
|
|
472
|
+
writeAudit(auditLog, {
|
|
473
|
+
caller_id: callerId,
|
|
474
|
+
surface: getRequestAuth()?.surface ?? "mcp",
|
|
475
|
+
action: "start_run",
|
|
476
|
+
outcome: "error",
|
|
477
|
+
error_code: result.code,
|
|
478
|
+
});
|
|
201
479
|
const { ok: _ok, reason, ...rest } = result;
|
|
202
480
|
return textResult({ error: reason, ...rest }, true);
|
|
203
481
|
}
|
|
204
|
-
|
|
482
|
+
writeAudit(auditLog, {
|
|
483
|
+
caller_id: callerId,
|
|
484
|
+
surface: getRequestAuth()?.surface ?? "mcp",
|
|
485
|
+
action: "start_run",
|
|
486
|
+
target_run_id: result.runId,
|
|
487
|
+
outcome: "ok",
|
|
488
|
+
});
|
|
489
|
+
return textResult({
|
|
490
|
+
runId: result.runId,
|
|
491
|
+
...(result.queued === true
|
|
492
|
+
? {
|
|
493
|
+
queued: true,
|
|
494
|
+
queuePosition: result.queuePosition,
|
|
495
|
+
...(result.queuedCode !== undefined
|
|
496
|
+
? { queuedCode: result.queuedCode }
|
|
497
|
+
: {}),
|
|
498
|
+
}
|
|
499
|
+
: {}),
|
|
500
|
+
});
|
|
205
501
|
});
|
|
206
502
|
server.registerTool("run_stage", {
|
|
207
503
|
description: "Run a single stage directly, without authoring a pipeline. `stage` is a filesystem path to a stage YAML file, or a bare inline stage body ({ id, system_prompt, io, model?, gate_kinds?, mcp?, verify?, timeout_ms? } — no uses:/route/pipeline wrapper), and exactly one of task_path, an inline task, or envelope_ref ({ runId, stageId, attempt? }) to resolve a previously stored envelope — from another run_stage call or any stage in a full pipeline run — as this stage's input. Internally this synthesizes a one-stage pipeline and executes it through the normal run path, so it shows up in list_runs/get_run and is polled with wait_run / get_envelope exactly like any other run. By default returns { runId, stageId } immediately (async); pass blocking:true to wait in this same call and get back { runId, stageId, status: \"completed\"|\"needs_input\"|\"timeout\", envelope? , pending_prompt? }.",
|
|
208
504
|
inputSchema: runStageSchema,
|
|
209
|
-
}, async ({ stage, task_path, task, envelope_ref, checkout, model, blocking, timeout_ms }) => {
|
|
505
|
+
}, async ({ stage, project_root, task_path, task, envelope_ref, checkout, model, blocking, timeout_ms }) => {
|
|
210
506
|
let taskInput = task_path ?? task;
|
|
211
507
|
if (envelope_ref) {
|
|
212
508
|
try {
|
|
@@ -223,11 +519,28 @@ export function registerCatalogTools(server, deps) {
|
|
|
223
519
|
return textResult({ error: "Exactly one of task_path, task, or envelope_ref is required" }, true);
|
|
224
520
|
}
|
|
225
521
|
let stageBody;
|
|
522
|
+
let stageProjectRoot;
|
|
226
523
|
if (typeof stage === "string") {
|
|
227
524
|
if (!stage.trim()) {
|
|
228
525
|
return textResult({ error: "stage is required" }, true);
|
|
229
526
|
}
|
|
230
|
-
|
|
527
|
+
let absPath = "";
|
|
528
|
+
try {
|
|
529
|
+
const { wireRoot, roots } = await resolveCatalogStartInput({ store: deps.store, bootCwd: deps.cwd }, project_root);
|
|
530
|
+
stageProjectRoot = wireRoot.path;
|
|
531
|
+
absPath = resolveCatalogRelativePath({
|
|
532
|
+
inputPath: stage,
|
|
533
|
+
projectRoot: wireRoot.project_root,
|
|
534
|
+
roots,
|
|
535
|
+
fieldName: "stage",
|
|
536
|
+
}).absolutePath;
|
|
537
|
+
}
|
|
538
|
+
catch (err) {
|
|
539
|
+
if (err instanceof CatalogPathError) {
|
|
540
|
+
return textResult(catalogPathErrorBody(err), true);
|
|
541
|
+
}
|
|
542
|
+
throw err;
|
|
543
|
+
}
|
|
231
544
|
try {
|
|
232
545
|
stageBody = await readYamlObject(absPath);
|
|
233
546
|
}
|
|
@@ -254,7 +567,11 @@ export function registerCatalogTools(server, deps) {
|
|
|
254
567
|
};
|
|
255
568
|
let result;
|
|
256
569
|
try {
|
|
257
|
-
result = await manager.startRun({
|
|
570
|
+
result = await manager.startRun({
|
|
571
|
+
pipeline,
|
|
572
|
+
task: taskInput,
|
|
573
|
+
...(stageProjectRoot !== undefined ? { projectRoot: stageProjectRoot } : {}),
|
|
574
|
+
});
|
|
258
575
|
}
|
|
259
576
|
catch (err) {
|
|
260
577
|
if (err instanceof PipelineValidationError) {
|
|
@@ -308,7 +625,25 @@ export function registerCatalogTools(server, deps) {
|
|
|
308
625
|
}, async ({ runId }) => {
|
|
309
626
|
try {
|
|
310
627
|
const detail = await store.readRun(runId);
|
|
311
|
-
return textResult(
|
|
628
|
+
return textResult({
|
|
629
|
+
...projectRunForMcp(detail),
|
|
630
|
+
run_manifest: redactRunManifestForRead(detail.run_manifest),
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
catch (err) {
|
|
634
|
+
const mapped = mapStoreLookupError(err, { policy: "run" });
|
|
635
|
+
return textResult({ error: mapped.error, status: mapped.status }, true);
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
server.registerTool("export_run", {
|
|
639
|
+
description: "Export a single run as projectRun projection plus run_manifest. Works for running, cancelled, and terminal runs. Prefer over CLI sf export-run when the Host is reachable.",
|
|
640
|
+
inputSchema: z.object({
|
|
641
|
+
runId: z.string(),
|
|
642
|
+
}),
|
|
643
|
+
}, async ({ runId }) => {
|
|
644
|
+
try {
|
|
645
|
+
const detail = await store.readRun(runId);
|
|
646
|
+
return textResult(buildRunExportPayload(detail));
|
|
312
647
|
}
|
|
313
648
|
catch (err) {
|
|
314
649
|
const mapped = mapStoreLookupError(err, { policy: "run" });
|
|
@@ -361,14 +696,21 @@ export function registerCatalogTools(server, deps) {
|
|
|
361
696
|
else if (task !== undefined && task.trim())
|
|
362
697
|
scope = "task";
|
|
363
698
|
if (scope === "full") {
|
|
364
|
-
const roots = await
|
|
699
|
+
const roots = await resolveCatalogRoots({
|
|
700
|
+
store: deps.store,
|
|
701
|
+
bootCwd: deps.cwd,
|
|
702
|
+
});
|
|
365
703
|
const results = [];
|
|
366
704
|
for (const root of roots) {
|
|
367
705
|
try {
|
|
368
|
-
results.push(await validateCatalog({
|
|
706
|
+
results.push(await validateCatalog({
|
|
707
|
+
cwd: root.path,
|
|
708
|
+
scope: "full",
|
|
709
|
+
strict: strict ?? false,
|
|
710
|
+
}));
|
|
369
711
|
}
|
|
370
712
|
catch {
|
|
371
|
-
//
|
|
713
|
+
// unreadable root; skip
|
|
372
714
|
}
|
|
373
715
|
}
|
|
374
716
|
const merged = {
|
|
@@ -383,13 +725,33 @@ export function registerCatalogTools(server, deps) {
|
|
|
383
725
|
return textResult(merged);
|
|
384
726
|
}
|
|
385
727
|
const target = scope === "pipeline" ? pipeline.trim() : task.trim();
|
|
386
|
-
const
|
|
728
|
+
const roots = await resolveCatalogRoots({
|
|
729
|
+
store: deps.store,
|
|
730
|
+
bootCwd: deps.cwd,
|
|
731
|
+
});
|
|
732
|
+
let resolvedTarget = target;
|
|
733
|
+
let projectRoot = deps.cwd;
|
|
734
|
+
try {
|
|
735
|
+
const resolved = resolveCatalogRelativePath({
|
|
736
|
+
inputPath: target,
|
|
737
|
+
roots,
|
|
738
|
+
fieldName: scope === "pipeline" ? "pipeline" : "task",
|
|
739
|
+
});
|
|
740
|
+
resolvedTarget = resolved.absolutePath;
|
|
741
|
+
projectRoot = resolved.root.path;
|
|
742
|
+
}
|
|
743
|
+
catch (err) {
|
|
744
|
+
if (err instanceof CatalogPathError) {
|
|
745
|
+
return textResult(catalogPathErrorBody(err), true);
|
|
746
|
+
}
|
|
747
|
+
throw err;
|
|
748
|
+
}
|
|
387
749
|
const result = await validateCatalog({
|
|
388
750
|
cwd: projectRoot,
|
|
389
751
|
scope,
|
|
390
752
|
projectRoot,
|
|
391
|
-
...(scope === "pipeline" ? { pipeline:
|
|
392
|
-
...(scope === "task" ? { task:
|
|
753
|
+
...(scope === "pipeline" ? { pipeline: resolvedTarget } : {}),
|
|
754
|
+
...(scope === "task" ? { task: resolvedTarget } : {}),
|
|
393
755
|
strict: strict ?? false,
|
|
394
756
|
});
|
|
395
757
|
return textResult(result);
|
|
@@ -400,23 +762,37 @@ export function registerCatalogTools(server, deps) {
|
|
|
400
762
|
}
|
|
401
763
|
});
|
|
402
764
|
server.registerTool("describe_pipeline", {
|
|
403
|
-
description: "Describe a pipeline DAG from a
|
|
765
|
+
description: "Describe a pipeline DAG from a catalog-relative path (same path contract as start_run): stages with inbound needs (id, on, optional if), fork, gate_kinds, Clone Chain clone_cap and clone_mode, and feedback_loop, entry, and replay_safe when set.",
|
|
404
766
|
inputSchema: z.object({
|
|
405
767
|
pipeline: z.string(),
|
|
768
|
+
project_root: z.string().optional(),
|
|
406
769
|
}),
|
|
407
|
-
}, async ({ pipeline }) => {
|
|
770
|
+
}, async ({ pipeline, project_root }) => {
|
|
408
771
|
if (!pipeline.trim()) {
|
|
409
772
|
return textResult({ error: "pipeline is required", status: 400 }, true);
|
|
410
773
|
}
|
|
411
774
|
try {
|
|
412
|
-
const
|
|
413
|
-
|
|
775
|
+
const roots = await resolveCatalogRoots({
|
|
776
|
+
store: deps.store,
|
|
777
|
+
bootCwd: deps.cwd,
|
|
778
|
+
});
|
|
779
|
+
const resolved = resolveCatalogRelativePath({
|
|
780
|
+
inputPath: pipeline.trim(),
|
|
781
|
+
projectRoot: project_root,
|
|
782
|
+
roots,
|
|
783
|
+
fieldName: "pipeline",
|
|
784
|
+
});
|
|
785
|
+
const loaded = await loadPipeline(resolved.absolutePath, {
|
|
786
|
+
projectRoot: resolved.root.path,
|
|
414
787
|
});
|
|
415
788
|
return textResult(describePipeline(loaded));
|
|
416
789
|
}
|
|
417
790
|
catch (err) {
|
|
791
|
+
if (err instanceof CatalogPathError) {
|
|
792
|
+
return textResult(catalogPathErrorBody(err), true);
|
|
793
|
+
}
|
|
418
794
|
const message = err instanceof Error ? err.message : String(err);
|
|
419
|
-
return textResult({ error: message, status:
|
|
795
|
+
return textResult({ error: message, status: 400 }, true);
|
|
420
796
|
}
|
|
421
797
|
});
|
|
422
798
|
}
|