stageflow 0.23.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 +24 -5
- package/dist/a2a/configDiscovery.d.ts +9 -0
- package/dist/a2a/configDiscovery.js +18 -0
- package/dist/a2a/contracts.d.ts +94 -0
- package/dist/a2a/contracts.js +164 -0
- package/dist/a2a/limits.d.ts +14 -0
- package/dist/a2a/limits.js +29 -0
- package/dist/a2a/registry.d.ts +46 -0
- package/dist/a2a/registry.js +178 -0
- package/dist/a2a/server.d.ts +36 -0
- package/dist/a2a/server.js +344 -0
- package/dist/a2a/service.d.ts +97 -0
- package/dist/a2a/service.js +545 -0
- package/dist/a2a/store.d.ts +109 -0
- package/dist/a2a/store.js +202 -0
- 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/a2aCommand.d.ts +8 -0
- package/dist/cli/a2aCommand.js +131 -0
- 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 +34 -0
- package/dist/cli/runStageCommand.js +426 -0
- package/dist/cli/runsCommand.d.ts +1 -1
- package/dist/cli/runsCommand.js +162 -8
- package/dist/cli.js +190 -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 +591 -76
- 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 +27 -0
- package/dist/runstore/createStore.js +75 -7
- 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 +119 -8
- 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 +37 -3
- package/dist/runstore/sqlite/SqliteRunStore.js +401 -227
- 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 +283 -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/submission.d.ts +11 -0
- package/dist/runstore/submission.js +7 -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 +38 -1
- package/dist/runtime/pipelineRunner.js +179 -15
- package/dist/runtime/pipelineScheduler.d.ts +15 -0
- package/dist/runtime/pipelineScheduler.js +167 -42
- package/dist/runtime/reloadRunCatalog.js +12 -1
- package/dist/runtime/repositoryMaterialize.d.ts +47 -0
- package/dist/runtime/repositoryMaterialize.js +235 -0
- package/dist/runtime/resolveEnvelopeRef.d.ts +30 -0
- package/dist/runtime/resolveEnvelopeRef.js +79 -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 +179 -4
- package/dist/runtime/runManager.js +1644 -83
- 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 +38 -2
- package/dist/server/bootstrap.js +219 -4
- 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 +109 -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 +6 -1
- package/skills/stageflow/SKILL.md +6 -6
- package/skills/stageflow/references/control-surface.md +11 -5
- package/skills/stageflow/scripts/detect-host.mjs +14 -1
- package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
- package/skills/stageflow-author/SKILL.md +4 -3
- package/skills/stageflow-author/references/catalog-mapping.md +16 -0
- package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
- package/skills/stageflow-run/SKILL.md +20 -12
- package/skills/stageflow-run/references/mcp-call.md +9 -1
- package/skills/stageflow-run/references/task-and-pipeline-selection.md +16 -5
- package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
- package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
- package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
- package/skills/stageflow-setup/SKILL.md +40 -8
- package/dist/ui/assets/index-Da5EHU6M.js +0 -119
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { access } from "node:fs/promises";
|
|
1
|
+
import { access, readFile, readdir } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { DefaultResourceLoader, SettingsManager, } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
function toListing(skill) {
|
|
4
|
+
function toListing(skill, origin) {
|
|
4
5
|
return {
|
|
5
6
|
name: skill.name,
|
|
6
7
|
description: skill.description,
|
|
@@ -9,8 +10,39 @@ function toListing(skill) {
|
|
|
9
10
|
scope: skill.sourceInfo.scope,
|
|
10
11
|
source: skill.sourceInfo.source,
|
|
11
12
|
disableModelInvocation: skill.disableModelInvocation,
|
|
13
|
+
...(origin !== undefined ? { origin } : {}),
|
|
12
14
|
};
|
|
13
15
|
}
|
|
16
|
+
function isUnderRoot(candidate, root) {
|
|
17
|
+
const resolvedRoot = path.resolve(root);
|
|
18
|
+
const resolved = path.resolve(candidate);
|
|
19
|
+
const rel = path.relative(resolvedRoot, resolved);
|
|
20
|
+
return rel === "" || (!rel.startsWith("..") && !path.isAbsolute(rel));
|
|
21
|
+
}
|
|
22
|
+
async function pathExists(filePath) {
|
|
23
|
+
try {
|
|
24
|
+
await access(filePath);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function descriptionFromSkillMd(content) {
|
|
32
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(content);
|
|
33
|
+
if (!match)
|
|
34
|
+
return undefined;
|
|
35
|
+
const block = match[1];
|
|
36
|
+
const descLine = /^description:\s*(.*)$/m.exec(block);
|
|
37
|
+
if (!descLine)
|
|
38
|
+
return undefined;
|
|
39
|
+
let value = descLine[1].trim();
|
|
40
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
41
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
42
|
+
value = value.slice(1, -1);
|
|
43
|
+
}
|
|
44
|
+
return value.length > 0 ? value : undefined;
|
|
45
|
+
}
|
|
14
46
|
async function openSkillCatalogLoader(options) {
|
|
15
47
|
const settingsManager = SettingsManager.create(options.cwd, options.agentDir, {
|
|
16
48
|
projectTrusted: true,
|
|
@@ -23,7 +55,67 @@ async function openSkillCatalogLoader(options) {
|
|
|
23
55
|
await loader.reload();
|
|
24
56
|
return loader;
|
|
25
57
|
}
|
|
58
|
+
async function resolveRunSkill(name, runSkillsDir) {
|
|
59
|
+
if (name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
const baseDir = path.join(runSkillsDir, name);
|
|
63
|
+
const filePath = path.join(baseDir, "SKILL.md");
|
|
64
|
+
if (!(await pathExists(filePath)))
|
|
65
|
+
return undefined;
|
|
66
|
+
return {
|
|
67
|
+
name,
|
|
68
|
+
filePath,
|
|
69
|
+
baseDir,
|
|
70
|
+
scope: "temporary",
|
|
71
|
+
source: "run",
|
|
72
|
+
origin: "run",
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async function resolveCheckoutSkill(name, checkoutRoot) {
|
|
76
|
+
if (name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
const baseDir = path.join(checkoutRoot, ".pi", "skills", name);
|
|
80
|
+
const filePath = path.join(baseDir, "SKILL.md");
|
|
81
|
+
if (!(await pathExists(filePath)))
|
|
82
|
+
return undefined;
|
|
83
|
+
return {
|
|
84
|
+
name,
|
|
85
|
+
filePath,
|
|
86
|
+
baseDir,
|
|
87
|
+
scope: "project",
|
|
88
|
+
source: "checkout",
|
|
89
|
+
origin: "checkout",
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function originForLoaderSkill(skill, options) {
|
|
93
|
+
if (options.checkoutRoot !== undefined &&
|
|
94
|
+
isUnderRoot(skill.filePath, path.join(options.checkoutRoot, ".pi", "skills"))) {
|
|
95
|
+
return "checkout";
|
|
96
|
+
}
|
|
97
|
+
if (isUnderRoot(skill.filePath, path.join(options.agentDir, "skills"))) {
|
|
98
|
+
return "host";
|
|
99
|
+
}
|
|
100
|
+
if (skill.sourceInfo.scope === "project") {
|
|
101
|
+
return "checkout";
|
|
102
|
+
}
|
|
103
|
+
return "host";
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Resolve a skill by name. Search order: run skills → checkout `.pi/skills` → host agentDir.
|
|
107
|
+
*/
|
|
26
108
|
export async function resolveSkillByName(name, options) {
|
|
109
|
+
if (options.runSkillsDir !== undefined) {
|
|
110
|
+
const run = await resolveRunSkill(name, options.runSkillsDir);
|
|
111
|
+
if (run)
|
|
112
|
+
return run;
|
|
113
|
+
}
|
|
114
|
+
if (options.checkoutRoot !== undefined) {
|
|
115
|
+
const checkout = await resolveCheckoutSkill(name, options.checkoutRoot);
|
|
116
|
+
if (checkout)
|
|
117
|
+
return checkout;
|
|
118
|
+
}
|
|
27
119
|
const loader = await openSkillCatalogLoader(options);
|
|
28
120
|
const match = loader.getSkills().skills.find((skill) => skill.name === name);
|
|
29
121
|
if (!match)
|
|
@@ -34,10 +126,24 @@ export async function resolveSkillByName(name, options) {
|
|
|
34
126
|
catch {
|
|
35
127
|
return undefined;
|
|
36
128
|
}
|
|
129
|
+
if (options.checkoutRoot !== undefined &&
|
|
130
|
+
isUnderRoot(match.filePath, path.join(options.checkoutRoot, ".pi", "skills"))) {
|
|
131
|
+
return {
|
|
132
|
+
name: match.name,
|
|
133
|
+
filePath: match.filePath,
|
|
134
|
+
baseDir: match.baseDir,
|
|
135
|
+
scope: match.sourceInfo.scope,
|
|
136
|
+
source: match.sourceInfo.source,
|
|
137
|
+
origin: "checkout",
|
|
138
|
+
};
|
|
139
|
+
}
|
|
37
140
|
return {
|
|
38
141
|
name: match.name,
|
|
39
142
|
filePath: match.filePath,
|
|
40
143
|
baseDir: match.baseDir,
|
|
144
|
+
scope: match.sourceInfo.scope,
|
|
145
|
+
source: match.sourceInfo.source,
|
|
146
|
+
origin: originForLoaderSkill(match, options),
|
|
41
147
|
};
|
|
42
148
|
}
|
|
43
149
|
export async function listSkills(options) {
|
|
@@ -45,7 +151,7 @@ export async function listSkills(options) {
|
|
|
45
151
|
const { skills, diagnostics } = loader.getSkills();
|
|
46
152
|
return {
|
|
47
153
|
skills: skills
|
|
48
|
-
.map(toListing)
|
|
154
|
+
.map((skill) => toListing(skill, originForLoaderSkill(skill, options)))
|
|
49
155
|
.sort((a, b) => a.name.localeCompare(b.name)),
|
|
50
156
|
diagnostics: diagnostics.map((d) => ({
|
|
51
157
|
message: d.message,
|
|
@@ -53,3 +159,84 @@ export async function listSkills(options) {
|
|
|
53
159
|
})),
|
|
54
160
|
};
|
|
55
161
|
}
|
|
162
|
+
async function listRunSkillOrigins(runSkillsDir) {
|
|
163
|
+
let names;
|
|
164
|
+
try {
|
|
165
|
+
names = await readdir(runSkillsDir);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
const out = [];
|
|
171
|
+
for (const name of names) {
|
|
172
|
+
if (name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const filePath = path.join(runSkillsDir, name, "SKILL.md");
|
|
176
|
+
try {
|
|
177
|
+
const content = await readFile(filePath, "utf8");
|
|
178
|
+
const description = descriptionFromSkillMd(content);
|
|
179
|
+
if (description === undefined)
|
|
180
|
+
continue;
|
|
181
|
+
out.push({ name, description, origin: "run" });
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// skip unreadable / incomplete packs
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* List skills with SkillOrigin. When runSkillsDir is set, run-tier skills win on name.
|
|
191
|
+
* Precedence for the merged view: run → checkout → host.
|
|
192
|
+
*/
|
|
193
|
+
export async function listSkillsWithOrigin(options) {
|
|
194
|
+
const byName = new Map();
|
|
195
|
+
const hostCatalog = await listSkills({
|
|
196
|
+
cwd: options.cwd,
|
|
197
|
+
agentDir: options.agentDir,
|
|
198
|
+
...(options.checkoutRoot !== undefined
|
|
199
|
+
? { checkoutRoot: options.checkoutRoot }
|
|
200
|
+
: {}),
|
|
201
|
+
});
|
|
202
|
+
for (const skill of hostCatalog.skills) {
|
|
203
|
+
const origin = skill.origin ??
|
|
204
|
+
(skill.scope === "project" ? "checkout" : "host");
|
|
205
|
+
byName.set(skill.name, {
|
|
206
|
+
name: skill.name,
|
|
207
|
+
description: skill.description,
|
|
208
|
+
origin,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
if (options.checkoutRoot !== undefined) {
|
|
212
|
+
let checkoutNames = [];
|
|
213
|
+
try {
|
|
214
|
+
checkoutNames = await readdir(path.join(options.checkoutRoot, ".pi", "skills"));
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
checkoutNames = [];
|
|
218
|
+
}
|
|
219
|
+
for (const name of checkoutNames) {
|
|
220
|
+
const filePath = path.join(options.checkoutRoot, ".pi", "skills", name, "SKILL.md");
|
|
221
|
+
try {
|
|
222
|
+
const content = await readFile(filePath, "utf8");
|
|
223
|
+
const description = descriptionFromSkillMd(content);
|
|
224
|
+
if (description === undefined)
|
|
225
|
+
continue;
|
|
226
|
+
byName.set(name, { name, description, origin: "checkout" });
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// skip
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (options.runSkillsDir !== undefined) {
|
|
234
|
+
for (const skill of await listRunSkillOrigins(options.runSkillsDir)) {
|
|
235
|
+
byName.set(skill.name, skill);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
skills: [...byName.values()].sort((a, b) => a.name.localeCompare(b.name)),
|
|
240
|
+
diagnostics: hostCatalog.diagnostics,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ValidationFindingCode } from "./validateCatalog.js";
|
|
2
|
-
export type TaskLoadCode = "task.invalid_shape" | "task.load_error";
|
|
2
|
+
export type TaskLoadCode = "task.invalid_shape" | "task.load_error" | "task.binding_conflict" | "task.repository_ref_required" | "task.ref_without_repository" | "task.repository_invalid";
|
|
3
3
|
export type LoadIssue = {
|
|
4
4
|
code: ValidationFindingCode;
|
|
5
5
|
message: string;
|
|
@@ -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
|
+
}>;
|