stageflow 0.32.0 → 0.35.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 +4 -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 +50 -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/fakeAgent.js +0 -6
- package/dist/agent/piAdapter.d.ts +2 -2
- package/dist/agent/piAdapter.js +116 -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 +2 -2
- package/dist/agent/providerAuth.d.ts +6 -0
- package/dist/agent/providerAuth.js +86 -17
- package/dist/agent/{resolveAgentPort.d.ts → resolveStagePort.d.ts} +8 -6
- package/dist/agent/{resolveAgentPort.js → resolveStagePort.js} +13 -9
- 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/cli/browserCommand.d.ts +3 -1
- package/dist/cli/browserCommand.js +25 -20
- 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 +41 -0
- package/dist/config/draftPackage.js +216 -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 +113 -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/listConfig.d.ts +0 -16
- package/dist/config/listConfig.js +0 -3
- package/dist/config/loadOutcome.d.ts +11 -6
- package/dist/config/loadPipeline.js +0 -1
- package/dist/config/loadStage.js +2 -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.js +3 -0
- package/dist/config/normalizePipelineStageEntry.js +10 -1
- 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 +6 -2
- package/dist/config/validateCatalog.js +48 -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/hosted/containment.d.ts +3 -0
- package/dist/hosted/containment.js +36 -0
- package/dist/hosted/errors.d.ts +21 -0
- package/dist/hosted/errors.js +30 -0
- package/dist/hosted/packageSkills.d.ts +3 -0
- package/dist/hosted/packageSkills.js +80 -0
- package/dist/hosted/runtime.d.ts +12 -0
- package/dist/hosted/runtime.js +596 -0
- package/dist/hosted/sequencer.d.ts +28 -0
- package/dist/hosted/sequencer.js +129 -0
- package/dist/hosted/translate.d.ts +3 -0
- package/dist/hosted/translate.js +43 -0
- package/dist/hosted/types.d.ts +108 -0
- package/dist/hosted/types.js +10 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +6 -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/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/projection/projectRun.d.ts +0 -1
- package/dist/projection/projectRun.js +0 -1
- 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/containerLimits.d.ts +0 -3
- package/dist/runtime/containerLimits.js +0 -5
- package/dist/runtime/credentialBinding.d.ts +3 -0
- package/dist/runtime/credentialBinding.js +23 -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/pipelineScheduler.d.ts +2 -2
- package/dist/runtime/pipelineScheduler.js +3 -0
- 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 +95 -30
- package/dist/runtime/runRetentionSweep.d.ts +0 -2
- package/dist/runtime/runRetentionSweep.js +0 -8
- 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 +10 -1
- package/dist/runtime/stageProcessLauncher.js +2 -2
- package/dist/runtime/stageRoots.js +12 -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 +7 -2
- package/dist/server/bootstrap.js +15 -1
- 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 +605 -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/readEmail.d.ts +3 -3
- package/dist/tools/writeStageArtifact.d.ts +9 -0
- package/dist/tools/writeStageArtifact.js +2 -47
- package/dist/types/pipeline.d.ts +1 -1
- package/dist/types/stage.d.ts +1 -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-BoFPkKFg.js +256 -0
- package/dist/ui/assets/{index-Bv4p1aPK.css → index-CIPbbBUi.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/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 +9 -1
- 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
|
@@ -21,6 +21,7 @@ import { hydrateScheduleFromStore, hydratedScheduleHasRunnableWork, resumeRun, r
|
|
|
21
21
|
import { resolveFeedbackLoopDecision, } from "./feedbackLoopDecision.js";
|
|
22
22
|
import { RunRetryCoordinator, readRetryRootWaitTimeoutMs, } from "./runRetryCoordinator.js";
|
|
23
23
|
import { readMaxActiveStageProcesses, readMaxActiveStagesPerRun, readStageExecutionMode, } from "./stageConcurrency.js";
|
|
24
|
+
import { runOwnerScope } from "../browser/ownerScope.js";
|
|
24
25
|
import { isHumanLoginStage } from "../browser/humanLogin.js";
|
|
25
26
|
import { defaultStageBrowserSupport, resolveStageBrowserEnv, } from "../browser/stageBrowserEnv.js";
|
|
26
27
|
import { teardownRunBrowsers, teardownStageBrowser, } from "../browser/browserTeardown.js";
|
|
@@ -267,6 +268,9 @@ export class RunManager {
|
|
|
267
268
|
queuedDone = new Map();
|
|
268
269
|
admissionDrainInFlight = false;
|
|
269
270
|
resumeInFlight = new Set();
|
|
271
|
+
gateClosedListeners = new Set();
|
|
272
|
+
beforeBrowserTeardownListeners = new Set();
|
|
273
|
+
shutdownListeners = new Set();
|
|
270
274
|
retryInFlight = new Set();
|
|
271
275
|
retryStartOwner = new Map();
|
|
272
276
|
retryStartWaiters = new Map();
|
|
@@ -357,7 +361,18 @@ export class RunManager {
|
|
|
357
361
|
return this.active.size;
|
|
358
362
|
}
|
|
359
363
|
stopAcceptingWork() {
|
|
364
|
+
const wasAccepting = this.acceptingWork;
|
|
360
365
|
this.acceptingWork = false;
|
|
366
|
+
if (wasAccepting) {
|
|
367
|
+
for (const listener of [...this.shutdownListeners]) {
|
|
368
|
+
try {
|
|
369
|
+
listener();
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
// listeners must not affect shutdown
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
361
376
|
for (const halt of this.schedulingHalts.values()) {
|
|
362
377
|
halt.halted = true;
|
|
363
378
|
halt.hostShutdown = true;
|
|
@@ -592,13 +607,14 @@ export class RunManager {
|
|
|
592
607
|
.some((entry) => entry.runId === runId && entry.stageId === stageId);
|
|
593
608
|
}
|
|
594
609
|
async sweepBrowserSessions() {
|
|
595
|
-
const support = this.
|
|
610
|
+
const support = this.browserSupport();
|
|
596
611
|
const isRunLive = createRunLiveness(this.options.store);
|
|
597
612
|
await stageProfileLock(support)
|
|
598
613
|
.reclaimStale(isRunLive)
|
|
599
614
|
.catch(() => 0);
|
|
600
615
|
return sweepOrphanBrowserSessions({
|
|
601
616
|
isRunLive,
|
|
617
|
+
host: support.host,
|
|
602
618
|
...(support.runner !== undefined ? { runner: support.runner } : {}),
|
|
603
619
|
...(support.closeWaitMs !== undefined
|
|
604
620
|
? { closeWaitMs: support.closeWaitMs }
|
|
@@ -833,6 +849,64 @@ export class RunManager {
|
|
|
833
849
|
}
|
|
834
850
|
await this.drainAdmissionQueue();
|
|
835
851
|
}
|
|
852
|
+
/** Called when a stage's gate stops accepting operator input (answered, abandoned) or a run is cancelled (no stage id). */
|
|
853
|
+
onGateClosed(listener) {
|
|
854
|
+
this.gateClosedListeners.add(listener);
|
|
855
|
+
return () => {
|
|
856
|
+
this.gateClosedListeners.delete(listener);
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
/** Awaited (bounded by the browser support) before a stage's or run's browser is torn down; stageId absent means the whole run. */
|
|
860
|
+
beforeBrowserTeardown(listener) {
|
|
861
|
+
this.beforeBrowserTeardownListeners.add(listener);
|
|
862
|
+
return () => {
|
|
863
|
+
this.beforeBrowserTeardownListeners.delete(listener);
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
/** Called once the Host stops accepting work (drain start). */
|
|
867
|
+
onShutdown(listener) {
|
|
868
|
+
this.shutdownListeners.add(listener);
|
|
869
|
+
return () => {
|
|
870
|
+
this.shutdownListeners.delete(listener);
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
browserSupport() {
|
|
874
|
+
const base = this.options.browser ?? defaultStageBrowserSupport();
|
|
875
|
+
if (this.beforeBrowserTeardownListeners.size === 0)
|
|
876
|
+
return base;
|
|
877
|
+
return {
|
|
878
|
+
...base,
|
|
879
|
+
beforeTeardown: async (input) => {
|
|
880
|
+
await Promise.all([
|
|
881
|
+
base.beforeTeardown?.(input),
|
|
882
|
+
...[...this.beforeBrowserTeardownListeners].map(async (listener) => {
|
|
883
|
+
try {
|
|
884
|
+
await listener(input);
|
|
885
|
+
}
|
|
886
|
+
catch {
|
|
887
|
+
// listeners must not block teardown
|
|
888
|
+
}
|
|
889
|
+
}),
|
|
890
|
+
]);
|
|
891
|
+
},
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
browserOption() {
|
|
895
|
+
if (this.options.browser === undefined && this.beforeBrowserTeardownListeners.size === 0) {
|
|
896
|
+
return {};
|
|
897
|
+
}
|
|
898
|
+
return { browser: this.browserSupport() };
|
|
899
|
+
}
|
|
900
|
+
notifyGateClosed(runId, stageId) {
|
|
901
|
+
for (const listener of [...this.gateClosedListeners]) {
|
|
902
|
+
try {
|
|
903
|
+
listener(runId, stageId);
|
|
904
|
+
}
|
|
905
|
+
catch {
|
|
906
|
+
// listeners must not affect run control
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
836
910
|
async abandonStage(runId, stageId) {
|
|
837
911
|
let detail;
|
|
838
912
|
try {
|
|
@@ -863,6 +937,7 @@ export class RunManager {
|
|
|
863
937
|
status: 409,
|
|
864
938
|
};
|
|
865
939
|
}
|
|
940
|
+
this.notifyGateClosed(runId, stageId);
|
|
866
941
|
if (this.stageProcessLauncher !== undefined) {
|
|
867
942
|
const hasActive = this.stageProcessLauncher
|
|
868
943
|
.getActiveStageProcesses()
|
|
@@ -871,7 +946,7 @@ export class RunManager {
|
|
|
871
946
|
await this.stageProcessLauncher.cancelRun(runId);
|
|
872
947
|
}
|
|
873
948
|
}
|
|
874
|
-
await teardownStageBrowser(this.
|
|
949
|
+
await teardownStageBrowser(this.browserSupport(), {
|
|
875
950
|
runId,
|
|
876
951
|
runDir: this.options.store.getWorkspaceDir(runId),
|
|
877
952
|
stageId,
|
|
@@ -893,7 +968,7 @@ export class RunManager {
|
|
|
893
968
|
const hasWaiting = after.stages.some((s) => s.status === "waiting_for_input");
|
|
894
969
|
if (!hasWaiting &&
|
|
895
970
|
!(await createRunLiveness(this.options.store)(runId).catch(() => true))) {
|
|
896
|
-
await teardownRunBrowsers(this.
|
|
971
|
+
await teardownRunBrowsers(this.browserSupport(), {
|
|
897
972
|
runId,
|
|
898
973
|
runDir: this.options.store.getWorkspaceDir(runId),
|
|
899
974
|
events: (stageId) => this.options.store.listStageEvents(runId, stageId),
|
|
@@ -931,6 +1006,7 @@ export class RunManager {
|
|
|
931
1006
|
};
|
|
932
1007
|
}
|
|
933
1008
|
await this.options.store.updateRunStatus(runId, "cancelled");
|
|
1009
|
+
this.notifyGateClosed(runId);
|
|
934
1010
|
await this.options.store.setCancelReason(runId, trimmedReason);
|
|
935
1011
|
await finaliseStoredRunManifest(this.options.store, runId).catch(() => undefined);
|
|
936
1012
|
await this.refreshRunDiskBytes(runId).catch(() => undefined);
|
|
@@ -950,7 +1026,7 @@ export class RunManager {
|
|
|
950
1026
|
if (this.stageProcessLauncher !== undefined) {
|
|
951
1027
|
await this.stageProcessLauncher.cancelRun(runId);
|
|
952
1028
|
}
|
|
953
|
-
await teardownRunBrowsers(this.
|
|
1029
|
+
await teardownRunBrowsers(this.browserSupport(), {
|
|
954
1030
|
runId,
|
|
955
1031
|
runDir: this.options.store.getWorkspaceDir(runId),
|
|
956
1032
|
events: (stageId) => this.options.store.listStageEvents(runId, stageId),
|
|
@@ -1530,9 +1606,7 @@ export class RunManager {
|
|
|
1530
1606
|
agent: this.options.agent,
|
|
1531
1607
|
cwd: meta.project_root ?? this.projectRoot,
|
|
1532
1608
|
operatorCatalog: this.options.operatorCatalog,
|
|
1533
|
-
...
|
|
1534
|
-
? { browser: this.options.browser }
|
|
1535
|
-
: {}),
|
|
1609
|
+
...this.browserOption(),
|
|
1536
1610
|
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
1537
1611
|
executionMode: this.executionMode,
|
|
1538
1612
|
stageProcessLauncher: this.stageProcessLauncher,
|
|
@@ -1757,6 +1831,7 @@ export class RunManager {
|
|
|
1757
1831
|
}
|
|
1758
1832
|
return prefix;
|
|
1759
1833
|
}
|
|
1834
|
+
this.notifyGateClosed(runId, stageId);
|
|
1760
1835
|
return await orchestrateAnswerResume({
|
|
1761
1836
|
prefixMode: prefix.mode,
|
|
1762
1837
|
executionMode: this.executionMode,
|
|
@@ -1896,9 +1971,7 @@ export class RunManager {
|
|
|
1896
1971
|
checkoutRoot: meta.checkout_root,
|
|
1897
1972
|
hitl: this.hitl,
|
|
1898
1973
|
operatorCatalog: this.options.operatorCatalog,
|
|
1899
|
-
...
|
|
1900
|
-
? { browser: this.options.browser }
|
|
1901
|
-
: {}),
|
|
1974
|
+
...this.browserOption(),
|
|
1902
1975
|
},
|
|
1903
1976
|
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
1904
1977
|
executionMode: this.executionMode,
|
|
@@ -1957,7 +2030,8 @@ export class RunManager {
|
|
|
1957
2030
|
});
|
|
1958
2031
|
const resumedStage = loaded.stages.find((s) => s.id === definitionIdForInstance(meta.pipeline_dag, stageId));
|
|
1959
2032
|
if (resumedStage?.browser?.profile !== undefined) {
|
|
1960
|
-
await acquireStageProfile(this.
|
|
2033
|
+
await acquireStageProfile(this.browserSupport(), {
|
|
2034
|
+
scope: runOwnerScope(this.browserSupport(), { runId }),
|
|
1961
2035
|
profile: resumedStage.browser.profile,
|
|
1962
2036
|
owner: { runId, stageId },
|
|
1963
2037
|
isRunLive: createRunLiveness(store),
|
|
@@ -1968,9 +2042,10 @@ export class RunManager {
|
|
|
1968
2042
|
}
|
|
1969
2043
|
});
|
|
1970
2044
|
}
|
|
1971
|
-
const browserEnv = await resolveStageBrowserEnv(this.
|
|
2045
|
+
const browserEnv = await resolveStageBrowserEnv(this.browserSupport(), {
|
|
1972
2046
|
runId,
|
|
1973
2047
|
stageId,
|
|
2048
|
+
scope: runOwnerScope(this.browserSupport(), { runId }),
|
|
1974
2049
|
runDir: workspaceDir,
|
|
1975
2050
|
browser: resumedStage?.browser,
|
|
1976
2051
|
attempt,
|
|
@@ -1999,7 +2074,7 @@ export class RunManager {
|
|
|
1999
2074
|
if (launchResult.type === "waiting") {
|
|
2000
2075
|
return { ok: true };
|
|
2001
2076
|
}
|
|
2002
|
-
await teardownStageBrowser(this.
|
|
2077
|
+
await teardownStageBrowser(this.browserSupport(), {
|
|
2003
2078
|
runId,
|
|
2004
2079
|
runDir: workspaceDir,
|
|
2005
2080
|
stageId,
|
|
@@ -2021,9 +2096,7 @@ export class RunManager {
|
|
|
2021
2096
|
checkoutRoot: meta.checkout_root,
|
|
2022
2097
|
hitl: this.hitl,
|
|
2023
2098
|
operatorCatalog: this.options.operatorCatalog,
|
|
2024
|
-
...
|
|
2025
|
-
? { browser: this.options.browser }
|
|
2026
|
-
: {}),
|
|
2099
|
+
...this.browserOption(),
|
|
2027
2100
|
},
|
|
2028
2101
|
retryRoots: new Map([[stageId, nextRepairAttempt]]),
|
|
2029
2102
|
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
@@ -2041,7 +2114,7 @@ export class RunManager {
|
|
|
2041
2114
|
reason: launchResult.reason,
|
|
2042
2115
|
}, eventOptions);
|
|
2043
2116
|
await store.updateRunStatus(runId, "failed");
|
|
2044
|
-
await teardownRunBrowsers(this.
|
|
2117
|
+
await teardownRunBrowsers(this.browserSupport(), {
|
|
2045
2118
|
runId,
|
|
2046
2119
|
runDir: workspaceDir,
|
|
2047
2120
|
events: (stageId) => store.listStageEvents(runId, stageId),
|
|
@@ -2067,9 +2140,7 @@ export class RunManager {
|
|
|
2067
2140
|
checkoutRoot: meta.checkout_root,
|
|
2068
2141
|
hitl: this.hitl,
|
|
2069
2142
|
operatorCatalog: this.options.operatorCatalog,
|
|
2070
|
-
...
|
|
2071
|
-
? { browser: this.options.browser }
|
|
2072
|
-
: {}),
|
|
2143
|
+
...this.browserOption(),
|
|
2073
2144
|
},
|
|
2074
2145
|
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
2075
2146
|
resumeFromStageId: stageId,
|
|
@@ -2093,7 +2164,7 @@ export class RunManager {
|
|
|
2093
2164
|
reason,
|
|
2094
2165
|
}, eventOptions);
|
|
2095
2166
|
await store.updateRunStatus(runId, "failed");
|
|
2096
|
-
await teardownRunBrowsers(this.
|
|
2167
|
+
await teardownRunBrowsers(this.browserSupport(), {
|
|
2097
2168
|
runId,
|
|
2098
2169
|
runDir: store.getWorkspaceDir(runId),
|
|
2099
2170
|
events: (stageId) => store.listStageEvents(runId, stageId),
|
|
@@ -2406,9 +2477,7 @@ export class RunManager {
|
|
|
2406
2477
|
const started = await startPipeline({
|
|
2407
2478
|
dispatchKey,
|
|
2408
2479
|
submission,
|
|
2409
|
-
...
|
|
2410
|
-
? { browser: this.options.browser }
|
|
2411
|
-
: {}),
|
|
2480
|
+
...this.browserOption(),
|
|
2412
2481
|
agent: this.options.agent,
|
|
2413
2482
|
store: this.options.store,
|
|
2414
2483
|
taskYaml,
|
|
@@ -2911,9 +2980,7 @@ export class RunManager {
|
|
|
2911
2980
|
const schedulingHalt = this.ensureSchedulingHalt(runId);
|
|
2912
2981
|
const started = await startPipeline({
|
|
2913
2982
|
submission,
|
|
2914
|
-
...
|
|
2915
|
-
? { browser: this.options.browser }
|
|
2916
|
-
: {}),
|
|
2983
|
+
...this.browserOption(),
|
|
2917
2984
|
agent: this.options.agent,
|
|
2918
2985
|
store: this.options.store,
|
|
2919
2986
|
taskYaml,
|
|
@@ -3018,9 +3085,7 @@ export class RunManager {
|
|
|
3018
3085
|
checkoutRoot: loadedMeta.checkout_root,
|
|
3019
3086
|
hitl: this.hitl,
|
|
3020
3087
|
operatorCatalog: this.options.operatorCatalog,
|
|
3021
|
-
...
|
|
3022
|
-
? { browser: this.options.browser }
|
|
3023
|
-
: {}),
|
|
3088
|
+
...this.browserOption(),
|
|
3024
3089
|
},
|
|
3025
3090
|
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
3026
3091
|
executionMode: this.executionMode,
|
|
@@ -15,8 +15,6 @@ export type RunRetentionSweepOptions = {
|
|
|
15
15
|
artifactMaxBytes?: number;
|
|
16
16
|
bareCacheTtlMs?: number;
|
|
17
17
|
};
|
|
18
|
-
export declare function getSlimWalkCallCount(): number;
|
|
19
|
-
export declare function resetSlimWalkCallCount(): void;
|
|
20
18
|
/**
|
|
21
19
|
* Walk attempt + legacy artifact trees and remove SLIM-eligible paths.
|
|
22
20
|
* Never removes envelope.json, log.jsonl, or under-threshold artifacts.
|
|
@@ -7,13 +7,6 @@ import { reclaimWorkspaceBinding, worktreePathForRun, } from "./repositoryMateri
|
|
|
7
7
|
import { deleteRunEverywhere } from "./runDeletion.js";
|
|
8
8
|
const SLIM_ATTEMPT_FILES = ["pi-session.jsonl", "stream.log"];
|
|
9
9
|
const SLIM_ATTEMPT_DIRS = [".pi-agent"];
|
|
10
|
-
let slimWalkCallCount = 0;
|
|
11
|
-
export function getSlimWalkCallCount() {
|
|
12
|
-
return slimWalkCallCount;
|
|
13
|
-
}
|
|
14
|
-
export function resetSlimWalkCallCount() {
|
|
15
|
-
slimWalkCallCount = 0;
|
|
16
|
-
}
|
|
17
10
|
async function pathExists(target) {
|
|
18
11
|
try {
|
|
19
12
|
await stat(target);
|
|
@@ -84,7 +77,6 @@ async function slimAttemptDir(attemptDir, maxBytes) {
|
|
|
84
77
|
* Never removes envelope.json, log.jsonl, or under-threshold artifacts.
|
|
85
78
|
*/
|
|
86
79
|
export async function slimRunWorkspaceArtifacts(workspaceDir, maxBytes) {
|
|
87
|
-
slimWalkCallCount += 1;
|
|
88
80
|
const stagesRoot = path.join(workspaceDir, "stages");
|
|
89
81
|
if (!(await pathExists(stagesRoot)))
|
|
90
82
|
return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StagePort } from "../agent/port.js";
|
|
2
2
|
import { type RunDetail, type RunPipelineDagSnapshot, type RunStatus, type RunStore, type StageSnapshot } from "../runstore/port.js";
|
|
3
3
|
import type { PipelineRunResult } from "./pipelineRunner.js";
|
|
4
4
|
import { type SchedulerPreparedPipeline } from "./pipelineScheduler.js";
|
|
@@ -56,7 +56,7 @@ export type RetryStageRequest = {
|
|
|
56
56
|
runId: string;
|
|
57
57
|
stageId: string;
|
|
58
58
|
store: RunStore;
|
|
59
|
-
agent:
|
|
59
|
+
agent: StagePort;
|
|
60
60
|
cwd: string;
|
|
61
61
|
operatorCatalog?: OperatorCatalog;
|
|
62
62
|
browser?: StageBrowserSupport;
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import { Cron } from "croner";
|
|
3
|
-
import {
|
|
4
|
-
import { loadTriggerOutcome } from "../config/loadTrigger.js";
|
|
5
|
-
import { catalogContextFromStageflow } from "../config/resolveCatalogContext.js";
|
|
6
|
-
import { resolveStageflowContext } from "../project/resolveStageflowContext.js";
|
|
2
|
+
import { listCatalogTriggerMatches, readTriggerStoreRecord, triggerStoreId, } from "../config/triggerCatalog.js";
|
|
7
3
|
export const DEFAULT_TRIGGER_TICK_INTERVAL_MS = 30_000;
|
|
8
4
|
/** Parse `STAGEFLOW_TRIGGER_TICK_INTERVAL_MS`; default 30s; `0` disables. */
|
|
9
5
|
export function triggerTickIntervalMsFromEnv(env = process.env) {
|
|
@@ -72,17 +68,14 @@ export class ScheduleSource {
|
|
|
72
68
|
* against an injected clock instead of waiting on real interval timers.
|
|
73
69
|
*/
|
|
74
70
|
async tick(onFire) {
|
|
75
|
-
const ctx = catalogContextFromStageflow(await resolveStageflowContext(this.cwd));
|
|
76
|
-
const scanPaths = await getCatalogScanPaths(ctx);
|
|
77
|
-
if (!scanPaths)
|
|
78
|
-
return;
|
|
79
71
|
const now = this.now();
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
72
|
+
const catalogTriggers = await listCatalogTriggerMatches({
|
|
73
|
+
store: this.store,
|
|
74
|
+
bootCwd: this.cwd,
|
|
75
|
+
sourceRootsOnly: true,
|
|
76
|
+
});
|
|
77
|
+
for (const match of catalogTriggers) {
|
|
78
|
+
const definition = match.definition;
|
|
86
79
|
if (definition.kind !== "schedule" || !definition.enabled || !definition.schedule) {
|
|
87
80
|
continue;
|
|
88
81
|
}
|
|
@@ -94,25 +87,23 @@ export class ScheduleSource {
|
|
|
94
87
|
this.logError(`invalid schedule for trigger "${definition.id}": ${err instanceof Error ? err.message : String(err)}`);
|
|
95
88
|
continue;
|
|
96
89
|
}
|
|
97
|
-
const
|
|
98
|
-
? path.relative(projectRoot, triggerPath).replace(/\\/g, "/")
|
|
99
|
-
: triggerPath;
|
|
90
|
+
const storeId = triggerStoreId(match.project_root, definition.id);
|
|
100
91
|
await this.store.upsertTrigger({
|
|
101
|
-
id:
|
|
102
|
-
definitionRef,
|
|
92
|
+
id: storeId,
|
|
93
|
+
definitionRef: match.definition_ref,
|
|
103
94
|
enabled: true,
|
|
104
95
|
});
|
|
105
|
-
const record = await this.store.
|
|
96
|
+
const record = await readTriggerStoreRecord(this.store, match.project_root, definition.id);
|
|
106
97
|
if (!record?.next_run_at) {
|
|
107
98
|
if (next)
|
|
108
|
-
await this.store.setTriggerNextRun(
|
|
99
|
+
await this.store.setTriggerNextRun(storeId, next.toISOString());
|
|
109
100
|
continue;
|
|
110
101
|
}
|
|
111
102
|
const dueAt = new Date(record.next_run_at);
|
|
112
103
|
if (dueAt.getTime() <= now.getTime()) {
|
|
113
|
-
await onFire({ triggerId: definition.id });
|
|
104
|
+
await onFire({ triggerId: definition.id, project_root: match.project_root });
|
|
114
105
|
if (next)
|
|
115
|
-
await this.store.setTriggerNextRun(
|
|
106
|
+
await this.store.setTriggerNextRun(storeId, next.toISOString());
|
|
116
107
|
}
|
|
117
108
|
}
|
|
118
109
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StagePort, FeedbackLoopContext, StageHandle, StageRunInput, StageSessionMode } from "../agent/port.js";
|
|
2
2
|
import { type StageStreamLogWriter } from "./stageStreamLog.js";
|
|
3
3
|
import type { RunStore } from "../runstore/port.js";
|
|
4
4
|
import type { StageEnvelope } from "../types/envelope.js";
|
|
@@ -12,7 +12,7 @@ export type OperatorCatalog = {
|
|
|
12
12
|
agentDir?: string;
|
|
13
13
|
};
|
|
14
14
|
export type StageAttemptOpenInput = {
|
|
15
|
-
agent: Pick<
|
|
15
|
+
agent: Pick<StagePort, "openStage">;
|
|
16
16
|
store: RunStore;
|
|
17
17
|
runId: string;
|
|
18
18
|
stage: LoadedStageConfig;
|
|
@@ -2,6 +2,7 @@ import { emailHostFor, stageEmail, workerStageEmail, validateStageEmailAccounts
|
|
|
2
2
|
import { EmailError } from "../email/port.js";
|
|
3
3
|
import { bindingKindForOrigin, catalogOrSeededOrigin, decideWorkspaceConfigTrust, } from "../config/configOrigin.js";
|
|
4
4
|
import { loginCheckPromptBlock, readStageLoginCheck, } from "../browser/loginCheck.js";
|
|
5
|
+
import { stageGateHandoff } from "../browser/stageHandoff.js";
|
|
5
6
|
import { humanLoginPromptBlock, isHumanLoginStage } from "../browser/humanLogin.js";
|
|
6
7
|
import { BROWSER_SKILL_NAME, resolveBuiltinSkillFile, } from "../config/builtinSkills.js";
|
|
7
8
|
import { resolveSkillByName, } from "../config/listSkills.js";
|
|
@@ -239,12 +240,20 @@ async function openStageWithOperatorCatalog(agent, input, catalog, factoryCwd, a
|
|
|
239
240
|
return { ok: false, reason: "browser login check result is missing" };
|
|
240
241
|
}
|
|
241
242
|
}
|
|
243
|
+
const humanLoginHandoff = humanLogin
|
|
244
|
+
? await stageGateHandoff({
|
|
245
|
+
runDir: resolveOptions.workspaceDir,
|
|
246
|
+
runId: resolveOptions.runId,
|
|
247
|
+
stageId: input.stage.id,
|
|
248
|
+
dirStageId: stageIdForManifest,
|
|
249
|
+
})
|
|
250
|
+
: undefined;
|
|
242
251
|
try {
|
|
243
252
|
const handle = agent.openStage({
|
|
244
253
|
...input,
|
|
245
254
|
stage: {
|
|
246
255
|
...input.stage,
|
|
247
|
-
system_prompt: `${stampStagePromptArtifactsDir(input.stage.system_prompt, artifactsDir)}${loginCheck !== undefined ? `\n\n${loginCheckPromptBlock(loginCheck)}` : ""}${humanLogin ? `\n\n${humanLoginPromptBlock(input.stage.browser?.login_url ?? input.stage.browser?.check?.url)}` : ""}`,
|
|
256
|
+
system_prompt: `${stampStagePromptArtifactsDir(input.stage.system_prompt, artifactsDir)}${loginCheck !== undefined ? `\n\n${loginCheckPromptBlock(loginCheck)}` : ""}${humanLogin ? `\n\n${humanLoginPromptBlock(input.stage.browser?.login_url ?? input.stage.browser?.check?.url, humanLoginHandoff?.kind === "live_view" ? "live_view" : "local_window")}` : ""}`,
|
|
248
257
|
...(loginCheck !== undefined
|
|
249
258
|
? {
|
|
250
259
|
pre_emit_checks: [
|
|
@@ -4,7 +4,7 @@ import { logger as rootLogger, resolveLogMaxLineBytes, } from "../logging/logger
|
|
|
4
4
|
import { isCursorModelRef, readCursorApiKey } from "../agent/cursorProvider.js";
|
|
5
5
|
import { BROWSER_ENV_PREFIX } from "../browser/browserHost.js";
|
|
6
6
|
import { PACKAGE_VERSION } from "../package-meta.js";
|
|
7
|
-
import { PI_HOME_AUTH_PATH_ENV,
|
|
7
|
+
import { PI_HOME_AUTH_PATH_ENV, sfOwnedAuthPath } from "./credentialBinding.js";
|
|
8
8
|
import { redactString } from "../logging/redact.js";
|
|
9
9
|
import { getNamedSecrets } from "../logging/namedSecrets.js";
|
|
10
10
|
import { readMaxActiveStageProcesses, } from "./stageConcurrency.js";
|
|
@@ -352,7 +352,7 @@ export class StageProcessLauncher {
|
|
|
352
352
|
: overlaid;
|
|
353
353
|
const childEnv = {
|
|
354
354
|
...withBrowser,
|
|
355
|
-
[PI_HOME_AUTH_PATH_ENV]:
|
|
355
|
+
[PI_HOME_AUTH_PATH_ENV]: sfOwnedAuthPath(),
|
|
356
356
|
};
|
|
357
357
|
const cursorApiKey = readCursorApiKey(hostEnv);
|
|
358
358
|
if (isCursorModelRef(input.model ?? "") &&
|
|
@@ -3,7 +3,8 @@ import path from "node:path";
|
|
|
3
3
|
import { isCursorModelRef } from "../agent/cursorProvider.js";
|
|
4
4
|
import { stageDir } from "../runstore/paths.js";
|
|
5
5
|
import { noAttemptContext } from "./stageAttemptContext.js";
|
|
6
|
-
import { resolveCredentialBinding } from "./credentialBinding.js";
|
|
6
|
+
import { resolveCredentialBinding, STAGEFLOW_AGENT_AUTH_PATH_ENV, currentExplicitAuthPath, } from "./credentialBinding.js";
|
|
7
|
+
import { SF_STAGE_WORKER } from "./stageWorkerProtocol.js";
|
|
7
8
|
export const STAGEFLOW_CHECKOUT = "STAGEFLOW_CHECKOUT";
|
|
8
9
|
export const STAGEFLOW_RUN_WORKSPACE = "STAGEFLOW_RUN_WORKSPACE";
|
|
9
10
|
export const STAGEFLOW_REPOSITORY = "STAGEFLOW_REPOSITORY";
|
|
@@ -127,6 +128,16 @@ export function stageBindingEnvFromRun(options) {
|
|
|
127
128
|
export function withResolvedAuthPath(roots, factoryCwd) {
|
|
128
129
|
if (roots.authPath)
|
|
129
130
|
return roots;
|
|
131
|
+
const explicit = currentExplicitAuthPath();
|
|
132
|
+
if (explicit !== undefined) {
|
|
133
|
+
return { ...roots, authPath: explicit };
|
|
134
|
+
}
|
|
135
|
+
if (process.env[SF_STAGE_WORKER] === "1") {
|
|
136
|
+
const stamped = process.env[STAGEFLOW_AGENT_AUTH_PATH_ENV]?.trim();
|
|
137
|
+
if (!stamped)
|
|
138
|
+
return roots;
|
|
139
|
+
return { ...roots, authPath: path.resolve(stamped) };
|
|
140
|
+
}
|
|
130
141
|
const binding = resolveCredentialBinding(factoryCwd);
|
|
131
142
|
return { ...roots, authPath: binding.authPath };
|
|
132
143
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StagePort, FeedbackLoopContext, StageHandle, StageRunResult, StageSessionMode } from "../agent/port.js";
|
|
2
2
|
import { type HostGateContext } from "../browser/gateHandoff.js";
|
|
3
3
|
import type { StageBrowserSupport } from "../browser/browserHost.js";
|
|
4
4
|
import type { StageEnvelope } from "../types/envelope.js";
|
|
@@ -20,7 +20,7 @@ export declare function isRunStageWaiting(outcome: RunStageOutcome): outcome is
|
|
|
20
20
|
waiting: true;
|
|
21
21
|
};
|
|
22
22
|
export type RunStageOptions = {
|
|
23
|
-
agent:
|
|
23
|
+
agent: StagePort;
|
|
24
24
|
store: RunStore;
|
|
25
25
|
runId: string;
|
|
26
26
|
stage: LoadedStageConfig;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { stampGateRequest } from "../browser/gateHandoff.js";
|
|
2
|
+
import { stageGateContext } from "../browser/stageHandoff.js";
|
|
2
3
|
import { deriveExecutionPatchFromEvent } from "../runstore/stageExecution.js";
|
|
3
4
|
import { buildStageRoots, withResolvedAuthPath, } from "./stageRoots.js";
|
|
4
5
|
import { createDefaultHitlQaHooks, recordWaitEnter, } from "./stageHitl.js";
|
|
@@ -231,7 +232,12 @@ export async function runStage(options) {
|
|
|
231
232
|
store: workerMode ? store : undefined,
|
|
232
233
|
attemptCtx,
|
|
233
234
|
skipGates,
|
|
234
|
-
gateContext:
|
|
235
|
+
gateContext: await stageGateContext({
|
|
236
|
+
runDir: workspaceDir ?? store.getWorkspaceDir(runId),
|
|
237
|
+
runId,
|
|
238
|
+
stageId,
|
|
239
|
+
browser: stage.browser,
|
|
240
|
+
}),
|
|
235
241
|
});
|
|
236
242
|
}
|
|
237
243
|
catch (err) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveStagePort } from "../agent/resolveStagePort.js";
|
|
2
2
|
import { asAgentBackendId } from "../agent/agentBackend.js";
|
|
3
3
|
import { loadStageflowManifestOutcome } from "../config/loadStageflowManifest.js";
|
|
4
4
|
import { loadNamedSecretsFromAttemptDir } from "../logging/namedSecrets.js";
|
|
@@ -29,7 +29,7 @@ export async function runStageWorker(input) {
|
|
|
29
29
|
}
|
|
30
30
|
const dag = meta.pipeline_dag ?? loaded.dag;
|
|
31
31
|
const manifestOutcome = await loadStageflowManifestOutcome(input.rootDir);
|
|
32
|
-
const agent =
|
|
32
|
+
const agent = resolveStagePort({
|
|
33
33
|
global: manifestOutcome.ok
|
|
34
34
|
? asAgentBackendId(manifestOutcome.value.manifest.agent)
|
|
35
35
|
: undefined,
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { TaskFile } from "../types/task.js";
|
|
2
2
|
export type TriggerFireEvent = {
|
|
3
3
|
triggerId: string;
|
|
4
|
+
project_root?: string;
|
|
4
5
|
task?: TaskFile;
|
|
5
6
|
};
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Long-running sources that decide "fire trigger X now". ScheduleSource,
|
|
9
|
+
* GithubPollSource, and EmailSource implement this. Webhook deliveries are
|
|
10
|
+
* request-driven: acceptWebhook shares TriggerFireEvent's optional task, and
|
|
11
|
+
* the HTTP route fires; a webhook is not a start/stop loop.
|
|
10
12
|
*/
|
|
11
13
|
export interface TriggerSourcePort {
|
|
12
14
|
start(onFire: (event: TriggerFireEvent) => Promise<void>): Promise<void>;
|