stageflow 0.25.0 → 0.30.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 +14 -3
- package/builtin-skills/browser/SKILL.md +42 -0
- 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/claudeAdapter.js +2 -2
- package/dist/agent/cursorProvider.d.ts +2 -0
- package/dist/agent/cursorProvider.js +30 -5
- package/dist/agent/fakeAgent.d.ts +1 -0
- package/dist/agent/fakeAgent.js +13 -0
- package/dist/agent/piAdapter.d.ts +11 -24
- package/dist/agent/piAdapter.js +107 -50
- package/dist/agent/piIsolatedMcp.d.ts +2 -0
- package/dist/agent/piIsolatedMcp.js +10 -2
- package/dist/agent/piSessionFactory.d.ts +38 -0
- package/dist/agent/piSessionFactory.js +60 -0
- package/dist/agent/port.d.ts +8 -0
- package/dist/agent/streamLogRedact.d.ts +7 -1
- package/dist/agent/streamLogRedact.js +26 -11
- package/dist/browser/anchor.d.ts +27 -0
- package/dist/browser/anchor.js +127 -0
- package/dist/browser/auditSink.d.ts +38 -0
- package/dist/browser/auditSink.js +34 -0
- package/dist/browser/browserHost.d.ts +86 -0
- package/dist/browser/browserHost.js +7 -0
- package/dist/browser/browserSweep.d.ts +14 -0
- package/dist/browser/browserSweep.js +54 -0
- package/dist/browser/browserTeardown.d.ts +56 -0
- package/dist/browser/browserTeardown.js +235 -0
- package/dist/browser/fakeRemoteBrowserHost.d.ts +2 -0
- package/dist/browser/fakeRemoteBrowserHost.js +34 -0
- package/dist/browser/gateHandoff.d.ts +25 -0
- package/dist/browser/gateHandoff.js +83 -0
- package/dist/browser/humanLogin.d.ts +18 -0
- package/dist/browser/humanLogin.js +34 -0
- package/dist/browser/keyProvider.d.ts +10 -0
- package/dist/browser/keyProvider.js +39 -0
- package/dist/browser/localBrowserHost.d.ts +10 -0
- package/dist/browser/localBrowserHost.js +152 -0
- package/dist/browser/localProfileLock.d.ts +2 -0
- package/dist/browser/localProfileLock.js +218 -0
- package/dist/browser/localProfileStore.d.ts +5 -0
- package/dist/browser/localProfileStore.js +91 -0
- package/dist/browser/loginCheck.d.ts +53 -0
- package/dist/browser/loginCheck.js +147 -0
- package/dist/browser/memoryProfileLock.d.ts +2 -0
- package/dist/browser/memoryProfileLock.js +53 -0
- package/dist/browser/memoryProfileStore.d.ts +2 -0
- package/dist/browser/memoryProfileStore.js +31 -0
- package/dist/browser/navigationAudit.d.ts +16 -0
- package/dist/browser/navigationAudit.js +53 -0
- package/dist/browser/persistedEnv.d.ts +3 -0
- package/dist/browser/persistedEnv.js +15 -0
- package/dist/browser/profileLock.d.ts +40 -0
- package/dist/browser/profileLock.js +10 -0
- package/dist/browser/profileStore.d.ts +23 -0
- package/dist/browser/profileStore.js +39 -0
- package/dist/browser/runLiveness.d.ts +13 -0
- package/dist/browser/runLiveness.js +39 -0
- package/dist/browser/sitePolicy.d.ts +10 -0
- package/dist/browser/sitePolicy.js +61 -0
- package/dist/browser/stageBrowserEnv.d.ts +22 -0
- package/dist/browser/stageBrowserEnv.js +147 -0
- package/dist/browser/stageProfileLock.d.ts +17 -0
- package/dist/browser/stageProfileLock.js +39 -0
- package/dist/cli/artifactCommand.js +9 -16
- package/dist/cli/backupCommand.d.ts +9 -0
- package/dist/cli/backupCommand.js +111 -0
- package/dist/cli/browserCommand.d.ts +44 -0
- package/dist/cli/browserCommand.js +472 -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 +41 -3
- package/dist/cli/hostClient.js +129 -14
- package/dist/cli/initCommand.d.ts +1 -0
- package/dist/cli/initCommand.js +23 -7
- package/dist/cli/initTemplates.d.ts +5 -2
- package/dist/cli/initTemplates.js +32 -2
- 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 +168 -10
- package/dist/cli/triggerCommand.d.ts +12 -0
- package/dist/cli/triggerCommand.js +183 -0
- package/dist/cli/validateCommand.d.ts +1 -1
- package/dist/cli/validateCommand.js +23 -6
- package/dist/cli.js +202 -32
- package/dist/config/browseCatalog.d.ts +1 -0
- package/dist/config/browseCatalog.js +5 -4
- package/dist/config/builtinSkills.d.ts +4 -0
- package/dist/config/builtinSkills.js +23 -0
- package/dist/config/catalogRelativePath.d.ts +63 -0
- package/dist/config/catalogRelativePath.js +126 -0
- package/dist/config/configOrigin.d.ts +27 -0
- package/dist/config/configOrigin.js +59 -0
- package/dist/config/createTrigger.d.ts +27 -0
- package/dist/config/createTrigger.js +232 -0
- package/dist/config/draftPackage.d.ts +117 -0
- package/dist/config/draftPackage.js +550 -0
- package/dist/config/ensureCatalogScanRoot.d.ts +16 -0
- package/dist/config/ensureCatalogScanRoot.js +73 -0
- package/dist/config/hostConfig.d.ts +57 -0
- package/dist/config/hostConfig.js +360 -0
- package/dist/config/listSkills.d.ts +26 -0
- package/dist/config/listSkills.js +206 -5
- package/dist/config/loadOutcome.d.ts +7 -1
- package/dist/config/loadPipeline.js +39 -2
- package/dist/config/loadStage.js +25 -0
- package/dist/config/loadStageflowManifest.js +25 -0
- package/dist/config/loadTask.d.ts +2 -0
- package/dist/config/loadTask.js +57 -18
- package/dist/config/loadTrigger.d.ts +9 -0
- package/dist/config/loadTrigger.js +120 -0
- 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 +32 -0
- package/dist/config/multiProjectCatalog.js +150 -0
- package/dist/config/normalizePipelineStageEntry.js +27 -1
- package/dist/config/parseCompletionContract.js +6 -0
- package/dist/config/pipelineStageKeys.js +3 -0
- package/dist/config/publishDraftPackage.d.ts +7 -0
- package/dist/config/publishDraftPackage.js +25 -0
- package/dist/config/resolveCatalogContext.js +1 -1
- 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/resolvePipelineDag.js +1 -1
- package/dist/config/resolveStageMcpServers.d.ts +9 -1
- package/dist/config/resolveStageMcpServers.js +36 -9
- package/dist/config/scanCatalogPaths.d.ts +1 -1
- package/dist/config/scanCatalogPaths.js +6 -2
- 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/stageBrowser.d.ts +12 -0
- package/dist/config/stageBrowser.js +118 -0
- package/dist/config/toolRequires.d.ts +24 -0
- package/dist/config/toolRequires.js +115 -0
- package/dist/config/triggerCatalog.d.ts +10 -0
- package/dist/config/triggerCatalog.js +37 -0
- package/dist/config/validateCatalog.d.ts +17 -3
- package/dist/config/validateCatalog.js +223 -3
- package/dist/config/validateCompletionContract.js +8 -0
- package/dist/diagnostics/checks.d.ts +39 -0
- package/dist/diagnostics/checks.js +135 -0
- package/dist/envelope/preEmitChecks.d.ts +1 -1
- package/dist/envelope/preEmitChecks.js +8 -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 +17 -0
- package/dist/logging/redact.js +105 -0
- package/dist/mcp/catalogTools.js +492 -81
- package/dist/mcp/checkoutTools.d.ts +52 -0
- package/dist/mcp/checkoutTools.js +332 -0
- package/dist/mcp/controlTools.js +182 -6
- package/dist/mcp/deps.d.ts +3 -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 +2 -0
- package/dist/mcp/tools.js +6 -0
- package/dist/mcp/triggerTools.d.ts +3 -0
- package/dist/mcp/triggerTools.js +176 -0
- package/dist/net/proxy.d.ts +14 -0
- package/dist/net/proxy.js +78 -0
- package/dist/operatorAgent/docsRetrieval.d.ts +40 -0
- package/dist/operatorAgent/docsRetrieval.js +269 -0
- package/dist/operatorAgent/draftContext.d.ts +16 -0
- package/dist/operatorAgent/draftContext.js +68 -0
- package/dist/operatorAgent/fakeHost.d.ts +39 -0
- package/dist/operatorAgent/fakeHost.js +92 -0
- package/dist/operatorAgent/host.d.ts +40 -0
- package/dist/operatorAgent/host.js +179 -0
- package/dist/operatorAgent/index.d.ts +9 -0
- package/dist/operatorAgent/index.js +8 -0
- package/dist/operatorAgent/piModel.d.ts +80 -0
- package/dist/operatorAgent/piModel.js +528 -0
- package/dist/operatorAgent/profiles/workshopAuthor.d.ts +23 -0
- package/dist/operatorAgent/profiles/workshopAuthor.js +338 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +6 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +103 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +57 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.js +623 -0
- package/dist/operatorAgent/proposals.d.ts +32 -0
- package/dist/operatorAgent/proposals.js +144 -0
- package/dist/operatorAgent/types.d.ts +128 -0
- package/dist/operatorAgent/types.js +1 -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/findManifestRoot.d.ts +3 -0
- package/dist/project/findManifestRoot.js +35 -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.d.ts +7 -0
- package/dist/project/resolveStageflowContext.js +46 -30
- 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 +25 -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 +139 -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 +35 -3
- package/dist/runstore/sqlite/SqliteRunStore.js +442 -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/008-triggers-table.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/008-triggers-table.js +19 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.js +19 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.js +17 -0
- package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
- package/dist/runstore/sqlite/migrations/index.js +78 -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/answerResume.d.ts +1 -0
- package/dist/runtime/answerResume.js +3 -1
- package/dist/runtime/completionCheckRunner.d.ts +15 -1
- package/dist/runtime/completionCheckRunner.js +67 -7
- package/dist/runtime/containerLimits.d.ts +16 -0
- package/dist/runtime/containerLimits.js +84 -0
- package/dist/runtime/credentialBinding.d.ts +2 -0
- package/dist/runtime/credentialBinding.js +3 -0
- package/dist/runtime/credentialMaterialisation.d.ts +28 -0
- package/dist/runtime/credentialMaterialisation.js +128 -0
- package/dist/runtime/emailSource.d.ts +72 -0
- package/dist/runtime/emailSource.js +304 -0
- package/dist/runtime/gitCheckoutCapability.js +7 -13
- package/dist/runtime/githubPollSource.d.ts +86 -0
- package/dist/runtime/githubPollSource.js +284 -0
- package/dist/runtime/pipelineRunner.d.ts +40 -1
- package/dist/runtime/pipelineRunner.js +181 -17
- package/dist/runtime/pipelineScheduler.d.ts +17 -0
- package/dist/runtime/pipelineScheduler.js +220 -28
- 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 +169 -4
- package/dist/runtime/runManager.js +1748 -83
- package/dist/runtime/runRetentionSweep.d.ts +31 -0
- package/dist/runtime/runRetentionSweep.js +328 -0
- package/dist/runtime/runRetryCoordinator.d.ts +4 -0
- package/dist/runtime/runRetryCoordinator.js +20 -2
- package/dist/runtime/runSkills.d.ts +40 -0
- package/dist/runtime/runSkills.js +173 -0
- package/dist/runtime/scheduleSource.d.ts +38 -0
- package/dist/runtime/scheduleSource.js +119 -0
- package/dist/runtime/settingsFile.d.ts +5 -0
- package/dist/runtime/settingsFile.js +61 -54
- package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
- package/dist/runtime/stageAttemptBootstrap.js +250 -27
- 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 +194 -0
- package/dist/runtime/stageHitl.d.ts +1 -0
- package/dist/runtime/stageHitl.js +5 -1
- package/dist/runtime/stageProcessLauncher.d.ts +20 -0
- package/dist/runtime/stageProcessLauncher.js +236 -41
- 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 +6 -0
- package/dist/runtime/stageRunner.js +32 -6
- 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/stageStreamLog.d.ts +1 -0
- package/dist/runtime/stageStreamLog.js +2 -1
- 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/triggerCatalog.d.ts +6 -0
- package/dist/runtime/triggerCatalog.js +24 -0
- package/dist/runtime/triggerEventMatch.d.ts +2 -0
- package/dist/runtime/triggerEventMatch.js +6 -0
- package/dist/runtime/triggerPort.d.ts +14 -0
- package/dist/runtime/triggerPort.js +1 -0
- package/dist/runtime/triggerRunner.d.ts +17 -0
- package/dist/runtime/triggerRunner.js +89 -0
- package/dist/runtime/verifiedStageExecution.d.ts +8 -0
- package/dist/runtime/verifiedStageExecution.js +16 -1
- package/dist/runtime/webhookSignature.d.ts +1 -0
- package/dist/runtime/webhookSignature.js +12 -0
- 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 +42 -2
- package/dist/server/bootstrap.js +273 -5
- package/dist/server/controlToken.d.ts +47 -0
- package/dist/server/controlToken.js +254 -0
- package/dist/server/createHttpHost.d.ts +11 -2
- package/dist/server/createHttpHost.js +106 -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 +123 -0
- package/dist/server/http.d.ts +27 -1
- package/dist/server/http.js +2254 -477
- 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/server/triggerRoutes.d.ts +15 -0
- package/dist/server/triggerRoutes.js +268 -0
- package/dist/tools/askOperator.d.ts +3 -2
- package/dist/types/completion.d.ts +3 -0
- package/dist/types/pipeline.d.ts +10 -1
- package/dist/types/preEmitCheck.d.ts +7 -0
- package/dist/types/stage.d.ts +22 -0
- package/dist/types/stageflowManifest.d.ts +3 -0
- package/dist/types/task.d.ts +8 -0
- package/dist/types/trigger.d.ts +18 -0
- package/dist/types/trigger.js +1 -0
- package/dist/ui/assets/{index-CSsDued1.css → index-Bv4p1aPK.css} +1 -1
- package/dist/ui/assets/index-CntB4bZR.js +133 -0
- package/dist/ui/index.html +2 -2
- package/dist/workshop/autosave.d.ts +58 -0
- package/dist/workshop/autosave.js +222 -0
- package/dist/workshop/buildStore.d.ts +79 -0
- package/dist/workshop/buildStore.js +326 -0
- package/dist/workshop/chatTurn.d.ts +232 -0
- package/dist/workshop/chatTurn.js +475 -0
- package/dist/workshop/modelSettings.d.ts +18 -0
- package/dist/workshop/modelSettings.js +44 -0
- package/dist/workshop/sessionStore.d.ts +61 -0
- package/dist/workshop/sessionStore.js +254 -0
- package/dist/workshop/workshopPin.d.ts +72 -0
- package/dist/workshop/workshopPin.js +193 -0
- package/examples/README.md +99 -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/browser-session/README.md +77 -0
- package/examples/browser-session/browser-session.pipeline.yaml +50 -0
- package/examples/browser-session/browser-session.task.yaml +6 -0
- package/examples/browser-session/check-login.yaml +22 -0
- package/examples/browser-session/fixture-server.mjs +64 -0
- package/examples/browser-session/human-login.yaml +31 -0
- package/examples/browser-session/merge.yaml +36 -0
- package/examples/browser-session/work-a.yaml +41 -0
- package/examples/browser-session/work-b.yaml +41 -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 +145 -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/stageflow.yaml +51 -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 +9 -1
- package/skills/stageflow/SKILL.md +6 -6
- package/skills/stageflow/references/control-surface.md +13 -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-author/references/stage-prompt-template.md +4 -4
- package/skills/stageflow-run/SKILL.md +22 -12
- package/skills/stageflow-run/references/mcp-call.md +9 -1
- package/skills/stageflow-run/references/task-and-pipeline-selection.md +19 -6
- 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 +51 -8
- package/dist/ui/assets/index-Da5EHU6M.js +0 -119
|
@@ -1,196 +1,20 @@
|
|
|
1
1
|
import Database from "better-sqlite3";
|
|
2
|
+
import { existsSync, statSync } from "node:fs";
|
|
2
3
|
import { mkdir } from "node:fs/promises";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { projectRunDetail, projectRunSummary, orderStageSnapshots } from "../runProjection.js";
|
|
5
|
-
import { normalizeCatalogPath } from "../normalizeCatalogPath.js";
|
|
6
|
+
import { normalizeCatalogPath, normalizeProjectRoot } from "../normalizeCatalogPath.js";
|
|
6
7
|
import { buildStageSnapshotFromStore } from "../stageSnapshot.js";
|
|
7
8
|
import { parsePipelineDagSnapshot } from "../pipelineDagSnapshot.js";
|
|
8
9
|
import { newRunId, runWorkspaceDir } from "../paths.js";
|
|
9
10
|
import { attemptAgentDir, attemptArtifactsDir, stageDir, } from "../workspaceLayout.js";
|
|
10
11
|
import { importDiskRunsIfEmpty } from "./migrateFromDisk.js";
|
|
11
|
-
import {
|
|
12
|
+
import { applyPendingMigrations, assertSchemaVersion, } from "./migrations/index.js";
|
|
13
|
+
import { StoreSchemaError } from "./storeSchemaError.js";
|
|
14
|
+
import { applyStorePragmas } from "./applyStorePragmas.js";
|
|
12
15
|
import { RunSubmissionExistsError } from "../submission.js";
|
|
16
|
+
const EXECUTION_SELECT_COLS = `run_id, stage_id, attempt, status, verification_outcome, started_at, finished_at, envelope_json, cost_usd, usage_json, auto_resume_count`;
|
|
13
17
|
const ensuredStageDirs = new Set();
|
|
14
|
-
const DEFAULT_SQLITE_BUSY_TIMEOUT_MS = 5000;
|
|
15
|
-
function readSqliteBusyTimeoutMs() {
|
|
16
|
-
const raw = process.env.STAGEFLOW_SQLITE_BUSY_TIMEOUT_MS;
|
|
17
|
-
if (raw === undefined || raw.trim() === "") {
|
|
18
|
-
return DEFAULT_SQLITE_BUSY_TIMEOUT_MS;
|
|
19
|
-
}
|
|
20
|
-
const parsed = Number.parseInt(raw, 10);
|
|
21
|
-
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
22
|
-
return DEFAULT_SQLITE_BUSY_TIMEOUT_MS;
|
|
23
|
-
}
|
|
24
|
-
return parsed;
|
|
25
|
-
}
|
|
26
|
-
function ensureCheckoutRootColumn(db) {
|
|
27
|
-
const cols = db.prepare(`PRAGMA table_info(runs)`).all();
|
|
28
|
-
if (!cols.some((c) => c.name === "checkout_root")) {
|
|
29
|
-
db.exec(`ALTER TABLE runs ADD COLUMN checkout_root TEXT`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function ensureCiIdentityColumns(db) {
|
|
33
|
-
const cols = db.prepare(`PRAGMA table_info(runs)`).all();
|
|
34
|
-
const names = new Set(cols.map((c) => c.name));
|
|
35
|
-
for (const name of ["git_sha", "ci_pr_url", "ci_job_url"]) {
|
|
36
|
-
if (!names.has(name)) {
|
|
37
|
-
db.exec(`ALTER TABLE runs ADD COLUMN ${name} TEXT`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function ensurePipelineDagColumn(db) {
|
|
42
|
-
const cols = db.prepare(`PRAGMA table_info(runs)`).all();
|
|
43
|
-
if (!cols.some((c) => c.name === "pipeline_dag_json")) {
|
|
44
|
-
db.exec(`ALTER TABLE runs ADD COLUMN pipeline_dag_json TEXT`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function ensureRunLocatorColumns(db) {
|
|
48
|
-
const cols = db.prepare(`PRAGMA table_info(runs)`).all();
|
|
49
|
-
const names = new Set(cols.map((c) => c.name));
|
|
50
|
-
for (const name of ["pipeline_path", "task_path", "project_root"]) {
|
|
51
|
-
if (!names.has(name)) {
|
|
52
|
-
db.exec(`ALTER TABLE runs ADD COLUMN ${name} TEXT`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
function ensureInlinePipelineColumn(db) {
|
|
57
|
-
const cols = db.prepare(`PRAGMA table_info(runs)`).all();
|
|
58
|
-
if (!cols.some((c) => c.name === "inline_pipeline_json")) {
|
|
59
|
-
db.exec(`ALTER TABLE runs ADD COLUMN inline_pipeline_json TEXT`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function ensureStageExecutionsTable(db) {
|
|
63
|
-
db.exec(`
|
|
64
|
-
CREATE TABLE IF NOT EXISTS stage_executions (
|
|
65
|
-
run_id TEXT NOT NULL,
|
|
66
|
-
stage_id TEXT NOT NULL,
|
|
67
|
-
attempt INTEGER NOT NULL,
|
|
68
|
-
status TEXT NOT NULL,
|
|
69
|
-
verification_outcome TEXT NOT NULL DEFAULT 'not_run',
|
|
70
|
-
started_at TEXT,
|
|
71
|
-
finished_at TEXT,
|
|
72
|
-
envelope_json TEXT,
|
|
73
|
-
PRIMARY KEY (run_id, stage_id, attempt),
|
|
74
|
-
FOREIGN KEY (run_id) REFERENCES runs(run_id)
|
|
75
|
-
);
|
|
76
|
-
CREATE INDEX IF NOT EXISTS idx_stage_executions_run_stage
|
|
77
|
-
ON stage_executions (run_id, stage_id, attempt);
|
|
78
|
-
`);
|
|
79
|
-
}
|
|
80
|
-
function ensureStageExecutionVerificationOutcomeColumn(db) {
|
|
81
|
-
const cols = db
|
|
82
|
-
.prepare(`PRAGMA table_info(stage_executions)`)
|
|
83
|
-
.all();
|
|
84
|
-
if (!cols.some((c) => c.name === "verification_outcome")) {
|
|
85
|
-
db.exec(`ALTER TABLE stage_executions ADD COLUMN verification_outcome TEXT NOT NULL DEFAULT 'not_run'`);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
function ensureStageExecutionCostColumns(db) {
|
|
89
|
-
const cols = db
|
|
90
|
-
.prepare(`PRAGMA table_info(stage_executions)`)
|
|
91
|
-
.all();
|
|
92
|
-
const names = new Set(cols.map((c) => c.name));
|
|
93
|
-
if (!names.has("cost_usd")) {
|
|
94
|
-
db.exec(`ALTER TABLE stage_executions ADD COLUMN cost_usd REAL`);
|
|
95
|
-
}
|
|
96
|
-
if (!names.has("usage_json")) {
|
|
97
|
-
db.exec(`ALTER TABLE stage_executions ADD COLUMN usage_json TEXT`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function backfillVerificationOutcomes(db) {
|
|
101
|
-
db.exec(`
|
|
102
|
-
UPDATE stage_executions
|
|
103
|
-
SET verification_outcome = CASE
|
|
104
|
-
WHEN status = 'succeeded'
|
|
105
|
-
AND EXISTS (
|
|
106
|
-
SELECT 1 FROM verification_check_results AS check_result
|
|
107
|
-
WHERE check_result.run_id = stage_executions.run_id
|
|
108
|
-
AND check_result.stage_id = stage_executions.stage_id
|
|
109
|
-
AND check_result.attempt = stage_executions.attempt
|
|
110
|
-
)
|
|
111
|
-
AND NOT EXISTS (
|
|
112
|
-
SELECT 1 FROM verification_check_results AS check_result
|
|
113
|
-
WHERE check_result.run_id = stage_executions.run_id
|
|
114
|
-
AND check_result.stage_id = stage_executions.stage_id
|
|
115
|
-
AND check_result.attempt = stage_executions.attempt
|
|
116
|
-
AND check_result.status != 'passed'
|
|
117
|
-
)
|
|
118
|
-
THEN 'passed'
|
|
119
|
-
WHEN status = 'failed'
|
|
120
|
-
AND EXISTS (
|
|
121
|
-
SELECT 1 FROM verification_check_results AS check_result
|
|
122
|
-
WHERE check_result.run_id = stage_executions.run_id
|
|
123
|
-
AND check_result.stage_id = stage_executions.stage_id
|
|
124
|
-
AND check_result.attempt = stage_executions.attempt
|
|
125
|
-
)
|
|
126
|
-
THEN 'failed'
|
|
127
|
-
ELSE verification_outcome
|
|
128
|
-
END
|
|
129
|
-
WHERE verification_outcome = 'not_run';
|
|
130
|
-
`);
|
|
131
|
-
}
|
|
132
|
-
function ensureStageEventsAttemptColumn(db) {
|
|
133
|
-
const cols = db
|
|
134
|
-
.prepare(`PRAGMA table_info(stage_events)`)
|
|
135
|
-
.all();
|
|
136
|
-
if (!cols.some((c) => c.name === "attempt")) {
|
|
137
|
-
db.exec(`ALTER TABLE stage_events ADD COLUMN attempt INTEGER NOT NULL DEFAULT 1`);
|
|
138
|
-
db.exec(`
|
|
139
|
-
CREATE INDEX IF NOT EXISTS idx_stage_events_run_stage_attempt_at
|
|
140
|
-
ON stage_events (run_id, stage_id, attempt, at);
|
|
141
|
-
`);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
function ensureVerificationCheckResultsTable(db) {
|
|
145
|
-
db.exec(`
|
|
146
|
-
CREATE TABLE IF NOT EXISTS verification_check_results (
|
|
147
|
-
run_id TEXT NOT NULL,
|
|
148
|
-
stage_id TEXT NOT NULL,
|
|
149
|
-
attempt INTEGER NOT NULL,
|
|
150
|
-
check_id TEXT NOT NULL,
|
|
151
|
-
check_type TEXT NOT NULL,
|
|
152
|
-
status TEXT NOT NULL,
|
|
153
|
-
started_at TEXT,
|
|
154
|
-
finished_at TEXT,
|
|
155
|
-
evidence_json TEXT,
|
|
156
|
-
PRIMARY KEY (run_id, stage_id, attempt, check_id),
|
|
157
|
-
FOREIGN KEY (run_id, stage_id, attempt)
|
|
158
|
-
REFERENCES stage_executions(run_id, stage_id, attempt)
|
|
159
|
-
);
|
|
160
|
-
CREATE INDEX IF NOT EXISTS idx_verification_check_results_execution
|
|
161
|
-
ON verification_check_results (run_id, stage_id, attempt, check_id);
|
|
162
|
-
`);
|
|
163
|
-
}
|
|
164
|
-
function ensureFeedbackReplayStagePassEnvelopeColumn(db) {
|
|
165
|
-
const cols = db
|
|
166
|
-
.prepare(`PRAGMA table_info(feedback_replay_stage_passes)`)
|
|
167
|
-
.all();
|
|
168
|
-
if (cols.length === 0)
|
|
169
|
-
return;
|
|
170
|
-
if (!cols.some((c) => c.name === "emitted_envelope_json")) {
|
|
171
|
-
db.exec(`ALTER TABLE feedback_replay_stage_passes ADD COLUMN emitted_envelope_json TEXT`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
function ensureFeedbackReplayStagePassSessionOriginColumn(db) {
|
|
175
|
-
const cols = db
|
|
176
|
-
.prepare(`PRAGMA table_info(feedback_replay_stage_passes)`)
|
|
177
|
-
.all();
|
|
178
|
-
if (cols.length === 0)
|
|
179
|
-
return;
|
|
180
|
-
if (!cols.some((c) => c.name === "session_origin_attempt")) {
|
|
181
|
-
db.exec(`ALTER TABLE feedback_replay_stage_passes ADD COLUMN session_origin_attempt INTEGER`);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
function ensureFeedbackLoopDeferredSendBackColumn(db) {
|
|
185
|
-
const cols = db
|
|
186
|
-
.prepare(`PRAGMA table_info(feedback_loops)`)
|
|
187
|
-
.all();
|
|
188
|
-
if (cols.length === 0)
|
|
189
|
-
return;
|
|
190
|
-
if (!cols.some((c) => c.name === "deferred_send_back_json")) {
|
|
191
|
-
db.exec(`ALTER TABLE feedback_loops ADD COLUMN deferred_send_back_json TEXT`);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
18
|
function executionFromRow(row) {
|
|
195
19
|
return {
|
|
196
20
|
run_id: row.run_id,
|
|
@@ -204,7 +28,10 @@ function executionFromRow(row) {
|
|
|
204
28
|
? JSON.parse(row.envelope_json)
|
|
205
29
|
: null,
|
|
206
30
|
...(row.cost_usd != null ? { cost_usd: row.cost_usd } : {}),
|
|
207
|
-
...(row.usage_json != null
|
|
31
|
+
...(row.usage_json != null
|
|
32
|
+
? { usage: JSON.parse(row.usage_json) }
|
|
33
|
+
: {}),
|
|
34
|
+
auto_resume_count: row.auto_resume_count ?? 0,
|
|
208
35
|
};
|
|
209
36
|
}
|
|
210
37
|
function verificationCheckResultFromRow(row) {
|
|
@@ -245,6 +72,18 @@ function feedbackLoopFromRow(row) {
|
|
|
245
72
|
updated_at: row.updated_at,
|
|
246
73
|
};
|
|
247
74
|
}
|
|
75
|
+
function triggerFromRow(row) {
|
|
76
|
+
return {
|
|
77
|
+
id: row.id,
|
|
78
|
+
definition_ref: row.definition_ref,
|
|
79
|
+
enabled: row.enabled !== 0,
|
|
80
|
+
...(row.last_fired_at != null ? { last_fired_at: row.last_fired_at } : {}),
|
|
81
|
+
...(row.last_run_id != null ? { last_run_id: row.last_run_id } : {}),
|
|
82
|
+
...(row.next_run_at != null ? { next_run_at: row.next_run_at } : {}),
|
|
83
|
+
created_at: row.created_at,
|
|
84
|
+
updated_at: row.updated_at,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
248
87
|
function feedbackReplayFromRow(row) {
|
|
249
88
|
return {
|
|
250
89
|
run_id: row.run_id,
|
|
@@ -300,33 +139,44 @@ export class SqliteRunStore {
|
|
|
300
139
|
storeRoot;
|
|
301
140
|
db;
|
|
302
141
|
migratePromise;
|
|
303
|
-
constructor(storeRoot) {
|
|
142
|
+
constructor(storeRoot, options) {
|
|
304
143
|
this.storeRoot = storeRoot;
|
|
144
|
+
const openerMode = options?.openerMode ??
|
|
145
|
+
(process.env.VITEST === "true" ? "migrate" : "assert");
|
|
305
146
|
const dbPath = path.join(storeRoot, "state.db");
|
|
147
|
+
if (openerMode === "assert") {
|
|
148
|
+
if (!existsSync(dbPath)) {
|
|
149
|
+
throw new StoreSchemaError("store_schema_migration_required: database file is missing", "store_schema_migration_required");
|
|
150
|
+
}
|
|
151
|
+
this.db = new Database(dbPath);
|
|
152
|
+
applyStorePragmas(this.db);
|
|
153
|
+
assertSchemaVersion(this.db);
|
|
154
|
+
this.migratePromise = Promise.resolve();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
306
157
|
this.db = new Database(dbPath);
|
|
307
|
-
this.db
|
|
308
|
-
this.db
|
|
309
|
-
this.db.exec(SCHEMA_SQL);
|
|
310
|
-
ensureCheckoutRootColumn(this.db);
|
|
311
|
-
ensureCiIdentityColumns(this.db);
|
|
312
|
-
ensurePipelineDagColumn(this.db);
|
|
313
|
-
ensureRunLocatorColumns(this.db);
|
|
314
|
-
ensureInlinePipelineColumn(this.db);
|
|
315
|
-
ensureStageExecutionsTable(this.db);
|
|
316
|
-
ensureStageExecutionVerificationOutcomeColumn(this.db);
|
|
317
|
-
ensureStageExecutionCostColumns(this.db);
|
|
318
|
-
ensureStageEventsAttemptColumn(this.db);
|
|
319
|
-
ensureVerificationCheckResultsTable(this.db);
|
|
320
|
-
ensureFeedbackReplayStagePassEnvelopeColumn(this.db);
|
|
321
|
-
ensureFeedbackReplayStagePassSessionOriginColumn(this.db);
|
|
322
|
-
ensureFeedbackLoopDeferredSendBackColumn(this.db);
|
|
323
|
-
backfillVerificationOutcomes(this.db);
|
|
158
|
+
applyStorePragmas(this.db);
|
|
159
|
+
applyPendingMigrations(this.db);
|
|
324
160
|
this.migratePromise = importDiskRunsIfEmpty(this.db, storeRoot).then(() => undefined);
|
|
325
161
|
}
|
|
326
162
|
/** Await one-shot disk import before catalog reads (create paths also wait). */
|
|
327
163
|
async ready() {
|
|
328
164
|
await this.migratePromise;
|
|
329
165
|
}
|
|
166
|
+
async close() {
|
|
167
|
+
await this.ready();
|
|
168
|
+
this.db.pragma("wal_checkpoint(TRUNCATE)");
|
|
169
|
+
this.db.close();
|
|
170
|
+
}
|
|
171
|
+
async snapshotInto(destPath) {
|
|
172
|
+
await this.ready();
|
|
173
|
+
const userVersion = this.db.pragma("user_version", {
|
|
174
|
+
simple: true,
|
|
175
|
+
});
|
|
176
|
+
const escaped = destPath.replace(/'/g, "''");
|
|
177
|
+
this.db.exec(`VACUUM INTO '${escaped}'`);
|
|
178
|
+
return { userVersion };
|
|
179
|
+
}
|
|
330
180
|
/**
|
|
331
181
|
* The connection this store owns, for the one caller allowed to share it: the composition root
|
|
332
182
|
* wiring the A2A tables into the same `state.db` file. Not part of the `RunStore` interface.
|
|
@@ -339,7 +189,7 @@ export class SqliteRunStore {
|
|
|
339
189
|
}
|
|
340
190
|
async createRun(input) {
|
|
341
191
|
await this.ready();
|
|
342
|
-
const runId = newRunId();
|
|
192
|
+
const runId = input.runId ?? newRunId();
|
|
343
193
|
const workspaceDir = this.getWorkspaceDir(runId);
|
|
344
194
|
await mkdir(path.join(workspaceDir, "stages"), { recursive: true });
|
|
345
195
|
const now = new Date().toISOString();
|
|
@@ -352,6 +202,12 @@ export class SqliteRunStore {
|
|
|
352
202
|
const projectRoot = input.projectRoot
|
|
353
203
|
? normalizeCatalogPath(input.projectRoot)
|
|
354
204
|
: null;
|
|
205
|
+
const pipelineBody = input.pipelineBody ??
|
|
206
|
+
(input.inlinePipeline !== undefined
|
|
207
|
+
? JSON.stringify(input.inlinePipeline)
|
|
208
|
+
: null);
|
|
209
|
+
const pipelineSource = input.pipelineSource ??
|
|
210
|
+
(pipelineBody != null && pipelinePath == null ? "inline" : null);
|
|
355
211
|
this.db.transaction(() => {
|
|
356
212
|
if (input.submission) {
|
|
357
213
|
const existing = this.readSubmission(input.submission.key);
|
|
@@ -360,15 +216,15 @@ export class SqliteRunStore {
|
|
|
360
216
|
}
|
|
361
217
|
this.db
|
|
362
218
|
.prepare(`INSERT INTO runs
|
|
363
|
-
(run_id, pipeline_id, task_id, task_yaml, status, created_at, updated_at, checkout_root, pipeline_dag_json, git_sha, ci_pr_url, ci_job_url, pipeline_path, task_path, project_root,
|
|
219
|
+
(run_id, pipeline_id, task_id, task_yaml, status, created_at, updated_at, checkout_root, pipeline_dag_json, git_sha, ci_pr_url, ci_job_url, pipeline_path, task_path, project_root, repository, ref, resolved_sha, run_branch, git_author_name, git_author_email, pipeline_source, pipeline_body, caller_id, run_manifest, skip_gates)
|
|
364
220
|
VALUES
|
|
365
|
-
(@run_id, @pipeline_id, @task_id, @task_yaml, @status, @created_at, @updated_at, @checkout_root, @pipeline_dag_json, @git_sha, @ci_pr_url, @ci_job_url, @pipeline_path, @task_path, @project_root, @
|
|
221
|
+
(@run_id, @pipeline_id, @task_id, @task_yaml, @status, @created_at, @updated_at, @checkout_root, @pipeline_dag_json, @git_sha, @ci_pr_url, @ci_job_url, @pipeline_path, @task_path, @project_root, @repository, @ref, @resolved_sha, @run_branch, @git_author_name, @git_author_email, @pipeline_source, @pipeline_body, @caller_id, @run_manifest, @skip_gates)`)
|
|
366
222
|
.run({
|
|
367
223
|
run_id: runId,
|
|
368
224
|
pipeline_id: input.pipelineId,
|
|
369
225
|
task_id: input.taskId ?? null,
|
|
370
226
|
task_yaml: input.taskYaml,
|
|
371
|
-
status: "running",
|
|
227
|
+
status: input.status ?? "running",
|
|
372
228
|
created_at: now,
|
|
373
229
|
updated_at: now,
|
|
374
230
|
checkout_root: input.checkoutRoot ?? null,
|
|
@@ -381,9 +237,19 @@ export class SqliteRunStore {
|
|
|
381
237
|
pipeline_path: pipelinePath,
|
|
382
238
|
task_path: taskPath,
|
|
383
239
|
project_root: projectRoot,
|
|
384
|
-
|
|
385
|
-
|
|
240
|
+
repository: input.repository ?? null,
|
|
241
|
+
ref: input.ref ?? null,
|
|
242
|
+
resolved_sha: input.resolvedSha ?? null,
|
|
243
|
+
run_branch: input.runBranch ?? null,
|
|
244
|
+
git_author_name: input.gitAuthorName ?? null,
|
|
245
|
+
git_author_email: input.gitAuthorEmail ?? null,
|
|
246
|
+
pipeline_source: pipelineSource,
|
|
247
|
+
pipeline_body: pipelineBody,
|
|
248
|
+
caller_id: input.callerId ?? null,
|
|
249
|
+
run_manifest: input.runManifest !== undefined
|
|
250
|
+
? JSON.stringify(input.runManifest)
|
|
386
251
|
: null,
|
|
252
|
+
skip_gates: input.skipGates === undefined ? null : input.skipGates ? 1 : 0,
|
|
387
253
|
});
|
|
388
254
|
if (input.submission) {
|
|
389
255
|
this.db.prepare("INSERT INTO run_submissions (submission_key, request_hash, run_id) VALUES (?, ?, ?)")
|
|
@@ -403,17 +269,198 @@ export class SqliteRunStore {
|
|
|
403
269
|
}
|
|
404
270
|
async updateRunStatus(runId, status) {
|
|
405
271
|
await this.ready();
|
|
272
|
+
const now = new Date().toISOString();
|
|
273
|
+
const isTerminal = status === "succeeded" || status === "failed" || status === "cancelled";
|
|
274
|
+
const result = isTerminal
|
|
275
|
+
? this.db
|
|
276
|
+
.prepare(`UPDATE runs SET status = @status, updated_at = @updated_at,
|
|
277
|
+
finished_at = COALESCE(finished_at, @finished_at)
|
|
278
|
+
WHERE run_id = @run_id`)
|
|
279
|
+
.run({
|
|
280
|
+
run_id: runId,
|
|
281
|
+
status,
|
|
282
|
+
updated_at: now,
|
|
283
|
+
finished_at: now,
|
|
284
|
+
})
|
|
285
|
+
: this.db
|
|
286
|
+
.prepare(`UPDATE runs SET status = @status, updated_at = @updated_at WHERE run_id = @run_id`)
|
|
287
|
+
.run({
|
|
288
|
+
run_id: runId,
|
|
289
|
+
status,
|
|
290
|
+
updated_at: now,
|
|
291
|
+
});
|
|
292
|
+
if (result.changes === 0) {
|
|
293
|
+
throw new Error(`Run not found: ${runId}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async tryUpdateRunStatus(runId, status, expectedStatus) {
|
|
297
|
+
await this.ready();
|
|
298
|
+
const now = new Date().toISOString();
|
|
299
|
+
const isTerminal = status === "succeeded" || status === "failed" || status === "cancelled";
|
|
300
|
+
const result = isTerminal
|
|
301
|
+
? this.db
|
|
302
|
+
.prepare(`UPDATE runs SET status = @status, updated_at = @updated_at,
|
|
303
|
+
finished_at = COALESCE(finished_at, @finished_at)
|
|
304
|
+
WHERE run_id = @run_id AND status = @expected_status`)
|
|
305
|
+
.run({
|
|
306
|
+
run_id: runId,
|
|
307
|
+
status,
|
|
308
|
+
expected_status: expectedStatus,
|
|
309
|
+
updated_at: now,
|
|
310
|
+
finished_at: now,
|
|
311
|
+
})
|
|
312
|
+
: this.db
|
|
313
|
+
.prepare(`UPDATE runs SET status = @status, updated_at = @updated_at
|
|
314
|
+
WHERE run_id = @run_id AND status = @expected_status`)
|
|
315
|
+
.run({
|
|
316
|
+
run_id: runId,
|
|
317
|
+
status,
|
|
318
|
+
expected_status: expectedStatus,
|
|
319
|
+
updated_at: now,
|
|
320
|
+
});
|
|
321
|
+
if (result.changes > 0)
|
|
322
|
+
return true;
|
|
323
|
+
const exists = this.db
|
|
324
|
+
.prepare(`SELECT 1 AS ok FROM runs WHERE run_id = ?`)
|
|
325
|
+
.get(runId);
|
|
326
|
+
if (exists === undefined) {
|
|
327
|
+
throw new Error(`Run not found: ${runId}`);
|
|
328
|
+
}
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
async patchRunWorkspaceBinding(runId, patch) {
|
|
332
|
+
await this.ready();
|
|
333
|
+
const sets = ["updated_at = @updated_at"];
|
|
334
|
+
const params = {
|
|
335
|
+
run_id: runId,
|
|
336
|
+
updated_at: new Date().toISOString(),
|
|
337
|
+
};
|
|
338
|
+
if (patch.checkoutRoot !== undefined) {
|
|
339
|
+
sets.push("checkout_root = @checkout_root");
|
|
340
|
+
params.checkout_root = patch.checkoutRoot;
|
|
341
|
+
}
|
|
342
|
+
if (patch.repository !== undefined) {
|
|
343
|
+
sets.push("repository = @repository");
|
|
344
|
+
params.repository = patch.repository;
|
|
345
|
+
}
|
|
346
|
+
if (patch.ref !== undefined) {
|
|
347
|
+
sets.push("ref = @ref");
|
|
348
|
+
params.ref = patch.ref;
|
|
349
|
+
}
|
|
350
|
+
if (patch.resolvedSha !== undefined) {
|
|
351
|
+
sets.push("resolved_sha = @resolved_sha");
|
|
352
|
+
params.resolved_sha = patch.resolvedSha;
|
|
353
|
+
}
|
|
354
|
+
if (patch.runBranch !== undefined) {
|
|
355
|
+
sets.push("run_branch = @run_branch");
|
|
356
|
+
params.run_branch = patch.runBranch;
|
|
357
|
+
}
|
|
358
|
+
if (sets.length === 1) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
406
361
|
const result = this.db
|
|
407
|
-
.prepare(`UPDATE runs SET
|
|
362
|
+
.prepare(`UPDATE runs SET ${sets.join(", ")} WHERE run_id = @run_id`)
|
|
363
|
+
.run(params);
|
|
364
|
+
if (result.changes === 0) {
|
|
365
|
+
throw new Error(`Run not found: ${runId}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
async appendConfigOrigins(runId, origins) {
|
|
369
|
+
await this.ready();
|
|
370
|
+
if (origins.length === 0)
|
|
371
|
+
return;
|
|
372
|
+
const row = this.getRunRow(runId);
|
|
373
|
+
const existing = row.config_origins_json
|
|
374
|
+
? JSON.parse(row.config_origins_json)
|
|
375
|
+
: [];
|
|
376
|
+
const keyOf = (o) => `${o.name}\0${o.origin}\0${o.path ?? ""}`;
|
|
377
|
+
const seen = new Set(existing.map(keyOf));
|
|
378
|
+
const merged = [...existing];
|
|
379
|
+
for (const origin of origins) {
|
|
380
|
+
const key = keyOf(origin);
|
|
381
|
+
if (seen.has(key))
|
|
382
|
+
continue;
|
|
383
|
+
seen.add(key);
|
|
384
|
+
merged.push(origin);
|
|
385
|
+
}
|
|
386
|
+
if (merged.length === existing.length)
|
|
387
|
+
return;
|
|
388
|
+
const result = this.db
|
|
389
|
+
.prepare(`UPDATE runs SET config_origins_json = @config_origins_json, updated_at = @updated_at WHERE run_id = @run_id`)
|
|
408
390
|
.run({
|
|
409
391
|
run_id: runId,
|
|
410
|
-
|
|
392
|
+
config_origins_json: JSON.stringify(merged),
|
|
393
|
+
updated_at: new Date().toISOString(),
|
|
394
|
+
});
|
|
395
|
+
if (result.changes === 0) {
|
|
396
|
+
throw new Error(`Run not found: ${runId}`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
async setCancelReason(runId, reason) {
|
|
400
|
+
await this.ready();
|
|
401
|
+
const result = this.db
|
|
402
|
+
.prepare(`UPDATE runs SET cancel_reason = @cancel_reason, updated_at = @updated_at WHERE run_id = @run_id`)
|
|
403
|
+
.run({
|
|
404
|
+
run_id: runId,
|
|
405
|
+
cancel_reason: reason,
|
|
411
406
|
updated_at: new Date().toISOString(),
|
|
412
407
|
});
|
|
413
408
|
if (result.changes === 0) {
|
|
414
409
|
throw new Error(`Run not found: ${runId}`);
|
|
415
410
|
}
|
|
416
411
|
}
|
|
412
|
+
async setRunDiskUsage(runId, diskBytes, measuredAt) {
|
|
413
|
+
await this.ready();
|
|
414
|
+
const result = this.db
|
|
415
|
+
.prepare(`UPDATE runs SET disk_bytes = @disk_bytes, disk_measured_at = @disk_measured_at
|
|
416
|
+
WHERE run_id = @run_id`)
|
|
417
|
+
.run({
|
|
418
|
+
run_id: runId,
|
|
419
|
+
disk_bytes: diskBytes,
|
|
420
|
+
disk_measured_at: measuredAt,
|
|
421
|
+
});
|
|
422
|
+
if (result.changes === 0) {
|
|
423
|
+
throw new Error(`Run not found: ${runId}`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
async setSlimmedAt(runId, slimmedAt) {
|
|
427
|
+
await this.ready();
|
|
428
|
+
const result = this.db
|
|
429
|
+
.prepare(`UPDATE runs SET slimmed_at = @slimmed_at WHERE run_id = @run_id`)
|
|
430
|
+
.run({
|
|
431
|
+
run_id: runId,
|
|
432
|
+
slimmed_at: slimmedAt,
|
|
433
|
+
});
|
|
434
|
+
if (result.changes === 0) {
|
|
435
|
+
throw new Error(`Run not found: ${runId}`);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
async deleteRun(runId) {
|
|
439
|
+
await this.ready();
|
|
440
|
+
const deleteAll = this.db.transaction(() => {
|
|
441
|
+
const exists = this.db
|
|
442
|
+
.prepare(`SELECT 1 AS ok FROM runs WHERE run_id = ?`)
|
|
443
|
+
.get(runId);
|
|
444
|
+
if (exists === undefined) {
|
|
445
|
+
throw new Error(`Run not found: ${runId}`);
|
|
446
|
+
}
|
|
447
|
+
this.db.prepare(`DELETE FROM stage_events WHERE run_id = ?`).run(runId);
|
|
448
|
+
this.db
|
|
449
|
+
.prepare(`DELETE FROM verification_check_results WHERE run_id = ?`)
|
|
450
|
+
.run(runId);
|
|
451
|
+
this.db.prepare(`DELETE FROM stage_executions WHERE run_id = ?`).run(runId);
|
|
452
|
+
this.db
|
|
453
|
+
.prepare(`DELETE FROM feedback_replay_stage_passes WHERE run_id = ?`)
|
|
454
|
+
.run(runId);
|
|
455
|
+
this.db.prepare(`DELETE FROM fork_generations WHERE run_id = ?`).run(runId);
|
|
456
|
+
this.db.prepare(`DELETE FROM feedback_replays WHERE run_id = ?`).run(runId);
|
|
457
|
+
this.db.prepare(`DELETE FROM feedback_loops WHERE run_id = ?`).run(runId);
|
|
458
|
+
this.db.prepare(`DELETE FROM stages WHERE run_id = ?`).run(runId);
|
|
459
|
+
this.db.prepare(`DELETE FROM run_submissions WHERE run_id = ?`).run(runId);
|
|
460
|
+
this.db.prepare(`DELETE FROM runs WHERE run_id = ?`).run(runId);
|
|
461
|
+
});
|
|
462
|
+
deleteAll();
|
|
463
|
+
}
|
|
417
464
|
async updatePipelineDag(runId, dag) {
|
|
418
465
|
await this.ready();
|
|
419
466
|
const result = this.db
|
|
@@ -435,6 +482,25 @@ export class SqliteRunStore {
|
|
|
435
482
|
await this.ready();
|
|
436
483
|
return this.getRunRow(runId).task_yaml;
|
|
437
484
|
}
|
|
485
|
+
async readPipelineBody(runId) {
|
|
486
|
+
await this.ready();
|
|
487
|
+
return this.getRunRow(runId).pipeline_body;
|
|
488
|
+
}
|
|
489
|
+
async updateRunManifest(runId, manifest) {
|
|
490
|
+
await this.ready();
|
|
491
|
+
const result = this.db
|
|
492
|
+
.prepare(`UPDATE runs SET run_manifest = @run_manifest, updated_at = @updated_at WHERE run_id = @run_id`)
|
|
493
|
+
.run({
|
|
494
|
+
run_id: runId,
|
|
495
|
+
run_manifest: manifest === null || manifest === undefined
|
|
496
|
+
? null
|
|
497
|
+
: JSON.stringify(manifest),
|
|
498
|
+
updated_at: new Date().toISOString(),
|
|
499
|
+
});
|
|
500
|
+
if (result.changes === 0) {
|
|
501
|
+
throw new Error(`Run not found: ${runId}`);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
438
504
|
async ensureStageWorkspace(runId, stageId) {
|
|
439
505
|
await this.ready();
|
|
440
506
|
this.getRunRow(runId);
|
|
@@ -485,7 +551,7 @@ export class SqliteRunStore {
|
|
|
485
551
|
verification_outcome: "not_run",
|
|
486
552
|
});
|
|
487
553
|
const row = this.db
|
|
488
|
-
.prepare(`SELECT
|
|
554
|
+
.prepare(`SELECT ${EXECUTION_SELECT_COLS}
|
|
489
555
|
FROM stage_executions
|
|
490
556
|
WHERE run_id = ? AND stage_id = ? AND attempt = ?`)
|
|
491
557
|
.get(runId, stageId, attempt);
|
|
@@ -495,7 +561,7 @@ export class SqliteRunStore {
|
|
|
495
561
|
async listStageExecutions(runId, stageId) {
|
|
496
562
|
await this.ready();
|
|
497
563
|
const rows = this.db
|
|
498
|
-
.prepare(`SELECT
|
|
564
|
+
.prepare(`SELECT ${EXECUTION_SELECT_COLS}
|
|
499
565
|
FROM stage_executions
|
|
500
566
|
WHERE run_id = ? AND stage_id = ?
|
|
501
567
|
ORDER BY attempt ASC`)
|
|
@@ -505,7 +571,7 @@ export class SqliteRunStore {
|
|
|
505
571
|
async getLatestStageExecution(runId, stageId) {
|
|
506
572
|
await this.ready();
|
|
507
573
|
const row = this.db
|
|
508
|
-
.prepare(`SELECT
|
|
574
|
+
.prepare(`SELECT ${EXECUTION_SELECT_COLS}
|
|
509
575
|
FROM stage_executions
|
|
510
576
|
WHERE run_id = ? AND stage_id = ?
|
|
511
577
|
ORDER BY attempt DESC
|
|
@@ -524,7 +590,7 @@ export class SqliteRunStore {
|
|
|
524
590
|
async getStageExecution(runId, stageId, attempt) {
|
|
525
591
|
await this.ready();
|
|
526
592
|
const row = this.db
|
|
527
|
-
.prepare(`SELECT
|
|
593
|
+
.prepare(`SELECT ${EXECUTION_SELECT_COLS}
|
|
528
594
|
FROM stage_executions
|
|
529
595
|
WHERE run_id = ? AND stage_id = ? AND attempt = ?`)
|
|
530
596
|
.get(runId, stageId, attempt);
|
|
@@ -533,6 +599,21 @@ export class SqliteRunStore {
|
|
|
533
599
|
}
|
|
534
600
|
return executionFromRow(row);
|
|
535
601
|
}
|
|
602
|
+
async listInterruptedStageExecutions() {
|
|
603
|
+
await this.ready();
|
|
604
|
+
const rows = this.db
|
|
605
|
+
.prepare(`SELECT ${EXECUTION_SELECT_COLS}
|
|
606
|
+
FROM stage_executions e
|
|
607
|
+
WHERE e.status = 'interrupted'
|
|
608
|
+
AND e.attempt = (
|
|
609
|
+
SELECT MAX(e2.attempt)
|
|
610
|
+
FROM stage_executions e2
|
|
611
|
+
WHERE e2.run_id = e.run_id AND e2.stage_id = e.stage_id
|
|
612
|
+
)
|
|
613
|
+
ORDER BY e.run_id ASC, e.stage_id ASC, e.attempt ASC`)
|
|
614
|
+
.all();
|
|
615
|
+
return rows.map(executionFromRow);
|
|
616
|
+
}
|
|
536
617
|
async updateStageExecution(runId, stageId, attempt, patch) {
|
|
537
618
|
await this.ready();
|
|
538
619
|
const sets = [];
|
|
@@ -570,6 +651,10 @@ export class SqliteRunStore {
|
|
|
570
651
|
sets.push("usage_json = @usage_json");
|
|
571
652
|
params.usage_json = JSON.stringify(patch.usage);
|
|
572
653
|
}
|
|
654
|
+
if (patch.auto_resume_count !== undefined) {
|
|
655
|
+
sets.push("auto_resume_count = @auto_resume_count");
|
|
656
|
+
params.auto_resume_count = patch.auto_resume_count;
|
|
657
|
+
}
|
|
573
658
|
if (sets.length === 0)
|
|
574
659
|
return;
|
|
575
660
|
const result = this.db
|
|
@@ -746,9 +831,13 @@ export class SqliteRunStore {
|
|
|
746
831
|
clauses.push("(pipeline_id = ? OR pipeline_path = ? OR pipeline_path = ?)");
|
|
747
832
|
params.push(pipeline, pipeline, normalized);
|
|
748
833
|
}
|
|
834
|
+
if (filter?.caller_id !== undefined) {
|
|
835
|
+
clauses.push("caller_id = ?");
|
|
836
|
+
params.push(filter.caller_id);
|
|
837
|
+
}
|
|
749
838
|
const where = clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
750
839
|
const rows = this.db
|
|
751
|
-
.prepare(`SELECT run_id, pipeline_id, task_id, task_yaml, status, created_at, updated_at, checkout_root, pipeline_dag_json, git_sha, ci_pr_url, ci_job_url, pipeline_path, task_path, project_root,
|
|
840
|
+
.prepare(`SELECT run_id, pipeline_id, task_id, task_yaml, status, created_at, updated_at, checkout_root, pipeline_dag_json, git_sha, ci_pr_url, ci_job_url, pipeline_path, task_path, project_root, repository, ref, resolved_sha, run_branch, git_author_name, git_author_email, cancel_reason, finished_at, slimmed_at, disk_bytes, disk_measured_at, config_origins_json, pipeline_source, pipeline_body, caller_id, run_manifest, skip_gates
|
|
752
841
|
FROM runs ${where} ORDER BY created_at DESC`)
|
|
753
842
|
.all(...params);
|
|
754
843
|
const summaries = [];
|
|
@@ -762,13 +851,115 @@ export class SqliteRunStore {
|
|
|
762
851
|
}
|
|
763
852
|
return summaries;
|
|
764
853
|
}
|
|
765
|
-
async
|
|
854
|
+
async ensureProject(absPath) {
|
|
855
|
+
await this.ready();
|
|
856
|
+
const resolved = path.resolve(absPath);
|
|
857
|
+
let st;
|
|
858
|
+
try {
|
|
859
|
+
st = statSync(resolved);
|
|
860
|
+
}
|
|
861
|
+
catch {
|
|
862
|
+
throw new Error(`project_root does not exist: ${resolved}`);
|
|
863
|
+
}
|
|
864
|
+
if (!st.isDirectory()) {
|
|
865
|
+
throw new Error(`project_root is not a directory: ${resolved}`);
|
|
866
|
+
}
|
|
867
|
+
const normalized = normalizeProjectRoot(absPath);
|
|
868
|
+
if (normalized === path.parse(normalized).root) {
|
|
869
|
+
throw new Error(`project_root must not be filesystem root: ${normalized}`);
|
|
870
|
+
}
|
|
871
|
+
const now = new Date().toISOString();
|
|
872
|
+
this.db
|
|
873
|
+
.prepare(`INSERT INTO projects (project_root, created_at) VALUES (?, ?)
|
|
874
|
+
ON CONFLICT(project_root) DO NOTHING`)
|
|
875
|
+
.run(normalized, now);
|
|
876
|
+
return normalized;
|
|
877
|
+
}
|
|
878
|
+
async listRegisteredProjects() {
|
|
766
879
|
await this.ready();
|
|
767
880
|
const rows = this.db
|
|
768
|
-
.prepare(`SELECT
|
|
881
|
+
.prepare(`SELECT project_root FROM projects ORDER BY project_root`)
|
|
769
882
|
.all();
|
|
770
883
|
return rows.map((row) => row.project_root);
|
|
771
884
|
}
|
|
885
|
+
async upsertTrigger(input) {
|
|
886
|
+
await this.ready();
|
|
887
|
+
const now = new Date().toISOString();
|
|
888
|
+
this.db
|
|
889
|
+
.prepare(`INSERT INTO triggers (id, definition_ref, enabled, created_at, updated_at)
|
|
890
|
+
VALUES (@id, @definition_ref, @enabled, @created_at, @updated_at)
|
|
891
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
892
|
+
definition_ref = @definition_ref,
|
|
893
|
+
enabled = @enabled,
|
|
894
|
+
updated_at = @updated_at`)
|
|
895
|
+
.run({
|
|
896
|
+
id: input.id,
|
|
897
|
+
definition_ref: input.definitionRef,
|
|
898
|
+
enabled: input.enabled ? 1 : 0,
|
|
899
|
+
created_at: now,
|
|
900
|
+
updated_at: now,
|
|
901
|
+
});
|
|
902
|
+
const record = await this.getTrigger(input.id);
|
|
903
|
+
if (!record)
|
|
904
|
+
throw new Error(`Trigger not found after upsert: ${input.id}`);
|
|
905
|
+
return record;
|
|
906
|
+
}
|
|
907
|
+
async getTrigger(id) {
|
|
908
|
+
await this.ready();
|
|
909
|
+
const row = this.db
|
|
910
|
+
.prepare(`SELECT id, definition_ref, enabled, last_fired_at, last_run_id, next_run_at, created_at, updated_at
|
|
911
|
+
FROM triggers WHERE id = ?`)
|
|
912
|
+
.get(id);
|
|
913
|
+
return row ? triggerFromRow(row) : null;
|
|
914
|
+
}
|
|
915
|
+
async listTriggers() {
|
|
916
|
+
await this.ready();
|
|
917
|
+
const rows = this.db
|
|
918
|
+
.prepare(`SELECT id, definition_ref, enabled, last_fired_at, last_run_id, next_run_at, created_at, updated_at
|
|
919
|
+
FROM triggers ORDER BY id`)
|
|
920
|
+
.all();
|
|
921
|
+
return rows.map(triggerFromRow);
|
|
922
|
+
}
|
|
923
|
+
async recordTriggerFired(id, runId) {
|
|
924
|
+
await this.ready();
|
|
925
|
+
const now = new Date().toISOString();
|
|
926
|
+
const result = this.db
|
|
927
|
+
.prepare(`UPDATE triggers SET last_fired_at = @last_fired_at, last_run_id = @last_run_id, updated_at = @updated_at
|
|
928
|
+
WHERE id = @id`)
|
|
929
|
+
.run({ id, last_fired_at: now, last_run_id: runId, updated_at: now });
|
|
930
|
+
if (result.changes === 0) {
|
|
931
|
+
throw new Error(`Trigger not found: ${id}`);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
async setTriggerNextRun(id, nextRunAt) {
|
|
935
|
+
await this.ready();
|
|
936
|
+
const now = new Date().toISOString();
|
|
937
|
+
const result = this.db
|
|
938
|
+
.prepare(`UPDATE triggers SET next_run_at = @next_run_at, updated_at = @updated_at
|
|
939
|
+
WHERE id = @id`)
|
|
940
|
+
.run({ id, next_run_at: nextRunAt, updated_at: now });
|
|
941
|
+
if (result.changes === 0) {
|
|
942
|
+
throw new Error(`Trigger not found: ${id}`);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
async getTriggerAdapterState(triggerId, key) {
|
|
946
|
+
await this.ready();
|
|
947
|
+
const row = this.db
|
|
948
|
+
.prepare(`SELECT value FROM trigger_adapter_state WHERE trigger_id = ? AND key = ?`)
|
|
949
|
+
.get(triggerId, key);
|
|
950
|
+
return row ? row.value : null;
|
|
951
|
+
}
|
|
952
|
+
async setTriggerAdapterState(triggerId, key, value) {
|
|
953
|
+
await this.ready();
|
|
954
|
+
const now = new Date().toISOString();
|
|
955
|
+
this.db
|
|
956
|
+
.prepare(`INSERT INTO trigger_adapter_state (trigger_id, key, value, updated_at)
|
|
957
|
+
VALUES (@trigger_id, @key, @value, @updated_at)
|
|
958
|
+
ON CONFLICT(trigger_id, key) DO UPDATE SET
|
|
959
|
+
value = @value,
|
|
960
|
+
updated_at = @updated_at`)
|
|
961
|
+
.run({ trigger_id: triggerId, key, value, updated_at: now });
|
|
962
|
+
}
|
|
772
963
|
async readRun(runId) {
|
|
773
964
|
await this.ready();
|
|
774
965
|
const row = this.getRunRow(runId);
|
|
@@ -1176,15 +1367,47 @@ export class SqliteRunStore {
|
|
|
1176
1367
|
...(row.pipeline_path != null ? { pipeline_path: row.pipeline_path } : {}),
|
|
1177
1368
|
...(row.task_path != null ? { task_path: row.task_path } : {}),
|
|
1178
1369
|
...(row.project_root != null ? { project_root: row.project_root } : {}),
|
|
1370
|
+
...(row.repository != null ? { repository: row.repository } : {}),
|
|
1371
|
+
...(row.ref != null ? { ref: row.ref } : {}),
|
|
1372
|
+
...(row.resolved_sha != null ? { resolved_sha: row.resolved_sha } : {}),
|
|
1373
|
+
...(row.run_branch != null ? { run_branch: row.run_branch } : {}),
|
|
1374
|
+
...(row.git_author_name != null
|
|
1375
|
+
? { git_author_name: row.git_author_name }
|
|
1376
|
+
: {}),
|
|
1377
|
+
...(row.git_author_email != null
|
|
1378
|
+
? { git_author_email: row.git_author_email }
|
|
1379
|
+
: {}),
|
|
1380
|
+
...(row.cancel_reason != null ? { cancel_reason: row.cancel_reason } : {}),
|
|
1381
|
+
...(row.finished_at != null ? { finished_at: row.finished_at } : {}),
|
|
1382
|
+
...(row.slimmed_at != null ? { slimmed_at: row.slimmed_at } : {}),
|
|
1383
|
+
...(row.disk_bytes != null ? { disk_bytes: row.disk_bytes } : {}),
|
|
1384
|
+
...(row.disk_measured_at != null
|
|
1385
|
+
? { disk_measured_at: row.disk_measured_at }
|
|
1386
|
+
: {}),
|
|
1387
|
+
...(row.config_origins_json
|
|
1388
|
+
? {
|
|
1389
|
+
config_origins: JSON.parse(row.config_origins_json),
|
|
1390
|
+
}
|
|
1391
|
+
: {}),
|
|
1392
|
+
...(row.pipeline_source === "inline" || row.pipeline_source === "path"
|
|
1393
|
+
? { pipeline_source: row.pipeline_source }
|
|
1394
|
+
: {}),
|
|
1395
|
+
...(row.caller_id != null ? { caller_id: row.caller_id } : {}),
|
|
1396
|
+
...(row.run_manifest
|
|
1397
|
+
? { run_manifest: JSON.parse(row.run_manifest) }
|
|
1398
|
+
: {}),
|
|
1399
|
+
...(row.skip_gates != null ? { skip_gates: row.skip_gates !== 0 } : {}),
|
|
1179
1400
|
...(pipeline_dag ? { pipeline_dag } : {}),
|
|
1180
|
-
...(row.
|
|
1181
|
-
? {
|
|
1401
|
+
...(row.pipeline_body
|
|
1402
|
+
? {
|
|
1403
|
+
inline_pipeline: JSON.parse(row.pipeline_body),
|
|
1404
|
+
}
|
|
1182
1405
|
: {}),
|
|
1183
1406
|
};
|
|
1184
1407
|
}
|
|
1185
1408
|
getRunRow(runId) {
|
|
1186
1409
|
const row = this.db
|
|
1187
|
-
.prepare(`SELECT run_id, pipeline_id, task_id, task_yaml, status, created_at, updated_at, checkout_root, pipeline_dag_json, git_sha, ci_pr_url, ci_job_url, pipeline_path, task_path, project_root,
|
|
1410
|
+
.prepare(`SELECT run_id, pipeline_id, task_id, task_yaml, status, created_at, updated_at, checkout_root, pipeline_dag_json, git_sha, ci_pr_url, ci_job_url, pipeline_path, task_path, project_root, repository, ref, resolved_sha, run_branch, git_author_name, git_author_email, cancel_reason, finished_at, slimmed_at, disk_bytes, disk_measured_at, config_origins_json, pipeline_source, pipeline_body, caller_id, run_manifest, skip_gates
|
|
1188
1411
|
FROM runs WHERE run_id = ?`)
|
|
1189
1412
|
.get(runId);
|
|
1190
1413
|
if (!row)
|