stageflow 0.33.0 → 0.36.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 +3 -3
- package/dist/agent/adapterSpill.d.ts +14 -0
- package/dist/agent/adapterSpill.js +83 -0
- package/dist/agent/agentBackend.d.ts +2 -2
- package/dist/agent/agentBackend.js +2 -2
- package/dist/agent/claudeAdapter.d.ts +13 -2
- package/dist/agent/claudeAdapter.js +56 -6
- package/dist/agent/cursorProvider.d.ts +3 -0
- package/dist/agent/cursorProvider.js +23 -6
- package/dist/agent/fakeAgent.d.ts +3 -3
- package/dist/agent/piAdapter.d.ts +2 -2
- package/dist/agent/piAdapter.js +125 -15
- package/dist/agent/piIsolatedMcp.d.ts +1 -0
- package/dist/agent/piIsolatedMcp.js +19 -1
- package/dist/agent/piIsolatedMcpProbe.d.ts +11 -0
- package/dist/agent/piIsolatedMcpProbe.js +20 -0
- package/dist/agent/port.d.ts +4 -2
- package/dist/agent/providerAuth.js +36 -3
- package/dist/agent/{resolveAgentPort.d.ts → resolveStagePort.d.ts} +8 -8
- package/dist/agent/{resolveAgentPort.js → resolveStagePort.js} +11 -11
- package/dist/agent/stageTurnDriver.d.ts +33 -0
- package/dist/agent/stageTurnDriver.js +64 -0
- package/dist/agent/toolOutputBudget.d.ts +46 -0
- package/dist/agent/toolOutputBudget.js +97 -0
- package/dist/agent/toolOutputBudgetExtension.d.ts +22 -0
- package/dist/agent/toolOutputBudgetExtension.js +141 -0
- package/dist/agent/toolOutputSpill.d.ts +34 -0
- package/dist/agent/toolOutputSpill.js +85 -0
- package/dist/browser/agentBrowserLiveViewRelay.d.ts +41 -0
- package/dist/browser/agentBrowserLiveViewRelay.js +801 -0
- package/dist/browser/anchor.d.ts +2 -0
- package/dist/browser/anchor.js +2 -1
- package/dist/browser/auditSink.d.ts +8 -0
- package/dist/browser/browserHost.d.ts +29 -0
- package/dist/browser/browserSweep.d.ts +4 -1
- package/dist/browser/browserSweep.js +7 -0
- package/dist/browser/browserTeardown.d.ts +1 -0
- package/dist/browser/browserTeardown.js +32 -2
- package/dist/browser/containerBrowserEndpoint.d.ts +11 -0
- package/dist/browser/containerBrowserEndpoint.js +57 -0
- package/dist/browser/containerBrowserHost.d.ts +24 -0
- package/dist/browser/containerBrowserHost.js +147 -0
- package/dist/browser/dockerSandboxOrchestrator.d.ts +26 -0
- package/dist/browser/dockerSandboxOrchestrator.js +142 -0
- package/dist/browser/fakeLiveViewRelay.d.ts +15 -0
- package/dist/browser/fakeLiveViewRelay.js +94 -0
- package/dist/browser/fakeLiveViewSource.d.ts +6 -0
- package/dist/browser/fakeLiveViewSource.js +16 -0
- package/dist/browser/fakeRemoteBrowserHost.d.ts +2 -1
- package/dist/browser/fakeRemoteBrowserHost.js +2 -1
- package/dist/browser/fakeSandboxOrchestrator.d.ts +9 -0
- package/dist/browser/fakeSandboxOrchestrator.js +44 -0
- package/dist/browser/gateHandoff.d.ts +0 -2
- package/dist/browser/gateHandoff.js +5 -11
- package/dist/browser/hostCapabilities.d.ts +23 -0
- package/dist/browser/hostCapabilities.js +23 -0
- package/dist/browser/humanLogin.d.ts +2 -2
- package/dist/browser/humanLogin.js +11 -2
- package/dist/browser/liveViewPersisted.d.ts +11 -0
- package/dist/browser/liveViewPersisted.js +22 -0
- package/dist/browser/liveViewRelay.d.ts +76 -0
- package/dist/browser/liveViewRelay.js +1 -0
- package/dist/browser/liveViewSessions.d.ts +25 -0
- package/dist/browser/liveViewSessions.js +139 -0
- package/dist/browser/liveViewSource.d.ts +25 -0
- package/dist/browser/liveViewSource.js +7 -0
- package/dist/browser/liveViewTickets.d.ts +46 -0
- package/dist/browser/liveViewTickets.js +122 -0
- package/dist/browser/localBrowserHost.d.ts +10 -0
- package/dist/browser/localBrowserHost.js +53 -7
- package/dist/browser/ownerScope.d.ts +10 -0
- package/dist/browser/ownerScope.js +6 -0
- package/dist/browser/profileStore.d.ts +5 -2
- package/dist/browser/profileStore.js +3 -5
- package/dist/browser/sandboxOrchestrator.d.ts +60 -0
- package/dist/browser/sandboxOrchestrator.js +8 -0
- package/dist/browser/sessionApiSandboxOrchestrator.d.ts +34 -0
- package/dist/browser/sessionApiSandboxOrchestrator.js +108 -0
- package/dist/browser/stageBrowserEnv.d.ts +7 -0
- package/dist/browser/stageBrowserEnv.js +53 -15
- package/dist/browser/stageHandoff.d.ts +47 -0
- package/dist/browser/stageHandoff.js +101 -0
- package/dist/browser/stageProfileLock.d.ts +1 -0
- package/dist/browser/stageProfileLock.js +1 -3
- package/dist/browser/volumeProfileStore.d.ts +7 -0
- package/dist/browser/volumeProfileStore.js +35 -0
- package/dist/channels/config.d.ts +11 -0
- package/dist/channels/config.js +95 -0
- package/dist/channels/configWriter.d.ts +40 -0
- package/dist/channels/configWriter.js +148 -0
- package/dist/channels/connectionEdits.d.ts +34 -0
- package/dist/channels/connectionEdits.js +53 -0
- package/dist/channels/errorInfo.d.ts +18 -0
- package/dist/channels/errorInfo.js +71 -0
- package/dist/channels/errors.d.ts +12 -0
- package/dist/channels/errors.js +13 -0
- package/dist/channels/health.d.ts +41 -0
- package/dist/channels/health.js +99 -0
- package/dist/channels/host.d.ts +55 -0
- package/dist/channels/host.js +185 -0
- package/dist/channels/http.d.ts +31 -0
- package/dist/channels/http.js +79 -0
- package/dist/channels/index.d.ts +10 -0
- package/dist/channels/index.js +9 -0
- package/dist/channels/ledger.d.ts +37 -0
- package/dist/channels/ledger.js +95 -0
- package/dist/channels/providers/agentmail.d.ts +26 -0
- package/dist/channels/providers/agentmail.js +81 -0
- package/dist/channels/providers/kit.d.ts +40 -0
- package/dist/channels/providers/kit.js +78 -0
- package/dist/channels/providers/photonImessage.d.ts +45 -0
- package/dist/channels/providers/photonImessage.js +152 -0
- package/dist/channels/providers/photonWhatsapp.d.ts +49 -0
- package/dist/channels/providers/photonWhatsapp.js +146 -0
- package/dist/channels/providers/slack.d.ts +25 -0
- package/dist/channels/providers/slack.js +101 -0
- package/dist/channels/providers/telegram.d.ts +21 -0
- package/dist/channels/providers/telegram.js +100 -0
- package/dist/channels/providers.d.ts +5 -0
- package/dist/channels/providers.js +22 -0
- package/dist/channels/registry.d.ts +54 -0
- package/dist/channels/registry.js +186 -0
- package/dist/channels/secretStore.d.ts +21 -0
- package/dist/channels/secretStore.js +75 -0
- package/dist/channels/secrets.d.ts +15 -0
- package/dist/channels/secrets.js +50 -0
- package/dist/channels/service.d.ts +54 -0
- package/dist/channels/service.js +307 -0
- package/dist/channels/stageChannels.d.ts +45 -0
- package/dist/channels/stageChannels.js +110 -0
- package/dist/channels/types.d.ts +142 -0
- package/dist/channels/types.js +1 -0
- package/dist/cli/browserCommand.d.ts +3 -1
- package/dist/cli/browserCommand.js +25 -20
- package/dist/cli/doctorCommand.js +3 -1
- package/dist/cli/resolveCliProjectRoot.d.ts +7 -0
- package/dist/cli/resolveCliProjectRoot.js +27 -0
- package/dist/cli/runCommand.d.ts +1 -1
- package/dist/cli/runCommand.js +59 -17
- package/dist/cli/skillsCommand.d.ts +20 -0
- package/dist/cli/skillsCommand.js +74 -31
- package/dist/cli/validateCommand.d.ts +1 -1
- package/dist/cli/validateCommand.js +22 -4
- package/dist/cli.js +4 -4
- package/dist/config/browseCatalog.d.ts +2 -0
- package/dist/config/browseCatalog.js +6 -0
- package/dist/config/catalogRelativePath.d.ts +4 -0
- package/dist/config/catalogRelativePath.js +37 -9
- package/dist/config/createStage.d.ts +1 -0
- package/dist/config/createStage.js +11 -2
- package/dist/config/createTask.d.ts +30 -0
- package/dist/config/createTask.js +161 -0
- package/dist/config/createTrigger.d.ts +15 -0
- package/dist/config/createTrigger.js +32 -25
- package/dist/config/draftPackage.d.ts +42 -0
- package/dist/config/draftPackage.js +220 -23
- package/dist/config/ensureCatalogScanRoot.d.ts +2 -1
- package/dist/config/ensureCatalogScanRoot.js +6 -2
- package/dist/config/findTaskInCatalog.d.ts +33 -0
- package/dist/config/findTaskInCatalog.js +69 -0
- package/dist/config/hostConfig.d.ts +21 -0
- package/dist/config/hostConfig.js +114 -1
- package/dist/config/importTask.d.ts +19 -0
- package/dist/config/importTask.js +133 -0
- package/dist/config/installSkillRequest.d.ts +40 -0
- package/dist/config/installSkillRequest.js +286 -0
- package/dist/config/loadOutcome.d.ts +11 -6
- package/dist/config/loadPipeline.js +27 -4
- package/dist/config/loadStage.js +17 -0
- package/dist/config/loadStageflowManifest.js +4 -1
- package/dist/config/loadTask.js +2 -0
- package/dist/config/loadTrigger.js +2 -0
- package/dist/config/mergePipelineIncludes.d.ts +3 -0
- package/dist/config/mergePipelineIncludes.js +30 -0
- package/dist/config/normalizePipelineStageEntry.js +10 -1
- package/dist/config/pipelineStageKeys.js +1 -0
- package/dist/config/printTargetYaml.js +0 -1
- package/dist/config/publishDraftPackage.d.ts +5 -1
- package/dist/config/publishDraftPackage.js +4 -1
- package/dist/config/resolveCatalogRoots.d.ts +4 -1
- package/dist/config/resolveCatalogRoots.js +18 -1
- package/dist/config/skillUsageIndex.d.ts +6 -0
- package/dist/config/skillUsageIndex.js +39 -0
- package/dist/config/stageBrowser.js +13 -0
- package/dist/config/triggerAdapterStatus.d.ts +11 -0
- package/dist/config/triggerAdapterStatus.js +90 -0
- package/dist/config/triggerCatalog.d.ts +41 -2
- package/dist/config/triggerCatalog.js +107 -15
- package/dist/config/updateTask.d.ts +30 -0
- package/dist/config/updateTask.js +119 -0
- package/dist/config/updateTrigger.d.ts +38 -0
- package/dist/config/updateTrigger.js +220 -0
- package/dist/config/validateCatalog.d.ts +9 -2
- package/dist/config/validateCatalog.js +71 -7
- package/dist/config/workshopCatalogFilenames.d.ts +37 -0
- package/dist/config/workshopCatalogFilenames.js +125 -0
- package/dist/config/workshopCatalogRepair.d.ts +7 -0
- package/dist/config/workshopCatalogRepair.js +144 -0
- package/dist/config/yamlParsePosition.d.ts +4 -0
- package/dist/config/yamlParsePosition.js +9 -0
- package/dist/errors/codes.d.ts +1 -1
- package/dist/errors/codes.js +1 -0
- package/dist/hosted/runtime.d.ts +2 -2
- package/dist/hosted/types.d.ts +1 -1
- package/dist/hosted/types.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/mcp/catalogTools.js +1 -0
- package/dist/mcp/getStartedTool.js +15 -6
- package/dist/mcp/triggerTools.js +2 -8
- package/dist/operatorAgent/agentPort.d.ts +11 -0
- package/dist/operatorAgent/agentPort.js +12 -0
- package/dist/operatorAgent/index.d.ts +1 -0
- package/dist/operatorAgent/index.js +1 -0
- package/dist/operatorAgent/piModel.js +26 -6
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +1 -1
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +4 -2
- package/dist/operatorAgent/profiles/workshopAuthorTools.js +103 -16
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/preflight/channelChecks.d.ts +17 -0
- package/dist/preflight/channelChecks.js +106 -0
- package/dist/preflight/pipelinePreflight.d.ts +9 -2
- package/dist/preflight/pipelinePreflight.js +9 -1
- package/dist/project/ensureProjectRootsFromEnv.d.ts +3 -0
- package/dist/project/ensureProjectRootsFromEnv.js +22 -0
- package/dist/project/globalHome.d.ts +1 -0
- package/dist/project/globalHome.js +18 -0
- package/dist/project/workspaceCatalog.d.ts +10 -0
- package/dist/project/workspaceCatalog.js +91 -0
- package/dist/runstore/backup.js +14 -4
- package/dist/runstore/port.d.ts +11 -1
- package/dist/runstore/restore.js +5 -2
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +8 -0
- package/dist/runstore/sqlite/SqliteRunStore.js +29 -9
- package/dist/runstore/sqlite/migrations/012-trigger-fires.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/012-trigger-fires.js +18 -0
- package/dist/runstore/sqlite/migrations/index.js +2 -0
- package/dist/runstore/stageSnapshot.d.ts +3 -1
- package/dist/runstore/stageSnapshot.js +19 -0
- package/dist/runstore/workspaceLayout.js +27 -0
- package/dist/runstore/writeContainedArtifact.d.ts +1 -0
- package/dist/runstore/writeContainedArtifact.js +52 -0
- package/dist/runtime/credentialBinding.js +14 -6
- package/dist/runtime/emailSource.js +20 -28
- package/dist/runtime/githubPollSource.js +20 -28
- package/dist/runtime/pipelineRunner.d.ts +4 -4
- package/dist/runtime/pipelineRunner.js +3 -1
- package/dist/runtime/pipelineScheduler.d.ts +2 -2
- package/dist/runtime/pipelineScheduler.js +3 -0
- package/dist/runtime/repositoryMaterialize.d.ts +1 -1
- package/dist/runtime/resumeReconstruct.d.ts +2 -2
- package/dist/runtime/resumeTimedOut.d.ts +2 -2
- package/dist/runtime/runManager.d.ts +18 -2
- package/dist/runtime/runManager.js +99 -31
- package/dist/runtime/runRetryCoordinator.d.ts +2 -2
- package/dist/runtime/scheduleSource.js +15 -24
- package/dist/runtime/stageAttemptBootstrap.d.ts +2 -2
- package/dist/runtime/stageAttemptBootstrap.js +26 -1
- package/dist/runtime/stageProcessLauncher.js +33 -3
- package/dist/runtime/stageRoots.js +8 -1
- package/dist/runtime/stageRunner.d.ts +2 -2
- package/dist/runtime/stageRunner.js +8 -2
- package/dist/runtime/stageWorker.js +2 -2
- package/dist/runtime/triggerPort.d.ts +5 -3
- package/dist/runtime/triggerRunner.d.ts +1 -0
- package/dist/runtime/triggerRunner.js +27 -20
- package/dist/runtime/webhookAccept.d.ts +25 -0
- package/dist/runtime/webhookAccept.js +56 -0
- package/dist/server/bootstrap.d.ts +10 -2
- package/dist/server/bootstrap.js +19 -1
- package/dist/server/channelRoutes.d.ts +9 -0
- package/dist/server/channelRoutes.js +88 -0
- package/dist/server/controlToken.d.ts +1 -1
- package/dist/server/controlToken.js +18 -2
- package/dist/server/healthSurfaces.d.ts +12 -0
- package/dist/server/healthSurfaces.js +27 -6
- package/dist/server/http.d.ts +19 -10
- package/dist/server/http.js +616 -85
- package/dist/server/liveViewPath.d.ts +9 -0
- package/dist/server/liveViewPath.js +8 -0
- package/dist/server/liveViewRoutes.d.ts +58 -0
- package/dist/server/liveViewRoutes.js +565 -0
- package/dist/server/mcpHost.d.ts +4 -2
- package/dist/server/mcpHost.js +2 -0
- package/dist/server/readCatalogFile.d.ts +29 -0
- package/dist/server/readCatalogFile.js +215 -0
- package/dist/server/triggerRoutes.d.ts +1 -0
- package/dist/server/triggerRoutes.js +200 -73
- package/dist/tools/sendMessage.d.ts +21 -0
- package/dist/tools/sendMessage.js +25 -0
- package/dist/tools/writeStageArtifact.d.ts +9 -0
- package/dist/tools/writeStageArtifact.js +2 -47
- package/dist/types/pipeline.d.ts +5 -2
- package/dist/types/stage.d.ts +14 -1
- package/dist/types/stageflowManifest.d.ts +1 -1
- package/dist/ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/ui/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/ui/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/ui/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/ui/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/ui/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/ui/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/ui/assets/index-BOhqnPNg.js +260 -0
- package/dist/ui/assets/{index-Bv4p1aPK.css → index-Clv4sJpU.css} +1 -1
- package/dist/ui/index.html +4 -4
- package/dist/workshop/autosave.d.ts +2 -2
- package/dist/workshop/autosave.js +4 -6
- package/dist/workshop/buildStore.d.ts +2 -0
- package/dist/workshop/chatAttachments.d.ts +27 -0
- package/dist/workshop/chatAttachments.js +98 -0
- package/dist/workshop/chatTurn.d.ts +5 -2
- package/dist/workshop/chatTurn.js +22 -18
- package/dist/workshop/sessionMutations.d.ts +17 -0
- package/dist/workshop/sessionMutations.js +107 -0
- package/dist/workshop/sessionStore.d.ts +10 -0
- package/dist/workshop/sessionStore.js +52 -0
- package/dist/workshop/workshopPin.d.ts +4 -3
- package/dist/workshop/workshopPin.js +26 -6
- package/dist/workshop/workshopTranscriptTurn.d.ts +8 -0
- package/dist/workshop/workshopTranscriptTurn.js +46 -0
- package/examples/README.md +1 -1
- package/examples/archify-on-pr/README.md +1 -1
- package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +0 -1
- package/examples/archify-on-pr/author-diagrams.yaml +1 -0
- package/examples/channels-smoke/README.md +12 -0
- package/examples/channels-smoke/channels-smoke.pipeline.yaml +11 -0
- package/examples/channels-smoke/channels-smoke.task.yaml +3 -0
- package/examples/channels-smoke/send-email.yaml +32 -0
- package/examples/channels-smoke/send-text.yaml +31 -0
- package/examples/conditional-fork/branch-a.yaml +1 -1
- package/examples/conditional-fork/decide.yaml +2 -1
- package/examples/feature-loop/{implement.yaml → feature-implement.yaml} +1 -1
- package/examples/feature-loop/feature-loop.pipeline.yaml +10 -10
- package/examples/feature-loop/{plan.yaml → feature-plan.yaml} +1 -1
- package/examples/feature-loop/{review.yaml → feature-review.yaml} +1 -1
- package/examples/feedback-loop/{implement.yaml → feedback-implement.yaml} +1 -1
- package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +9 -9
- package/examples/feedback-loop/feedback-loop.pipeline.yaml +9 -9
- package/examples/feedback-loop/{plan.yaml → feedback-plan.yaml} +1 -1
- package/examples/feedback-loop/{review.yaml → feedback-review.yaml} +1 -1
- package/examples/generic-fan-in/{research.yaml → fan-in-research.yaml} +1 -1
- package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +3 -3
- package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +3 -3
- package/examples/hello-world/{research.yaml → hello-research.yaml} +1 -1
- package/examples/hello-world/hello.pipeline.yaml +2 -2
- package/examples/mcp-hitl-tour/{review.yaml → mcp-hitl-review.yaml} +1 -1
- package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +3 -3
- package/examples/oss-issue-contribution/oss-explain-fix.yaml +1 -0
- package/examples/oss-issue-contribution/oss-explain-issue.yaml +1 -0
- package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +0 -2
- package/examples/stageflow.yaml +6 -0
- package/examples/triggers/sample-github-pr.trigger.yaml +12 -0
- package/examples/triggers/sample-inbox-email.trigger.yaml +14 -0
- package/examples/triggers/sample-manual-hello.trigger.yaml +5 -0
- package/examples/triggers/sample-nightly-hello.trigger.yaml +8 -0
- package/examples/triggers/sample-signed-webhook.trigger.yaml +11 -0
- package/examples/triggers-readiness/README.md +48 -0
- package/examples/triggers-readiness/readiness-emit.yaml +18 -0
- package/examples/triggers-readiness/readiness.pipeline.yaml +4 -0
- package/examples/triggers-readiness/readiness.task.yaml +6 -0
- package/examples/triggers-readiness/stageflow.yaml +13 -0
- package/examples/triggers-readiness/triggers/readiness-dynamic-manual.trigger.yaml +4 -0
- package/examples/triggers-readiness/triggers/readiness-email.trigger.yaml +12 -0
- package/examples/triggers-readiness/triggers/readiness-github-pr.trigger.yaml +12 -0
- package/examples/triggers-readiness/triggers/readiness-manual.trigger.yaml +5 -0
- package/examples/triggers-readiness/triggers/readiness-schedule.trigger.yaml +8 -0
- package/examples/triggers-readiness/triggers/readiness-webhook.trigger.yaml +11 -0
- package/package.json +8 -3
- package/skills/stageflow/references/control-surface.md +1 -1
- package/skills/stageflow-author/references/catalog-write-conventions.md +2 -2
- package/skills/stageflow-run/SKILL.md +1 -1
- package/skills/stageflow-run/references/mcp-call.md +1 -1
- package/skills/stageflow-setup/SKILL.md +1 -1
- package/dist/ui/assets/index-59cjF0OA.js +0 -133
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
import type { ValidationFindingCode } from "./validateCatalog.js";
|
|
2
2
|
export type TaskLoadCode = "task.invalid_shape" | "task.load_error" | "task.binding_conflict" | "task.repository_ref_required" | "task.ref_without_repository" | "task.repository_invalid";
|
|
3
3
|
export type TriggerLoadCode = "trigger.invalid_shape" | "trigger.load_error" | "trigger.unknown_pipeline" | "trigger.unknown_task";
|
|
4
|
-
|
|
4
|
+
type LoadIssueLocation = {
|
|
5
|
+
line?: number;
|
|
6
|
+
column?: number;
|
|
7
|
+
};
|
|
8
|
+
export type LoadIssue = ({
|
|
5
9
|
code: ValidationFindingCode;
|
|
6
10
|
message: string;
|
|
7
11
|
category: "pipeline";
|
|
8
12
|
pipelineId?: string;
|
|
9
13
|
stageId?: string;
|
|
10
|
-
} | {
|
|
14
|
+
} & LoadIssueLocation) | ({
|
|
11
15
|
code: ValidationFindingCode;
|
|
12
16
|
message: string;
|
|
13
17
|
category: "stage";
|
|
14
18
|
stageId?: string;
|
|
15
|
-
} | {
|
|
19
|
+
} & LoadIssueLocation) | ({
|
|
16
20
|
code: TaskLoadCode;
|
|
17
21
|
message: string;
|
|
18
22
|
category: "task";
|
|
19
23
|
taskId?: string;
|
|
20
|
-
} | {
|
|
24
|
+
} & LoadIssueLocation) | ({
|
|
21
25
|
code: TriggerLoadCode;
|
|
22
26
|
message: string;
|
|
23
27
|
category: "trigger";
|
|
24
28
|
triggerId?: string;
|
|
25
|
-
} | {
|
|
29
|
+
} & LoadIssueLocation) | ({
|
|
26
30
|
code: ValidationFindingCode | string;
|
|
27
31
|
message: string;
|
|
28
32
|
category: "catalog";
|
|
29
|
-
};
|
|
33
|
+
} & LoadIssueLocation);
|
|
30
34
|
export type LoadOutcome<T> = {
|
|
31
35
|
ok: true;
|
|
32
36
|
value: T;
|
|
@@ -37,3 +41,4 @@ export type LoadOutcome<T> = {
|
|
|
37
41
|
};
|
|
38
42
|
export declare function loadFailure<T>(issues: LoadIssue[]): LoadOutcome<T>;
|
|
39
43
|
export declare function loadSuccess<T>(value: T, issues?: LoadIssue[]): LoadOutcome<T>;
|
|
44
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MAX_STAGE_CHANNELS, channelLimitMessage, mergeChannelDefaults, stageChannelLimit } from "../channels/stageChannels.js";
|
|
1
2
|
import { access } from "node:fs/promises";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { compilePayloadSchema, expandPayloadSchemaRefs, isPayloadSchemaSubset, UnresolvedSchemaRefError, } from "../envelope/payloadSchema.js";
|
|
@@ -128,9 +129,25 @@ export async function loadPipelineFromObject(raw, options = {}) {
|
|
|
128
129
|
}
|
|
129
130
|
return outcome.value;
|
|
130
131
|
}
|
|
132
|
+
function applyPipelineChannels(stage, defaults, pipelineId) {
|
|
133
|
+
const channels = mergeChannelDefaults(defaults, stage.channels);
|
|
134
|
+
if (channels === undefined)
|
|
135
|
+
return loadSuccess(stage);
|
|
136
|
+
if (channels.length > Math.min(MAX_STAGE_CHANNELS, stageChannelLimit())) {
|
|
137
|
+
return loadFailure([
|
|
138
|
+
{
|
|
139
|
+
code: "stage.invalid_channels",
|
|
140
|
+
message: `Pipeline ${pipelineId}: stage "${stage.id}" ends up with ${channels.length} channels after merging pipeline defaults, but ${channelLimitMessage()}. Use \`channels: []\` on the stage to drop the pipeline default.`,
|
|
141
|
+
category: "stage",
|
|
142
|
+
stageId: stage.id,
|
|
143
|
+
},
|
|
144
|
+
]);
|
|
145
|
+
}
|
|
146
|
+
return loadSuccess({ ...stage, channels });
|
|
147
|
+
}
|
|
131
148
|
async function buildLoadedPipelineFromMerge(merge, options) {
|
|
132
149
|
const { projectRoot, requireIo, pipelinePath } = options;
|
|
133
|
-
const { entries: rawEntries, pipelineId, agent: pipelineAgent, model: pipelineModel, schemas: pipelineSchemas, requires: pipelineRequires, warnings: mergeWarnings, } = merge;
|
|
150
|
+
const { entries: rawEntries, pipelineId, agent: pipelineAgent, model: pipelineModel, schemas: pipelineSchemas, requires: pipelineRequires, channels: pipelineChannels, warnings: mergeWarnings, } = merge;
|
|
134
151
|
const ctx = { pipelineId, path: pipelinePath };
|
|
135
152
|
const warnings = [...mergeWarnings];
|
|
136
153
|
const normalizeOutcome = normalizePipelineStageEntries(rawEntries, ctx);
|
|
@@ -199,7 +216,10 @@ async function buildLoadedPipelineFromMerge(merge, options) {
|
|
|
199
216
|
if (inlineRequires.value !== undefined) {
|
|
200
217
|
stage = { ...stage, requires: inlineRequires.value };
|
|
201
218
|
}
|
|
202
|
-
|
|
219
|
+
const inlineChannels = applyPipelineChannels(stage, pipelineChannels, pipelineId);
|
|
220
|
+
if (!inlineChannels.ok)
|
|
221
|
+
return loadFailure(inlineChannels.issues);
|
|
222
|
+
stages.push(inlineChannels.value);
|
|
203
223
|
stageSources[stageId] = { kind: "inline" };
|
|
204
224
|
continue;
|
|
205
225
|
}
|
|
@@ -259,10 +279,12 @@ async function buildLoadedPipelineFromMerge(merge, options) {
|
|
|
259
279
|
if (!fileRequires.ok)
|
|
260
280
|
return loadFailure(fileRequires.issues);
|
|
261
281
|
stageRequires = fileRequires.value;
|
|
282
|
+
const withChannels = applyPipelineChannels(stageOutcome.value, pipelineChannels, pipelineId);
|
|
283
|
+
if (!withChannels.ok)
|
|
284
|
+
return loadFailure(withChannels.issues);
|
|
262
285
|
const stage = {
|
|
263
|
-
...
|
|
286
|
+
...withChannels.value,
|
|
264
287
|
...(browser !== undefined ? { browser } : {}),
|
|
265
|
-
...(entry.skill !== undefined ? { skill: entry.skill } : {}),
|
|
266
288
|
...(entry.mcp !== undefined ? { mcp: entry.mcp } : {}),
|
|
267
289
|
...(entry.secrets !== undefined ? { secrets: entry.secrets } : {}),
|
|
268
290
|
...(stageRequires !== undefined ? { requires: stageRequires } : {}),
|
|
@@ -316,6 +338,7 @@ async function buildLoadedPipelineFromMerge(merge, options) {
|
|
|
316
338
|
...(pipelineModel !== undefined ? { model: pipelineModel } : {}),
|
|
317
339
|
...(pipelineSchemas !== undefined ? { schemas: pipelineSchemas } : {}),
|
|
318
340
|
...(pipelineRequires !== undefined ? { requires: pipelineRequires } : {}),
|
|
341
|
+
...(pipelineChannels !== undefined ? { channels: pipelineChannels } : {}),
|
|
319
342
|
};
|
|
320
343
|
const effectiveRequires = mergeToolRequires([pipelineRequires, ...loadedStages.map((s) => s.requires)], { pipelineId });
|
|
321
344
|
if (!effectiveRequires.ok)
|
package/dist/config/loadStage.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parseChannels } from "../channels/stageChannels.js";
|
|
1
2
|
import { parseAgentField } from "../agent/agentBackend.js";
|
|
2
3
|
import { STAGEFLOW_MCP_SERVER_NAME } from "../agent/claudeTools.js";
|
|
3
4
|
import { STAGE_GATE_KINDS, } from "../types/stage.js";
|
|
@@ -7,6 +8,7 @@ import { parseModelField } from "./modelField.js";
|
|
|
7
8
|
import { allowLegacyYamlAuthoring, dialectWarningForDocument, legacyAuthoringRejected, presentLegacyKeys, } from "./legacyYaml.js";
|
|
8
9
|
import { parsePreEmitChecks } from "./parsePreEmitChecks.js";
|
|
9
10
|
import { readYamlObject } from "./readYamlObject.js";
|
|
11
|
+
import { yamlParsePosition } from "./yamlParsePosition.js";
|
|
10
12
|
import { z } from "zod";
|
|
11
13
|
import { parseStageSecrets } from "../runtime/stageSecretDecl.js";
|
|
12
14
|
import { parseToolRequires } from "./toolRequires.js";
|
|
@@ -361,6 +363,20 @@ function parseStageFields(raw, label, entryId, deferSchemaRefs, requireIo, compi
|
|
|
361
363
|
if (mcpOutcome.value !== undefined) {
|
|
362
364
|
stage.mcp = mcpOutcome.value;
|
|
363
365
|
}
|
|
366
|
+
if (raw.channels !== undefined) {
|
|
367
|
+
const channels = parseChannels(raw.channels);
|
|
368
|
+
if (!channels.ok) {
|
|
369
|
+
return loadFailure([
|
|
370
|
+
{
|
|
371
|
+
code: "stage.invalid_channels",
|
|
372
|
+
message: `Invalid stage ${label}: ${channels.message}`,
|
|
373
|
+
category: "stage",
|
|
374
|
+
stageId: entryId,
|
|
375
|
+
},
|
|
376
|
+
]);
|
|
377
|
+
}
|
|
378
|
+
stage.channels = channels.value;
|
|
379
|
+
}
|
|
364
380
|
const secretsOutcome = parseStageSecrets(raw.secrets, label, entryId);
|
|
365
381
|
if (!secretsOutcome.ok)
|
|
366
382
|
return secretsOutcome;
|
|
@@ -436,6 +452,7 @@ export async function loadStageOutcome(filePath, options = {}) {
|
|
|
436
452
|
code: "stage.load_error",
|
|
437
453
|
message,
|
|
438
454
|
category: "stage",
|
|
455
|
+
...yamlParsePosition(err),
|
|
439
456
|
},
|
|
440
457
|
]);
|
|
441
458
|
}
|
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { parse as parseYaml } from "yaml";
|
|
4
4
|
import { parseAgentField } from "../agent/agentBackend.js";
|
|
5
5
|
import { loadFailure, loadSuccess } from "./loadOutcome.js";
|
|
6
|
+
import { yamlParsePosition } from "./yamlParsePosition.js";
|
|
6
7
|
import { parseModelField } from "./modelField.js";
|
|
7
8
|
const DEFAULT_PIPELINE_PATTERN = "*.pipeline.yaml";
|
|
8
9
|
const DEFAULT_TASK_PATTERN = "*.task.yaml";
|
|
@@ -87,7 +88,9 @@ export function parseStageflowManifestOutcome(yamlText, manifestPath, projectRoo
|
|
|
87
88
|
}
|
|
88
89
|
catch (err) {
|
|
89
90
|
const message = err instanceof Error ? err.message : String(err);
|
|
90
|
-
return loadFailure([
|
|
91
|
+
return loadFailure([
|
|
92
|
+
{ ...catalogIssue("catalog.manifest_load_error", message), ...yamlParsePosition(err) },
|
|
93
|
+
]);
|
|
91
94
|
}
|
|
92
95
|
const issues = [];
|
|
93
96
|
const record = raw;
|
package/dist/config/loadTask.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import { parse as parseYaml } from "yaml";
|
|
3
3
|
import { resolveWorkspaceBinding } from "../runtime/workspaceBinding.js";
|
|
4
4
|
import { loadFailure, loadSuccess } from "./loadOutcome.js";
|
|
5
|
+
import { yamlParsePosition } from "./yamlParsePosition.js";
|
|
5
6
|
function isPlainObject(value) {
|
|
6
7
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7
8
|
}
|
|
@@ -86,6 +87,7 @@ export function loadTaskFromYamlOutcome(yamlText, source = "task yaml") {
|
|
|
86
87
|
code: "task.load_error",
|
|
87
88
|
message,
|
|
88
89
|
category: "task",
|
|
90
|
+
...yamlParsePosition(err),
|
|
89
91
|
},
|
|
90
92
|
]);
|
|
91
93
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { parse as parseYaml } from "yaml";
|
|
3
3
|
import { loadFailure, loadSuccess } from "./loadOutcome.js";
|
|
4
|
+
import { yamlParsePosition } from "./yamlParsePosition.js";
|
|
4
5
|
function isPlainObject(value) {
|
|
5
6
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
7
|
}
|
|
@@ -84,6 +85,7 @@ export function loadTriggerFromYamlOutcome(yamlText, source = "trigger yaml") {
|
|
|
84
85
|
code: "trigger.load_error",
|
|
85
86
|
message,
|
|
86
87
|
category: "trigger",
|
|
88
|
+
...yamlParsePosition(err),
|
|
87
89
|
},
|
|
88
90
|
]);
|
|
89
91
|
}
|
|
@@ -2,6 +2,7 @@ import type { PayloadSchemaMap } from "../envelope/payloadSchema.js";
|
|
|
2
2
|
import type { InlinePipelineDefinition } from "../types/pipeline.js";
|
|
3
3
|
import { type LoadIssue, type LoadOutcome } from "./loadOutcome.js";
|
|
4
4
|
import { type ToolRequirement } from "./toolRequires.js";
|
|
5
|
+
import type { StageChannel } from "../types/stage.js";
|
|
5
6
|
export type RawMergedEntry = {
|
|
6
7
|
raw: unknown;
|
|
7
8
|
declaringPath: string;
|
|
@@ -13,6 +14,7 @@ export declare function mergePipelineStages(rootPath: string): Promise<LoadOutco
|
|
|
13
14
|
model?: string;
|
|
14
15
|
schemas?: PayloadSchemaMap;
|
|
15
16
|
requires?: ToolRequirement[];
|
|
17
|
+
channels?: StageChannel[];
|
|
16
18
|
warnings: LoadIssue[];
|
|
17
19
|
}>>;
|
|
18
20
|
/** Synthetic `declaringPath` for stage entries with no backing file. */
|
|
@@ -24,5 +26,6 @@ export declare function mergeInlinePipelineStages(raw: InlinePipelineDefinition)
|
|
|
24
26
|
model?: string;
|
|
25
27
|
schemas?: PayloadSchemaMap;
|
|
26
28
|
requires?: ToolRequirement[];
|
|
29
|
+
channels?: StageChannel[];
|
|
27
30
|
warnings: LoadIssue[];
|
|
28
31
|
}>>;
|
|
@@ -4,7 +4,9 @@ import { loadFailure, loadSuccess } from "./loadOutcome.js";
|
|
|
4
4
|
import { allowLegacyYamlAuthoring, dialectWarningForDocument, legacyAuthoringRejected, presentLegacyKeys, } from "./legacyYaml.js";
|
|
5
5
|
import { parseModelField } from "./modelField.js";
|
|
6
6
|
import { readYamlObject } from "./readYamlObject.js";
|
|
7
|
+
import { yamlParsePosition } from "./yamlParsePosition.js";
|
|
7
8
|
import { parseToolRequires } from "./toolRequires.js";
|
|
9
|
+
import { parseChannels } from "../channels/stageChannels.js";
|
|
8
10
|
import { classifyYamlDocument, collectDocumentKeys, mixedDialectIssue, } from "./yamlDialect.js";
|
|
9
11
|
function isPlainObject(value) {
|
|
10
12
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -39,6 +41,7 @@ async function visitPipelineFile(filePath, stack, idLocations, entries, warnings
|
|
|
39
41
|
code: "pipeline.load_error",
|
|
40
42
|
message,
|
|
41
43
|
category: "pipeline",
|
|
44
|
+
...yamlParsePosition(err),
|
|
42
45
|
},
|
|
43
46
|
]);
|
|
44
47
|
}
|
|
@@ -128,6 +131,7 @@ export async function mergePipelineStages(rootPath) {
|
|
|
128
131
|
code: "pipeline.load_error",
|
|
129
132
|
message,
|
|
130
133
|
category: "pipeline",
|
|
134
|
+
...yamlParsePosition(err),
|
|
131
135
|
},
|
|
132
136
|
]);
|
|
133
137
|
}
|
|
@@ -186,6 +190,10 @@ export async function mergePipelineStages(rootPath) {
|
|
|
186
190
|
if (!requiresOutcome.ok)
|
|
187
191
|
return requiresOutcome;
|
|
188
192
|
const requires = requiresOutcome.value;
|
|
193
|
+
const channelsOutcome = parsePipelineChannels(raw.channels, `pipeline ${absRoot}`, pipelineId);
|
|
194
|
+
if (!channelsOutcome.ok)
|
|
195
|
+
return channelsOutcome;
|
|
196
|
+
const channels = channelsOutcome.value;
|
|
189
197
|
const idLocations = new Map();
|
|
190
198
|
const entries = [];
|
|
191
199
|
const warnings = [];
|
|
@@ -208,6 +216,7 @@ export async function mergePipelineStages(rootPath) {
|
|
|
208
216
|
...(model !== undefined ? { model } : {}),
|
|
209
217
|
...(schemas !== undefined ? { schemas } : {}),
|
|
210
218
|
...(requires !== undefined ? { requires } : {}),
|
|
219
|
+
...(channels !== undefined ? { channels } : {}),
|
|
211
220
|
warnings,
|
|
212
221
|
});
|
|
213
222
|
}
|
|
@@ -270,6 +279,10 @@ export async function mergeInlinePipelineStages(raw) {
|
|
|
270
279
|
if (!requiresOutcome.ok)
|
|
271
280
|
return requiresOutcome;
|
|
272
281
|
const requires = requiresOutcome.value;
|
|
282
|
+
const channelsOutcome = parsePipelineChannels(raw.channels, `inline pipeline ${pipelineId}`, pipelineId);
|
|
283
|
+
if (!channelsOutcome.ok)
|
|
284
|
+
return channelsOutcome;
|
|
285
|
+
const channels = channelsOutcome.value;
|
|
273
286
|
const entries = [];
|
|
274
287
|
for (let index = 0; index < raw.stages.length; index++) {
|
|
275
288
|
const entry = raw.stages[index];
|
|
@@ -292,9 +305,26 @@ export async function mergeInlinePipelineStages(raw) {
|
|
|
292
305
|
...(model !== undefined ? { model } : {}),
|
|
293
306
|
...(schemas !== undefined ? { schemas } : {}),
|
|
294
307
|
...(requires !== undefined ? { requires } : {}),
|
|
308
|
+
...(channels !== undefined ? { channels } : {}),
|
|
295
309
|
warnings: [],
|
|
296
310
|
});
|
|
297
311
|
}
|
|
312
|
+
function parsePipelineChannels(raw, label, pipelineId) {
|
|
313
|
+
if (raw === undefined)
|
|
314
|
+
return loadSuccess(undefined);
|
|
315
|
+
const parsed = parseChannels(raw);
|
|
316
|
+
if (!parsed.ok) {
|
|
317
|
+
return loadFailure([
|
|
318
|
+
{
|
|
319
|
+
code: "pipeline.invalid_channels",
|
|
320
|
+
message: `Invalid ${label}: ${parsed.message}`,
|
|
321
|
+
category: "pipeline",
|
|
322
|
+
pipelineId,
|
|
323
|
+
},
|
|
324
|
+
]);
|
|
325
|
+
}
|
|
326
|
+
return loadSuccess(parsed.value);
|
|
327
|
+
}
|
|
298
328
|
function parsePipelineSchemas(raw, absPath, pipelineId) {
|
|
299
329
|
if (raw === undefined)
|
|
300
330
|
return loadSuccess(undefined);
|
|
@@ -43,7 +43,6 @@ function extractBodyRaw(raw) {
|
|
|
43
43
|
}
|
|
44
44
|
function hasBodyKey(raw) {
|
|
45
45
|
return Object.keys(raw).some((key) => BODY_KEYS.has(key) &&
|
|
46
|
-
key !== "skill" &&
|
|
47
46
|
key !== "mcp" &&
|
|
48
47
|
key !== "secrets" &&
|
|
49
48
|
key !== "requires" &&
|
|
@@ -116,6 +115,16 @@ export function normalizePipelineStageEntries(rawEntries, ctx) {
|
|
|
116
115
|
return skillOutcome;
|
|
117
116
|
}
|
|
118
117
|
const skill = skillOutcome?.ok ? skillOutcome.value : undefined;
|
|
118
|
+
if (uses && skill !== undefined) {
|
|
119
|
+
return loadFailure([
|
|
120
|
+
{
|
|
121
|
+
code: "pipeline.stage_wrapper_skill_rejected",
|
|
122
|
+
message: `Pipeline ${ctx.pipelineId} (${ctx.path}): stage entry at index ${index} sets skill: on a uses: wrapper; put skill: on the stage file (${uses}) instead`,
|
|
123
|
+
category: "pipeline",
|
|
124
|
+
pipelineId: ctx.pipelineId,
|
|
125
|
+
},
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
119
128
|
const mcpOutcome = parseStageMcp(raw.mcp, `entry at index ${index} in ${declaringPath}`);
|
|
120
129
|
if (!mcpOutcome.ok)
|
|
121
130
|
return mcpOutcome;
|
|
@@ -29,6 +29,7 @@ export const WIRING_KEYS = new Set([
|
|
|
29
29
|
/** Stage body keys. Target: `io` / `verify`. IR/legacy: `payload_schema`, `pre_emit_checks`, `clone_input_schema`. */
|
|
30
30
|
export const BODY_KEYS = new Set([
|
|
31
31
|
"email",
|
|
32
|
+
"channels",
|
|
32
33
|
"system_prompt",
|
|
33
34
|
"model",
|
|
34
35
|
"payload_schema",
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { type CreateDraftPackageInput, type DraftPackageWriteResult } from "./draftPackage.js";
|
|
2
|
+
import type { CatalogRootKind } from "./resolveCatalogRoots.js";
|
|
2
3
|
export type PublishDraftPackageMode = "create" | "overwrite" | "auto";
|
|
4
|
+
export type PublishDraftPackageOptions = {
|
|
5
|
+
catalogRootKind?: CatalogRootKind;
|
|
6
|
+
};
|
|
3
7
|
export type PublishDraftPackageResult = {
|
|
4
8
|
write: DraftPackageWriteResult;
|
|
5
9
|
catalogChanged: boolean;
|
|
6
10
|
};
|
|
7
|
-
export declare function publishDraftPackage(projectRoot: string, input: CreateDraftPackageInput, mode: PublishDraftPackageMode): Promise<PublishDraftPackageResult>;
|
|
11
|
+
export declare function publishDraftPackage(projectRoot: string, input: CreateDraftPackageInput, mode: PublishDraftPackageMode, options?: PublishDraftPackageOptions): Promise<PublishDraftPackageResult>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createDraftPackage, overwriteDraftPackage, } from "./draftPackage.js";
|
|
2
2
|
import { ensureCatalogScanRoot } from "./ensureCatalogScanRoot.js";
|
|
3
|
-
export async function publishDraftPackage(projectRoot, input, mode) {
|
|
3
|
+
export async function publishDraftPackage(projectRoot, input, mode, options = {}) {
|
|
4
4
|
let write;
|
|
5
5
|
if (mode === "create") {
|
|
6
6
|
write = await createDraftPackage(projectRoot, input);
|
|
@@ -20,6 +20,9 @@ export async function publishDraftPackage(projectRoot, input, mode) {
|
|
|
20
20
|
if (!write.ok) {
|
|
21
21
|
return { write, catalogChanged: false };
|
|
22
22
|
}
|
|
23
|
+
if (options.catalogRootKind === "workspace") {
|
|
24
|
+
return { write, catalogChanged: false };
|
|
25
|
+
}
|
|
23
26
|
const catalogChanged = await ensureCatalogScanRoot(projectRoot, input.directory);
|
|
24
27
|
return { write, catalogChanged };
|
|
25
28
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RunStore } from "../runstore/port.js";
|
|
2
|
-
export type CatalogRootKind = "registered" | "seeded";
|
|
2
|
+
export type CatalogRootKind = "registered" | "seeded" | "workspace";
|
|
3
3
|
export type CatalogRoot = {
|
|
4
4
|
/** Wire id: absolute path for registered; symbolic id for seeded (e.g. "examples"). */
|
|
5
5
|
project_root: string;
|
|
@@ -7,6 +7,9 @@ export type CatalogRoot = {
|
|
|
7
7
|
path: string;
|
|
8
8
|
kind: CatalogRootKind;
|
|
9
9
|
read_only: boolean;
|
|
10
|
+
/** False when workspace provisioning failed at boot. */
|
|
11
|
+
available?: boolean;
|
|
12
|
+
unavailable_reason?: string;
|
|
10
13
|
};
|
|
11
14
|
export type ResolveCatalogRootsOptions = {
|
|
12
15
|
store: RunStore;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { realpathSync, constants } from "node:fs";
|
|
3
3
|
import { access } from "node:fs/promises";
|
|
4
|
+
import { WORKSPACE_CATALOG_ID, lastWorkspaceProvisionResult, workspaceCatalogPath, } from "../project/workspaceCatalog.js";
|
|
4
5
|
function realOrResolve(p) {
|
|
5
6
|
const resolved = path.resolve(p);
|
|
6
7
|
try {
|
|
@@ -19,6 +20,7 @@ export async function resolveCatalogRoots(options) {
|
|
|
19
20
|
const seenPaths = new Set();
|
|
20
21
|
const seededRoots = options.seededRoots ??
|
|
21
22
|
(await import("./seededCatalog.js")).defaultSeededRoots();
|
|
23
|
+
const workspaceAbs = realOrResolve(workspaceCatalogPath());
|
|
22
24
|
let registered = [];
|
|
23
25
|
try {
|
|
24
26
|
registered = await options.store.listRegisteredProjects();
|
|
@@ -28,7 +30,7 @@ export async function resolveCatalogRoots(options) {
|
|
|
28
30
|
}
|
|
29
31
|
for (const root of registered) {
|
|
30
32
|
const abs = realOrResolve(root);
|
|
31
|
-
if (seenPaths.has(abs))
|
|
33
|
+
if (seenPaths.has(abs) || abs === workspaceAbs)
|
|
32
34
|
continue;
|
|
33
35
|
seenPaths.add(abs);
|
|
34
36
|
roots.push({
|
|
@@ -38,6 +40,21 @@ export async function resolveCatalogRoots(options) {
|
|
|
38
40
|
read_only: false,
|
|
39
41
|
});
|
|
40
42
|
}
|
|
43
|
+
if (!seenPaths.has(workspaceAbs)) {
|
|
44
|
+
seenPaths.add(workspaceAbs);
|
|
45
|
+
const provision = lastWorkspaceProvisionResult();
|
|
46
|
+
const available = provision === undefined || provision.ok;
|
|
47
|
+
roots.push({
|
|
48
|
+
project_root: WORKSPACE_CATALOG_ID,
|
|
49
|
+
path: workspaceCatalogPath(),
|
|
50
|
+
kind: "workspace",
|
|
51
|
+
read_only: false,
|
|
52
|
+
available,
|
|
53
|
+
...(provision !== undefined && !provision.ok && provision.reason
|
|
54
|
+
? { unavailable_reason: provision.reason }
|
|
55
|
+
: {}),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
41
58
|
for (const seeded of seededRoots) {
|
|
42
59
|
const abs = realOrResolve(seeded.path);
|
|
43
60
|
if (seenPaths.has(abs))
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { loadPipelineOutcome } from "./loadPipeline.js";
|
|
2
|
+
import { getCatalogScanPaths } from "./browseCatalog.js";
|
|
3
|
+
import { catalogContextFromStageflow } from "./resolveCatalogContext.js";
|
|
4
|
+
import { resolveStageflowContext } from "../project/resolveStageflowContext.js";
|
|
5
|
+
function addUsage(index, skillName, pipelineId, stageId) {
|
|
6
|
+
const entry = index[skillName] ?? { stage_ids: [], pipeline_ids: [] };
|
|
7
|
+
if (!entry.pipeline_ids.includes(pipelineId)) {
|
|
8
|
+
entry.pipeline_ids.push(pipelineId);
|
|
9
|
+
entry.pipeline_ids.sort((a, b) => a.localeCompare(b));
|
|
10
|
+
}
|
|
11
|
+
if (!entry.stage_ids.includes(stageId)) {
|
|
12
|
+
entry.stage_ids.push(stageId);
|
|
13
|
+
entry.stage_ids.sort((a, b) => a.localeCompare(b));
|
|
14
|
+
}
|
|
15
|
+
index[skillName] = entry;
|
|
16
|
+
}
|
|
17
|
+
export async function buildSkillUsageIndex(cwd) {
|
|
18
|
+
const ctx = catalogContextFromStageflow(await resolveStageflowContext(cwd));
|
|
19
|
+
const scanPaths = await getCatalogScanPaths(ctx);
|
|
20
|
+
if (!scanPaths) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const index = {};
|
|
24
|
+
const loadCwd = ctx.projectRoot ?? cwd;
|
|
25
|
+
for (const pipelinePath of scanPaths.pipelinePaths) {
|
|
26
|
+
const outcome = await loadPipelineOutcome(pipelinePath, { cwd: loadCwd });
|
|
27
|
+
if (!outcome.ok) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const pipelineId = outcome.value.pipeline.id;
|
|
31
|
+
for (const stage of outcome.value.stages) {
|
|
32
|
+
if (stage.skill === undefined) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
addUsage(index, stage.skill, pipelineId, stage.id);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return index;
|
|
39
|
+
}
|
|
@@ -4,6 +4,16 @@ export const BROWSER_TOOL_NAME = "agent-browser";
|
|
|
4
4
|
const ALLOWED_KEYS = new Set(["profile", "headed", "allow_domains", "login_url", "check"]);
|
|
5
5
|
const CHECK_KEYS = new Set(["url", "logged_in_url", "logged_out_url"]);
|
|
6
6
|
const REJECTED_KEYS = new Set(["path", "scope", "secret"]);
|
|
7
|
+
const HOST_ONLY_KEYS = new Set([
|
|
8
|
+
"launch_args",
|
|
9
|
+
"args",
|
|
10
|
+
"executable_path",
|
|
11
|
+
"executable",
|
|
12
|
+
"display",
|
|
13
|
+
"headless",
|
|
14
|
+
"xvfb",
|
|
15
|
+
"env",
|
|
16
|
+
]);
|
|
7
17
|
const PROFILE_NAME = /^[A-Za-z0-9_-]{1,64}$/;
|
|
8
18
|
const DOMAIN = /^(\*\.)?[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
|
|
9
19
|
function isPlainObject(value) {
|
|
@@ -67,6 +77,9 @@ export function parseStageBrowser(raw, label, stageId) {
|
|
|
67
77
|
if (REJECTED_KEYS.has(key)) {
|
|
68
78
|
return fail(label, stageId, `"${key}" is not allowed (the Host chooses profile location and scope)`);
|
|
69
79
|
}
|
|
80
|
+
if (HOST_ONLY_KEYS.has(key)) {
|
|
81
|
+
return fail(label, stageId, `"${key}" is not allowed (browser launch options are Host config: browser.launch_args and browser.executable_path in $STAGEFLOW_HOME/config.yaml)`);
|
|
82
|
+
}
|
|
70
83
|
if (!ALLOWED_KEYS.has(key)) {
|
|
71
84
|
return fail(label, stageId, `unknown key "${key}" (allowed: profile, headed, allow_domains, login_url, check)`);
|
|
72
85
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TriggerFile } from "../types/trigger.js";
|
|
2
|
+
import type { RunStore } from "../runstore/port.js";
|
|
3
|
+
export type TriggerAdapterStatus = {
|
|
4
|
+
adapter: string;
|
|
5
|
+
state: string;
|
|
6
|
+
detail?: string;
|
|
7
|
+
last_poll_at?: string;
|
|
8
|
+
last_seen_at?: string;
|
|
9
|
+
last_error?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function readTriggerAdapterStatus(trigger: TriggerFile, store: RunStore): Promise<TriggerAdapterStatus>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
function parseGithubCursor(raw) {
|
|
2
|
+
if (raw === null) {
|
|
3
|
+
return null;
|
|
4
|
+
}
|
|
5
|
+
try {
|
|
6
|
+
const parsed = JSON.parse(raw);
|
|
7
|
+
if (typeof parsed.updatedAt === "string") {
|
|
8
|
+
return { updatedAt: parsed.updatedAt };
|
|
9
|
+
}
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function mailboxKeyForTrigger(trigger) {
|
|
17
|
+
const config = trigger.event?.config;
|
|
18
|
+
const host = config?.host;
|
|
19
|
+
const port = config?.port;
|
|
20
|
+
const user = config?.user;
|
|
21
|
+
if (typeof host !== "string" ||
|
|
22
|
+
host.length === 0 ||
|
|
23
|
+
typeof port !== "number" ||
|
|
24
|
+
!Number.isFinite(port) ||
|
|
25
|
+
typeof user !== "string" ||
|
|
26
|
+
user.length === 0) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
return `email:${host}:${port}:${user}`;
|
|
30
|
+
}
|
|
31
|
+
async function adapterStateUpdatedAt(store, adapterId, key) {
|
|
32
|
+
const meta = await store.getTriggerAdapterStateMeta(adapterId, key);
|
|
33
|
+
return meta?.updated_at;
|
|
34
|
+
}
|
|
35
|
+
export async function readTriggerAdapterStatus(trigger, store) {
|
|
36
|
+
if (!trigger.enabled) {
|
|
37
|
+
return { adapter: trigger.kind, state: "disabled" };
|
|
38
|
+
}
|
|
39
|
+
if (trigger.kind === "manual") {
|
|
40
|
+
return { adapter: "manual", state: "idle" };
|
|
41
|
+
}
|
|
42
|
+
if (trigger.kind === "schedule") {
|
|
43
|
+
return { adapter: "schedule", state: "scheduled" };
|
|
44
|
+
}
|
|
45
|
+
const source = trigger.event?.source ?? "";
|
|
46
|
+
if (source === "webhook") {
|
|
47
|
+
return { adapter: "webhook", state: "ready", detail: "Endpoint ready when host is running" };
|
|
48
|
+
}
|
|
49
|
+
if (source.startsWith("github.")) {
|
|
50
|
+
const repo = trigger.event?.config?.repo;
|
|
51
|
+
if (typeof repo !== "string" || repo.length === 0) {
|
|
52
|
+
return {
|
|
53
|
+
adapter: "github",
|
|
54
|
+
state: "error",
|
|
55
|
+
detail: "event.config.repo is required",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const adapterId = `github:${repo}`;
|
|
59
|
+
const cursor = parseGithubCursor(await store.getTriggerAdapterState(adapterId, "cursor"));
|
|
60
|
+
const lastPoll = await adapterStateUpdatedAt(store, adapterId, "etag");
|
|
61
|
+
const lastSeen = cursor?.updatedAt ?? lastPoll;
|
|
62
|
+
return {
|
|
63
|
+
adapter: "github",
|
|
64
|
+
state: cursor !== null || lastPoll !== undefined ? "polling" : "idle",
|
|
65
|
+
...(lastPoll !== undefined ? { last_poll_at: lastPoll } : {}),
|
|
66
|
+
...(lastSeen !== undefined ? { last_seen_at: lastSeen } : {}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (source === "email.message") {
|
|
70
|
+
const mailboxKey = mailboxKeyForTrigger(trigger);
|
|
71
|
+
if (mailboxKey === undefined) {
|
|
72
|
+
return {
|
|
73
|
+
adapter: "email",
|
|
74
|
+
state: "error",
|
|
75
|
+
detail: "Incomplete email event.config",
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const uid = await store.getTriggerAdapterState(mailboxKey, "uid");
|
|
79
|
+
const lastSeen = await adapterStateUpdatedAt(store, mailboxKey, "uid");
|
|
80
|
+
return {
|
|
81
|
+
adapter: "email",
|
|
82
|
+
state: uid !== null ? "connected" : "watching",
|
|
83
|
+
...(lastSeen !== undefined ? { last_seen_at: lastSeen } : {}),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
adapter: source.length > 0 ? source : "event",
|
|
88
|
+
state: "idle",
|
|
89
|
+
};
|
|
90
|
+
}
|