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,12 +1,17 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { globalStageflowHome } from "../project/globalHome.js";
|
|
2
3
|
import { INLINE_PIPELINE_PATH, loadPipelineFromObjectOutcome, loadPipelineOutcome, resolvePipelinePath, } from "./loadPipeline.js";
|
|
3
4
|
import { loadStageOutcome } from "./loadStage.js";
|
|
4
5
|
import { loadTaskOutcome } from "./loadTask.js";
|
|
6
|
+
import { loadTriggerOutcome } from "./loadTrigger.js";
|
|
5
7
|
import { readYamlObject } from "./readYamlObject.js";
|
|
6
8
|
import { resolveCatalogContext } from "./resolveCatalogContext.js";
|
|
7
9
|
import { getCatalogScanPaths } from "./browseCatalog.js";
|
|
8
10
|
import { manifestPathForProject } from "./loadStageflowManifest.js";
|
|
9
11
|
import { MCP_CATALOG_FILENAME, StageMcpError, assertMcpAllowlistKnown, loadMcpCatalog, mcpCatalogPath, } from "./resolveStageMcpServers.js";
|
|
12
|
+
import { loadSecretRegistry } from "../runtime/stageSecrets.js";
|
|
13
|
+
import { isForeverDeniedSecret } from "../runtime/stageEnvironment.js";
|
|
14
|
+
import { findMissingMcpCommands } from "../preflight/mcpCommands.js";
|
|
10
15
|
export function relPath(cwd, absPath) {
|
|
11
16
|
return path.relative(cwd, absPath).replace(/\\/g, "/");
|
|
12
17
|
}
|
|
@@ -99,6 +104,15 @@ function findingTaskError(cwd, absPath, message, code) {
|
|
|
99
104
|
category: "task",
|
|
100
105
|
}, "error");
|
|
101
106
|
}
|
|
107
|
+
function findingTriggerError(cwd, absPath, message, code) {
|
|
108
|
+
return baseFinding({
|
|
109
|
+
cwd,
|
|
110
|
+
absPath,
|
|
111
|
+
message,
|
|
112
|
+
code,
|
|
113
|
+
category: "trigger",
|
|
114
|
+
}, "error");
|
|
115
|
+
}
|
|
102
116
|
function findingCatalog(cwd, absPath, message, code, severity) {
|
|
103
117
|
return baseFinding({
|
|
104
118
|
cwd,
|
|
@@ -138,6 +152,11 @@ export function findingsFromLoadIssues(cwd, absPath, issues) {
|
|
|
138
152
|
findingTaskError(cwd, absPath, issue.message, issue.code),
|
|
139
153
|
];
|
|
140
154
|
}
|
|
155
|
+
if (issue.category === "trigger") {
|
|
156
|
+
return [
|
|
157
|
+
findingTriggerError(cwd, absPath, issue.message, issue.code),
|
|
158
|
+
];
|
|
159
|
+
}
|
|
141
160
|
if (issue.category === "catalog") {
|
|
142
161
|
const code = issue.code;
|
|
143
162
|
const severity = code === "catalog.manifest_missing" ||
|
|
@@ -160,6 +179,35 @@ export function findingStageIdFilenameMismatch(cwd, absPath, fileStem, declaredI
|
|
|
160
179
|
stageId: declaredId,
|
|
161
180
|
}, "error");
|
|
162
181
|
}
|
|
182
|
+
/** Parent readdir case check — warn by default; error under --strict. */
|
|
183
|
+
export async function findingPathCaseMismatch(cwd, referencedPath) {
|
|
184
|
+
const { readdir } = await import("node:fs/promises");
|
|
185
|
+
const abs = path.isAbsolute(referencedPath)
|
|
186
|
+
? referencedPath
|
|
187
|
+
: path.resolve(cwd, referencedPath);
|
|
188
|
+
const parent = path.dirname(abs);
|
|
189
|
+
const base = path.basename(abs);
|
|
190
|
+
let entries;
|
|
191
|
+
try {
|
|
192
|
+
entries = await readdir(parent);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
const exact = entries.includes(base);
|
|
198
|
+
if (exact)
|
|
199
|
+
return null;
|
|
200
|
+
const match = entries.find((e) => e.toLowerCase() === base.toLowerCase());
|
|
201
|
+
if (match === undefined)
|
|
202
|
+
return null;
|
|
203
|
+
return baseFinding({
|
|
204
|
+
cwd,
|
|
205
|
+
absPath: abs,
|
|
206
|
+
message: `Path casing differs on disk: referenced "${base}" but found "${match}"`,
|
|
207
|
+
code: "catalog.path_case_mismatch",
|
|
208
|
+
category: "catalog",
|
|
209
|
+
}, "warning");
|
|
210
|
+
}
|
|
163
211
|
async function checkStageIdFilename(cwd, stagePath) {
|
|
164
212
|
const fileStem = path.basename(stagePath, ".yaml");
|
|
165
213
|
try {
|
|
@@ -197,6 +245,100 @@ function collectMcpAllowlistNames(loaded) {
|
|
|
197
245
|
}
|
|
198
246
|
return [...names];
|
|
199
247
|
}
|
|
248
|
+
function findingsForStageSecrets(cwd, pipelinePath, loaded) {
|
|
249
|
+
const registry = loadSecretRegistry(process.env);
|
|
250
|
+
const findings = [];
|
|
251
|
+
for (const stage of loaded.stages) {
|
|
252
|
+
for (const decl of stage.secrets ?? []) {
|
|
253
|
+
if (isForeverDeniedSecret(decl.name)) {
|
|
254
|
+
findings.push(findingStageError(cwd, pipelinePath, `secret "${decl.name}" is permanently denied and cannot be granted`, "stage.denied_secret", stage.id));
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (!registry.has(decl.name)) {
|
|
258
|
+
findings.push(findingStageError(cwd, pipelinePath, `unknown secret "${decl.name}" is not in the Host secret registry`, "stage.unknown_secret", stage.id));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return findings;
|
|
263
|
+
}
|
|
264
|
+
const ABSOLUTE_PATH_IN_TEXT_RE = /(?:^|[\s"'`=:(])(\/(?:[^\s"'`;|&<>()]+))/g;
|
|
265
|
+
const TRAILING_PATH_PUNCT_RE = /[.,:;!?)\]]+$/;
|
|
266
|
+
export function collectAbsolutePathCandidates(text) {
|
|
267
|
+
const found = [];
|
|
268
|
+
const seen = new Set();
|
|
269
|
+
ABSOLUTE_PATH_IN_TEXT_RE.lastIndex = 0;
|
|
270
|
+
let match;
|
|
271
|
+
while ((match = ABSOLUTE_PATH_IN_TEXT_RE.exec(text)) !== null) {
|
|
272
|
+
const raw = match[1]?.replace(TRAILING_PATH_PUNCT_RE, "") ?? "";
|
|
273
|
+
if (!raw || !path.isAbsolute(raw) || seen.has(raw))
|
|
274
|
+
continue;
|
|
275
|
+
seen.add(raw);
|
|
276
|
+
found.push(raw);
|
|
277
|
+
}
|
|
278
|
+
return found;
|
|
279
|
+
}
|
|
280
|
+
export function isPathUnderStageflowHome(candidate, home) {
|
|
281
|
+
if (!path.isAbsolute(candidate))
|
|
282
|
+
return false;
|
|
283
|
+
const resolved = path.resolve(candidate);
|
|
284
|
+
const homeResolved = path.resolve(home);
|
|
285
|
+
return (resolved === homeResolved || resolved.startsWith(`${homeResolved}${path.sep}`));
|
|
286
|
+
}
|
|
287
|
+
function stageSourcePath(loaded, stageId) {
|
|
288
|
+
const source = loaded.stageSources?.[stageId];
|
|
289
|
+
if (source?.kind === "file")
|
|
290
|
+
return source.path;
|
|
291
|
+
return loaded.pipelinePath;
|
|
292
|
+
}
|
|
293
|
+
function stageflowHomeAbsolutePathMessage(stageId, location, absolutePath) {
|
|
294
|
+
return (`Stage "${stageId}" ${location} contains absolute path under STAGEFLOW_HOME ` +
|
|
295
|
+
`("${absolutePath}"). Use STAGEFLOW_CHECKOUT / STAGEFLOW_RUN_WORKSPACE ` +
|
|
296
|
+
`(and related binding env vars) instead of durable-home paths`);
|
|
297
|
+
}
|
|
298
|
+
function findingsForStageflowHomeAbsolutePaths(cwd, loaded) {
|
|
299
|
+
const home = globalStageflowHome();
|
|
300
|
+
const findings = [];
|
|
301
|
+
const seen = new Set();
|
|
302
|
+
const pushFinding = (stageId, absPath, location, absolutePath) => {
|
|
303
|
+
const key = `${stageId}\0${location}\0${absolutePath}`;
|
|
304
|
+
if (seen.has(key))
|
|
305
|
+
return;
|
|
306
|
+
seen.add(key);
|
|
307
|
+
findings.push(baseFinding({
|
|
308
|
+
cwd,
|
|
309
|
+
absPath,
|
|
310
|
+
message: stageflowHomeAbsolutePathMessage(stageId, location, absolutePath),
|
|
311
|
+
code: "catalog.stageflow_home_absolute_path",
|
|
312
|
+
category: "catalog",
|
|
313
|
+
pipelineId: loaded.pipeline.id,
|
|
314
|
+
stageId,
|
|
315
|
+
}, "error"));
|
|
316
|
+
};
|
|
317
|
+
const scanText = (stageId, absPath, location, text) => {
|
|
318
|
+
for (const candidate of collectAbsolutePathCandidates(text)) {
|
|
319
|
+
if (isPathUnderStageflowHome(candidate, home)) {
|
|
320
|
+
pushFinding(stageId, absPath, location, candidate);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
for (const stage of loaded.stages) {
|
|
325
|
+
const absPath = stageSourcePath(loaded, stage.id);
|
|
326
|
+
scanText(stage.id, absPath, "system_prompt", stage.system_prompt);
|
|
327
|
+
}
|
|
328
|
+
for (const node of loaded.dag.nodes) {
|
|
329
|
+
const checks = node.completion?.checks ?? [];
|
|
330
|
+
for (const check of checks) {
|
|
331
|
+
if (check.type !== "command")
|
|
332
|
+
continue;
|
|
333
|
+
const absPath = stageSourcePath(loaded, node.id);
|
|
334
|
+
scanText(node.id, absPath, `verify command "${check.id}" run`, check.run);
|
|
335
|
+
if (typeof check.cwd === "string") {
|
|
336
|
+
scanText(node.id, absPath, `verify command "${check.id}" cwd`, check.cwd);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return findings;
|
|
341
|
+
}
|
|
200
342
|
async function findingsForStageMcpCatalog(cwd, loaded) {
|
|
201
343
|
const allowlist = collectMcpAllowlistNames(loaded);
|
|
202
344
|
const ctx = await resolveCatalogContext(cwd);
|
|
@@ -235,7 +377,17 @@ async function findingsForStageMcpCatalog(cwd, loaded) {
|
|
|
235
377
|
}
|
|
236
378
|
throw err;
|
|
237
379
|
}
|
|
238
|
-
|
|
380
|
+
const findings = [];
|
|
381
|
+
const serversForPath = {};
|
|
382
|
+
for (const name of allowlist) {
|
|
383
|
+
const entry = catalog.servers[name];
|
|
384
|
+
if (entry)
|
|
385
|
+
serversForPath[name] = entry;
|
|
386
|
+
}
|
|
387
|
+
for (const missing of findMissingMcpCommands(serversForPath, process.env)) {
|
|
388
|
+
findings.push(findingCatalog(cwd, catalogAbsPath, `MCP server "${missing.serverName}" command "${missing.command}" was not found on PATH`, "catalog.mcp_command_missing", "error"));
|
|
389
|
+
}
|
|
390
|
+
return findings;
|
|
239
391
|
}
|
|
240
392
|
async function runPipelineValidation(nameOrPath, options) {
|
|
241
393
|
const { cwd, validateStages } = options;
|
|
@@ -274,6 +426,8 @@ async function runPipelineValidation(nameOrPath, options) {
|
|
|
274
426
|
findings.push(...findingsFromLoadIssues(cwd, pipelinePath, outcome.issues));
|
|
275
427
|
}
|
|
276
428
|
findings.push(...(await findingsForStageMcpCatalog(cwd, outcome.value)));
|
|
429
|
+
findings.push(...findingsForStageSecrets(cwd, pipelinePath, outcome.value));
|
|
430
|
+
findings.push(...findingsForStageflowHomeAbsolutePaths(cwd, outcome.value));
|
|
277
431
|
if (validateStages && outcome.value.stageSources) {
|
|
278
432
|
for (const source of Object.values(outcome.value.stageSources)) {
|
|
279
433
|
if (source.kind === "file") {
|
|
@@ -330,7 +484,7 @@ function findingManifestMissing(cwd, projectRoot) {
|
|
|
330
484
|
function findingEmptyCatalog(cwd, manifestPath, kind) {
|
|
331
485
|
return findingCatalog(cwd, manifestPath, `Manifest catalog.${kind} is empty`, "catalog.empty_catalog", "warning");
|
|
332
486
|
}
|
|
333
|
-
async function collectPipelineIdsFromPaths(pipelinePaths) {
|
|
487
|
+
export async function collectPipelineIdsFromPaths(pipelinePaths) {
|
|
334
488
|
const idToPaths = new Map();
|
|
335
489
|
for (const filePath of pipelinePaths) {
|
|
336
490
|
try {
|
|
@@ -347,6 +501,20 @@ async function collectPipelineIdsFromPaths(pipelinePaths) {
|
|
|
347
501
|
}
|
|
348
502
|
return idToPaths;
|
|
349
503
|
}
|
|
504
|
+
export async function collectTaskIdsFromPaths(taskPaths) {
|
|
505
|
+
const ids = new Set();
|
|
506
|
+
for (const filePath of taskPaths) {
|
|
507
|
+
try {
|
|
508
|
+
const raw = await readYamlObject(filePath);
|
|
509
|
+
if (typeof raw?.id === "string")
|
|
510
|
+
ids.add(raw.id);
|
|
511
|
+
}
|
|
512
|
+
catch {
|
|
513
|
+
// unreadable files handled by task validation loop
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return ids;
|
|
517
|
+
}
|
|
350
518
|
function findingsForDuplicatePipelineIds(cwd, idToPaths) {
|
|
351
519
|
const findings = [];
|
|
352
520
|
for (const [pipelineId, paths] of idToPaths) {
|
|
@@ -391,7 +559,7 @@ async function validateManifestAll(invocationCwd) {
|
|
|
391
559
|
if (!scanPaths) {
|
|
392
560
|
return findings;
|
|
393
561
|
}
|
|
394
|
-
const { pipelinePaths, taskPaths } = scanPaths;
|
|
562
|
+
const { pipelinePaths, taskPaths, triggerPaths } = scanPaths;
|
|
395
563
|
for (const pipelinePath of pipelinePaths) {
|
|
396
564
|
const core = await runPipelineValidation(pipelinePath, {
|
|
397
565
|
cwd: projectRoot,
|
|
@@ -409,6 +577,32 @@ async function validateManifestAll(invocationCwd) {
|
|
|
409
577
|
}
|
|
410
578
|
const idToPaths = await collectPipelineIdsFromPaths(pipelinePaths);
|
|
411
579
|
findings.push(...findingsForDuplicatePipelineIds(projectRoot, idToPaths));
|
|
580
|
+
if (triggerPaths.length > 0) {
|
|
581
|
+
const pipelineIds = new Set(idToPaths.keys());
|
|
582
|
+
const taskIds = await collectTaskIdsFromPaths(taskPaths);
|
|
583
|
+
for (const triggerPath of triggerPaths) {
|
|
584
|
+
const outcome = await loadTriggerOutcome(triggerPath);
|
|
585
|
+
if (!outcome.ok) {
|
|
586
|
+
findings.push(...findingsFromLoadIssues(projectRoot, triggerPath, outcome.issues));
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
findings.push(...findingsForTriggerRefs(projectRoot, triggerPath, outcome.value, {
|
|
590
|
+
pipelineIds,
|
|
591
|
+
taskIds,
|
|
592
|
+
}));
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return findings;
|
|
596
|
+
}
|
|
597
|
+
/** Confirms a trigger's `pipeline`/`task` refs resolve against known catalog ids. */
|
|
598
|
+
export function findingsForTriggerRefs(cwd, absPath, trigger, refs) {
|
|
599
|
+
const findings = [];
|
|
600
|
+
if (!refs.pipelineIds.has(trigger.pipeline)) {
|
|
601
|
+
findings.push(findingTriggerError(cwd, absPath, `Trigger "${trigger.id}" references unknown pipeline "${trigger.pipeline}"`, "trigger.unknown_pipeline"));
|
|
602
|
+
}
|
|
603
|
+
if (trigger.task !== undefined && !refs.taskIds.has(trigger.task)) {
|
|
604
|
+
findings.push(findingTriggerError(cwd, absPath, `Trigger "${trigger.id}" references unknown task "${trigger.task}"`, "trigger.unknown_task"));
|
|
605
|
+
}
|
|
412
606
|
return findings;
|
|
413
607
|
}
|
|
414
608
|
async function validateSingleTask(invocationCwd, taskArg) {
|
|
@@ -421,6 +615,26 @@ async function validateSingleTask(invocationCwd, taskArg) {
|
|
|
421
615
|
}
|
|
422
616
|
return [];
|
|
423
617
|
}
|
|
618
|
+
async function validateSingleTrigger(invocationCwd, triggerArg) {
|
|
619
|
+
const ctx = await resolveCatalogContext(invocationCwd);
|
|
620
|
+
const relCwd = ctx.projectRoot ?? invocationCwd;
|
|
621
|
+
const triggerPath = path.resolve(invocationCwd, triggerArg);
|
|
622
|
+
const outcome = await loadTriggerOutcome(triggerPath);
|
|
623
|
+
if (!outcome.ok) {
|
|
624
|
+
return findingsFromLoadIssues(relCwd, triggerPath, outcome.issues);
|
|
625
|
+
}
|
|
626
|
+
const scanPaths = await getCatalogScanPaths(ctx);
|
|
627
|
+
const pipelineIds = scanPaths
|
|
628
|
+
? new Set((await collectPipelineIdsFromPaths(scanPaths.pipelinePaths)).keys())
|
|
629
|
+
: new Set();
|
|
630
|
+
const taskIds = scanPaths
|
|
631
|
+
? await collectTaskIdsFromPaths(scanPaths.taskPaths)
|
|
632
|
+
: new Set();
|
|
633
|
+
return findingsForTriggerRefs(relCwd, triggerPath, outcome.value, {
|
|
634
|
+
pipelineIds,
|
|
635
|
+
taskIds,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
424
638
|
export async function validateCatalog(options) {
|
|
425
639
|
const cwd = options.cwd ?? process.cwd();
|
|
426
640
|
const strict = options.strict ?? false;
|
|
@@ -430,6 +644,9 @@ export async function validateCatalog(options) {
|
|
|
430
644
|
if (options.scope === "task" && !options.task) {
|
|
431
645
|
throw new Error("validateCatalog: task is required when scope is \"task\"");
|
|
432
646
|
}
|
|
647
|
+
if (options.scope === "trigger" && !options.trigger) {
|
|
648
|
+
throw new Error("validateCatalog: trigger is required when scope is \"trigger\"");
|
|
649
|
+
}
|
|
433
650
|
const allFindings = [];
|
|
434
651
|
if (options.scope === "pipeline") {
|
|
435
652
|
return validatePipeline(options.pipeline, {
|
|
@@ -442,6 +659,9 @@ export async function validateCatalog(options) {
|
|
|
442
659
|
else if (options.scope === "task") {
|
|
443
660
|
allFindings.push(...(await validateSingleTask(cwd, options.task)));
|
|
444
661
|
}
|
|
662
|
+
else if (options.scope === "trigger") {
|
|
663
|
+
allFindings.push(...(await validateSingleTrigger(cwd, options.trigger)));
|
|
664
|
+
}
|
|
445
665
|
else {
|
|
446
666
|
allFindings.push(...(await validateManifestAll(cwd)));
|
|
447
667
|
}
|
|
@@ -45,6 +45,14 @@ export function validateCompletionContractForStage(stage, completion) {
|
|
|
45
45
|
!stage.gate_kinds?.includes(check.kind)) {
|
|
46
46
|
return failure(stage.id, `gate check "${check.id}" requires gate_kinds to include "${check.kind}"`);
|
|
47
47
|
}
|
|
48
|
+
if (check.type === "browser_login") {
|
|
49
|
+
if (stage.browser?.check === undefined) {
|
|
50
|
+
return failure(stage.id, `check "${check.id}" requires the stage to declare browser.check`);
|
|
51
|
+
}
|
|
52
|
+
if (stage.browser.headed === false) {
|
|
53
|
+
return failure(stage.id, `check "${check.id}" is a human login check and needs a visible browser (browser.headed must not be false)`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
48
56
|
if (check.type === "checkout_changes") {
|
|
49
57
|
for (const field of check.path_fields ?? []) {
|
|
50
58
|
if (!isRequiredStringArrayField(stage.payload_schema, field)) {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { RunStore } from "../runstore/port.js";
|
|
2
|
+
export type DiagnosticSeverity = "error" | "warn" | "skipped";
|
|
3
|
+
export type DiagnosticCheckResult = {
|
|
4
|
+
id: string;
|
|
5
|
+
ok: boolean;
|
|
6
|
+
severity: DiagnosticSeverity;
|
|
7
|
+
message: string;
|
|
8
|
+
code?: string;
|
|
9
|
+
detail?: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
export type ReadyzChecks = {
|
|
12
|
+
store_openable: boolean;
|
|
13
|
+
home_writable: boolean;
|
|
14
|
+
migrations_complete: boolean;
|
|
15
|
+
git_present: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type ReadyzResult = {
|
|
18
|
+
ready: boolean;
|
|
19
|
+
checks: ReadyzChecks;
|
|
20
|
+
code?: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function resetReadyzCacheForTests(): void;
|
|
23
|
+
export declare function livezBody(): {
|
|
24
|
+
ok: true;
|
|
25
|
+
status: "live";
|
|
26
|
+
};
|
|
27
|
+
export declare function probeGitVersion(): Promise<string | undefined>;
|
|
28
|
+
export declare function runReadyzChecks(options: {
|
|
29
|
+
store: RunStore;
|
|
30
|
+
homeDir?: string;
|
|
31
|
+
now?: number;
|
|
32
|
+
bypassCache?: boolean;
|
|
33
|
+
}): Promise<ReadyzResult>;
|
|
34
|
+
export type SchemaHealthStub = {
|
|
35
|
+
user_version: number | null;
|
|
36
|
+
schema_migrations: "present" | "absent" | "unknown";
|
|
37
|
+
note?: string;
|
|
38
|
+
};
|
|
39
|
+
export declare function readSchemaHealth(store: RunStore): SchemaHealthStub;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { accessSync, constants, writeFileSync, unlinkSync } from "node:fs";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import { globalStageflowHome } from "../project/globalHome.js";
|
|
5
|
+
const execFileAsync = promisify(execFile);
|
|
6
|
+
const READYZ_TTL_MS = 4_000;
|
|
7
|
+
let readyzCache;
|
|
8
|
+
export function resetReadyzCacheForTests() {
|
|
9
|
+
readyzCache = undefined;
|
|
10
|
+
}
|
|
11
|
+
export function livezBody() {
|
|
12
|
+
return { ok: true, status: "live" };
|
|
13
|
+
}
|
|
14
|
+
async function checkGitPresent() {
|
|
15
|
+
try {
|
|
16
|
+
await execFileAsync("git", ["--version"], {
|
|
17
|
+
timeout: 5_000,
|
|
18
|
+
windowsHide: true,
|
|
19
|
+
});
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export async function probeGitVersion() {
|
|
27
|
+
try {
|
|
28
|
+
const { stdout } = await execFileAsync("git", ["--version"], {
|
|
29
|
+
timeout: 5_000,
|
|
30
|
+
windowsHide: true,
|
|
31
|
+
});
|
|
32
|
+
return stdout.trim();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function checkHomeWritable(home) {
|
|
39
|
+
try {
|
|
40
|
+
accessSync(home, constants.W_OK);
|
|
41
|
+
const probe = `${home}/.stageflow-write-probe-${process.pid}`;
|
|
42
|
+
writeFileSync(probe, "ok");
|
|
43
|
+
unlinkSync(probe);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function checkStoreOpenable(store) {
|
|
51
|
+
try {
|
|
52
|
+
await store.listRuns();
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function checkMigrationsComplete(store) {
|
|
60
|
+
const connection = store.connection;
|
|
61
|
+
if (connection === undefined || typeof connection.pragma !== "function") {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const version = connection.pragma("user_version", { simple: true });
|
|
66
|
+
return typeof version === "number" && version >= 0;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export async function runReadyzChecks(options) {
|
|
73
|
+
const now = options.now ?? Date.now();
|
|
74
|
+
if (!options.bypassCache &&
|
|
75
|
+
readyzCache !== undefined &&
|
|
76
|
+
readyzCache.expiresAt > now) {
|
|
77
|
+
return readyzCache.result;
|
|
78
|
+
}
|
|
79
|
+
const home = options.homeDir ?? globalStageflowHome();
|
|
80
|
+
const checks = {
|
|
81
|
+
store_openable: await checkStoreOpenable(options.store),
|
|
82
|
+
home_writable: checkHomeWritable(home),
|
|
83
|
+
migrations_complete: checkMigrationsComplete(options.store),
|
|
84
|
+
git_present: await checkGitPresent(),
|
|
85
|
+
};
|
|
86
|
+
let code;
|
|
87
|
+
if (!checks.store_openable)
|
|
88
|
+
code = "store_not_openable";
|
|
89
|
+
else if (!checks.home_writable)
|
|
90
|
+
code = "home_not_writable";
|
|
91
|
+
else if (!checks.migrations_complete)
|
|
92
|
+
code = "migrations_incomplete";
|
|
93
|
+
else if (!checks.git_present)
|
|
94
|
+
code = "git_not_present";
|
|
95
|
+
const result = {
|
|
96
|
+
ready: code === undefined,
|
|
97
|
+
checks,
|
|
98
|
+
...(code !== undefined ? { code } : {}),
|
|
99
|
+
};
|
|
100
|
+
readyzCache = { expiresAt: now + READYZ_TTL_MS, result };
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
export function readSchemaHealth(store) {
|
|
104
|
+
const connection = store.connection;
|
|
105
|
+
if (connection === undefined || typeof connection.pragma !== "function") {
|
|
106
|
+
return {
|
|
107
|
+
user_version: null,
|
|
108
|
+
schema_migrations: "unknown",
|
|
109
|
+
note: "Slot 1 schema reporting stub — store has no sqlite connection",
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const user_version = connection.pragma("user_version", {
|
|
114
|
+
simple: true,
|
|
115
|
+
});
|
|
116
|
+
let schema_migrations = "unknown";
|
|
117
|
+
if (typeof connection.prepare === "function") {
|
|
118
|
+
try {
|
|
119
|
+
connection.prepare(`SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'schema_migrations'`).get();
|
|
120
|
+
schema_migrations = "present";
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
schema_migrations = "absent";
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return { user_version, schema_migrations };
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return {
|
|
130
|
+
user_version: null,
|
|
131
|
+
schema_migrations: "unknown",
|
|
132
|
+
note: "Slot 1 schema reporting stub — pragma failed",
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -26,4 +26,4 @@ export declare function declaredArtifactIssue(artifacts: readonly string[], chec
|
|
|
26
26
|
* `gate` check with no `readQaTrail` fails closed (cannot be verified). No
|
|
27
27
|
* `checks` (or an empty list) is a no-op.
|
|
28
28
|
*/
|
|
29
|
-
export declare function assertPreEmitChecks(envelope: Pick<StageEnvelope, "artifacts">, options: PreEmitCheckOptions | undefined): Promise<void>;
|
|
29
|
+
export declare function assertPreEmitChecks(envelope: Pick<StageEnvelope, "artifacts" | "payload">, options: PreEmitCheckOptions | undefined): Promise<void>;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* why this stays separate from `CompletionCheck`'s `artifact`/`gate` runners.
|
|
11
11
|
*/
|
|
12
12
|
import { preEmitGateIssue } from "../hitl/qaTrail.js";
|
|
13
|
+
import { loginCheckIssue } from "../browser/loginCheck.js";
|
|
13
14
|
import { EnvelopeError } from "../types/envelope.js";
|
|
14
15
|
function artifactListsBasename(artifact, basename) {
|
|
15
16
|
return artifact === basename || artifact.endsWith(`/${basename}`);
|
|
@@ -42,6 +43,13 @@ export async function assertPreEmitChecks(envelope, options) {
|
|
|
42
43
|
}
|
|
43
44
|
continue;
|
|
44
45
|
}
|
|
46
|
+
if (check.type === "browser_login_check") {
|
|
47
|
+
const issue = loginCheckIssue(envelope.payload, check);
|
|
48
|
+
if (issue !== undefined) {
|
|
49
|
+
throw new EnvelopeError(issue);
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
45
53
|
// check.type === "gate"
|
|
46
54
|
if (options?.readQaTrail === undefined) {
|
|
47
55
|
throw new EnvelopeError("declared gate kinds cannot be verified without a QA trail reader");
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Stable network-facing error codes (snake_case). Keep strings unchanged once shipped. */
|
|
2
|
+
export declare const BUSY_CAPACITY: "busy_capacity";
|
|
3
|
+
export declare const BUSY_CHECKOUT: "busy_checkout";
|
|
4
|
+
/** Per-caller concurrency quota: queued when under global capacity; reject when queue full. */
|
|
5
|
+
export declare const BUSY_CALLER_QUOTA: "busy_caller_quota";
|
|
6
|
+
export declare const ABORTED: "aborted";
|
|
7
|
+
export declare const NETWORK_ERROR_CODES: readonly ["busy_capacity", "busy_checkout", "busy_caller_quota", "aborted", "unknown_project_root", "absolute_path_not_allowed", "path_outside_project_root", "catalog_root_unreadable", "ensure_project_not_allowed", "config_invalid", "config_unknown_key", "provider_not_configured", "a2a_configuration_error", "untrusted_config_origin", "command_not_on_path", "missing_tool", "tool_version_mismatch", "unknown_version", "secret_unavailable", "not_ready", "internal_error", "retry_in_progress", "hitl_not_retriable", "run_not_retryable", "stage_not_failed", "manual_recovery_required", "run_not_found", "stage_not_found", "artifact_not_found", "artifact_path_denied", "envelope_not_found", "insufficient_disk", "disk_check_failed", "shutting_down", "start.token_rejected", "inline_pipeline_too_large", "skills_invalid_name", "skills_invalid_path", "skills_missing_skill_md", "skills_payload_too_large", "pinned_sha_unavailable", "store_integrity_failed", "store_unsupported_filesystem", "tmpdir_unusable", "backup_insufficient_disk"];
|
|
8
|
+
export type NetworkErrorCode = (typeof NETWORK_ERROR_CODES)[number] | string;
|
|
9
|
+
export type NetworkErrorBody = {
|
|
10
|
+
code: NetworkErrorCode;
|
|
11
|
+
error: string;
|
|
12
|
+
} & Record<string, unknown>;
|
|
13
|
+
export declare function networkError(code: NetworkErrorCode, error: string, detail?: Record<string, unknown>): NetworkErrorBody;
|
|
14
|
+
export declare function codeOrInternal(code: string | undefined): NetworkErrorCode;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Stable network-facing error codes (snake_case). Keep strings unchanged once shipped. */
|
|
2
|
+
export const BUSY_CAPACITY = "busy_capacity";
|
|
3
|
+
export const BUSY_CHECKOUT = "busy_checkout";
|
|
4
|
+
/** Per-caller concurrency quota: queued when under global capacity; reject when queue full. */
|
|
5
|
+
export const BUSY_CALLER_QUOTA = "busy_caller_quota";
|
|
6
|
+
export const ABORTED = "aborted";
|
|
7
|
+
export const NETWORK_ERROR_CODES = [
|
|
8
|
+
BUSY_CAPACITY,
|
|
9
|
+
BUSY_CHECKOUT,
|
|
10
|
+
BUSY_CALLER_QUOTA,
|
|
11
|
+
ABORTED,
|
|
12
|
+
"unknown_project_root",
|
|
13
|
+
"absolute_path_not_allowed",
|
|
14
|
+
"path_outside_project_root",
|
|
15
|
+
"catalog_root_unreadable",
|
|
16
|
+
"ensure_project_not_allowed",
|
|
17
|
+
"config_invalid",
|
|
18
|
+
"config_unknown_key",
|
|
19
|
+
"provider_not_configured",
|
|
20
|
+
"a2a_configuration_error",
|
|
21
|
+
"untrusted_config_origin",
|
|
22
|
+
"command_not_on_path",
|
|
23
|
+
"missing_tool",
|
|
24
|
+
"tool_version_mismatch",
|
|
25
|
+
"unknown_version",
|
|
26
|
+
"secret_unavailable",
|
|
27
|
+
"not_ready",
|
|
28
|
+
"internal_error",
|
|
29
|
+
"retry_in_progress",
|
|
30
|
+
"hitl_not_retriable",
|
|
31
|
+
"run_not_retryable",
|
|
32
|
+
"stage_not_failed",
|
|
33
|
+
"manual_recovery_required",
|
|
34
|
+
"run_not_found",
|
|
35
|
+
"stage_not_found",
|
|
36
|
+
"artifact_not_found",
|
|
37
|
+
"artifact_path_denied",
|
|
38
|
+
"envelope_not_found",
|
|
39
|
+
"insufficient_disk",
|
|
40
|
+
"disk_check_failed",
|
|
41
|
+
"shutting_down",
|
|
42
|
+
"start.token_rejected",
|
|
43
|
+
"inline_pipeline_too_large",
|
|
44
|
+
"skills_invalid_name",
|
|
45
|
+
"skills_invalid_path",
|
|
46
|
+
"skills_missing_skill_md",
|
|
47
|
+
"skills_payload_too_large",
|
|
48
|
+
"pinned_sha_unavailable",
|
|
49
|
+
"store_integrity_failed",
|
|
50
|
+
"store_unsupported_filesystem",
|
|
51
|
+
"tmpdir_unusable",
|
|
52
|
+
"backup_insufficient_disk",
|
|
53
|
+
];
|
|
54
|
+
export function networkError(code, error, detail) {
|
|
55
|
+
return { code, error, ...detail };
|
|
56
|
+
}
|
|
57
|
+
export function codeOrInternal(code) {
|
|
58
|
+
return code && code.length > 0 ? code : "internal_error";
|
|
59
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function setBareCacheRemoteUrlOverrideForTests(override: ((repository: string) => string | undefined) | null): void;
|
|
2
|
+
export declare function resetBareCacheStateForTests(): void;
|
|
3
|
+
export declare function githubHttpsRemoteUrl(repository: string): string;
|
|
4
|
+
export declare function bareCachePath(repository: string): string;
|
|
5
|
+
export declare function remoteUrlForRepository(repository: string): string;
|
|
6
|
+
export type EnsureBareCacheResult = {
|
|
7
|
+
cachePath: string;
|
|
8
|
+
fetched: boolean;
|
|
9
|
+
};
|
|
10
|
+
export type EnsureBareCacheOptions = {
|
|
11
|
+
env?: NodeJS.ProcessEnv;
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
};
|
|
14
|
+
export declare function ensureBareCache(repository: string, ref: string, options?: EnsureBareCacheOptions): Promise<EnsureBareCacheResult>;
|