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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { readdir, stat, statfs } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const BLOCK_SIZE = 512;
|
|
4
|
+
const STATE_DB_NAMES = ["state.db", "state.db-wal", "state.db-shm"];
|
|
5
|
+
export const DISK_WARN_LOG_PREFIX = "stageflow.disk_warn";
|
|
6
|
+
let walkCallCount = 0;
|
|
7
|
+
let freeSpaceReaderOverride = null;
|
|
8
|
+
export function getDiskUsageWalkCallCount() {
|
|
9
|
+
return walkCallCount;
|
|
10
|
+
}
|
|
11
|
+
export function resetDiskUsageWalkCallCount() {
|
|
12
|
+
walkCallCount = 0;
|
|
13
|
+
}
|
|
14
|
+
export function setFreeSpaceReaderForTests(reader) {
|
|
15
|
+
freeSpaceReaderOverride = reader;
|
|
16
|
+
}
|
|
17
|
+
function allocatedBytes(st) {
|
|
18
|
+
return st.blocks * BLOCK_SIZE;
|
|
19
|
+
}
|
|
20
|
+
async function pathExists(target) {
|
|
21
|
+
try {
|
|
22
|
+
await stat(target);
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (err.code === "ENOENT")
|
|
27
|
+
return false;
|
|
28
|
+
throw err;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Walk `rootPath` summing `stat().blocks * 512`. Missing path → 0. */
|
|
32
|
+
export async function diskUsageOf(rootPath) {
|
|
33
|
+
walkCallCount += 1;
|
|
34
|
+
if (!(await pathExists(rootPath)))
|
|
35
|
+
return 0;
|
|
36
|
+
let total = 0;
|
|
37
|
+
async function walk(current) {
|
|
38
|
+
let st;
|
|
39
|
+
try {
|
|
40
|
+
st = await stat(current);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err.code === "ENOENT")
|
|
44
|
+
return;
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
total += allocatedBytes(st);
|
|
48
|
+
if (!st.isDirectory())
|
|
49
|
+
return;
|
|
50
|
+
let entries;
|
|
51
|
+
try {
|
|
52
|
+
entries = await readdir(current, { withFileTypes: true });
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
if (err.code === "ENOENT")
|
|
56
|
+
return;
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
await walk(path.join(current, entry.name));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
await walk(rootPath);
|
|
64
|
+
return total;
|
|
65
|
+
}
|
|
66
|
+
export async function readFilesystemSize(rootPath) {
|
|
67
|
+
if (freeSpaceReaderOverride !== null) {
|
|
68
|
+
return freeSpaceReaderOverride(rootPath);
|
|
69
|
+
}
|
|
70
|
+
let target = path.resolve(rootPath);
|
|
71
|
+
for (;;) {
|
|
72
|
+
try {
|
|
73
|
+
const fsStats = await statfs(target);
|
|
74
|
+
const blockSize = fsStats.bsize;
|
|
75
|
+
return {
|
|
76
|
+
freeBytes: fsStats.bavail * blockSize,
|
|
77
|
+
totalBytes: fsStats.blocks * blockSize,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
if (err.code !== "ENOENT")
|
|
82
|
+
throw err;
|
|
83
|
+
const parent = path.dirname(target);
|
|
84
|
+
if (parent === target)
|
|
85
|
+
throw err;
|
|
86
|
+
target = parent;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function usageOfMissingOk(target) {
|
|
91
|
+
try {
|
|
92
|
+
return await diskUsageOf(target);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (err.code === "ENOENT")
|
|
96
|
+
return 0;
|
|
97
|
+
throw err;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function stateDbBytes(durableRoot) {
|
|
101
|
+
let total = 0;
|
|
102
|
+
for (const name of STATE_DB_NAMES) {
|
|
103
|
+
const filePath = path.join(durableRoot, name);
|
|
104
|
+
try {
|
|
105
|
+
const st = await stat(filePath);
|
|
106
|
+
if (st.isFile()) {
|
|
107
|
+
walkCallCount += 1;
|
|
108
|
+
total += allocatedBytes(st);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
if (err.code === "ENOENT")
|
|
113
|
+
continue;
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return total;
|
|
118
|
+
}
|
|
119
|
+
/** Category breakdown for the durable root, reusing `diskUsageOf` for directory trees. */
|
|
120
|
+
export async function durableRootDiskBreakdown(durableRoot, options) {
|
|
121
|
+
const freeSpace = options?.freeSpace ?? readFilesystemSize;
|
|
122
|
+
const [runs_bytes, worktrees_bytes, repos_bytes, state_db_bytes, a2a_artifacts_bytes, cache_bytes, size] = await Promise.all([
|
|
123
|
+
usageOfMissingOk(path.join(durableRoot, "runs")),
|
|
124
|
+
usageOfMissingOk(path.join(durableRoot, "worktrees")),
|
|
125
|
+
usageOfMissingOk(path.join(durableRoot, "repos")),
|
|
126
|
+
stateDbBytes(durableRoot),
|
|
127
|
+
usageOfMissingOk(path.join(durableRoot, "a2a-artifacts")),
|
|
128
|
+
usageOfMissingOk(path.join(durableRoot, "cache")),
|
|
129
|
+
freeSpace(durableRoot),
|
|
130
|
+
]);
|
|
131
|
+
return {
|
|
132
|
+
runs_bytes,
|
|
133
|
+
worktrees_bytes,
|
|
134
|
+
repos_bytes,
|
|
135
|
+
state_db_bytes,
|
|
136
|
+
a2a_artifacts_bytes,
|
|
137
|
+
cache_bytes,
|
|
138
|
+
free_bytes: size.freeBytes,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Parse `STAGEFLOW_DISK_WARN_BYTES` / floor-style env: integer bytes or `N%` of filesystem.
|
|
143
|
+
* Empty / unset / invalid → undefined (no threshold).
|
|
144
|
+
*/
|
|
145
|
+
export function parseDiskBytesThreshold(raw, filesystemTotalBytes) {
|
|
146
|
+
if (raw === undefined)
|
|
147
|
+
return undefined;
|
|
148
|
+
const trimmed = raw.trim();
|
|
149
|
+
if (trimmed === "")
|
|
150
|
+
return undefined;
|
|
151
|
+
if (trimmed.endsWith("%")) {
|
|
152
|
+
const pct = Number.parseFloat(trimmed.slice(0, -1));
|
|
153
|
+
if (!Number.isFinite(pct) || pct < 0 || pct > 100)
|
|
154
|
+
return undefined;
|
|
155
|
+
if (!Number.isFinite(filesystemTotalBytes) || filesystemTotalBytes < 0) {
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
return Math.floor((filesystemTotalBytes * pct) / 100);
|
|
159
|
+
}
|
|
160
|
+
const n = Number.parseInt(trimmed, 10);
|
|
161
|
+
if (!Number.isFinite(n) || n < 0)
|
|
162
|
+
return undefined;
|
|
163
|
+
return n;
|
|
164
|
+
}
|
|
165
|
+
const DEFAULT_MIN_FREE_DISK_BYTES = 2 * 1024 * 1024 * 1024;
|
|
166
|
+
/**
|
|
167
|
+
* Resolve `STAGEFLOW_MIN_FREE_DISK_BYTES`: bytes or `%` of filesystem.
|
|
168
|
+
* Unset / empty / invalid → `max(2 GiB, 10% of filesystemTotalBytes)`.
|
|
169
|
+
*/
|
|
170
|
+
export function resolveMinFreeDiskFloor(raw, filesystemTotalBytes) {
|
|
171
|
+
const parsed = parseDiskBytesThreshold(raw, filesystemTotalBytes);
|
|
172
|
+
if (parsed !== undefined)
|
|
173
|
+
return parsed;
|
|
174
|
+
const total = Number.isFinite(filesystemTotalBytes) && filesystemTotalBytes > 0
|
|
175
|
+
? filesystemTotalBytes
|
|
176
|
+
: 0;
|
|
177
|
+
const tenPercent = Math.floor(total * 0.1);
|
|
178
|
+
return Math.max(DEFAULT_MIN_FREE_DISK_BYTES, tenPercent);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* One named warning when free space is below `STAGEFLOW_DISK_WARN_BYTES`. Never throws.
|
|
182
|
+
* @returns true when a warning line was emitted
|
|
183
|
+
*/
|
|
184
|
+
export async function warnDurableRootDiskIfNeeded(durableRoot, options) {
|
|
185
|
+
try {
|
|
186
|
+
const env = options?.env ?? process.env;
|
|
187
|
+
const raw = env.STAGEFLOW_DISK_WARN_BYTES;
|
|
188
|
+
if (raw === undefined || raw.trim() === "")
|
|
189
|
+
return false;
|
|
190
|
+
const freeSpace = options?.freeSpace ?? readFilesystemSize;
|
|
191
|
+
const size = await freeSpace(durableRoot);
|
|
192
|
+
const threshold = parseDiskBytesThreshold(raw, size.totalBytes);
|
|
193
|
+
if (threshold === undefined)
|
|
194
|
+
return false;
|
|
195
|
+
if (size.freeBytes >= threshold)
|
|
196
|
+
return false;
|
|
197
|
+
const log = options?.log ?? ((line) => console.warn(line));
|
|
198
|
+
log(`${DISK_WARN_LOG_PREFIX}: durable root free space ${size.freeBytes} bytes is below threshold ${threshold} bytes (${raw.trim()}); run sf runs gc`);
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
const log = options?.log ?? ((line) => console.warn(line));
|
|
203
|
+
log(`${DISK_WARN_LOG_PREFIX}: free-space measurement failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/** Measure one run workspace and persist `disk_bytes` / `disk_measured_at`. */
|
|
208
|
+
export async function refreshRunDiskUsage(store, runId, options) {
|
|
209
|
+
const workspaceDir = store.getWorkspaceDir(runId);
|
|
210
|
+
const bytes = await diskUsageOf(workspaceDir);
|
|
211
|
+
const measuredAt = (options?.now ?? new Date()).toISOString();
|
|
212
|
+
await store.setRunDiskUsage(runId, bytes, measuredAt);
|
|
213
|
+
return bytes;
|
|
214
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RunProjection } from "../projection/projectRun.js";
|
|
2
|
+
import type { RunDetail } from "./port.js";
|
|
3
|
+
import { type RunManifest } from "./runManifest.js";
|
|
4
|
+
export type RunExportPayload = RunProjection & {
|
|
5
|
+
run_manifest: RunManifest | null;
|
|
6
|
+
};
|
|
7
|
+
export declare function buildRunExportPayload(detail: RunDetail): RunExportPayload;
|
|
8
|
+
export declare function runDetailWithRedactedManifest(detail: RunDetail): RunDetail;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { projectRun } from "../projection/projectRun.js";
|
|
2
|
+
import { redactRunManifestForRead, } from "./runManifest.js";
|
|
3
|
+
import { getNamedSecrets } from "../logging/namedSecrets.js";
|
|
4
|
+
export function buildRunExportPayload(detail) {
|
|
5
|
+
return {
|
|
6
|
+
...projectRun(detail),
|
|
7
|
+
run_manifest: redactRunManifestForRead(detail.run_manifest, {
|
|
8
|
+
namedSecrets: getNamedSecrets(),
|
|
9
|
+
}),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function runDetailWithRedactedManifest(detail) {
|
|
13
|
+
const run_manifest = redactRunManifestForRead(detail.run_manifest, {
|
|
14
|
+
namedSecrets: getNamedSecrets(),
|
|
15
|
+
});
|
|
16
|
+
if (run_manifest === null) {
|
|
17
|
+
if (detail.run_manifest === undefined)
|
|
18
|
+
return detail;
|
|
19
|
+
const { run_manifest: _drop, ...rest } = detail;
|
|
20
|
+
return rest;
|
|
21
|
+
}
|
|
22
|
+
return { ...detail, run_manifest };
|
|
23
|
+
}
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
1
2
|
import path from "node:path";
|
|
2
3
|
export function normalizeCatalogPath(raw) {
|
|
3
4
|
return path.resolve(raw);
|
|
4
5
|
}
|
|
6
|
+
export function normalizeProjectRoot(raw) {
|
|
7
|
+
const resolved = path.resolve(raw);
|
|
8
|
+
try {
|
|
9
|
+
return realpathSync(resolved);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return resolved;
|
|
13
|
+
}
|
|
14
|
+
}
|
package/dist/runstore/paths.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export declare function newRunId(): string;
|
|
2
2
|
/** Root for factory state under a project: `<rootDir>/.stageflow`. */
|
|
3
3
|
export declare function storeRootFor(rootDir: string): string;
|
|
4
|
+
export declare function isGlobalStageflowHome(rootDir: string): boolean;
|
|
5
|
+
/** Project store root or the durable home when `rootDir` is the global home. */
|
|
6
|
+
export declare function resolveStoreRoot(rootDir: string): string;
|
|
7
|
+
export declare const NESTED_GLOBAL_STORE_CONFLICT = "Cannot open the global store: flat state.db has no runs table while nested .stageflow/state.db still holds run data. Resolve the conflict manually.";
|
|
8
|
+
export declare function flattenNestedGlobalStore(home: string): void;
|
|
4
9
|
export declare function migrateLegacyStoreRoot(rootDir: string): void;
|
|
5
10
|
export declare function runsDir(storeRoot: string): string;
|
|
6
11
|
export declare function runWorkspaceDir(storeRoot: string, runId: string): string;
|
package/dist/runstore/paths.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
-
import { readdirSync, renameSync, rmdirSync, statSync } from "node:fs";
|
|
2
|
+
import { existsSync, readdirSync, renameSync, rmdirSync, statSync, } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import Database from "better-sqlite3";
|
|
5
|
+
import { globalStageflowHome } from "../project/globalHome.js";
|
|
4
6
|
import { guardStageId } from "./workspaceLayout.js";
|
|
5
7
|
export function newRunId() {
|
|
6
8
|
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
@@ -10,6 +12,148 @@ export function newRunId() {
|
|
|
10
12
|
export function storeRootFor(rootDir) {
|
|
11
13
|
return path.join(rootDir, ".stageflow");
|
|
12
14
|
}
|
|
15
|
+
export function isGlobalStageflowHome(rootDir) {
|
|
16
|
+
return path.resolve(rootDir) === globalStageflowHome();
|
|
17
|
+
}
|
|
18
|
+
/** Project store root or the durable home when `rootDir` is the global home. */
|
|
19
|
+
export function resolveStoreRoot(rootDir) {
|
|
20
|
+
if (isGlobalStageflowHome(rootDir)) {
|
|
21
|
+
return globalStageflowHome();
|
|
22
|
+
}
|
|
23
|
+
return storeRootFor(rootDir);
|
|
24
|
+
}
|
|
25
|
+
const NESTED_GLOBAL_STORE_DIR = ".stageflow";
|
|
26
|
+
const STATE_DB_BASENAME = "state.db";
|
|
27
|
+
const STATE_DB_SIDECARS = ["state.db-wal", "state.db-shm"];
|
|
28
|
+
const NESTED_STORE_MOVE_DIRS = ["runs", "a2a-artifacts"];
|
|
29
|
+
export const NESTED_GLOBAL_STORE_CONFLICT = "Cannot open the global store: flat state.db has no runs table while nested .stageflow/state.db still holds run data. Resolve the conflict manually.";
|
|
30
|
+
function sqliteHasRunsTable(dbPath) {
|
|
31
|
+
if (!existsSync(dbPath)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
let db;
|
|
35
|
+
try {
|
|
36
|
+
db = new Database(dbPath, { readonly: true, fileMustExist: true });
|
|
37
|
+
const row = db
|
|
38
|
+
.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'runs'")
|
|
39
|
+
.get();
|
|
40
|
+
return row !== undefined;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
db?.close();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function assertNoNestedGlobalStoreConflict(home) {
|
|
50
|
+
const flatDb = path.join(home, STATE_DB_BASENAME);
|
|
51
|
+
const nestedDb = path.join(home, NESTED_GLOBAL_STORE_DIR, STATE_DB_BASENAME);
|
|
52
|
+
if (!existsSync(flatDb) || !existsSync(nestedDb)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (!sqliteHasRunsTable(flatDb) && sqliteHasRunsTable(nestedDb)) {
|
|
56
|
+
throw new Error(NESTED_GLOBAL_STORE_CONFLICT);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function renameIfExists(from, to) {
|
|
60
|
+
if (!existsSync(from) || existsSync(to)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
renameSync(from, to);
|
|
64
|
+
}
|
|
65
|
+
function rollbackStateDbSet(home, nested, moved) {
|
|
66
|
+
for (const name of [...moved].reverse()) {
|
|
67
|
+
const from = path.join(home, name);
|
|
68
|
+
const to = path.join(nested, name);
|
|
69
|
+
if (existsSync(from) && !existsSync(to)) {
|
|
70
|
+
renameSync(from, to);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function moveStateDbSet(home, nested) {
|
|
75
|
+
const flatMain = path.join(home, STATE_DB_BASENAME);
|
|
76
|
+
const nestedMain = path.join(nested, STATE_DB_BASENAME);
|
|
77
|
+
const flatHasMain = existsSync(flatMain);
|
|
78
|
+
const nestedHasMain = existsSync(nestedMain);
|
|
79
|
+
if (flatHasMain && nestedHasMain) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (flatHasMain && !nestedHasMain) {
|
|
83
|
+
for (const sidecar of STATE_DB_SIDECARS) {
|
|
84
|
+
renameIfExists(path.join(nested, sidecar), path.join(home, sidecar));
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (!flatHasMain && nestedHasMain) {
|
|
89
|
+
const names = [STATE_DB_BASENAME, ...STATE_DB_SIDECARS];
|
|
90
|
+
const moved = [];
|
|
91
|
+
try {
|
|
92
|
+
for (const name of names) {
|
|
93
|
+
const from = path.join(nested, name);
|
|
94
|
+
const to = path.join(home, name);
|
|
95
|
+
if (existsSync(from) && !existsSync(to)) {
|
|
96
|
+
renameSync(from, to);
|
|
97
|
+
moved.push(name);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
rollbackStateDbSet(home, nested, moved);
|
|
103
|
+
throw err;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function flatStorePathAbsent(home, name) {
|
|
108
|
+
const target = path.join(home, name);
|
|
109
|
+
const state = directoryState(target);
|
|
110
|
+
return state === "missing";
|
|
111
|
+
}
|
|
112
|
+
function moveNestedStoreDirs(home, nested) {
|
|
113
|
+
for (const dirName of NESTED_STORE_MOVE_DIRS) {
|
|
114
|
+
const from = path.join(nested, dirName);
|
|
115
|
+
const to = path.join(home, dirName);
|
|
116
|
+
if (directoryState(from) === "missing") {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (!flatStorePathAbsent(home, dirName)) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
renameSync(from, to);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function removeNestedGlobalStoreDirIfEmpty(home) {
|
|
126
|
+
const nested = path.join(home, NESTED_GLOBAL_STORE_DIR);
|
|
127
|
+
const state = directoryState(nested);
|
|
128
|
+
if (state === "missing" || state === "other") {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const inventory = [
|
|
132
|
+
STATE_DB_BASENAME,
|
|
133
|
+
...STATE_DB_SIDECARS,
|
|
134
|
+
...NESTED_STORE_MOVE_DIRS,
|
|
135
|
+
];
|
|
136
|
+
for (const name of inventory) {
|
|
137
|
+
if (existsSync(path.join(nested, name))) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (state === "empty") {
|
|
142
|
+
rmdirSync(nested);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
export function flattenNestedGlobalStore(home) {
|
|
146
|
+
const nested = path.join(home, NESTED_GLOBAL_STORE_DIR);
|
|
147
|
+
const nestedState = directoryState(nested);
|
|
148
|
+
if (nestedState === "missing" || nestedState === "other") {
|
|
149
|
+
assertNoNestedGlobalStoreConflict(home);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
assertNoNestedGlobalStoreConflict(home);
|
|
153
|
+
moveStateDbSet(home, nested);
|
|
154
|
+
moveNestedStoreDirs(home, nested);
|
|
155
|
+
removeNestedGlobalStoreDirIfEmpty(home);
|
|
156
|
+
}
|
|
13
157
|
function directoryState(dirPath) {
|
|
14
158
|
try {
|
|
15
159
|
const st = statSync(dirPath);
|
package/dist/runstore/port.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { StageLogLine } from "../agent/activity.js";
|
|
2
|
+
import type { ConfigOriginRecord } from "../config/configOrigin.js";
|
|
2
3
|
import type { RunSubmission, RunSubmissionRecord } from "./submission.js";
|
|
3
4
|
import type { AskOperatorPrompt } from "../tools/askOperator.js";
|
|
4
5
|
import type { StageEnvelope } from "../types/envelope.js";
|
|
@@ -6,14 +7,15 @@ import type { FeedbackLoopConfig, InlinePipelineDefinition, ResolvedPipelineDag
|
|
|
6
7
|
import type { CompletionCheck } from "../types/completion.js";
|
|
7
8
|
import type { StageGateKind } from "../types/stage.js";
|
|
8
9
|
import type { StageUsage } from "../types/usage.js";
|
|
9
|
-
export type
|
|
10
|
+
export type { ConfigOriginRecord };
|
|
11
|
+
export type RunStatus = "created" | "queued" | "running" | "succeeded" | "failed" | "cancelled";
|
|
10
12
|
export type RunPipelineDagSnapshot = ResolvedPipelineDag & {
|
|
11
13
|
stage_ids: string[];
|
|
12
14
|
gate_kinds?: Record<string, StageGateKind[]>;
|
|
13
15
|
/** IR: per-stage clone assignment schema. YAML: `io.input.schema`. */
|
|
14
16
|
clone_input_schema?: Record<string, unknown>;
|
|
15
17
|
};
|
|
16
|
-
export type StageReadiness = "blocked" | "ready" | "running" | "waiting" | "succeeded" | "failed" | "skipped";
|
|
18
|
+
export type StageReadiness = "blocked" | "ready" | "running" | "waiting" | "interrupted" | "succeeded" | "failed" | "skipped";
|
|
17
19
|
export type PipelineTrackNode = {
|
|
18
20
|
stage_id: string;
|
|
19
21
|
status: StageSnapshot["status"];
|
|
@@ -52,12 +54,25 @@ export type RunMeta = {
|
|
|
52
54
|
pipeline_path?: string;
|
|
53
55
|
task_path?: string;
|
|
54
56
|
project_root?: string;
|
|
57
|
+
repository?: string;
|
|
58
|
+
ref?: string;
|
|
59
|
+
resolved_sha?: string;
|
|
60
|
+
run_branch?: string;
|
|
61
|
+
git_author_name?: string;
|
|
62
|
+
git_author_email?: string;
|
|
63
|
+
cancel_reason?: string;
|
|
64
|
+
finished_at?: string;
|
|
65
|
+
slimmed_at?: string;
|
|
66
|
+
disk_bytes?: number;
|
|
67
|
+
disk_measured_at?: string;
|
|
68
|
+
config_origins?: ConfigOriginRecord[];
|
|
69
|
+
pipeline_source?: "inline" | "path";
|
|
70
|
+
caller_id?: string;
|
|
71
|
+
run_manifest?: unknown;
|
|
72
|
+
skip_gates?: boolean;
|
|
55
73
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* memory of the original in-process call — reconstruct the pipeline
|
|
59
|
-
* without needing a catalog file, mirroring how task_yaml already lets
|
|
60
|
-
* task reconstruction work without a task_path.
|
|
74
|
+
* Parsed inline pipeline body for stage-worker reload when there is no
|
|
75
|
+
* pipeline_path. Derived from stored pipeline_body.
|
|
61
76
|
*/
|
|
62
77
|
inline_pipeline?: InlinePipelineDefinition;
|
|
63
78
|
};
|
|
@@ -73,7 +88,7 @@ export type StageLogEvent = StageLogLine & {
|
|
|
73
88
|
export type StageSnapshot = {
|
|
74
89
|
stage_id: string;
|
|
75
90
|
definition_id?: string;
|
|
76
|
-
status: "pending" | "running" | "waiting_for_input" | "succeeded" | "failed" | "skipped";
|
|
91
|
+
status: "pending" | "running" | "waiting_for_input" | "interrupted" | "succeeded" | "failed" | "skipped";
|
|
77
92
|
events: StageLogEvent[];
|
|
78
93
|
envelope: StageEnvelope | null;
|
|
79
94
|
artifacts: string[];
|
|
@@ -94,6 +109,7 @@ export type StageExecution = {
|
|
|
94
109
|
envelope: StageEnvelope | null;
|
|
95
110
|
cost_usd?: number;
|
|
96
111
|
usage?: StageUsage;
|
|
112
|
+
auto_resume_count: number;
|
|
97
113
|
};
|
|
98
114
|
export type StageExecutionPatch = {
|
|
99
115
|
status?: StageSnapshot["status"];
|
|
@@ -103,6 +119,7 @@ export type StageExecutionPatch = {
|
|
|
103
119
|
envelope?: StageEnvelope | null;
|
|
104
120
|
cost_usd?: number;
|
|
105
121
|
usage?: StageUsage;
|
|
122
|
+
auto_resume_count?: number;
|
|
106
123
|
};
|
|
107
124
|
/** The durable disposition of completion verification for one stage attempt. */
|
|
108
125
|
export type VerificationOutcome = "not_run" | "passed" | "failed" | "error";
|
|
@@ -238,6 +255,16 @@ export type CompactStage = {
|
|
|
238
255
|
definition_id?: string;
|
|
239
256
|
cost_usd?: number;
|
|
240
257
|
};
|
|
258
|
+
export type RunBindingCompact = {
|
|
259
|
+
kind: "repository" | "checkout" | "unbound";
|
|
260
|
+
repository?: string;
|
|
261
|
+
ref?: string;
|
|
262
|
+
resolved_sha?: string;
|
|
263
|
+
};
|
|
264
|
+
export type RunBindingDetail = RunBindingCompact & {
|
|
265
|
+
run_branch?: string;
|
|
266
|
+
checkout_root?: string;
|
|
267
|
+
};
|
|
241
268
|
export type RunSummary = {
|
|
242
269
|
run_id: string;
|
|
243
270
|
pipeline_id: string;
|
|
@@ -245,9 +272,11 @@ export type RunSummary = {
|
|
|
245
272
|
pipeline_path?: string;
|
|
246
273
|
task_path?: string;
|
|
247
274
|
project_root?: string;
|
|
275
|
+
pipeline_source?: "inline" | "path";
|
|
248
276
|
status: RunStatus;
|
|
249
277
|
created_at: string;
|
|
250
278
|
updated_at?: string;
|
|
279
|
+
binding: RunBindingCompact;
|
|
251
280
|
stages: CompactStage[];
|
|
252
281
|
/** Present when a stage is waiting_for_input (first such stage). */
|
|
253
282
|
waiting_stage_id?: string;
|
|
@@ -265,13 +294,22 @@ export type RunSummary = {
|
|
|
265
294
|
active_feedback_loop?: FeedbackLoopRecord;
|
|
266
295
|
/** Sum of every stage's cost_usd; omitted when no stage reported usage. */
|
|
267
296
|
total_cost_usd?: number;
|
|
297
|
+
cancel_reason?: string;
|
|
298
|
+
finished_at?: string;
|
|
299
|
+
slimmed_at?: string;
|
|
300
|
+
disk_bytes?: number;
|
|
301
|
+
disk_measured_at?: string;
|
|
268
302
|
};
|
|
269
|
-
export type RunDetail = Omit<RunSummary, "stages"> & {
|
|
303
|
+
export type RunDetail = Omit<RunSummary, "stages" | "binding"> & {
|
|
304
|
+
binding: RunBindingDetail;
|
|
270
305
|
task_yaml: string;
|
|
271
306
|
stages: StageSnapshot[];
|
|
272
307
|
pipeline_track: PipelineTrackProjection;
|
|
273
308
|
/** Append-only feedback-loop and replay history, ordered by creation. */
|
|
274
309
|
feedback_loops: FeedbackLoopHistory[];
|
|
310
|
+
config_origins?: ConfigOriginRecord[];
|
|
311
|
+
caller_id?: string;
|
|
312
|
+
run_manifest?: unknown;
|
|
275
313
|
};
|
|
276
314
|
export type FeedbackLoopHistory = {
|
|
277
315
|
loop: FeedbackLoopRecord;
|
|
@@ -285,6 +323,7 @@ export type FeedbackLoopHistory = {
|
|
|
285
323
|
};
|
|
286
324
|
export type CreateRunInput = {
|
|
287
325
|
submission?: RunSubmission;
|
|
326
|
+
runId?: string;
|
|
288
327
|
pipelineId: string;
|
|
289
328
|
taskYaml: string;
|
|
290
329
|
taskId?: string;
|
|
@@ -296,8 +335,24 @@ export type CreateRunInput = {
|
|
|
296
335
|
pipelinePath?: string;
|
|
297
336
|
taskPath?: string;
|
|
298
337
|
projectRoot?: string;
|
|
299
|
-
|
|
338
|
+
repository?: string;
|
|
339
|
+
ref?: string;
|
|
340
|
+
resolvedSha?: string;
|
|
341
|
+
runBranch?: string;
|
|
342
|
+
gitAuthorName?: string;
|
|
343
|
+
gitAuthorEmail?: string;
|
|
344
|
+
status?: RunStatus;
|
|
345
|
+
pipelineSource?: "inline" | "path";
|
|
346
|
+
/** Durable JSON string stored in pipeline_body. Prefer this for slots writers. */
|
|
347
|
+
pipelineBody?: string;
|
|
348
|
+
/**
|
|
349
|
+
* Convenience for callers/tests that have a parsed inline pipeline.
|
|
350
|
+
* Stored as pipeline_body JSON; surfaced back as meta.inline_pipeline on read.
|
|
351
|
+
*/
|
|
300
352
|
inlinePipeline?: InlinePipelineDefinition;
|
|
353
|
+
callerId?: string;
|
|
354
|
+
runManifest?: unknown;
|
|
355
|
+
skipGates?: boolean;
|
|
301
356
|
};
|
|
302
357
|
export type ListRunsFilter = {
|
|
303
358
|
status?: RunStatus;
|
|
@@ -305,6 +360,7 @@ export type ListRunsFilter = {
|
|
|
305
360
|
since?: string;
|
|
306
361
|
/** Match pipeline_id or pipeline_path */
|
|
307
362
|
pipeline?: string;
|
|
363
|
+
caller_id?: string;
|
|
308
364
|
};
|
|
309
365
|
/**
|
|
310
366
|
* Persistence port for pipeline run state.
|
|
@@ -313,11 +369,49 @@ export type ListRunsFilter = {
|
|
|
313
369
|
* run id is all you have (catalog / rehydrate).
|
|
314
370
|
*/
|
|
315
371
|
export interface RunStore {
|
|
372
|
+
/** Checkpoint WAL (when applicable) and release the store connection. */
|
|
373
|
+
close(): Promise<void>;
|
|
374
|
+
/**
|
|
375
|
+
* Consistent compacted snapshot of the live DB via `VACUUM INTO`.
|
|
376
|
+
* Only SqliteRunStore implements this; callers must not open a second raw connection.
|
|
377
|
+
*/
|
|
378
|
+
snapshotInto(destPath: string): Promise<{
|
|
379
|
+
userVersion: number;
|
|
380
|
+
}>;
|
|
316
381
|
getRunBySubmission(key: string): Promise<RunSubmissionRecord | null>;
|
|
317
382
|
createRun(input: CreateRunInput): Promise<CreatedRun>;
|
|
318
383
|
updateRunStatus(runId: string, status: RunStatus): Promise<void>;
|
|
384
|
+
/**
|
|
385
|
+
* Conditional status update (CAS): sets `status` only when the row currently
|
|
386
|
+
* has `expectedStatus`. Returns false when the run exists but status differs;
|
|
387
|
+
* throws when the run is missing.
|
|
388
|
+
*/
|
|
389
|
+
tryUpdateRunStatus(runId: string, status: RunStatus, expectedStatus: RunStatus): Promise<boolean>;
|
|
390
|
+
/** Patch workspace-binding columns on an existing run (queued → materialize). */
|
|
391
|
+
patchRunWorkspaceBinding(runId: string, patch: {
|
|
392
|
+
checkoutRoot?: string;
|
|
393
|
+
repository?: string;
|
|
394
|
+
ref?: string;
|
|
395
|
+
resolvedSha?: string;
|
|
396
|
+
runBranch?: string;
|
|
397
|
+
}): Promise<void>;
|
|
398
|
+
/** Append resolved config origin records (MCP / skill / verify). Dedupes by name+origin+path. */
|
|
399
|
+
appendConfigOrigins(runId: string, origins: ConfigOriginRecord[]): Promise<void>;
|
|
400
|
+
setCancelReason(runId: string, reason: string): Promise<void>;
|
|
401
|
+
/** Persist cached disk usage for `listRuns` (never measured inside listRuns). */
|
|
402
|
+
setRunDiskUsage(runId: string, diskBytes: number, measuredAt: string): Promise<void>;
|
|
403
|
+
/** Record that SLIM reclaim completed for this run (R18 idempotency gate). */
|
|
404
|
+
setSlimmedAt(runId: string, slimmedAt: string): Promise<void>;
|
|
405
|
+
/** Hard-delete every run-scoped row. Throws `Run not found: …` when missing. */
|
|
406
|
+
deleteRun(runId: string): Promise<void>;
|
|
319
407
|
readRunMeta(runId: string): Promise<RunMeta>;
|
|
320
408
|
readTaskYaml(runId: string): Promise<string>;
|
|
409
|
+
readPipelineBody(runId: string): Promise<string | null>;
|
|
410
|
+
/**
|
|
411
|
+
* Atomic replace of the `run_manifest` JSON blob (build → redact → write).
|
|
412
|
+
* Pass `null` to clear.
|
|
413
|
+
*/
|
|
414
|
+
updateRunManifest(runId: string, manifest: unknown): Promise<void>;
|
|
321
415
|
/** Opaque run workspace root for agents and artifact tools. */
|
|
322
416
|
getWorkspaceDir(runId: string): string;
|
|
323
417
|
ensureStageWorkspace(runId: string, stageId: string): Promise<void>;
|
|
@@ -327,6 +421,8 @@ export interface RunStore {
|
|
|
327
421
|
getLatestStageExecution(runId: string, stageId: string): Promise<StageExecution | null>;
|
|
328
422
|
countStageAttempts(runId: string, stageId: string): Promise<number>;
|
|
329
423
|
getStageExecution(runId: string, stageId: string, attempt: number): Promise<StageExecution>;
|
|
424
|
+
/** Latest attempt rows whose status is `interrupted` (targeted scan; not listRuns). */
|
|
425
|
+
listInterruptedStageExecutions(): Promise<StageExecution[]>;
|
|
330
426
|
updateStageExecution(runId: string, stageId: string, attempt: number, patch: StageExecutionPatch): Promise<void>;
|
|
331
427
|
/** Create or update evidence for one check in a stage execution attempt. */
|
|
332
428
|
upsertVerificationCheckResult(runId: string, stageId: string, result: VerificationCheckResultPatch, options?: {
|
|
@@ -346,8 +442,10 @@ export interface RunStore {
|
|
|
346
442
|
}): Promise<void>;
|
|
347
443
|
listStageEvents(runId: string, stageId: string, attempt?: number): Promise<StageLogEvent[]>;
|
|
348
444
|
listRuns(filter?: ListRunsFilter): Promise<RunSummary[]>;
|
|
349
|
-
/**
|
|
350
|
-
|
|
445
|
+
/** Idempotent upsert; returns the realpath/resolve-normalized absolute key. */
|
|
446
|
+
ensureProject(absPath: string): Promise<string>;
|
|
447
|
+
/** Absolute roots from the durable projects registry. */
|
|
448
|
+
listRegisteredProjects(): Promise<string[]>;
|
|
351
449
|
readRun(runId: string): Promise<RunDetail>;
|
|
352
450
|
updatePipelineDag(runId: string, dag: RunPipelineDagSnapshot): Promise<void>;
|
|
353
451
|
createFeedbackLoop(runId: string, input: CreateFeedbackLoopInput): Promise<FeedbackLoopRecord>;
|
|
@@ -377,4 +475,4 @@ export interface RunStore {
|
|
|
377
475
|
}
|
|
378
476
|
export declare function stageStatusFromEvents(events: StageLogEvent[]): StageSnapshot["status"];
|
|
379
477
|
export declare function findUnhandledFailedStage(stages: StageSnapshot[], dag?: Pick<RunPipelineDagSnapshot, "nodes"> | null): StageSnapshot | undefined;
|
|
380
|
-
export declare function deriveStatusFromStages(stages: StageSnapshot[], dag?: Pick<RunPipelineDagSnapshot, "nodes"> | null): RunStatus;
|
|
478
|
+
export declare function deriveStatusFromStages(stages: StageSnapshot[], dag?: Pick<RunPipelineDagSnapshot, "nodes"> | null, currentStatus?: RunStatus): RunStatus;
|