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/README.md
CHANGED
|
@@ -38,7 +38,8 @@ The same pipeline runs three ways without rewriting anything:
|
|
|
38
38
|
- **Standalone stage execution** — run a single stage directly with `run_stage` (MCP tool, `sf run-stage` CLI, or the A2A `run_stage` operation), no pipeline file required; chain calls with `envelope_ref` (one or many prior results) instead of a pipeline DAG
|
|
39
39
|
- **CI / headless** — `sf validate --strict --json`, `sf run --json` with exit codes `0` / `1` / `2`
|
|
40
40
|
- **Parallel stages** — pipeline DAG with fan-out, join, and Clone Chains (one Clone Instance per Clone Array element; see [YAML catalog](docs/yaml-catalog.md#clone-chain))
|
|
41
|
-
- **
|
|
41
|
+
- **Definition-time graph view** — `sf graph --pipeline <path>` prints how a pipeline is wired before any run (terminal diagram or `--json`)
|
|
42
|
+
- **SQLite run store** — global `~/.stageflow/.stageflow/` state plus per-run workspaces, shared across every project since Stageflow became a single auto-starting service
|
|
42
43
|
|
|
43
44
|
## Architecture at a glance
|
|
44
45
|
|
|
@@ -97,6 +98,8 @@ sf run --pipeline pipelines/hello.pipeline.yaml --task tasks/hello.task.yaml
|
|
|
97
98
|
|
|
98
99
|
Expanded walkthrough: [docs/quickstart.md](docs/quickstart.md)
|
|
99
100
|
|
|
101
|
+
**Docker Compose** (UI + MCP in one Host): copy [`.env.example`](.env.example) → `.env`, set `STAGEFLOW_CONTROL_TOKEN`, then `docker compose up --build -d`. Checklist: [docs/docker.md](docs/docker.md#local-try-compose).
|
|
102
|
+
|
|
100
103
|
## Connect a model provider
|
|
101
104
|
|
|
102
105
|
Each stage sets a **`model`** id in YAML (e.g. `anthropic/claude-sonnet-4-5`). The matching provider must be authenticated before runs succeed — `sf validate` does not check auth.
|
|
@@ -185,12 +188,14 @@ See [docs/ci.md](docs/ci.md) for the full CI recipe and [`.github/actions/sf-run
|
|
|
185
188
|
|
|
186
189
|
## State
|
|
187
190
|
|
|
188
|
-
Runtime state
|
|
191
|
+
Runtime state (SQLite run store + per-run workspaces) is **global** — `~/.stageflow/.stageflow/` — shared across every project on the machine, since Stageflow became a single auto-starting service. Global config and `sf_owned` auth live directly under **`~/.stageflow/`**; per-project settings (`maxConcurrent`, `credentialSource`) still live at `<git-root>/.stageflow/settings.json`. If `.stageflow` is missing and `.software-factory` exists from an older install, the next store open renames it to `.stageflow` once.
|
|
189
192
|
|
|
190
193
|
## MCP
|
|
191
194
|
|
|
192
195
|
Host MCP via `sf ui` or `sf mcp` at `http://127.0.0.1:3847/mcp` (URL printed on boot). Sessions are the default. Point a Cursor (or other) MCP client at that URL. Do not run both hosts against the same store.
|
|
193
196
|
|
|
197
|
+
Stageflow runs as **one global auto-starting service per machine** (not one process per project): `sf run`, `sf run-stage`, and `sf runs *` health-probe the well-known port and spawn the service headlessly if nothing answers, so you do not have to start `sf ui`/`sf mcp` by hand before using the CLI.
|
|
198
|
+
|
|
194
199
|
HITL-aware tools include `wait_run`, `answer_gate`, `list_waiting`, and `decide_feedback_loop`. Inspect tools (`list_providers`, `list_models`, `describe_pipeline`, …) are read-only. `run_stage` runs a single stage directly, no pipeline file required — see [Standalone stages](#standalone-stages) below. Full tool list: [docs/mcp.md](docs/mcp.md).
|
|
195
200
|
|
|
196
201
|
Stages use project `.mcp.json` plus stage `mcp` names. See [YAML catalog — Stage MCP](docs/yaml-catalog.md#stage-mcp).
|
|
@@ -248,13 +253,15 @@ Full docs: **[tejasghutukade.github.io/stageflow](https://tejasghutukade.github.
|
|
|
248
253
|
| [docs/architecture.md](docs/architecture.md) | Runtime components, execution flow, persistence, and design decisions |
|
|
249
254
|
| [docs/quickstart.md](docs/quickstart.md) | Expanded quick start |
|
|
250
255
|
| [docs/yaml-catalog.md](docs/yaml-catalog.md) | Pipelines, stages, tasks schema |
|
|
251
|
-
| [docs/cli-reference.md](docs/cli-reference.md) | `sf init`, `sf run`, `sf run-stage`, `sf validate`, `sf ui`, `sf mcp`, `sf envelope`, `sf export-run`, `sf artifact`, `sf skills`, `sf providers` |
|
|
256
|
+
| [docs/cli-reference.md](docs/cli-reference.md) | `sf init`, `sf run`, `sf run-stage`, `sf graph`, `sf validate`, `sf ui`, `sf mcp`, `sf envelope`, `sf export-run`, `sf artifact`, `sf skills`, `sf providers` |
|
|
252
257
|
| [docs/envelopes.md](docs/envelopes.md) | Handoff envelope contract |
|
|
258
|
+
| [docs/verified-stage-execution.md](docs/verified-stage-execution.md) | After-phase `verify`, evidence, and `on_verify_fail` repair / manual recovery |
|
|
253
259
|
| [docs/hitl.md](docs/hitl.md) | Gate kinds, `--skip-gates`, exit code `2` |
|
|
254
260
|
| [docs/ci.md](docs/ci.md) | `--json`, env vars, GitHub Actions |
|
|
255
261
|
| [docs/mcp.md](docs/mcp.md) | MCP tool reference, including standalone `run_stage` |
|
|
256
262
|
| [docs/a2a.md](docs/a2a.md) | Publish pipelines for other agents to call over JSON-RPC (A2A), plus the wildcard-access `run_stage` operation |
|
|
257
263
|
| [docs/providers.md](docs/providers.md) | Pi providers, `sf providers` |
|
|
264
|
+
| [docs/docker.md](docs/docker.md) | Docker Compose local try, image pull/run, backup, self-hosting |
|
|
258
265
|
| [docs/operator-console.md](docs/operator-console.md) | Console IA and settings |
|
|
259
266
|
| [docs/skills-suite.md](docs/skills-suite.md) | Harness skills — router + jobs for Cursor, Claude Code, Codex, Pi, OpenCode |
|
|
260
267
|
|
package/dist/a2a/contracts.d.ts
CHANGED
|
@@ -55,6 +55,7 @@ export type RunStageCommand = {
|
|
|
55
55
|
contextId?: string;
|
|
56
56
|
stage?: string | Record<string, unknown>;
|
|
57
57
|
pipeline?: string | Record<string, unknown>;
|
|
58
|
+
project_root?: string;
|
|
58
59
|
task_path?: string;
|
|
59
60
|
task?: TaskFileInput;
|
|
60
61
|
envelope_ref?: EnvelopeRefInput | EnvelopeRefInput[];
|
package/dist/a2a/contracts.js
CHANGED
|
@@ -57,6 +57,7 @@ const runStageDataPart = z
|
|
|
57
57
|
operation: z.literal("run_stage"),
|
|
58
58
|
stage: z.union([z.string().min(1), z.record(z.string(), z.unknown())]).optional(),
|
|
59
59
|
pipeline: z.union([z.string().min(1), z.record(z.string(), z.unknown())]).optional(),
|
|
60
|
+
project_root: z.string().optional(),
|
|
60
61
|
task_path: z.string().optional(),
|
|
61
62
|
task: taskFileSchema.optional(),
|
|
62
63
|
envelope_ref: z.union([envelopeRefSchema, z.array(envelopeRefSchema).min(1)]).optional(),
|
package/dist/a2a/registry.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ declare const publicationSchema: z.ZodObject<{
|
|
|
6
6
|
project_root: z.ZodString;
|
|
7
7
|
pipeline: z.ZodString;
|
|
8
8
|
goal: z.ZodString;
|
|
9
|
+
repository: z.ZodOptional<z.ZodString>;
|
|
10
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
9
11
|
allowed_callers: z.ZodArray<z.ZodString>;
|
|
10
12
|
input_schema: z.ZodString;
|
|
11
13
|
results: z.ZodObject<{
|
package/dist/a2a/registry.js
CHANGED
|
@@ -13,6 +13,8 @@ const publicationSchema = z.object({
|
|
|
13
13
|
project_root: z.string().min(1),
|
|
14
14
|
pipeline: z.string().min(1),
|
|
15
15
|
goal: z.string().trim().min(1),
|
|
16
|
+
repository: z.string().trim().min(1).optional(),
|
|
17
|
+
ref: z.string().trim().min(1).optional(),
|
|
16
18
|
allowed_callers: z.array(identifier).min(1),
|
|
17
19
|
input_schema: z.string().min(1),
|
|
18
20
|
results: z.object({
|
|
@@ -21,7 +23,24 @@ const publicationSchema = z.object({
|
|
|
21
23
|
artifacts: z.array(z.string().regex(/^[^/\\.][^/\\]*$/)).default([]),
|
|
22
24
|
}).strict(),
|
|
23
25
|
caller_answerable_stages: z.array(identifier).default([]),
|
|
24
|
-
}).strict()
|
|
26
|
+
}).strict().superRefine((data, ctx) => {
|
|
27
|
+
const hasRepo = data.repository !== undefined;
|
|
28
|
+
const hasRef = data.ref !== undefined;
|
|
29
|
+
if (hasRepo && !hasRef) {
|
|
30
|
+
ctx.addIssue({
|
|
31
|
+
code: z.ZodIssueCode.custom,
|
|
32
|
+
message: "repository requires ref",
|
|
33
|
+
path: ["ref"],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (hasRef && !hasRepo) {
|
|
37
|
+
ctx.addIssue({
|
|
38
|
+
code: z.ZodIssueCode.custom,
|
|
39
|
+
message: "ref requires repository",
|
|
40
|
+
path: ["repository"],
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
});
|
|
25
44
|
const configSchema = z.object({
|
|
26
45
|
version: z.literal(1),
|
|
27
46
|
public_url: z.string().url(),
|
package/dist/a2a/server.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { AgentCard } from "@a2a-js/sdk";
|
|
|
4
4
|
import type { RunStore } from "../runstore/port.js";
|
|
5
5
|
import type { RunManager } from "../runtime/runManager.js";
|
|
6
6
|
import { type PublicationRegistry } from "./registry.js";
|
|
7
|
+
import type { A2aStore } from "./store.js";
|
|
7
8
|
export declare const A2A_BODY_LIMIT: number;
|
|
8
9
|
export declare function publicationCard(registry: PublicationRegistry, caller: string): AgentCard;
|
|
9
10
|
export type A2aRuntime = {
|
|
@@ -12,11 +13,17 @@ export type A2aRuntime = {
|
|
|
12
13
|
rootDir: string;
|
|
13
14
|
/** The SqliteRunStore's own connection to `state.db`, when the caller constructed one via `createRunStoreWithConnection`. */
|
|
14
15
|
connection?: Database.Database;
|
|
16
|
+
/** Shared A2A store when the Host composition root already opened one for delete_run. */
|
|
17
|
+
a2aStore?: A2aStore;
|
|
15
18
|
};
|
|
16
19
|
export type A2aHost = {
|
|
17
20
|
status: {
|
|
18
21
|
state: "disabled" | "enabled" | "configuration_error";
|
|
19
22
|
configPath?: string;
|
|
23
|
+
error?: {
|
|
24
|
+
code: string;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
20
27
|
};
|
|
21
28
|
handle(req: HttpIncomingMessage, res: ServerResponse, pathname: string): Promise<boolean>;
|
|
22
29
|
/** Deletes expired terminal tasks/artifacts and message tombstones. A no-op when A2A is not enabled. */
|
package/dist/a2a/server.js
CHANGED
|
@@ -210,10 +210,13 @@ export async function createA2aHost(runtime, configPath, env = process.env) {
|
|
|
210
210
|
registry = await loadPublicationRegistry(configPath, env);
|
|
211
211
|
status.configPath = registry.configPath;
|
|
212
212
|
status.state = "enabled";
|
|
213
|
-
invocations = createA2aInvocations(registry, runtime.manager, runtime.runStore, runtime.rootDir, runtime.connection);
|
|
213
|
+
invocations = createA2aInvocations(registry, runtime.manager, runtime.runStore, runtime.rootDir, runtime.connection, undefined, runtime.a2aStore);
|
|
214
214
|
}
|
|
215
|
-
catch {
|
|
215
|
+
catch (err) {
|
|
216
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
216
217
|
status.state = "configuration_error";
|
|
218
|
+
status.error = { code: "a2a_configuration_error", message };
|
|
219
|
+
console.error(`stageflow: A2A configuration error: ${message}`);
|
|
217
220
|
}
|
|
218
221
|
}
|
|
219
222
|
const sweep = invocations
|
package/dist/a2a/service.d.ts
CHANGED
|
@@ -94,4 +94,4 @@ export declare class A2aInvocations {
|
|
|
94
94
|
private buildTask;
|
|
95
95
|
private projectTask;
|
|
96
96
|
}
|
|
97
|
-
export declare function createA2aInvocations(registry: PublicationRegistry, manager: RunManager, runStore: RunStore, rootDir: string, connection?: Database.Database, rateLimiter?: RateLimiter): A2aInvocations;
|
|
97
|
+
export declare function createA2aInvocations(registry: PublicationRegistry, manager: RunManager, runStore: RunStore, rootDir: string, connection?: Database.Database, rateLimiter?: RateLimiter, a2aStore?: A2aStore): A2aInvocations;
|
package/dist/a2a/service.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import { readRunArtifactBytes, artifactMediaType } from "../mcp/readArtifact.js";
|
|
2
|
+
import { CatalogPathError, resolveCatalogRelativePath, resolveCatalogStartInput, } from "../config/catalogRelativePath.js";
|
|
3
3
|
import { waitRun } from "../mcp/waitRun.js";
|
|
4
4
|
import { readYamlObject } from "../config/readYamlObject.js";
|
|
5
5
|
import { payloadInstanceMismatch } from "../envelope/payloadSchema.js";
|
|
@@ -126,7 +126,18 @@ export class A2aInvocations {
|
|
|
126
126
|
}
|
|
127
127
|
const taskId = existingTask?.task_id ?? newTaskId();
|
|
128
128
|
const contextIdResolved = existingTask?.context_id ?? this.store.ensureContext(caller.id, contextId);
|
|
129
|
-
const result = await this.manager.startRunOnce({
|
|
129
|
+
const result = await this.manager.startRunOnce({
|
|
130
|
+
pipeline: publication.pipeline,
|
|
131
|
+
task: {
|
|
132
|
+
id: taskId,
|
|
133
|
+
goal: publication.goal,
|
|
134
|
+
input: input,
|
|
135
|
+
...(publication.repository !== undefined
|
|
136
|
+
? { repository: publication.repository }
|
|
137
|
+
: {}),
|
|
138
|
+
...(publication.ref !== undefined ? { ref: publication.ref } : {}),
|
|
139
|
+
},
|
|
140
|
+
}, { key: submissionKey, requestHash: hash });
|
|
130
141
|
if (!result.ok) {
|
|
131
142
|
throw mapStartFailure(result);
|
|
132
143
|
}
|
|
@@ -143,7 +154,13 @@ export class A2aInvocations {
|
|
|
143
154
|
if (result.done) {
|
|
144
155
|
void result.done
|
|
145
156
|
.catch(() => undefined)
|
|
146
|
-
.then(() =>
|
|
157
|
+
.then(() => {
|
|
158
|
+
const row = this.store.getTask(taskId);
|
|
159
|
+
if (!row)
|
|
160
|
+
return;
|
|
161
|
+
return this.maybeFinalize(row);
|
|
162
|
+
})
|
|
163
|
+
.catch(() => undefined);
|
|
147
164
|
}
|
|
148
165
|
}
|
|
149
166
|
this.store.recordMessage({ callerId: caller.id, messageId, taskId, operation: "invoke", requestHash: hash, outcome: { ok: true } });
|
|
@@ -176,12 +193,29 @@ export class A2aInvocations {
|
|
|
176
193
|
}
|
|
177
194
|
let pipelineArg;
|
|
178
195
|
let resultStageId;
|
|
196
|
+
let runProjectRoot;
|
|
179
197
|
if (cmd.stage !== undefined) {
|
|
180
198
|
let stageBody;
|
|
181
199
|
if (typeof cmd.stage === "string") {
|
|
182
200
|
if (!cmd.stage.trim())
|
|
183
201
|
throw new A2aApplicationError("invalid-input", "stage is required");
|
|
184
|
-
|
|
202
|
+
let absPath = "";
|
|
203
|
+
try {
|
|
204
|
+
const { wireRoot, roots } = await resolveCatalogStartInput({ store: this.runStore }, cmd.project_root);
|
|
205
|
+
runProjectRoot = wireRoot.path;
|
|
206
|
+
absPath = resolveCatalogRelativePath({
|
|
207
|
+
inputPath: cmd.stage,
|
|
208
|
+
projectRoot: wireRoot.project_root,
|
|
209
|
+
roots,
|
|
210
|
+
fieldName: "stage",
|
|
211
|
+
}).absolutePath;
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
if (err instanceof CatalogPathError) {
|
|
215
|
+
throw new A2aApplicationError("invalid-input", err.message);
|
|
216
|
+
}
|
|
217
|
+
throw err;
|
|
218
|
+
}
|
|
185
219
|
try {
|
|
186
220
|
stageBody = await readYamlObject(absPath);
|
|
187
221
|
}
|
|
@@ -242,7 +276,11 @@ export class A2aInvocations {
|
|
|
242
276
|
const contextIdResolved = existingTask?.context_id ?? this.store.ensureContext(caller.id, cmd.contextId);
|
|
243
277
|
let result;
|
|
244
278
|
try {
|
|
245
|
-
result = await this.manager.startRunOnce({
|
|
279
|
+
result = await this.manager.startRunOnce({
|
|
280
|
+
pipeline: pipelineArg,
|
|
281
|
+
task: taskInput,
|
|
282
|
+
...(runProjectRoot !== undefined ? { projectRoot: runProjectRoot } : {}),
|
|
283
|
+
}, { key: submissionKey, requestHash: hash });
|
|
246
284
|
}
|
|
247
285
|
catch (err) {
|
|
248
286
|
if (err instanceof PipelineValidationError) {
|
|
@@ -268,7 +306,13 @@ export class A2aInvocations {
|
|
|
268
306
|
if (result.done) {
|
|
269
307
|
void result.done
|
|
270
308
|
.catch(() => undefined)
|
|
271
|
-
.then(() =>
|
|
309
|
+
.then(() => {
|
|
310
|
+
const row = this.store.getTask(taskId);
|
|
311
|
+
if (!row)
|
|
312
|
+
return;
|
|
313
|
+
return this.maybeFinalize(row);
|
|
314
|
+
})
|
|
315
|
+
.catch(() => undefined);
|
|
272
316
|
}
|
|
273
317
|
}
|
|
274
318
|
this.store.recordMessage({ callerId: caller.id, messageId: cmd.messageId, taskId, operation: "run_stage", requestHash: hash, outcome: { ok: true } });
|
|
@@ -491,6 +535,11 @@ function mapStartFailure(result) {
|
|
|
491
535
|
}
|
|
492
536
|
return new A2aApplicationError("invalid-input", result.reason);
|
|
493
537
|
}
|
|
494
|
-
export function createA2aInvocations(registry, manager, runStore, rootDir, connection, rateLimiter) {
|
|
495
|
-
|
|
538
|
+
export function createA2aInvocations(registry, manager, runStore, rootDir, connection, rateLimiter, a2aStore) {
|
|
539
|
+
const store = a2aStore ??
|
|
540
|
+
(connection !== undefined ? new A2aStore(rootDir, connection) : undefined);
|
|
541
|
+
if (!store) {
|
|
542
|
+
throw new Error("A2A requires the Host SQLite connection");
|
|
543
|
+
}
|
|
544
|
+
return new A2aInvocations(registry, manager, runStore, rootDir, store, rateLimiter);
|
|
496
545
|
}
|
package/dist/a2a/store.d.ts
CHANGED
|
@@ -51,12 +51,11 @@ export declare class A2aStore {
|
|
|
51
51
|
private readonly artifactsRoot;
|
|
52
52
|
private readonly ownsConnection;
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* non-SQLite `RunStore` in bootstrap).
|
|
54
|
+
* Uses the SqliteRunStore connection to the same `state.db` file so the two stores share one
|
|
55
|
+
* transaction domain. The Host must open the run store in migrate mode before constructing
|
|
56
|
+
* A2aStore. Additive `kind` / `result_stage_id` columns for run_stage are applied here.
|
|
58
57
|
*/
|
|
59
|
-
constructor(rootDir: string, connection
|
|
58
|
+
constructor(rootDir: string, connection: Database.Database);
|
|
60
59
|
/**
|
|
61
60
|
* Additive migration for a `state.db` created before the run_stage A2A
|
|
62
61
|
* operation existed: `CREATE TABLE IF NOT EXISTS` above never alters an
|
|
@@ -103,4 +102,8 @@ export declare class A2aStore {
|
|
|
103
102
|
removedTasks: number;
|
|
104
103
|
removedMessages: number;
|
|
105
104
|
}>;
|
|
105
|
+
/** Deletes every A2A task (and frozen artifact files) bound to a Stageflow run. */
|
|
106
|
+
deleteByRunId(runId: string): Promise<{
|
|
107
|
+
removedTasks: number;
|
|
108
|
+
}>;
|
|
106
109
|
}
|
package/dist/a2a/store.js
CHANGED
|
@@ -1,57 +1,8 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { mkdir, unlink, writeFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import
|
|
5
|
-
import { storeRootFor } from "../runstore/paths.js";
|
|
4
|
+
import { resolveStoreRoot } from "../runstore/paths.js";
|
|
6
5
|
import { MESSAGE_TOMBSTONE_RETENTION_MS, TERMINAL_RETENTION_MS } from "./limits.js";
|
|
7
|
-
const SCHEMA_SQL = `
|
|
8
|
-
CREATE TABLE IF NOT EXISTS a2a_contexts (
|
|
9
|
-
context_id TEXT PRIMARY KEY,
|
|
10
|
-
caller_id TEXT NOT NULL,
|
|
11
|
-
created_at TEXT NOT NULL
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
CREATE TABLE IF NOT EXISTS a2a_tasks (
|
|
15
|
-
task_id TEXT PRIMARY KEY,
|
|
16
|
-
context_id TEXT NOT NULL,
|
|
17
|
-
caller_id TEXT NOT NULL,
|
|
18
|
-
publication_id TEXT NOT NULL,
|
|
19
|
-
publication_revision TEXT NOT NULL,
|
|
20
|
-
submission_key TEXT NOT NULL UNIQUE,
|
|
21
|
-
run_id TEXT,
|
|
22
|
-
state TEXT NOT NULL,
|
|
23
|
-
result_json TEXT,
|
|
24
|
-
kind TEXT NOT NULL DEFAULT 'invoke',
|
|
25
|
-
result_stage_id TEXT,
|
|
26
|
-
created_at TEXT NOT NULL,
|
|
27
|
-
updated_at TEXT NOT NULL
|
|
28
|
-
);
|
|
29
|
-
CREATE INDEX IF NOT EXISTS a2a_tasks_context ON a2a_tasks(context_id);
|
|
30
|
-
CREATE INDEX IF NOT EXISTS a2a_tasks_caller ON a2a_tasks(caller_id);
|
|
31
|
-
|
|
32
|
-
CREATE TABLE IF NOT EXISTS a2a_messages (
|
|
33
|
-
caller_id TEXT NOT NULL,
|
|
34
|
-
message_id TEXT NOT NULL,
|
|
35
|
-
task_id TEXT NOT NULL,
|
|
36
|
-
operation TEXT NOT NULL,
|
|
37
|
-
request_hash TEXT NOT NULL,
|
|
38
|
-
outcome_json TEXT,
|
|
39
|
-
created_at TEXT NOT NULL,
|
|
40
|
-
PRIMARY KEY (caller_id, message_id)
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
CREATE TABLE IF NOT EXISTS a2a_artifacts (
|
|
44
|
-
artifact_id TEXT PRIMARY KEY,
|
|
45
|
-
task_id TEXT NOT NULL,
|
|
46
|
-
name TEXT NOT NULL,
|
|
47
|
-
media_type TEXT,
|
|
48
|
-
size INTEGER NOT NULL,
|
|
49
|
-
content_path TEXT NOT NULL,
|
|
50
|
-
hash TEXT NOT NULL,
|
|
51
|
-
created_at TEXT NOT NULL
|
|
52
|
-
);
|
|
53
|
-
CREATE INDEX IF NOT EXISTS a2a_artifacts_task ON a2a_artifacts(task_id);
|
|
54
|
-
`;
|
|
55
6
|
function nowIso() {
|
|
56
7
|
return new Date().toISOString();
|
|
57
8
|
}
|
|
@@ -60,26 +11,15 @@ export class A2aStore {
|
|
|
60
11
|
artifactsRoot;
|
|
61
12
|
ownsConnection;
|
|
62
13
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* non-SQLite `RunStore` in bootstrap).
|
|
14
|
+
* Uses the SqliteRunStore connection to the same `state.db` file so the two stores share one
|
|
15
|
+
* transaction domain. The Host must open the run store in migrate mode before constructing
|
|
16
|
+
* A2aStore. Additive `kind` / `result_stage_id` columns for run_stage are applied here.
|
|
67
17
|
*/
|
|
68
18
|
constructor(rootDir, connection) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.db = connection;
|
|
72
|
-
this.ownsConnection = false;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
this.db = new Database(path.join(storeRoot, "state.db"));
|
|
76
|
-
this.db.pragma("journal_mode = WAL");
|
|
77
|
-
this.db.pragma("busy_timeout = 5000");
|
|
78
|
-
this.ownsConnection = true;
|
|
79
|
-
}
|
|
80
|
-
this.db.exec(SCHEMA_SQL);
|
|
19
|
+
this.db = connection;
|
|
20
|
+
this.ownsConnection = false;
|
|
81
21
|
this.migrateAddStandaloneColumns();
|
|
82
|
-
this.artifactsRoot = path.join(
|
|
22
|
+
this.artifactsRoot = path.join(resolveStoreRoot(rootDir), "a2a-artifacts");
|
|
83
23
|
}
|
|
84
24
|
/**
|
|
85
25
|
* Additive migration for a `state.db` created before the run_stage A2A
|
|
@@ -242,4 +182,21 @@ export class A2aStore {
|
|
|
242
182
|
const removedMessages = this.db.prepare("DELETE FROM a2a_messages WHERE created_at < ?").run(messageCutoff).changes;
|
|
243
183
|
return { removedTasks: expiredTasks.length, removedMessages };
|
|
244
184
|
}
|
|
185
|
+
/** Deletes every A2A task (and frozen artifact files) bound to a Stageflow run. */
|
|
186
|
+
async deleteByRunId(runId) {
|
|
187
|
+
const tasks = this.db
|
|
188
|
+
.prepare("SELECT task_id FROM a2a_tasks WHERE run_id = ?")
|
|
189
|
+
.all(runId);
|
|
190
|
+
for (const { task_id: taskId } of tasks) {
|
|
191
|
+
for (const artifact of this.listArtifacts(taskId)) {
|
|
192
|
+
await unlink(artifact.content_path).catch(() => undefined);
|
|
193
|
+
}
|
|
194
|
+
this.db.transaction(() => {
|
|
195
|
+
this.db.prepare("DELETE FROM a2a_artifacts WHERE task_id = ?").run(taskId);
|
|
196
|
+
this.db.prepare("DELETE FROM a2a_messages WHERE task_id = ?").run(taskId);
|
|
197
|
+
this.db.prepare("DELETE FROM a2a_tasks WHERE task_id = ?").run(taskId);
|
|
198
|
+
})();
|
|
199
|
+
}
|
|
200
|
+
return { removedTasks: tasks.length };
|
|
201
|
+
}
|
|
245
202
|
}
|
package/dist/agent/activity.d.ts
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ProviderAuthContext } from "./providerAuth.js";
|
|
2
|
+
export type BootProviderResult = {
|
|
3
|
+
configured: string[];
|
|
4
|
+
failures: Array<{
|
|
5
|
+
providerId: string;
|
|
6
|
+
code: string;
|
|
7
|
+
message: string;
|
|
8
|
+
}>;
|
|
9
|
+
};
|
|
10
|
+
export type BootProviderOptions = {
|
|
11
|
+
cwd: string;
|
|
12
|
+
env?: NodeJS.ProcessEnv;
|
|
13
|
+
requireProviders?: string[];
|
|
14
|
+
authContext?: ProviderAuthContext;
|
|
15
|
+
logError?: (message: string) => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Configure providers from STAGEFLOW_PROVIDER_<ID>_API_KEY / _FILE at Host boot.
|
|
19
|
+
* Soft-fails unreadable/rejected keys by default; requireProviders makes missing ids fatal.
|
|
20
|
+
*/
|
|
21
|
+
export declare function bootProviderConfig(options: BootProviderOptions): Promise<BootProviderResult>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { loginWithApiKey, } from "./providerAuth.js";
|
|
2
|
+
import { readSecretFromEnvOrFile, SecretFromEnvError, } from "../config/secretFromEnvOrFile.js";
|
|
3
|
+
const PROVIDER_KEY_RE = /^STAGEFLOW_PROVIDER_([A-Za-z0-9_]+)_API_KEY$/;
|
|
4
|
+
const PROVIDER_FILE_RE = /^STAGEFLOW_PROVIDER_([A-Za-z0-9_]+)_API_KEY_FILE$/;
|
|
5
|
+
function discoverProviders(env) {
|
|
6
|
+
const byLower = new Map();
|
|
7
|
+
for (const key of Object.keys(env)) {
|
|
8
|
+
let envId;
|
|
9
|
+
const plain = key.match(PROVIDER_KEY_RE);
|
|
10
|
+
if (plain)
|
|
11
|
+
envId = plain[1];
|
|
12
|
+
else {
|
|
13
|
+
const file = key.match(PROVIDER_FILE_RE);
|
|
14
|
+
if (file)
|
|
15
|
+
envId = file[1];
|
|
16
|
+
}
|
|
17
|
+
if (envId === undefined)
|
|
18
|
+
continue;
|
|
19
|
+
const providerId = envId.toLowerCase().replace(/_/g, "-");
|
|
20
|
+
if (!byLower.has(providerId)) {
|
|
21
|
+
byLower.set(providerId, { envId, providerId });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return [...byLower.values()].sort((a, b) => a.providerId.localeCompare(b.providerId));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Configure providers from STAGEFLOW_PROVIDER_<ID>_API_KEY / _FILE at Host boot.
|
|
28
|
+
* Soft-fails unreadable/rejected keys by default; requireProviders makes missing ids fatal.
|
|
29
|
+
*/
|
|
30
|
+
export async function bootProviderConfig(options) {
|
|
31
|
+
const env = options.env ?? process.env;
|
|
32
|
+
const logError = options.logError ?? ((message) => console.error(message));
|
|
33
|
+
const configured = [];
|
|
34
|
+
const failures = [];
|
|
35
|
+
for (const { envId, providerId } of discoverProviders(env)) {
|
|
36
|
+
const envName = `STAGEFLOW_PROVIDER_${envId}_API_KEY`;
|
|
37
|
+
let secret;
|
|
38
|
+
try {
|
|
39
|
+
secret = readSecretFromEnvOrFile(env, envName);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
43
|
+
if (err instanceof SecretFromEnvError &&
|
|
44
|
+
message.includes("not both")) {
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
const code = err instanceof SecretFromEnvError ? err.code : "config_invalid";
|
|
48
|
+
failures.push({ providerId, code, message });
|
|
49
|
+
logError(`stageflow: provider ${providerId} boot failed: ${message}`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (secret === undefined)
|
|
53
|
+
continue;
|
|
54
|
+
try {
|
|
55
|
+
await loginWithApiKey(options.cwd, providerId, secret, options.authContext);
|
|
56
|
+
configured.push(providerId);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
60
|
+
failures.push({
|
|
61
|
+
providerId,
|
|
62
|
+
code: "provider_not_configured",
|
|
63
|
+
message,
|
|
64
|
+
});
|
|
65
|
+
logError(`stageflow: provider ${providerId} boot failed: ${message}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const required = (options.requireProviders ?? []).map((id) => id.toLowerCase());
|
|
69
|
+
const missing = required.filter((id) => !configured.includes(id));
|
|
70
|
+
if (missing.length > 0) {
|
|
71
|
+
throw new Error(`STAGEFLOW_REQUIRE_PROVIDERS: missing configured providers: ${missing.join(", ")}`);
|
|
72
|
+
}
|
|
73
|
+
return { configured, failures };
|
|
74
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AgentSession, type EventBus, type InlineExtension, DefaultResourceLoader, SessionManager, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
1
|
+
import { type AgentSession, type EventBus, type ExtensionFactory, type InlineExtension, DefaultResourceLoader, SessionManager, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import type { StageRoots } from "../runtime/stageRoots.js";
|
|
3
3
|
import { type AskOperatorPrompt, type AskOperatorWaitBridge } from "../tools/askOperator.js";
|
|
4
4
|
import "./cursorProvider.js";
|
|
@@ -6,6 +6,14 @@ import { type StageActivityObserver } from "./activityObserver.js";
|
|
|
6
6
|
import type { AgentPort, OpaqueAnswer, StageHandle, StageHandleCloseOptions, StageRunInput, StageRunResult } from "./port.js";
|
|
7
7
|
import type { StageGateKind } from "../types/stage.js";
|
|
8
8
|
import { type StageUsage } from "../types/usage.js";
|
|
9
|
+
import { STAGEFLOW_PATH_DENIED } from "../runstore/workspaceLayout.js";
|
|
10
|
+
export { STAGEFLOW_PATH_DENIED };
|
|
11
|
+
export declare const STAGEFLOW_PATH_DENY_EXTENSION_NAME = "stageflow-path-deny";
|
|
12
|
+
export declare function createDurableRootPathDenyExtension(options: {
|
|
13
|
+
runWorkspaceDir: string;
|
|
14
|
+
durableRoot: string;
|
|
15
|
+
checkoutRoot?: string;
|
|
16
|
+
}): ExtensionFactory;
|
|
9
17
|
/**
|
|
10
18
|
* Stage tool allowlist for sealed Pi sessions.
|
|
11
19
|
* Includes `ask_operator` unless `gateKinds` is an empty list (R6).
|
package/dist/agent/piAdapter.js
CHANGED
|
@@ -49,6 +49,36 @@ import { createStageActivityObserver, } from "./activityObserver.js";
|
|
|
49
49
|
import { DEFAULT_STAGE_TIMEOUT_MS, runtimeStageId, runStageViaOpen } from "./port.js";
|
|
50
50
|
import { addModelUsage, emptyStageUsage } from "../types/usage.js";
|
|
51
51
|
import { TIMEOUT_ABORT_TOOL_RESULT, composeTimeoutResumePrompt, stageTimeoutReason, } from "./stageTimeout.js";
|
|
52
|
+
import { globalStageflowHome } from "../project/globalHome.js";
|
|
53
|
+
import { durableRootFileToolDenial, STAGEFLOW_PATH_DENIED, } from "../runstore/workspaceLayout.js";
|
|
54
|
+
export { STAGEFLOW_PATH_DENIED };
|
|
55
|
+
export const STAGEFLOW_PATH_DENY_EXTENSION_NAME = "stageflow-path-deny";
|
|
56
|
+
const PATH_DENY_FILE_TOOLS = new Set(["read", "write", "edit"]);
|
|
57
|
+
export function createDurableRootPathDenyExtension(options) {
|
|
58
|
+
const { runWorkspaceDir, durableRoot, checkoutRoot } = options;
|
|
59
|
+
const allowlistedRoots = checkoutRoot !== undefined && checkoutRoot !== ""
|
|
60
|
+
? [checkoutRoot]
|
|
61
|
+
: undefined;
|
|
62
|
+
return (pi) => {
|
|
63
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
64
|
+
if (!PATH_DENY_FILE_TOOLS.has(event.toolName)) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const rawPath = event.input.path;
|
|
68
|
+
if (typeof rawPath !== "string" || rawPath.trim().length === 0) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
const candidate = path.isAbsolute(rawPath)
|
|
72
|
+
? rawPath
|
|
73
|
+
: path.resolve(ctx.cwd, rawPath);
|
|
74
|
+
const reason = await durableRootFileToolDenial(candidate, runWorkspaceDir, durableRoot, allowlistedRoots);
|
|
75
|
+
if (reason !== undefined) {
|
|
76
|
+
return { block: true, reason };
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
}
|
|
52
82
|
/**
|
|
53
83
|
* Stage tool allowlist for sealed Pi sessions.
|
|
54
84
|
* Includes `ask_operator` unless `gateKinds` is an empty list (R6).
|
|
@@ -825,6 +855,19 @@ async function prepareStageSessionWiring(input, sessionManager, existingAskWaitC
|
|
|
825
855
|
restoreProvider?.();
|
|
826
856
|
return { ok: false, reason };
|
|
827
857
|
};
|
|
858
|
+
const extensionFactories = [
|
|
859
|
+
{
|
|
860
|
+
name: STAGEFLOW_PATH_DENY_EXTENSION_NAME,
|
|
861
|
+
factory: createDurableRootPathDenyExtension({
|
|
862
|
+
runWorkspaceDir: roots.runWorkspaceDir,
|
|
863
|
+
durableRoot: globalStageflowHome(),
|
|
864
|
+
...(roots.checkoutRoot !== undefined
|
|
865
|
+
? { checkoutRoot: roots.checkoutRoot }
|
|
866
|
+
: {}),
|
|
867
|
+
}),
|
|
868
|
+
},
|
|
869
|
+
...(attached.extensionFactories ?? []),
|
|
870
|
+
];
|
|
828
871
|
const loader = createSealedResourceLoader({
|
|
829
872
|
cwd: roots.cwd,
|
|
830
873
|
agentDir: roots.agentDir,
|
|
@@ -834,9 +877,7 @@ async function prepareStageSessionWiring(input, sessionManager, existingAskWaitC
|
|
|
834
877
|
...(input.skillFilePath !== undefined
|
|
835
878
|
? { additionalSkillPaths: [input.skillFilePath] }
|
|
836
879
|
: {}),
|
|
837
|
-
|
|
838
|
-
? { extensionFactories: attached.extensionFactories }
|
|
839
|
-
: {}),
|
|
880
|
+
extensionFactories,
|
|
840
881
|
...(attached.eventBus !== undefined ? { eventBus: attached.eventBus } : {}),
|
|
841
882
|
});
|
|
842
883
|
await loader.reload();
|
|
@@ -943,6 +984,13 @@ export async function reconstructStageSessionForAnswer(input, answer) {
|
|
|
943
984
|
if (resolved.thinkingLevel) {
|
|
944
985
|
session.setThinkingLevel(resolved.thinkingLevel);
|
|
945
986
|
}
|
|
987
|
+
await input.onResolvedModel?.({
|
|
988
|
+
stageId: runtimeStageId(input),
|
|
989
|
+
model: resolved.model.id,
|
|
990
|
+
...(resolved.thinkingLevel !== undefined
|
|
991
|
+
? { thinkingLevel: resolved.thinkingLevel }
|
|
992
|
+
: {}),
|
|
993
|
+
});
|
|
946
994
|
const liveSession = session;
|
|
947
995
|
return {
|
|
948
996
|
session: liveSession,
|
|
@@ -1011,6 +1059,13 @@ async function bindStageSession(input, sessionManager, wiring) {
|
|
|
1011
1059
|
if (resolved.thinkingLevel) {
|
|
1012
1060
|
session.setThinkingLevel(resolved.thinkingLevel);
|
|
1013
1061
|
}
|
|
1062
|
+
await input.onResolvedModel?.({
|
|
1063
|
+
stageId: runtimeStageId(input),
|
|
1064
|
+
model: resolved.model.id,
|
|
1065
|
+
...(resolved.thinkingLevel !== undefined
|
|
1066
|
+
? { thinkingLevel: resolved.thinkingLevel }
|
|
1067
|
+
: {}),
|
|
1068
|
+
});
|
|
1014
1069
|
}
|
|
1015
1070
|
catch (err) {
|
|
1016
1071
|
await shutdownSession(session);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type EventBus, type InlineExtension } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { type ResolvedMcpServers } from "../config/resolveStageMcpServers.js";
|
|
3
3
|
export declare const STAGEFLOW_PI_MCP_EXTENSION_NAME = "stageflow-mcp";
|
|
4
|
+
export declare function jitiFsCacheDir(): string;
|
|
5
|
+
export declare function resetCreateMcpAdapterCacheForTests(): void;
|
|
4
6
|
type IsolatedMcpServerEntry = Record<string, unknown> & {
|
|
5
7
|
lifecycle: "lazy" | "eager";
|
|
6
8
|
directTools: true;
|