stageflow 0.27.0 → 0.31.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 -0
- package/builtin-skills/browser/SKILL.md +42 -0
- package/dist/agent/claudeAdapter.js +2 -2
- package/dist/agent/cursorProvider.d.ts +10 -0
- package/dist/agent/cursorProvider.js +83 -8
- package/dist/agent/fakeAgent.d.ts +1 -0
- package/dist/agent/fakeAgent.js +13 -0
- package/dist/agent/piAdapter.d.ts +3 -24
- package/dist/agent/piAdapter.js +49 -47
- package/dist/agent/piSessionFactory.d.ts +38 -0
- package/dist/agent/piSessionFactory.js +60 -0
- package/dist/agent/port.d.ts +2 -0
- package/dist/agent/providerAuth.d.ts +7 -3
- package/dist/agent/providerAuth.js +5 -3
- package/dist/agent/streamLogRedact.d.ts +6 -0
- package/dist/agent/streamLogRedact.js +23 -1
- package/dist/browser/anchor.d.ts +27 -0
- package/dist/browser/anchor.js +127 -0
- package/dist/browser/auditSink.d.ts +38 -0
- package/dist/browser/auditSink.js +34 -0
- package/dist/browser/browserHost.d.ts +86 -0
- package/dist/browser/browserHost.js +7 -0
- package/dist/browser/browserSweep.d.ts +14 -0
- package/dist/browser/browserSweep.js +54 -0
- package/dist/browser/browserTeardown.d.ts +56 -0
- package/dist/browser/browserTeardown.js +235 -0
- package/dist/browser/fakeRemoteBrowserHost.d.ts +2 -0
- package/dist/browser/fakeRemoteBrowserHost.js +34 -0
- package/dist/browser/gateHandoff.d.ts +25 -0
- package/dist/browser/gateHandoff.js +83 -0
- package/dist/browser/humanLogin.d.ts +18 -0
- package/dist/browser/humanLogin.js +34 -0
- package/dist/browser/keyProvider.d.ts +10 -0
- package/dist/browser/keyProvider.js +39 -0
- package/dist/browser/localBrowserHost.d.ts +10 -0
- package/dist/browser/localBrowserHost.js +152 -0
- package/dist/browser/localProfileLock.d.ts +2 -0
- package/dist/browser/localProfileLock.js +218 -0
- package/dist/browser/localProfileStore.d.ts +5 -0
- package/dist/browser/localProfileStore.js +91 -0
- package/dist/browser/loginCheck.d.ts +53 -0
- package/dist/browser/loginCheck.js +147 -0
- package/dist/browser/memoryProfileLock.d.ts +2 -0
- package/dist/browser/memoryProfileLock.js +53 -0
- package/dist/browser/memoryProfileStore.d.ts +2 -0
- package/dist/browser/memoryProfileStore.js +31 -0
- package/dist/browser/navigationAudit.d.ts +16 -0
- package/dist/browser/navigationAudit.js +53 -0
- package/dist/browser/persistedEnv.d.ts +3 -0
- package/dist/browser/persistedEnv.js +15 -0
- package/dist/browser/profileLock.d.ts +40 -0
- package/dist/browser/profileLock.js +10 -0
- package/dist/browser/profileStore.d.ts +23 -0
- package/dist/browser/profileStore.js +39 -0
- package/dist/browser/runLiveness.d.ts +13 -0
- package/dist/browser/runLiveness.js +39 -0
- package/dist/browser/sitePolicy.d.ts +10 -0
- package/dist/browser/sitePolicy.js +61 -0
- package/dist/browser/stageBrowserEnv.d.ts +22 -0
- package/dist/browser/stageBrowserEnv.js +147 -0
- package/dist/browser/stageProfileLock.d.ts +17 -0
- package/dist/browser/stageProfileLock.js +39 -0
- package/dist/cli/browserCommand.d.ts +44 -0
- package/dist/cli/browserCommand.js +472 -0
- package/dist/cli/doctorCommand.js +7 -0
- package/dist/cli/hostClient.d.ts +20 -0
- package/dist/cli/hostClient.js +36 -2
- package/dist/cli/initCommand.d.ts +1 -0
- package/dist/cli/initCommand.js +23 -7
- package/dist/cli/initTemplates.d.ts +5 -2
- package/dist/cli/initTemplates.js +25 -2
- package/dist/cli/providersCommand.d.ts +1 -1
- package/dist/cli/providersCommand.js +4 -4
- package/dist/cli/runsCommand.js +6 -2
- package/dist/cli/triggerCommand.d.ts +12 -0
- package/dist/cli/triggerCommand.js +183 -0
- package/dist/cli/validateCommand.d.ts +1 -1
- package/dist/cli/validateCommand.js +23 -6
- package/dist/cli.js +32 -3
- package/dist/config/browseCatalog.d.ts +1 -0
- package/dist/config/browseCatalog.js +5 -4
- package/dist/config/builtinSkills.d.ts +4 -0
- package/dist/config/builtinSkills.js +23 -0
- package/dist/config/catalogRelativePath.d.ts +1 -0
- package/dist/config/catalogRelativePath.js +10 -2
- package/dist/config/createTrigger.d.ts +27 -0
- package/dist/config/createTrigger.js +232 -0
- package/dist/config/draftPackage.d.ts +117 -0
- package/dist/config/draftPackage.js +550 -0
- package/dist/config/ensureCatalogScanRoot.d.ts +16 -0
- package/dist/config/ensureCatalogScanRoot.js +73 -0
- package/dist/config/hostConfig.d.ts +2 -0
- package/dist/config/hostConfig.js +27 -0
- package/dist/config/listSkills.d.ts +2 -2
- package/dist/config/listSkills.js +17 -3
- package/dist/config/loadOutcome.d.ts +6 -0
- package/dist/config/loadPipeline.js +16 -0
- package/dist/config/loadStage.js +7 -0
- package/dist/config/loadStageflowManifest.js +25 -0
- package/dist/config/loadTrigger.d.ts +9 -0
- package/dist/config/loadTrigger.js +120 -0
- package/dist/config/multiProjectCatalog.d.ts +2 -0
- package/dist/config/multiProjectCatalog.js +26 -18
- package/dist/config/normalizePipelineStageEntry.js +8 -1
- package/dist/config/parseCompletionContract.js +6 -0
- package/dist/config/pipelineStageKeys.js +1 -0
- package/dist/config/publishDraftPackage.d.ts +7 -0
- package/dist/config/publishDraftPackage.js +25 -0
- package/dist/config/resolveCatalogContext.js +1 -1
- package/dist/config/resolvePipelineDag.js +1 -1
- package/dist/config/scanCatalogPaths.d.ts +1 -1
- package/dist/config/scanCatalogPaths.js +6 -2
- package/dist/config/stageBrowser.d.ts +12 -0
- package/dist/config/stageBrowser.js +118 -0
- package/dist/config/triggerCatalog.d.ts +10 -0
- package/dist/config/triggerCatalog.js +37 -0
- package/dist/config/validateCatalog.d.ts +13 -3
- package/dist/config/validateCatalog.js +83 -2
- package/dist/config/validateCompletionContract.js +8 -0
- package/dist/envelope/preEmitChecks.d.ts +1 -1
- package/dist/envelope/preEmitChecks.js +8 -0
- package/dist/logging/redact.d.ts +4 -0
- package/dist/logging/redact.js +17 -0
- package/dist/mcp/catalogTools.js +43 -8
- package/dist/mcp/controlTools.js +3 -1
- package/dist/mcp/deps.d.ts +2 -0
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.js +2 -0
- package/dist/mcp/triggerTools.d.ts +3 -0
- package/dist/mcp/triggerTools.js +176 -0
- package/dist/operatorAgent/docsRetrieval.d.ts +40 -0
- package/dist/operatorAgent/docsRetrieval.js +269 -0
- package/dist/operatorAgent/draftContext.d.ts +16 -0
- package/dist/operatorAgent/draftContext.js +68 -0
- package/dist/operatorAgent/fakeHost.d.ts +39 -0
- package/dist/operatorAgent/fakeHost.js +92 -0
- package/dist/operatorAgent/host.d.ts +40 -0
- package/dist/operatorAgent/host.js +179 -0
- package/dist/operatorAgent/index.d.ts +9 -0
- package/dist/operatorAgent/index.js +8 -0
- package/dist/operatorAgent/piModel.d.ts +80 -0
- package/dist/operatorAgent/piModel.js +528 -0
- package/dist/operatorAgent/profiles/workshopAuthor.d.ts +23 -0
- package/dist/operatorAgent/profiles/workshopAuthor.js +338 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +6 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +103 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +57 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.js +623 -0
- package/dist/operatorAgent/proposals.d.ts +32 -0
- package/dist/operatorAgent/proposals.js +144 -0
- package/dist/operatorAgent/types.d.ts +128 -0
- package/dist/operatorAgent/types.js +1 -0
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/project/findManifestRoot.d.ts +3 -0
- package/dist/project/findManifestRoot.js +35 -0
- package/dist/project/resolveStageflowContext.d.ts +7 -0
- package/dist/project/resolveStageflowContext.js +44 -28
- package/dist/runstore/assertTmpdir.js +6 -2
- package/dist/runstore/diskUsage.d.ts +1 -1
- package/dist/runstore/diskUsage.js +2 -7
- package/dist/runstore/port.d.ts +28 -0
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +8 -1
- package/dist/runstore/sqlite/SqliteRunStore.js +90 -0
- package/dist/runstore/sqlite/migrations/008-triggers-table.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/008-triggers-table.js +19 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.js +19 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.js +17 -0
- package/dist/runstore/sqlite/migrations/index.js +6 -0
- package/dist/runtime/answerResume.d.ts +1 -0
- package/dist/runtime/answerResume.js +3 -1
- package/dist/runtime/completionCheckRunner.d.ts +12 -1
- package/dist/runtime/completionCheckRunner.js +22 -0
- package/dist/runtime/credentialBinding.d.ts +7 -2
- package/dist/runtime/credentialBinding.js +20 -28
- package/dist/runtime/emailSource.d.ts +72 -0
- package/dist/runtime/emailSource.js +304 -0
- package/dist/runtime/githubPollSource.d.ts +86 -0
- package/dist/runtime/githubPollSource.js +284 -0
- package/dist/runtime/pipelineRunner.d.ts +4 -0
- package/dist/runtime/pipelineRunner.js +3 -0
- package/dist/runtime/pipelineScheduler.d.ts +2 -0
- package/dist/runtime/pipelineScheduler.js +86 -1
- package/dist/runtime/repositoryMaterialize.d.ts +1 -1
- package/dist/runtime/runManager.d.ts +11 -0
- package/dist/runtime/runManager.js +161 -3
- package/dist/runtime/runRetryCoordinator.d.ts +2 -0
- package/dist/runtime/runRetryCoordinator.js +1 -0
- package/dist/runtime/scheduleSource.d.ts +38 -0
- package/dist/runtime/scheduleSource.js +119 -0
- package/dist/runtime/settingsFile.d.ts +7 -2
- package/dist/runtime/settingsFile.js +66 -56
- package/dist/runtime/stageAttemptBootstrap.js +55 -3
- package/dist/runtime/stageEnvironment.js +1 -0
- package/dist/runtime/stageHitl.d.ts +1 -0
- package/dist/runtime/stageHitl.js +5 -1
- package/dist/runtime/stageProcessLauncher.d.ts +3 -0
- package/dist/runtime/stageProcessLauncher.js +52 -5
- package/dist/runtime/stageRunner.d.ts +5 -0
- package/dist/runtime/stageRunner.js +30 -6
- package/dist/runtime/stageStreamLog.d.ts +1 -0
- package/dist/runtime/stageStreamLog.js +2 -1
- package/dist/runtime/triggerCatalog.d.ts +6 -0
- package/dist/runtime/triggerCatalog.js +24 -0
- package/dist/runtime/triggerEventMatch.d.ts +2 -0
- package/dist/runtime/triggerEventMatch.js +6 -0
- package/dist/runtime/triggerPort.d.ts +14 -0
- package/dist/runtime/triggerPort.js +1 -0
- package/dist/runtime/triggerRunner.d.ts +17 -0
- package/dist/runtime/triggerRunner.js +89 -0
- package/dist/runtime/verifiedStageExecution.d.ts +7 -0
- package/dist/runtime/verifiedStageExecution.js +14 -0
- package/dist/runtime/webhookSignature.d.ts +1 -0
- package/dist/runtime/webhookSignature.js +12 -0
- package/dist/server/bootstrap.d.ts +6 -0
- package/dist/server/bootstrap.js +70 -0
- package/dist/server/controlToken.js +13 -0
- package/dist/server/createHttpHost.js +3 -0
- package/dist/server/healthSurfaces.js +31 -6
- package/dist/server/http.d.ts +15 -0
- package/dist/server/http.js +1251 -74
- package/dist/server/requestAuthContext.d.ts +1 -1
- package/dist/server/triggerRoutes.d.ts +15 -0
- package/dist/server/triggerRoutes.js +268 -0
- package/dist/tools/askOperator.d.ts +3 -2
- package/dist/types/completion.d.ts +3 -0
- package/dist/types/pipeline.d.ts +3 -1
- package/dist/types/preEmitCheck.d.ts +7 -0
- package/dist/types/stage.d.ts +14 -0
- package/dist/types/stageflowManifest.d.ts +3 -0
- package/dist/types/trigger.d.ts +18 -0
- package/dist/types/trigger.js +1 -0
- package/dist/ui/assets/{index-CSsDued1.css → index-Bv4p1aPK.css} +1 -1
- package/dist/ui/assets/index-p8Iou3zk.js +133 -0
- package/dist/ui/index.html +2 -2
- package/dist/workshop/autosave.d.ts +58 -0
- package/dist/workshop/autosave.js +222 -0
- package/dist/workshop/buildStore.d.ts +79 -0
- package/dist/workshop/buildStore.js +326 -0
- package/dist/workshop/chatTurn.d.ts +232 -0
- package/dist/workshop/chatTurn.js +475 -0
- package/dist/workshop/modelSettings.d.ts +18 -0
- package/dist/workshop/modelSettings.js +44 -0
- package/dist/workshop/sessionStore.d.ts +61 -0
- package/dist/workshop/sessionStore.js +254 -0
- package/dist/workshop/workshopPin.d.ts +72 -0
- package/dist/workshop/workshopPin.js +193 -0
- package/examples/README.md +2 -1
- package/examples/browser-session/README.md +77 -0
- package/examples/browser-session/browser-session.pipeline.yaml +50 -0
- package/examples/browser-session/browser-session.task.yaml +6 -0
- package/examples/browser-session/check-login.yaml +22 -0
- package/examples/browser-session/fixture-server.mjs +64 -0
- package/examples/browser-session/human-login.yaml +31 -0
- package/examples/browser-session/merge.yaml +36 -0
- package/examples/browser-session/work-a.yaml +41 -0
- package/examples/browser-session/work-b.yaml +41 -0
- package/examples/conditional-fork/decide.yaml +1 -1
- package/examples/github-release/README.md +17 -3
- package/examples/stage-mcp/README.md +3 -2
- package/examples/stageflow.yaml +51 -0
- package/package.json +9 -4
- package/skills/stageflow/references/control-surface.md +3 -1
- package/skills/stageflow-author/references/stage-prompt-template.md +4 -4
- package/skills/stageflow-run/SKILL.md +2 -0
- package/skills/stageflow-run/references/task-and-pipeline-selection.md +3 -1
- package/skills/stageflow-setup/SKILL.md +11 -0
- package/dist/ui/assets/index-B6hlSXXn.js +0 -120
|
@@ -17,10 +17,17 @@ import { buildPipelineDagSnapshotFromLoaded } from "../runstore/pipelineDagSnaps
|
|
|
17
17
|
import { InlinePipelineTooLargeError, PipelinePreflightError, PipelineValidationError, QueuedRunActivationAborted, startPipeline, } from "./pipelineRunner.js";
|
|
18
18
|
import { INLINE_PIPELINE_TOO_LARGE, pipelineBodyBytes, pipelinePersistenceForStart, } from "./startPayload.js";
|
|
19
19
|
import { materializeRunSkills, validateSkillsPayload, } from "./runSkills.js";
|
|
20
|
-
import { hydrateScheduleFromStore, hydratedScheduleHasRunnableWork, resumeRun, runPipelineDag, } from "./pipelineScheduler.js";
|
|
20
|
+
import { hydrateScheduleFromStore, hydratedScheduleHasRunnableWork, resumeRun, retryRun, runPipelineDag, } from "./pipelineScheduler.js";
|
|
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 { isHumanLoginStage } from "../browser/humanLogin.js";
|
|
25
|
+
import { defaultStageBrowserSupport, resolveStageBrowserEnv, } from "../browser/stageBrowserEnv.js";
|
|
26
|
+
import { teardownRunBrowsers, teardownStageBrowser, } from "../browser/browserTeardown.js";
|
|
27
|
+
import { createRunLiveness } from "../browser/runLiveness.js";
|
|
28
|
+
import { acquireStageProfile, stageProfileLock, } from "../browser/stageProfileLock.js";
|
|
29
|
+
import { sweepOrphanBrowserSessions } from "../browser/browserSweep.js";
|
|
30
|
+
import { definitionIdForInstance } from "../runstore/stageInstanceId.js";
|
|
24
31
|
import { StageProcessLauncher } from "./stageProcessLauncher.js";
|
|
25
32
|
import { logger as rootLogger } from "../logging/logger.js";
|
|
26
33
|
import { registerNamedSecrets } from "../logging/namedSecrets.js";
|
|
@@ -584,6 +591,23 @@ export class RunManager {
|
|
|
584
591
|
.getActiveStageProcesses()
|
|
585
592
|
.some((entry) => entry.runId === runId && entry.stageId === stageId);
|
|
586
593
|
}
|
|
594
|
+
async sweepBrowserSessions() {
|
|
595
|
+
const support = this.options.browser ?? defaultStageBrowserSupport();
|
|
596
|
+
const isRunLive = createRunLiveness(this.options.store);
|
|
597
|
+
await stageProfileLock(support)
|
|
598
|
+
.reclaimStale(isRunLive)
|
|
599
|
+
.catch(() => 0);
|
|
600
|
+
return sweepOrphanBrowserSessions({
|
|
601
|
+
isRunLive,
|
|
602
|
+
...(support.runner !== undefined ? { runner: support.runner } : {}),
|
|
603
|
+
...(support.closeWaitMs !== undefined
|
|
604
|
+
? { closeWaitMs: support.closeWaitMs }
|
|
605
|
+
: {}),
|
|
606
|
+
...(support.socketRoot !== undefined
|
|
607
|
+
? { socketRoot: support.socketRoot }
|
|
608
|
+
: {}),
|
|
609
|
+
});
|
|
610
|
+
}
|
|
587
611
|
async reconcileOrphanedStages() {
|
|
588
612
|
const reconciled = [];
|
|
589
613
|
const runs = await this.options.store.listRuns();
|
|
@@ -847,6 +871,12 @@ export class RunManager {
|
|
|
847
871
|
await this.stageProcessLauncher.cancelRun(runId);
|
|
848
872
|
}
|
|
849
873
|
}
|
|
874
|
+
await teardownStageBrowser(this.options.browser ?? defaultStageBrowserSupport(), {
|
|
875
|
+
runId,
|
|
876
|
+
runDir: this.options.store.getWorkspaceDir(runId),
|
|
877
|
+
stageId,
|
|
878
|
+
events: () => this.options.store.listStageEvents(runId, stageId),
|
|
879
|
+
}).catch(() => undefined);
|
|
850
880
|
await markStageInterrupted({
|
|
851
881
|
store: this.options.store,
|
|
852
882
|
runId,
|
|
@@ -861,6 +891,14 @@ export class RunManager {
|
|
|
861
891
|
await syncRunStatusFromStages(this.options.store, runId);
|
|
862
892
|
const after = await this.options.store.readRun(runId);
|
|
863
893
|
const hasWaiting = after.stages.some((s) => s.status === "waiting_for_input");
|
|
894
|
+
if (!hasWaiting &&
|
|
895
|
+
!(await createRunLiveness(this.options.store)(runId).catch(() => true))) {
|
|
896
|
+
await teardownRunBrowsers(this.options.browser ?? defaultStageBrowserSupport(), {
|
|
897
|
+
runId,
|
|
898
|
+
runDir: this.options.store.getWorkspaceDir(runId),
|
|
899
|
+
events: (stageId) => this.options.store.listStageEvents(runId, stageId),
|
|
900
|
+
}).catch(() => undefined);
|
|
901
|
+
}
|
|
864
902
|
if (!hasWaiting && this.active.has(runId)) {
|
|
865
903
|
this.removeActiveEntry(runId, false);
|
|
866
904
|
}
|
|
@@ -912,6 +950,11 @@ export class RunManager {
|
|
|
912
950
|
if (this.stageProcessLauncher !== undefined) {
|
|
913
951
|
await this.stageProcessLauncher.cancelRun(runId);
|
|
914
952
|
}
|
|
953
|
+
await teardownRunBrowsers(this.options.browser ?? defaultStageBrowserSupport(), {
|
|
954
|
+
runId,
|
|
955
|
+
runDir: this.options.store.getWorkspaceDir(runId),
|
|
956
|
+
events: (stageId) => this.options.store.listStageEvents(runId, stageId),
|
|
957
|
+
});
|
|
915
958
|
const detail = await this.options.store.readRun(runId);
|
|
916
959
|
for (const stage of detail.stages) {
|
|
917
960
|
if (stage.status !== "pending" &&
|
|
@@ -1478,6 +1521,9 @@ export class RunManager {
|
|
|
1478
1521
|
agent: this.options.agent,
|
|
1479
1522
|
cwd: meta.project_root ?? this.projectRoot,
|
|
1480
1523
|
operatorCatalog: this.options.operatorCatalog,
|
|
1524
|
+
...(this.options.browser !== undefined
|
|
1525
|
+
? { browser: this.options.browser }
|
|
1526
|
+
: {}),
|
|
1481
1527
|
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
1482
1528
|
executionMode: this.executionMode,
|
|
1483
1529
|
stageProcessLauncher: this.stageProcessLauncher,
|
|
@@ -1841,6 +1887,9 @@ export class RunManager {
|
|
|
1841
1887
|
checkoutRoot: meta.checkout_root,
|
|
1842
1888
|
hitl: this.hitl,
|
|
1843
1889
|
operatorCatalog: this.options.operatorCatalog,
|
|
1890
|
+
...(this.options.browser !== undefined
|
|
1891
|
+
? { browser: this.options.browser }
|
|
1892
|
+
: {}),
|
|
1844
1893
|
},
|
|
1845
1894
|
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
1846
1895
|
executionMode: this.executionMode,
|
|
@@ -1897,16 +1946,40 @@ export class RunManager {
|
|
|
1897
1946
|
runWorkspaceDir: workspaceDir,
|
|
1898
1947
|
hostEnv: process.env,
|
|
1899
1948
|
});
|
|
1949
|
+
const resumedStage = loaded.stages.find((s) => s.id === definitionIdForInstance(meta.pipeline_dag, stageId));
|
|
1950
|
+
if (resumedStage?.browser?.profile !== undefined) {
|
|
1951
|
+
await acquireStageProfile(this.options.browser ?? defaultStageBrowserSupport(), {
|
|
1952
|
+
profile: resumedStage.browser.profile,
|
|
1953
|
+
owner: { runId, stageId },
|
|
1954
|
+
isRunLive: createRunLiveness(store),
|
|
1955
|
+
halted: () => true,
|
|
1956
|
+
}).then((outcome) => {
|
|
1957
|
+
if (outcome === "halted") {
|
|
1958
|
+
throw new Error(`browser profile "${resumedStage.browser?.profile}" is held by another run`);
|
|
1959
|
+
}
|
|
1960
|
+
});
|
|
1961
|
+
}
|
|
1962
|
+
const browserEnv = await resolveStageBrowserEnv(this.options.browser ?? defaultStageBrowserSupport(), {
|
|
1963
|
+
runId,
|
|
1964
|
+
stageId,
|
|
1965
|
+
runDir: workspaceDir,
|
|
1966
|
+
browser: resumedStage?.browser,
|
|
1967
|
+
attempt,
|
|
1968
|
+
humanLogin: isHumanLoginStage(meta.pipeline_dag, definitionIdForInstance(meta.pipeline_dag, stageId), resumedStage?.browser),
|
|
1969
|
+
resuming: true,
|
|
1970
|
+
});
|
|
1900
1971
|
const launchResult = await launcher.launch({
|
|
1901
1972
|
runId,
|
|
1902
1973
|
stageId,
|
|
1903
1974
|
rootDir: runProjectRoot,
|
|
1975
|
+
...(browserEnv !== undefined ? { browserEnv } : {}),
|
|
1904
1976
|
mode: "resume",
|
|
1905
1977
|
resumeAnswer: opaqueAnswer,
|
|
1906
1978
|
attempt,
|
|
1907
1979
|
sessionFilePath,
|
|
1908
1980
|
env: stageBinding.env,
|
|
1909
1981
|
bindingKind: stageBinding.kind,
|
|
1982
|
+
...(resumedStage !== undefined ? { model: resumedStage.model } : {}),
|
|
1910
1983
|
...(this.options.operatorCatalog !== undefined
|
|
1911
1984
|
? { operatorCatalog: this.options.operatorCatalog }
|
|
1912
1985
|
: {}),
|
|
@@ -1914,12 +1987,53 @@ export class RunManager {
|
|
|
1914
1987
|
if (launchResult.type === "waiting") {
|
|
1915
1988
|
return { ok: true };
|
|
1916
1989
|
}
|
|
1990
|
+
await teardownStageBrowser(this.options.browser ?? defaultStageBrowserSupport(), {
|
|
1991
|
+
runId,
|
|
1992
|
+
runDir: workspaceDir,
|
|
1993
|
+
stageId,
|
|
1994
|
+
events: () => store.listStageEvents(runId, stageId),
|
|
1995
|
+
}).catch(() => undefined);
|
|
1917
1996
|
if (launchResult.type === "failed") {
|
|
1997
|
+
const nextRepairAttempt = await this.scheduleRepairAfterVerifyFailure(runId, stageId, meta.pipeline_dag);
|
|
1998
|
+
if (nextRepairAttempt !== undefined) {
|
|
1999
|
+
await store.updateRunStatus(runId, "running");
|
|
2000
|
+
const repaired = await retryRun({
|
|
2001
|
+
prepared: {
|
|
2002
|
+
task,
|
|
2003
|
+
loaded,
|
|
2004
|
+
run: { runId, workspaceDir: store.getWorkspaceDir(runId) },
|
|
2005
|
+
agent: this.options.agent,
|
|
2006
|
+
store,
|
|
2007
|
+
cwd: meta.project_root ?? this.projectRoot,
|
|
2008
|
+
projectRoot: meta.project_root ?? this.projectRoot,
|
|
2009
|
+
checkoutRoot: meta.checkout_root,
|
|
2010
|
+
hitl: this.hitl,
|
|
2011
|
+
operatorCatalog: this.options.operatorCatalog,
|
|
2012
|
+
...(this.options.browser !== undefined
|
|
2013
|
+
? { browser: this.options.browser }
|
|
2014
|
+
: {}),
|
|
2015
|
+
},
|
|
2016
|
+
retryRoots: new Map([[stageId, nextRepairAttempt]]),
|
|
2017
|
+
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
2018
|
+
executionMode: this.executionMode,
|
|
2019
|
+
stageProcessLauncher: launcher,
|
|
2020
|
+
schedulingHalt: this.ensureSchedulingHalt(runId),
|
|
2021
|
+
});
|
|
2022
|
+
if (repaired.outcome === "failed") {
|
|
2023
|
+
return { ok: false, reason: repaired.reason };
|
|
2024
|
+
}
|
|
2025
|
+
return { ok: true, verification: "failed_retrying" };
|
|
2026
|
+
}
|
|
1918
2027
|
await store.appendStageEvent(runId, stageId, {
|
|
1919
2028
|
event: "failed",
|
|
1920
2029
|
reason: launchResult.reason,
|
|
1921
2030
|
}, eventOptions);
|
|
1922
2031
|
await store.updateRunStatus(runId, "failed");
|
|
2032
|
+
await teardownRunBrowsers(this.options.browser ?? defaultStageBrowserSupport(), {
|
|
2033
|
+
runId,
|
|
2034
|
+
runDir: workspaceDir,
|
|
2035
|
+
events: (stageId) => store.listStageEvents(runId, stageId),
|
|
2036
|
+
}).catch(() => undefined);
|
|
1923
2037
|
return { ok: false, reason: launchResult.reason };
|
|
1924
2038
|
}
|
|
1925
2039
|
let initialPrior = null;
|
|
@@ -1941,6 +2055,9 @@ export class RunManager {
|
|
|
1941
2055
|
checkoutRoot: meta.checkout_root,
|
|
1942
2056
|
hitl: this.hitl,
|
|
1943
2057
|
operatorCatalog: this.options.operatorCatalog,
|
|
2058
|
+
...(this.options.browser !== undefined
|
|
2059
|
+
? { browser: this.options.browser }
|
|
2060
|
+
: {}),
|
|
1944
2061
|
},
|
|
1945
2062
|
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
1946
2063
|
resumeFromStageId: stageId,
|
|
@@ -1964,6 +2081,11 @@ export class RunManager {
|
|
|
1964
2081
|
reason,
|
|
1965
2082
|
}, eventOptions);
|
|
1966
2083
|
await store.updateRunStatus(runId, "failed");
|
|
2084
|
+
await teardownRunBrowsers(this.options.browser ?? defaultStageBrowserSupport(), {
|
|
2085
|
+
runId,
|
|
2086
|
+
runDir: store.getWorkspaceDir(runId),
|
|
2087
|
+
events: (stageId) => store.listStageEvents(runId, stageId),
|
|
2088
|
+
}).catch(() => undefined);
|
|
1967
2089
|
}
|
|
1968
2090
|
catch {
|
|
1969
2091
|
// ignore secondary failures
|
|
@@ -1974,6 +2096,24 @@ export class RunManager {
|
|
|
1974
2096
|
this.attachedWaiting.delete(`${runId}\0${stageId}`);
|
|
1975
2097
|
}
|
|
1976
2098
|
}
|
|
2099
|
+
/**
|
|
2100
|
+
* A resumed stage whose after-phase verification failed is repaired by the
|
|
2101
|
+
* same policy the scheduler applies to a first-launch failure. Returns the
|
|
2102
|
+
* freshly created attempt, or undefined when the failure is final.
|
|
2103
|
+
*/
|
|
2104
|
+
async scheduleRepairAfterVerifyFailure(runId, stageId, dag) {
|
|
2105
|
+
const store = this.options.store;
|
|
2106
|
+
const recovery = dag?.nodes.find((node) => node.id === stageId)?.recovery;
|
|
2107
|
+
if (recovery?.mode !== "repair")
|
|
2108
|
+
return undefined;
|
|
2109
|
+
const latest = await store.getLatestStageExecution(runId, stageId);
|
|
2110
|
+
if (latest?.verification_outcome !== "failed")
|
|
2111
|
+
return undefined;
|
|
2112
|
+
const attempts = await store.countStageAttempts(runId, stageId);
|
|
2113
|
+
if (attempts >= recovery.max_attempts)
|
|
2114
|
+
return undefined;
|
|
2115
|
+
return (await store.createStageExecution(runId, stageId)).attempt;
|
|
2116
|
+
}
|
|
1977
2117
|
async reconstructAndContinue(runId, stageId, opaqueAnswer) {
|
|
1978
2118
|
try {
|
|
1979
2119
|
return await resumeReconstructAndContinue({
|
|
@@ -2248,6 +2388,9 @@ export class RunManager {
|
|
|
2248
2388
|
const schedulingHalt = this.ensureSchedulingHalt(materialized.runId);
|
|
2249
2389
|
const started = await startPipeline({
|
|
2250
2390
|
submission,
|
|
2391
|
+
...(this.options.browser !== undefined
|
|
2392
|
+
? { browser: this.options.browser }
|
|
2393
|
+
: {}),
|
|
2251
2394
|
agent: this.options.agent,
|
|
2252
2395
|
store: this.options.store,
|
|
2253
2396
|
taskYaml,
|
|
@@ -2364,17 +2507,26 @@ export class RunManager {
|
|
|
2364
2507
|
};
|
|
2365
2508
|
}
|
|
2366
2509
|
async checkDiskFloorAdmission() {
|
|
2510
|
+
const raw = process.env.STAGEFLOW_MIN_FREE_DISK_BYTES;
|
|
2511
|
+
if (raw === undefined || raw.trim() === "") {
|
|
2512
|
+
return undefined;
|
|
2513
|
+
}
|
|
2367
2514
|
try {
|
|
2368
2515
|
const readFree = this.options.freeSpaceReader ?? readFilesystemSize;
|
|
2369
2516
|
const size = await readFree(globalStageflowHome());
|
|
2370
|
-
const minFreeBytes = resolveMinFreeDiskFloor(
|
|
2517
|
+
const minFreeBytes = resolveMinFreeDiskFloor(raw, size.totalBytes);
|
|
2518
|
+
if (minFreeBytes === 0) {
|
|
2519
|
+
return undefined;
|
|
2520
|
+
}
|
|
2371
2521
|
if (size.freeBytes < minFreeBytes) {
|
|
2372
2522
|
return this.insufficientDiskFailure(size.freeBytes, minFreeBytes);
|
|
2373
2523
|
}
|
|
2374
2524
|
return undefined;
|
|
2375
2525
|
}
|
|
2376
2526
|
catch (err) {
|
|
2377
|
-
|
|
2527
|
+
if (resolveMinFreeDiskFloor(raw, 0) === 0 && !raw.trim().endsWith("%")) {
|
|
2528
|
+
return undefined;
|
|
2529
|
+
}
|
|
2378
2530
|
return {
|
|
2379
2531
|
ok: false,
|
|
2380
2532
|
reason: `Disk free-space check failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
@@ -2738,6 +2890,9 @@ export class RunManager {
|
|
|
2738
2890
|
const schedulingHalt = this.ensureSchedulingHalt(runId);
|
|
2739
2891
|
const started = await startPipeline({
|
|
2740
2892
|
submission,
|
|
2893
|
+
...(this.options.browser !== undefined
|
|
2894
|
+
? { browser: this.options.browser }
|
|
2895
|
+
: {}),
|
|
2741
2896
|
agent: this.options.agent,
|
|
2742
2897
|
store: this.options.store,
|
|
2743
2898
|
taskYaml,
|
|
@@ -2842,6 +2997,9 @@ export class RunManager {
|
|
|
2842
2997
|
checkoutRoot: loadedMeta.checkout_root,
|
|
2843
2998
|
hitl: this.hitl,
|
|
2844
2999
|
operatorCatalog: this.options.operatorCatalog,
|
|
3000
|
+
...(this.options.browser !== undefined
|
|
3001
|
+
? { browser: this.options.browser }
|
|
3002
|
+
: {}),
|
|
2845
3003
|
},
|
|
2846
3004
|
maxActiveStagesPerRun: this.maxActiveStagesPerRun,
|
|
2847
3005
|
executionMode: this.executionMode,
|
|
@@ -3,6 +3,7 @@ import { type RunDetail, type RunPipelineDagSnapshot, type RunStatus, type RunSt
|
|
|
3
3
|
import type { PipelineRunResult } from "./pipelineRunner.js";
|
|
4
4
|
import { type SchedulerPreparedPipeline } from "./pipelineScheduler.js";
|
|
5
5
|
import type { StageExecutionMode } from "./stageConcurrency.js";
|
|
6
|
+
import type { StageBrowserSupport } from "../browser/browserHost.js";
|
|
6
7
|
import type { StageProcessLauncher } from "./stageProcessLauncher.js";
|
|
7
8
|
import type { StageHitlController } from "./stageHitl.js";
|
|
8
9
|
import type { OperatorCatalog } from "./stageAttemptBootstrap.js";
|
|
@@ -58,6 +59,7 @@ export type RetryStageRequest = {
|
|
|
58
59
|
agent: AgentPort;
|
|
59
60
|
cwd: string;
|
|
60
61
|
operatorCatalog?: OperatorCatalog;
|
|
62
|
+
browser?: StageBrowserSupport;
|
|
61
63
|
maxActiveStagesPerRun: number;
|
|
62
64
|
executionMode: StageExecutionMode;
|
|
63
65
|
stageProcessLauncher?: StageProcessLauncher;
|
|
@@ -344,6 +344,7 @@ export class RunRetryCoordinator {
|
|
|
344
344
|
checkoutRoot: meta.checkout_root,
|
|
345
345
|
hitl: req.hitl,
|
|
346
346
|
operatorCatalog: req.operatorCatalog,
|
|
347
|
+
...(req.browser !== undefined ? { browser: req.browser } : {}),
|
|
347
348
|
};
|
|
348
349
|
if (this.isActive(runId)) {
|
|
349
350
|
await this.addRoot(runId, stageId, execution.attempt);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { RunStore } from "../runstore/port.js";
|
|
2
|
+
import type { TriggerFireEvent, TriggerSourcePort } from "./triggerPort.js";
|
|
3
|
+
export declare const DEFAULT_TRIGGER_TICK_INTERVAL_MS = 30000;
|
|
4
|
+
/** Parse `STAGEFLOW_TRIGGER_TICK_INTERVAL_MS`; default 30s; `0` disables. */
|
|
5
|
+
export declare function triggerTickIntervalMsFromEnv(env?: NodeJS.ProcessEnv): number;
|
|
6
|
+
export type ScheduleSourceOptions = {
|
|
7
|
+
store: RunStore;
|
|
8
|
+
cwd?: string;
|
|
9
|
+
intervalMs?: number;
|
|
10
|
+
/** Injectable clock so tests can drive `tick()` without real timers. */
|
|
11
|
+
now?: () => Date;
|
|
12
|
+
logError?: (message: string) => void;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* `TriggerSourcePort` adapter for `schedule`-kind triggers. Ticks on an
|
|
16
|
+
* interval; each tick re-scans the catalog for enabled `schedule` triggers,
|
|
17
|
+
* seeds `next_run_at` for any that don't have one yet (without firing), and
|
|
18
|
+
* fires any trigger whose `next_run_at` has passed — always recomputing the
|
|
19
|
+
* next fire time from *now*, never from the stale `next_run_at`, so a tick
|
|
20
|
+
* never backfills more than one missed occurrence.
|
|
21
|
+
*/
|
|
22
|
+
export declare class ScheduleSource implements TriggerSourcePort {
|
|
23
|
+
private readonly store;
|
|
24
|
+
private readonly cwd;
|
|
25
|
+
private readonly intervalMs;
|
|
26
|
+
private readonly now;
|
|
27
|
+
private readonly logError;
|
|
28
|
+
private interval;
|
|
29
|
+
private inFlight;
|
|
30
|
+
constructor(options: ScheduleSourceOptions);
|
|
31
|
+
start(onFire: (event: TriggerFireEvent) => Promise<void>): Promise<void>;
|
|
32
|
+
stop(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* One discovery + seed + fire pass. Public so tests can drive it directly
|
|
35
|
+
* against an injected clock instead of waiting on real interval timers.
|
|
36
|
+
*/
|
|
37
|
+
tick(onFire: (event: TriggerFireEvent) => Promise<void>): Promise<void>;
|
|
38
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { Cron } from "croner";
|
|
3
|
+
import { getCatalogScanPaths } from "../config/browseCatalog.js";
|
|
4
|
+
import { loadTriggerOutcome } from "../config/loadTrigger.js";
|
|
5
|
+
import { catalogContextFromStageflow } from "../config/resolveCatalogContext.js";
|
|
6
|
+
import { resolveStageflowContext } from "../project/resolveStageflowContext.js";
|
|
7
|
+
export const DEFAULT_TRIGGER_TICK_INTERVAL_MS = 30_000;
|
|
8
|
+
/** Parse `STAGEFLOW_TRIGGER_TICK_INTERVAL_MS`; default 30s; `0` disables. */
|
|
9
|
+
export function triggerTickIntervalMsFromEnv(env = process.env) {
|
|
10
|
+
const raw = env.STAGEFLOW_TRIGGER_TICK_INTERVAL_MS;
|
|
11
|
+
if (raw === undefined || raw.trim() === "")
|
|
12
|
+
return DEFAULT_TRIGGER_TICK_INTERVAL_MS;
|
|
13
|
+
const parsed = Number(raw);
|
|
14
|
+
if (!Number.isFinite(parsed) || parsed < 0)
|
|
15
|
+
return DEFAULT_TRIGGER_TICK_INTERVAL_MS;
|
|
16
|
+
return parsed;
|
|
17
|
+
}
|
|
18
|
+
function computeNextRunAt(schedule, from) {
|
|
19
|
+
const job = new Cron(schedule.cron, schedule.timezone !== undefined ? { timezone: schedule.timezone } : {});
|
|
20
|
+
return job.nextRun(from);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* `TriggerSourcePort` adapter for `schedule`-kind triggers. Ticks on an
|
|
24
|
+
* interval; each tick re-scans the catalog for enabled `schedule` triggers,
|
|
25
|
+
* seeds `next_run_at` for any that don't have one yet (without firing), and
|
|
26
|
+
* fires any trigger whose `next_run_at` has passed — always recomputing the
|
|
27
|
+
* next fire time from *now*, never from the stale `next_run_at`, so a tick
|
|
28
|
+
* never backfills more than one missed occurrence.
|
|
29
|
+
*/
|
|
30
|
+
export class ScheduleSource {
|
|
31
|
+
store;
|
|
32
|
+
cwd;
|
|
33
|
+
intervalMs;
|
|
34
|
+
now;
|
|
35
|
+
logError;
|
|
36
|
+
interval;
|
|
37
|
+
inFlight = false;
|
|
38
|
+
constructor(options) {
|
|
39
|
+
this.store = options.store;
|
|
40
|
+
this.cwd = options.cwd ?? process.cwd();
|
|
41
|
+
this.intervalMs = options.intervalMs ?? DEFAULT_TRIGGER_TICK_INTERVAL_MS;
|
|
42
|
+
this.now = options.now ?? (() => new Date());
|
|
43
|
+
this.logError =
|
|
44
|
+
options.logError ??
|
|
45
|
+
((message) => {
|
|
46
|
+
console.error(message);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async start(onFire) {
|
|
50
|
+
if (this.intervalMs <= 0)
|
|
51
|
+
return;
|
|
52
|
+
this.interval = setInterval(() => {
|
|
53
|
+
if (this.inFlight)
|
|
54
|
+
return;
|
|
55
|
+
this.inFlight = true;
|
|
56
|
+
void this.tick(onFire)
|
|
57
|
+
.catch((err) => {
|
|
58
|
+
this.logError(`trigger schedule tick failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
59
|
+
})
|
|
60
|
+
.finally(() => {
|
|
61
|
+
this.inFlight = false;
|
|
62
|
+
});
|
|
63
|
+
}, this.intervalMs).unref();
|
|
64
|
+
}
|
|
65
|
+
async stop() {
|
|
66
|
+
if (this.interval !== undefined)
|
|
67
|
+
clearInterval(this.interval);
|
|
68
|
+
this.interval = undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* One discovery + seed + fire pass. Public so tests can drive it directly
|
|
72
|
+
* against an injected clock instead of waiting on real interval timers.
|
|
73
|
+
*/
|
|
74
|
+
async tick(onFire) {
|
|
75
|
+
const ctx = catalogContextFromStageflow(await resolveStageflowContext(this.cwd));
|
|
76
|
+
const scanPaths = await getCatalogScanPaths(ctx);
|
|
77
|
+
if (!scanPaths)
|
|
78
|
+
return;
|
|
79
|
+
const now = this.now();
|
|
80
|
+
const projectRoot = ctx.projectRoot ?? undefined;
|
|
81
|
+
for (const triggerPath of scanPaths.triggerPaths) {
|
|
82
|
+
const outcome = await loadTriggerOutcome(triggerPath);
|
|
83
|
+
if (!outcome.ok)
|
|
84
|
+
continue;
|
|
85
|
+
const definition = outcome.value;
|
|
86
|
+
if (definition.kind !== "schedule" || !definition.enabled || !definition.schedule) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
let next;
|
|
90
|
+
try {
|
|
91
|
+
next = computeNextRunAt(definition.schedule, now);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
this.logError(`invalid schedule for trigger "${definition.id}": ${err instanceof Error ? err.message : String(err)}`);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const definitionRef = projectRoot !== undefined
|
|
98
|
+
? path.relative(projectRoot, triggerPath).replace(/\\/g, "/")
|
|
99
|
+
: triggerPath;
|
|
100
|
+
await this.store.upsertTrigger({
|
|
101
|
+
id: definition.id,
|
|
102
|
+
definitionRef,
|
|
103
|
+
enabled: true,
|
|
104
|
+
});
|
|
105
|
+
const record = await this.store.getTrigger(definition.id);
|
|
106
|
+
if (!record?.next_run_at) {
|
|
107
|
+
if (next)
|
|
108
|
+
await this.store.setTriggerNextRun(definition.id, next.toISOString());
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const dueAt = new Date(record.next_run_at);
|
|
112
|
+
if (dueAt.getTime() <= now.getTime()) {
|
|
113
|
+
await onFire({ triggerId: definition.id });
|
|
114
|
+
if (next)
|
|
115
|
+
await this.store.setTriggerNextRun(definition.id, next.toISOString());
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -2,17 +2,20 @@ import type { ProjectContext } from "../project/resolveProjectContext.js";
|
|
|
2
2
|
import type { StageflowContext } from "../project/resolveStageflowContext.js";
|
|
3
3
|
export declare const SETTINGS_FILE_NAME = "settings.json";
|
|
4
4
|
export declare const INVALID_SLOT_COUNT_MESSAGE = "maxConcurrent must be an integer >= 1";
|
|
5
|
-
export declare const INVALID_CREDENTIAL_SOURCE_MESSAGE = "credentialSource must be \"
|
|
6
|
-
export
|
|
5
|
+
export declare const INVALID_CREDENTIAL_SOURCE_MESSAGE = "credentialSource must be \"sf_owned\"";
|
|
6
|
+
export declare const INVALID_WORKSHOP_MODEL_MESSAGE = "workshopModel must be a non-empty string";
|
|
7
|
+
export type CredentialSource = "sf_owned";
|
|
7
8
|
export type FactorySettings = {
|
|
8
9
|
maxConcurrent?: number;
|
|
9
10
|
credentialSource?: CredentialSource;
|
|
11
|
+
workshopModel?: string;
|
|
10
12
|
};
|
|
11
13
|
export declare function globalSettingsFilePath(): string;
|
|
12
14
|
export declare function settingsFilePathForContext(ctx: ProjectContext | StageflowContext): string;
|
|
13
15
|
export declare function settingsFilePath(cwd: string): string;
|
|
14
16
|
export declare function parseSlotCount(value: unknown): number | undefined;
|
|
15
17
|
export declare function parseCredentialSource(value: unknown): CredentialSource | undefined;
|
|
18
|
+
export declare function parseWorkshopModelSetting(value: unknown): string | undefined;
|
|
16
19
|
export declare function readCredentialSourceFromContext(ctx: ProjectContext): CredentialSource | undefined;
|
|
17
20
|
export declare function readPersistedCredentialSourceFromContext(ctx: ProjectContext): CredentialSource | undefined;
|
|
18
21
|
export declare function readFactorySettingsForContext(ctx: ProjectContext): FactorySettings;
|
|
@@ -25,6 +28,8 @@ export declare function writeMaxConcurrentToContext(ctx: ProjectContext, maxConc
|
|
|
25
28
|
export declare function writeMaxConcurrentToFile(cwd: string, maxConcurrent: number): void;
|
|
26
29
|
export declare function readMaxConcurrentFromGlobal(): number | undefined;
|
|
27
30
|
export declare function writeMaxConcurrentToGlobal(maxConcurrent: number): void;
|
|
31
|
+
export declare function readWorkshopModelFromFile(cwd: string): string | undefined;
|
|
32
|
+
export declare function writeWorkshopModelToFile(cwd: string, workshopModel: string): void;
|
|
28
33
|
export declare function readCredentialSourceFromFile(cwd: string): CredentialSource | undefined;
|
|
29
34
|
export declare function writeCredentialSourceToContext(ctx: ProjectContext, credentialSource: CredentialSource): void;
|
|
30
35
|
export declare function writeCredentialSourceToFile(cwd: string, credentialSource: CredentialSource): void;
|