stageflow 0.25.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -3
- package/builtin-skills/browser/SKILL.md +42 -0
- package/dist/a2a/contracts.d.ts +1 -0
- package/dist/a2a/contracts.js +1 -0
- package/dist/a2a/registry.d.ts +2 -0
- package/dist/a2a/registry.js +20 -1
- package/dist/a2a/server.d.ts +7 -0
- package/dist/a2a/server.js +5 -2
- package/dist/a2a/service.d.ts +1 -1
- package/dist/a2a/service.js +57 -8
- package/dist/a2a/store.d.ts +8 -5
- package/dist/a2a/store.js +24 -67
- package/dist/agent/activity.d.ts +3 -0
- package/dist/agent/bootProviderConfig.d.ts +21 -0
- package/dist/agent/bootProviderConfig.js +74 -0
- package/dist/agent/claudeAdapter.js +2 -2
- package/dist/agent/cursorProvider.d.ts +2 -0
- package/dist/agent/cursorProvider.js +30 -5
- package/dist/agent/fakeAgent.d.ts +1 -0
- package/dist/agent/fakeAgent.js +13 -0
- package/dist/agent/piAdapter.d.ts +11 -24
- package/dist/agent/piAdapter.js +107 -50
- package/dist/agent/piIsolatedMcp.d.ts +2 -0
- package/dist/agent/piIsolatedMcp.js +10 -2
- package/dist/agent/piSessionFactory.d.ts +38 -0
- package/dist/agent/piSessionFactory.js +60 -0
- package/dist/agent/port.d.ts +8 -0
- package/dist/agent/streamLogRedact.d.ts +7 -1
- package/dist/agent/streamLogRedact.js +26 -11
- package/dist/browser/anchor.d.ts +27 -0
- package/dist/browser/anchor.js +127 -0
- package/dist/browser/auditSink.d.ts +38 -0
- package/dist/browser/auditSink.js +34 -0
- package/dist/browser/browserHost.d.ts +86 -0
- package/dist/browser/browserHost.js +7 -0
- package/dist/browser/browserSweep.d.ts +14 -0
- package/dist/browser/browserSweep.js +54 -0
- package/dist/browser/browserTeardown.d.ts +56 -0
- package/dist/browser/browserTeardown.js +235 -0
- package/dist/browser/fakeRemoteBrowserHost.d.ts +2 -0
- package/dist/browser/fakeRemoteBrowserHost.js +34 -0
- package/dist/browser/gateHandoff.d.ts +25 -0
- package/dist/browser/gateHandoff.js +83 -0
- package/dist/browser/humanLogin.d.ts +18 -0
- package/dist/browser/humanLogin.js +34 -0
- package/dist/browser/keyProvider.d.ts +10 -0
- package/dist/browser/keyProvider.js +39 -0
- package/dist/browser/localBrowserHost.d.ts +10 -0
- package/dist/browser/localBrowserHost.js +152 -0
- package/dist/browser/localProfileLock.d.ts +2 -0
- package/dist/browser/localProfileLock.js +218 -0
- package/dist/browser/localProfileStore.d.ts +5 -0
- package/dist/browser/localProfileStore.js +91 -0
- package/dist/browser/loginCheck.d.ts +53 -0
- package/dist/browser/loginCheck.js +147 -0
- package/dist/browser/memoryProfileLock.d.ts +2 -0
- package/dist/browser/memoryProfileLock.js +53 -0
- package/dist/browser/memoryProfileStore.d.ts +2 -0
- package/dist/browser/memoryProfileStore.js +31 -0
- package/dist/browser/navigationAudit.d.ts +16 -0
- package/dist/browser/navigationAudit.js +53 -0
- package/dist/browser/persistedEnv.d.ts +3 -0
- package/dist/browser/persistedEnv.js +15 -0
- package/dist/browser/profileLock.d.ts +40 -0
- package/dist/browser/profileLock.js +10 -0
- package/dist/browser/profileStore.d.ts +23 -0
- package/dist/browser/profileStore.js +39 -0
- package/dist/browser/runLiveness.d.ts +13 -0
- package/dist/browser/runLiveness.js +39 -0
- package/dist/browser/sitePolicy.d.ts +10 -0
- package/dist/browser/sitePolicy.js +61 -0
- package/dist/browser/stageBrowserEnv.d.ts +22 -0
- package/dist/browser/stageBrowserEnv.js +147 -0
- package/dist/browser/stageProfileLock.d.ts +17 -0
- package/dist/browser/stageProfileLock.js +39 -0
- package/dist/cli/artifactCommand.js +9 -16
- package/dist/cli/backupCommand.d.ts +9 -0
- package/dist/cli/backupCommand.js +111 -0
- package/dist/cli/browserCommand.d.ts +44 -0
- package/dist/cli/browserCommand.js +472 -0
- package/dist/cli/debugRunCommand.d.ts +10 -0
- package/dist/cli/debugRunCommand.js +109 -0
- package/dist/cli/doctorCommand.d.ts +32 -0
- package/dist/cli/doctorCommand.js +453 -0
- package/dist/cli/envelopeCommand.js +9 -2
- package/dist/cli/exportAllCommand.d.ts +55 -0
- package/dist/cli/exportAllCommand.js +218 -0
- package/dist/cli/exportRunCommand.js +23 -21
- package/dist/cli/hostClient.d.ts +41 -3
- package/dist/cli/hostClient.js +129 -14
- package/dist/cli/initCommand.d.ts +1 -0
- package/dist/cli/initCommand.js +23 -7
- package/dist/cli/initTemplates.d.ts +5 -2
- package/dist/cli/initTemplates.js +32 -2
- package/dist/cli/resolveSafeOutPath.d.ts +2 -0
- package/dist/cli/resolveSafeOutPath.js +40 -0
- package/dist/cli/restoreCommand.d.ts +10 -0
- package/dist/cli/restoreCommand.js +90 -0
- package/dist/cli/runCommand.d.ts +3 -2
- package/dist/cli/runCommand.js +93 -11
- package/dist/cli/runOutput.d.ts +4 -0
- package/dist/cli/runOutput.js +33 -7
- package/dist/cli/runStageCommand.d.ts +1 -0
- package/dist/cli/runStageCommand.js +44 -25
- package/dist/cli/runsCommand.d.ts +1 -1
- package/dist/cli/runsCommand.js +168 -10
- package/dist/cli/triggerCommand.d.ts +12 -0
- package/dist/cli/triggerCommand.js +183 -0
- package/dist/cli/validateCommand.d.ts +1 -1
- package/dist/cli/validateCommand.js +23 -6
- package/dist/cli.js +202 -32
- package/dist/config/browseCatalog.d.ts +1 -0
- package/dist/config/browseCatalog.js +5 -4
- package/dist/config/builtinSkills.d.ts +4 -0
- package/dist/config/builtinSkills.js +23 -0
- package/dist/config/catalogRelativePath.d.ts +63 -0
- package/dist/config/catalogRelativePath.js +126 -0
- package/dist/config/configOrigin.d.ts +27 -0
- package/dist/config/configOrigin.js +59 -0
- package/dist/config/createTrigger.d.ts +27 -0
- package/dist/config/createTrigger.js +232 -0
- package/dist/config/draftPackage.d.ts +117 -0
- package/dist/config/draftPackage.js +550 -0
- package/dist/config/ensureCatalogScanRoot.d.ts +16 -0
- package/dist/config/ensureCatalogScanRoot.js +73 -0
- package/dist/config/hostConfig.d.ts +57 -0
- package/dist/config/hostConfig.js +360 -0
- package/dist/config/listSkills.d.ts +26 -0
- package/dist/config/listSkills.js +206 -5
- package/dist/config/loadOutcome.d.ts +7 -1
- package/dist/config/loadPipeline.js +39 -2
- package/dist/config/loadStage.js +25 -0
- package/dist/config/loadStageflowManifest.js +25 -0
- package/dist/config/loadTask.d.ts +2 -0
- package/dist/config/loadTask.js +57 -18
- package/dist/config/loadTrigger.d.ts +9 -0
- package/dist/config/loadTrigger.js +120 -0
- package/dist/config/materializeStageModels.js +5 -1
- package/dist/config/mergePipelineIncludes.d.ts +3 -0
- package/dist/config/mergePipelineIncludes.js +19 -0
- package/dist/config/migrateYaml.js +6 -11
- package/dist/config/multiProjectCatalog.d.ts +32 -0
- package/dist/config/multiProjectCatalog.js +150 -0
- package/dist/config/normalizePipelineStageEntry.js +27 -1
- package/dist/config/parseCompletionContract.js +6 -0
- package/dist/config/pipelineStageKeys.js +3 -0
- package/dist/config/publishDraftPackage.d.ts +7 -0
- package/dist/config/publishDraftPackage.js +25 -0
- package/dist/config/resolveCatalogContext.js +1 -1
- package/dist/config/resolveCatalogRoots.d.ts +27 -0
- package/dist/config/resolveCatalogRoots.js +76 -0
- package/dist/config/resolveModel.d.ts +7 -1
- package/dist/config/resolveModel.js +11 -1
- package/dist/config/resolvePipelineDag.js +1 -1
- package/dist/config/resolveStageMcpServers.d.ts +9 -1
- package/dist/config/resolveStageMcpServers.js +36 -9
- package/dist/config/scanCatalogPaths.d.ts +1 -1
- package/dist/config/scanCatalogPaths.js +6 -2
- package/dist/config/secretFromEnvOrFile.d.ts +9 -0
- package/dist/config/secretFromEnvOrFile.js +34 -0
- package/dist/config/seededCatalog.d.ts +11 -0
- package/dist/config/seededCatalog.js +29 -0
- package/dist/config/stageBrowser.d.ts +12 -0
- package/dist/config/stageBrowser.js +118 -0
- package/dist/config/toolRequires.d.ts +24 -0
- package/dist/config/toolRequires.js +115 -0
- package/dist/config/triggerCatalog.d.ts +10 -0
- package/dist/config/triggerCatalog.js +37 -0
- package/dist/config/validateCatalog.d.ts +17 -3
- package/dist/config/validateCatalog.js +223 -3
- package/dist/config/validateCompletionContract.js +8 -0
- package/dist/diagnostics/checks.d.ts +39 -0
- package/dist/diagnostics/checks.js +135 -0
- package/dist/envelope/preEmitChecks.d.ts +1 -1
- package/dist/envelope/preEmitChecks.js +8 -0
- package/dist/errors/codes.d.ts +14 -0
- package/dist/errors/codes.js +59 -0
- package/dist/git/cache.d.ts +14 -0
- package/dist/git/cache.js +150 -0
- package/dist/git/credentials.d.ts +9 -0
- package/dist/git/credentials.js +88 -0
- package/dist/git/errors.d.ts +20 -0
- package/dist/git/errors.js +94 -0
- package/dist/git/exec.d.ts +16 -0
- package/dist/git/exec.js +135 -0
- package/dist/git/operations.d.ts +29 -0
- package/dist/git/operations.js +153 -0
- package/dist/git/version.d.ts +1 -0
- package/dist/git/version.js +10 -0
- package/dist/logging/audit.d.ts +16 -0
- package/dist/logging/audit.js +19 -0
- package/dist/logging/commonWords.d.ts +2 -0
- package/dist/logging/commonWords.js +13 -0
- package/dist/logging/logger.d.ts +49 -0
- package/dist/logging/logger.js +193 -0
- package/dist/logging/namedSecrets.d.ts +6 -0
- package/dist/logging/namedSecrets.js +58 -0
- package/dist/logging/redact.d.ts +17 -0
- package/dist/logging/redact.js +105 -0
- package/dist/mcp/catalogTools.js +492 -81
- package/dist/mcp/checkoutTools.d.ts +52 -0
- package/dist/mcp/checkoutTools.js +332 -0
- package/dist/mcp/controlTools.js +182 -6
- package/dist/mcp/deps.d.ts +3 -0
- package/dist/mcp/getStartedTool.d.ts +3 -0
- package/dist/mcp/getStartedTool.js +62 -0
- package/dist/mcp/readArtifact.d.ts +11 -0
- package/dist/mcp/readArtifact.js +46 -30
- package/dist/mcp/server.js +2 -0
- package/dist/mcp/tools.js +6 -0
- package/dist/mcp/triggerTools.d.ts +3 -0
- package/dist/mcp/triggerTools.js +176 -0
- package/dist/net/proxy.d.ts +14 -0
- package/dist/net/proxy.js +78 -0
- package/dist/operatorAgent/docsRetrieval.d.ts +40 -0
- package/dist/operatorAgent/docsRetrieval.js +269 -0
- package/dist/operatorAgent/draftContext.d.ts +16 -0
- package/dist/operatorAgent/draftContext.js +68 -0
- package/dist/operatorAgent/fakeHost.d.ts +39 -0
- package/dist/operatorAgent/fakeHost.js +92 -0
- package/dist/operatorAgent/host.d.ts +40 -0
- package/dist/operatorAgent/host.js +179 -0
- package/dist/operatorAgent/index.d.ts +9 -0
- package/dist/operatorAgent/index.js +8 -0
- package/dist/operatorAgent/piModel.d.ts +80 -0
- package/dist/operatorAgent/piModel.js +528 -0
- package/dist/operatorAgent/profiles/workshopAuthor.d.ts +23 -0
- package/dist/operatorAgent/profiles/workshopAuthor.js +338 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +6 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +103 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +57 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.js +623 -0
- package/dist/operatorAgent/proposals.d.ts +32 -0
- package/dist/operatorAgent/proposals.js +144 -0
- package/dist/operatorAgent/types.d.ts +128 -0
- package/dist/operatorAgent/types.js +1 -0
- package/dist/package-meta.d.ts +2 -1
- package/dist/package-meta.js +2 -1
- package/dist/preflight/bash.d.ts +8 -0
- package/dist/preflight/bash.js +34 -0
- package/dist/preflight/claudeRoot.d.ts +11 -0
- package/dist/preflight/claudeRoot.js +23 -0
- package/dist/preflight/mcpCommands.d.ts +8 -0
- package/dist/preflight/mcpCommands.js +36 -0
- package/dist/preflight/pipelinePreflight.d.ts +40 -0
- package/dist/preflight/pipelinePreflight.js +192 -0
- package/dist/preflight/tls.d.ts +6 -0
- package/dist/preflight/tls.js +18 -0
- package/dist/preflight/toolchain.d.ts +45 -0
- package/dist/preflight/toolchain.js +219 -0
- package/dist/project/findManifestRoot.d.ts +3 -0
- package/dist/project/findManifestRoot.js +35 -0
- package/dist/project/findProjectRoot.js +3 -4
- package/dist/project/globalHome.d.ts +7 -0
- package/dist/project/globalHome.js +63 -2
- package/dist/project/resolveProjectContext.js +2 -2
- package/dist/project/resolveStageflowContext.d.ts +7 -0
- package/dist/project/resolveStageflowContext.js +46 -30
- package/dist/projection/projectRun.d.ts +2 -1
- package/dist/projection/projectRun.js +1 -0
- package/dist/runstore/assertTmpdir.d.ts +1 -0
- package/dist/runstore/assertTmpdir.js +25 -0
- package/dist/runstore/backup.d.ts +52 -0
- package/dist/runstore/backup.js +292 -0
- package/dist/runstore/createStore.d.ts +18 -1
- package/dist/runstore/createStore.js +64 -5
- package/dist/runstore/debugBundle.d.ts +60 -0
- package/dist/runstore/debugBundle.js +143 -0
- package/dist/runstore/diskUsage.d.ts +50 -0
- package/dist/runstore/diskUsage.js +214 -0
- package/dist/runstore/exportRunPayload.d.ts +8 -0
- package/dist/runstore/exportRunPayload.js +23 -0
- package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
- package/dist/runstore/normalizeCatalogPath.js +10 -0
- package/dist/runstore/paths.d.ts +5 -0
- package/dist/runstore/paths.js +145 -1
- package/dist/runstore/port.d.ts +139 -13
- package/dist/runstore/port.js +8 -1
- package/dist/runstore/restore.d.ts +81 -0
- package/dist/runstore/restore.js +355 -0
- package/dist/runstore/retention.d.ts +27 -0
- package/dist/runstore/retention.js +74 -0
- package/dist/runstore/runManifest.d.ts +146 -0
- package/dist/runstore/runManifest.js +288 -0
- package/dist/runstore/runProjection.d.ts +3 -1
- package/dist/runstore/runProjection.js +63 -1
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +35 -3
- package/dist/runstore/sqlite/SqliteRunStore.js +442 -219
- package/dist/runstore/sqlite/applyStorePragmas.d.ts +39 -0
- package/dist/runstore/sqlite/applyStorePragmas.js +145 -0
- package/dist/runstore/sqlite/migrations/001-baseline.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/001-baseline.js +10 -0
- package/dist/runstore/sqlite/migrations/002-repository-binding.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/002-repository-binding.js +29 -0
- package/dist/runstore/sqlite/migrations/003-run-lifecycle.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/003-run-lifecycle.js +28 -0
- package/dist/runstore/sqlite/migrations/004-auto-resume-count.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/004-auto-resume-count.js +19 -0
- package/dist/runstore/sqlite/migrations/005-config-origins.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/005-config-origins.js +19 -0
- package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.js +28 -0
- package/dist/runstore/sqlite/migrations/007-projects-registry.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/007-projects-registry.js +31 -0
- package/dist/runstore/sqlite/migrations/008-triggers-table.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/008-triggers-table.js +19 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.js +19 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.js +17 -0
- package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
- package/dist/runstore/sqlite/migrations/index.js +78 -0
- package/dist/runstore/sqlite/schema.d.ts +20 -1
- package/dist/runstore/sqlite/schema.js +277 -1
- package/dist/runstore/sqlite/storeOpenError.d.ts +6 -0
- package/dist/runstore/sqlite/storeOpenError.js +11 -0
- package/dist/runstore/sqlite/storeSchemaError.d.ts +5 -0
- package/dist/runstore/sqlite/storeSchemaError.js +8 -0
- package/dist/runstore/stageExecution.js +3 -0
- package/dist/runstore/storeFilesystem.d.ts +32 -0
- package/dist/runstore/storeFilesystem.js +148 -0
- package/dist/runstore/trackProjection.js +2 -0
- package/dist/runstore/workspaceLayout.d.ts +13 -0
- package/dist/runstore/workspaceLayout.js +76 -0
- package/dist/runtime/answerResume.d.ts +1 -0
- package/dist/runtime/answerResume.js +3 -1
- package/dist/runtime/completionCheckRunner.d.ts +15 -1
- package/dist/runtime/completionCheckRunner.js +67 -7
- package/dist/runtime/containerLimits.d.ts +16 -0
- package/dist/runtime/containerLimits.js +84 -0
- package/dist/runtime/credentialBinding.d.ts +2 -0
- package/dist/runtime/credentialBinding.js +3 -0
- package/dist/runtime/credentialMaterialisation.d.ts +28 -0
- package/dist/runtime/credentialMaterialisation.js +128 -0
- package/dist/runtime/emailSource.d.ts +72 -0
- package/dist/runtime/emailSource.js +304 -0
- package/dist/runtime/gitCheckoutCapability.js +7 -13
- package/dist/runtime/githubPollSource.d.ts +86 -0
- package/dist/runtime/githubPollSource.js +284 -0
- package/dist/runtime/pipelineRunner.d.ts +40 -1
- package/dist/runtime/pipelineRunner.js +181 -17
- package/dist/runtime/pipelineScheduler.d.ts +17 -0
- package/dist/runtime/pipelineScheduler.js +220 -28
- package/dist/runtime/reloadRunCatalog.js +6 -1
- package/dist/runtime/repositoryMaterialize.d.ts +47 -0
- package/dist/runtime/repositoryMaterialize.js +235 -0
- package/dist/runtime/resumeTimedOut.d.ts +1 -1
- package/dist/runtime/resumeTimedOut.js +5 -2
- package/dist/runtime/runChangeBus.js +9 -0
- package/dist/runtime/runDeletion.d.ts +7 -0
- package/dist/runtime/runDeletion.js +37 -0
- package/dist/runtime/runManager.d.ts +169 -4
- package/dist/runtime/runManager.js +1748 -83
- package/dist/runtime/runRetentionSweep.d.ts +31 -0
- package/dist/runtime/runRetentionSweep.js +328 -0
- package/dist/runtime/runRetryCoordinator.d.ts +4 -0
- package/dist/runtime/runRetryCoordinator.js +20 -2
- package/dist/runtime/runSkills.d.ts +40 -0
- package/dist/runtime/runSkills.js +173 -0
- package/dist/runtime/scheduleSource.d.ts +38 -0
- package/dist/runtime/scheduleSource.js +119 -0
- package/dist/runtime/settingsFile.d.ts +5 -0
- package/dist/runtime/settingsFile.js +61 -54
- package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
- package/dist/runtime/stageAttemptBootstrap.js +250 -27
- package/dist/runtime/stageCacheEnv.d.ts +6 -0
- package/dist/runtime/stageCacheEnv.js +34 -0
- package/dist/runtime/stageConcurrency.d.ts +2 -1
- package/dist/runtime/stageConcurrency.js +4 -2
- package/dist/runtime/stageEnvironment.d.ts +38 -0
- package/dist/runtime/stageEnvironment.js +194 -0
- package/dist/runtime/stageHitl.d.ts +1 -0
- package/dist/runtime/stageHitl.js +5 -1
- package/dist/runtime/stageProcessLauncher.d.ts +20 -0
- package/dist/runtime/stageProcessLauncher.js +236 -41
- package/dist/runtime/stageRecovery.d.ts +3 -1
- package/dist/runtime/stageRecovery.js +19 -4
- package/dist/runtime/stageRoots.d.ts +38 -1
- package/dist/runtime/stageRoots.js +118 -0
- package/dist/runtime/stageRunner.d.ts +6 -0
- package/dist/runtime/stageRunner.js +32 -6
- package/dist/runtime/stageSecretDecl.d.ts +9 -0
- package/dist/runtime/stageSecretDecl.js +102 -0
- package/dist/runtime/stageSecrets.d.ts +40 -0
- package/dist/runtime/stageSecrets.js +181 -0
- package/dist/runtime/stageStreamLog.d.ts +1 -0
- package/dist/runtime/stageStreamLog.js +2 -1
- package/dist/runtime/stageWorker.d.ts +3 -2
- package/dist/runtime/stageWorker.js +58 -10
- package/dist/runtime/stageWorkerProtocol.d.ts +5 -0
- package/dist/runtime/stageWorkerProtocol.js +8 -0
- package/dist/runtime/startPayload.d.ts +32 -0
- package/dist/runtime/startPayload.js +59 -0
- package/dist/runtime/taskInput.js +14 -5
- package/dist/runtime/triggerCatalog.d.ts +6 -0
- package/dist/runtime/triggerCatalog.js +24 -0
- package/dist/runtime/triggerEventMatch.d.ts +2 -0
- package/dist/runtime/triggerEventMatch.js +6 -0
- package/dist/runtime/triggerPort.d.ts +14 -0
- package/dist/runtime/triggerPort.js +1 -0
- package/dist/runtime/triggerRunner.d.ts +17 -0
- package/dist/runtime/triggerRunner.js +89 -0
- package/dist/runtime/verifiedStageExecution.d.ts +8 -0
- package/dist/runtime/verifiedStageExecution.js +16 -1
- package/dist/runtime/webhookSignature.d.ts +1 -0
- package/dist/runtime/webhookSignature.js +12 -0
- package/dist/runtime/workspaceBinding.d.ts +20 -0
- package/dist/runtime/workspaceBinding.js +60 -0
- package/dist/server/allowedHosts.d.ts +19 -0
- package/dist/server/allowedHosts.js +179 -0
- package/dist/server/bootstrap.d.ts +42 -2
- package/dist/server/bootstrap.js +273 -5
- package/dist/server/controlToken.d.ts +47 -0
- package/dist/server/controlToken.js +254 -0
- package/dist/server/createHttpHost.d.ts +11 -2
- package/dist/server/createHttpHost.js +106 -10
- package/dist/server/ensureGlobalService.d.ts +5 -1
- package/dist/server/ensureGlobalService.js +35 -1
- package/dist/server/healthSurfaces.d.ts +6 -0
- package/dist/server/healthSurfaces.js +123 -0
- package/dist/server/http.d.ts +27 -1
- package/dist/server/http.js +2254 -477
- package/dist/server/listenHost.d.ts +5 -0
- package/dist/server/listenHost.js +56 -0
- package/dist/server/mcpHost.d.ts +10 -1
- package/dist/server/mcpHost.js +36 -6
- package/dist/server/operatorResults.d.ts +2 -2
- package/dist/server/operatorResults.js +40 -29
- package/dist/server/requestAuthContext.d.ts +12 -0
- package/dist/server/requestAuthContext.js +21 -0
- package/dist/server/shutdown.d.ts +69 -0
- package/dist/server/shutdown.js +219 -0
- package/dist/server/triggerRoutes.d.ts +15 -0
- package/dist/server/triggerRoutes.js +268 -0
- package/dist/tools/askOperator.d.ts +3 -2
- package/dist/types/completion.d.ts +3 -0
- package/dist/types/pipeline.d.ts +10 -1
- package/dist/types/preEmitCheck.d.ts +7 -0
- package/dist/types/stage.d.ts +22 -0
- package/dist/types/stageflowManifest.d.ts +3 -0
- package/dist/types/task.d.ts +8 -0
- package/dist/types/trigger.d.ts +18 -0
- package/dist/types/trigger.js +1 -0
- package/dist/ui/assets/{index-CSsDued1.css → index-Bv4p1aPK.css} +1 -1
- package/dist/ui/assets/index-CntB4bZR.js +133 -0
- package/dist/ui/index.html +2 -2
- package/dist/workshop/autosave.d.ts +58 -0
- package/dist/workshop/autosave.js +222 -0
- package/dist/workshop/buildStore.d.ts +79 -0
- package/dist/workshop/buildStore.js +326 -0
- package/dist/workshop/chatTurn.d.ts +232 -0
- package/dist/workshop/chatTurn.js +475 -0
- package/dist/workshop/modelSettings.d.ts +18 -0
- package/dist/workshop/modelSettings.js +44 -0
- package/dist/workshop/sessionStore.d.ts +61 -0
- package/dist/workshop/sessionStore.js +254 -0
- package/dist/workshop/workshopPin.d.ts +72 -0
- package/dist/workshop/workshopPin.js +193 -0
- package/examples/README.md +99 -0
- package/examples/archify-on-pr/README.md +213 -0
- package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +19 -0
- package/examples/archify-on-pr/archify-on-pr.task.yaml +19 -0
- package/examples/archify-on-pr/author-diagrams.yaml +106 -0
- package/examples/archify-on-pr/detect-changes.yaml +89 -0
- package/examples/browser-session/README.md +77 -0
- package/examples/browser-session/browser-session.pipeline.yaml +50 -0
- package/examples/browser-session/browser-session.task.yaml +6 -0
- package/examples/browser-session/check-login.yaml +22 -0
- package/examples/browser-session/fixture-server.mjs +64 -0
- package/examples/browser-session/human-login.yaml +31 -0
- package/examples/browser-session/merge.yaml +36 -0
- package/examples/browser-session/work-a.yaml +41 -0
- package/examples/browser-session/work-b.yaml +41 -0
- package/examples/ci-validate/README.md +35 -0
- package/examples/ci-validate/check.yaml +13 -0
- package/examples/ci-validate/ci-demo.pipeline.yaml +4 -0
- package/examples/ci-validate/validate.sh +5 -0
- package/examples/compliance-review-demo/README.md +125 -0
- package/examples/compliance-review-demo/compliance-review-demo.pipeline.yaml +29 -0
- package/examples/compliance-review-demo/connect-account.yaml +47 -0
- package/examples/compliance-review-demo/map-to-control.yaml +123 -0
- package/examples/compliance-review-demo/poll-bucket-config.yaml +103 -0
- package/examples/compliance-review-demo/publish-report.yaml +79 -0
- package/examples/compliance-review-demo/review-verdict.yaml +122 -0
- package/examples/compliance-review-demo/run-compliance-check.yaml +96 -0
- package/examples/compliance-review-demo/store-evidence.yaml +143 -0
- package/examples/conditional-fork/README.md +89 -0
- package/examples/conditional-fork/branch-a.yaml +13 -0
- package/examples/conditional-fork/branch-b.yaml +13 -0
- package/examples/conditional-fork/decide.yaml +35 -0
- package/examples/conditional-fork/fork-demo.pipeline.yaml +20 -0
- package/examples/conditional-fork/fork-demo.task.yaml +8 -0
- package/examples/context7-mcp/README.md +42 -0
- package/examples/context7-mcp/context7-mcp.pipeline.yaml +15 -0
- package/examples/context7-mcp/context7-mcp.task.yaml +4 -0
- package/examples/context7-mcp/fetch-docs.yaml +52 -0
- package/examples/context7-mcp/resolve-library.yaml +31 -0
- package/examples/context7-mcp/write-brief.yaml +52 -0
- package/examples/feature-loop/README.md +104 -0
- package/examples/feature-loop/address-feedback.yaml +148 -0
- package/examples/feature-loop/align.yaml +116 -0
- package/examples/feature-loop/decompose.yaml +86 -0
- package/examples/feature-loop/default-model-hierarchy.task.yaml +58 -0
- package/examples/feature-loop/feature-loop.pipeline.yaml +140 -0
- package/examples/feature-loop/feature-loop.task.yaml +25 -0
- package/examples/feature-loop/implement.yaml +128 -0
- package/examples/feature-loop/plan.yaml +111 -0
- package/examples/feature-loop/publish.yaml +167 -0
- package/examples/feature-loop/review.yaml +146 -0
- package/examples/feature-loop/verify.yaml +106 -0
- package/examples/feedback-loop/README.md +72 -0
- package/examples/feedback-loop/VERIFY.md +208 -0
- package/examples/feedback-loop/continue-only.task.yaml +4 -0
- package/examples/feedback-loop/exhaust-require-continue.task.yaml +6 -0
- package/examples/feedback-loop/exhaust-wait-human.task.yaml +11 -0
- package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +23 -0
- package/examples/feedback-loop/feedback-loop.pipeline.yaml +23 -0
- package/examples/feedback-loop/feedback-loop.task.yaml +4 -0
- package/examples/feedback-loop/implement.yaml +14 -0
- package/examples/feedback-loop/plan.yaml +14 -0
- package/examples/feedback-loop/review.yaml +15 -0
- package/examples/feedback-loop/send-back-once.task.yaml +6 -0
- package/examples/feedback-loop/submit.yaml +12 -0
- package/examples/generic-fan-in/README.md +151 -0
- package/examples/generic-fan-in/clarify.yaml +18 -0
- package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +19 -0
- package/examples/generic-fan-in/generic-fan-in-accepted.task.yaml +8 -0
- package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +18 -0
- package/examples/generic-fan-in/generic-fan-in.task.yaml +9 -0
- package/examples/generic-fan-in/research.yaml +45 -0
- package/examples/generic-fan-in/synthesize.yaml +66 -0
- package/examples/generic-fan-in/validation.yaml +45 -0
- package/examples/github-release/README.md +78 -0
- package/examples/github-release/draft-release-notes.yaml +64 -0
- package/examples/github-release/github-release.pipeline.yaml +11 -0
- package/examples/github-release/github-release.task.yaml +13 -0
- package/examples/github-release/publish-github-release.yaml +64 -0
- package/examples/hello-world/README.md +28 -0
- package/examples/hello-world/hello.pipeline.yaml +4 -0
- package/examples/hello-world/my-task.task.yaml +6 -0
- package/examples/hello-world/research.yaml +18 -0
- package/examples/mcp-hitl-tour/README.md +113 -0
- package/examples/mcp-hitl-tour/draft-angle.yaml +33 -0
- package/examples/mcp-hitl-tour/draft-short.yaml +32 -0
- package/examples/mcp-hitl-tour/emit-angles.yaml +45 -0
- package/examples/mcp-hitl-tour/gather.yaml +31 -0
- package/examples/mcp-hitl-tour/intake.yaml +62 -0
- package/examples/mcp-hitl-tour/mcp-hitl-tour-exhaust.task.yaml +13 -0
- package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +54 -0
- package/examples/mcp-hitl-tour/mcp-hitl-tour.task.yaml +16 -0
- package/examples/mcp-hitl-tour/polish.yaml +33 -0
- package/examples/mcp-hitl-tour/review.yaml +17 -0
- package/examples/mcp-hitl-tour/ship.yaml +25 -0
- package/examples/oss-issue-contribution/README.md +218 -0
- package/examples/oss-issue-contribution/oss-address-review-feedback.yaml +117 -0
- package/examples/oss-issue-contribution/oss-approve-contribution.yaml +181 -0
- package/examples/oss-issue-contribution/oss-approve-plan.yaml +111 -0
- package/examples/oss-issue-contribution/oss-explain-fix.yaml +108 -0
- package/examples/oss-issue-contribution/oss-explain-issue.yaml +114 -0
- package/examples/oss-issue-contribution/oss-implement-source-fix.yaml +171 -0
- package/examples/oss-issue-contribution/oss-investigate-area.yaml +116 -0
- package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +125 -0
- package/examples/oss-issue-contribution/oss-issue-intake.yaml +106 -0
- package/examples/oss-issue-contribution/oss-plan-investigation.yaml +112 -0
- package/examples/oss-issue-contribution/oss-plan-review.yaml +109 -0
- package/examples/oss-issue-contribution/oss-reproduce-issue.yaml +140 -0
- package/examples/oss-issue-contribution/oss-review-change.yaml +107 -0
- package/examples/oss-issue-contribution/oss-verify-fix.yaml +130 -0
- package/examples/oss-issue-contribution/oss-write-regression-test.yaml +135 -0
- package/examples/oss-issue-contribution/pi-7629.task.yaml +79 -0
- package/examples/oss-issue-contribution/pi-8919.task.yaml +75 -0
- package/examples/oss-issue-contribution/pydantic-ai-7971.task.yaml +53 -0
- package/examples/oss-quick-fix/README.md +65 -0
- package/examples/oss-quick-fix/implement-fix.yaml +84 -0
- package/examples/oss-quick-fix/oss-quick-fix.pipeline.yaml +35 -0
- package/examples/oss-quick-fix/oss-quick-fix.task.yaml +19 -0
- package/examples/oss-quick-fix/ship-fix.yaml +81 -0
- package/examples/oss-quick-fix/understand-issue.yaml +67 -0
- package/examples/oss-quick-fix/verify-fix.yaml +73 -0
- package/examples/plan-review/README.md +37 -0
- package/examples/plan-review/plan-review-followup.yaml +13 -0
- package/examples/plan-review/plan-review.pipeline.yaml +9 -0
- package/examples/plan-review/plan-review.task.yaml +9 -0
- package/examples/plan-review/plan-review.yaml +25 -0
- package/examples/playwright-mcp/README.md +39 -0
- package/examples/playwright-mcp/playwright-mcp.pipeline.yaml +5 -0
- package/examples/playwright-mcp/playwright-mcp.task.yaml +4 -0
- package/examples/playwright-mcp/screenshot.yaml +40 -0
- package/examples/retry-tour/README.md +75 -0
- package/examples/retry-tour/retry-tour.pipeline.yaml +122 -0
- package/examples/retry-tour/retry-tour.task.yaml +9 -0
- package/examples/route-if-tour/README.md +202 -0
- package/examples/route-if-tour/route-if-tour.pipeline.yaml +950 -0
- package/examples/route-if-tour/route-if-tour.task.yaml +4 -0
- package/examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml +168 -0
- package/examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml +44 -0
- package/examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml +28 -0
- package/examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml +27 -0
- package/examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml +110 -0
- package/examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml +82 -0
- package/examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml +82 -0
- package/examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml +77 -0
- package/examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml +102 -0
- package/examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml +23 -0
- package/examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml +37 -0
- package/examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml +138 -0
- package/examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml +84 -0
- package/examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml +50 -0
- package/examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml +37 -0
- package/examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml +65 -0
- package/examples/route-wiring-smoke-test/17-if-join.pipeline.yaml +80 -0
- package/examples/route-wiring-smoke-test/README.md +377 -0
- package/examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml +26 -0
- package/examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml +25 -0
- package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml +30 -0
- package/examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml +24 -0
- package/examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml +35 -0
- package/examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml +37 -0
- package/examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml +27 -0
- package/examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml +42 -0
- package/examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml +26 -0
- package/examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml +55 -0
- package/examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml +51 -0
- package/examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml +35 -0
- package/examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml +15 -0
- package/examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml +15 -0
- package/examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml +33 -0
- package/examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml +51 -0
- package/examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml +55 -0
- package/examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml +36 -0
- package/examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml +42 -0
- package/examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml +33 -0
- package/examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml +32 -0
- package/examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml +31 -0
- package/examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml +33 -0
- package/examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml +36 -0
- package/examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml +63 -0
- package/examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml +46 -0
- package/examples/route-wiring-smoke-test/smoke-test.task.yaml +4 -0
- package/examples/route-wiring-smoke-test/stages/branch-a.yaml +12 -0
- package/examples/route-wiring-smoke-test/stages/branch-b.yaml +12 -0
- package/examples/route-wiring-smoke-test/stages/decide.yaml +12 -0
- package/examples/route-wiring-smoke-test/stages/finish.yaml +12 -0
- package/examples/ship-feature/README.md +190 -0
- package/examples/ship-feature/feat-address-feedback.yaml +119 -0
- package/examples/ship-feature/feat-implement.yaml +180 -0
- package/examples/ship-feature/feat-plan.yaml +120 -0
- package/examples/ship-feature/feat-review.yaml +109 -0
- package/examples/ship-feature/feat-ship.yaml +203 -0
- package/examples/ship-feature/ship-feature.pipeline.yaml +44 -0
- package/examples/ship-feature/ship-feature.task.yaml +78 -0
- package/examples/stage-mcp/README.md +145 -0
- package/examples/stage-mcp/echo-mcp.mjs +20 -0
- package/examples/stage-mcp/stage-mcp-dead.pipeline.yaml +5 -0
- package/examples/stage-mcp/stage-mcp-dead.task.yaml +3 -0
- package/examples/stage-mcp/stage-mcp-missing-var.pipeline.yaml +5 -0
- package/examples/stage-mcp/stage-mcp-missing-var.task.yaml +3 -0
- package/examples/stage-mcp/stage-mcp.pipeline.yaml +5 -0
- package/examples/stage-mcp/stage-mcp.task.yaml +4 -0
- package/examples/stage-mcp/use-echo.yaml +20 -0
- package/examples/stageflow.yaml +51 -0
- package/examples/verify-tour/README.md +80 -0
- package/examples/verify-tour/verify-tour.pipeline.yaml +162 -0
- package/examples/verify-tour/verify-tour.task.yaml +11 -0
- package/package.json +9 -1
- package/skills/stageflow/SKILL.md +6 -6
- package/skills/stageflow/references/control-surface.md +13 -5
- package/skills/stageflow/scripts/detect-host.mjs +14 -1
- package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
- package/skills/stageflow-author/SKILL.md +4 -3
- package/skills/stageflow-author/references/catalog-mapping.md +16 -0
- package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
- package/skills/stageflow-author/references/stage-prompt-template.md +4 -4
- package/skills/stageflow-run/SKILL.md +22 -12
- package/skills/stageflow-run/references/mcp-call.md +9 -1
- package/skills/stageflow-run/references/task-and-pipeline-selection.md +19 -6
- package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
- package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
- package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
- package/skills/stageflow-setup/SKILL.md +51 -8
- package/dist/ui/assets/index-Da5EHU6M.js +0 -119
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import type { DraftPackage } from "../config/draftPackage.js";
|
|
2
|
+
import { type OperatorAgentHost, type OperatorAgentProposal, type OperatorAgentSession, type OperatorAgentSessionEvent, type ProposalArtifactDiff, type WorkshopToolActivityUpdate } from "../operatorAgent/index.js";
|
|
3
|
+
import { WorkshopSessionStoreError } from "./sessionStore.js";
|
|
4
|
+
import { type WorkshopPointerChange } from "./workshopPin.js";
|
|
5
|
+
export type { WorkshopPointerChange };
|
|
6
|
+
type LiveTurnBinding = {
|
|
7
|
+
storeRoot: string;
|
|
8
|
+
onPointerChange?: (frame: WorkshopPointerChange) => void;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Accept-card / soft-undo payload for a mutation that is **already applied**
|
|
12
|
+
* to the in-memory draft. `nextDraft` is current; `baseDraft` + fingerprint
|
|
13
|
+
* are the undo restore target when Reject is safe. Not a gated propose→Accept
|
|
14
|
+
* patch — create/edit tools mutate immediately.
|
|
15
|
+
*/
|
|
16
|
+
export type WorkshopChatProposalPayload = {
|
|
17
|
+
id: string;
|
|
18
|
+
summary: string;
|
|
19
|
+
nextDraft: DraftPackage;
|
|
20
|
+
baseDraft: DraftPackage;
|
|
21
|
+
baseFingerprint: string;
|
|
22
|
+
artifacts: ProposalArtifactDiff[];
|
|
23
|
+
affectedStageIds: string[];
|
|
24
|
+
};
|
|
25
|
+
export type WorkshopChatWireEvent = {
|
|
26
|
+
type: "message";
|
|
27
|
+
role: "assistant" | "user" | "system";
|
|
28
|
+
text: string;
|
|
29
|
+
}
|
|
30
|
+
/** Mutation receipt for Accept/Reject UX (draft already mutated). */
|
|
31
|
+
| {
|
|
32
|
+
type: "proposal";
|
|
33
|
+
proposal: WorkshopChatProposalPayload;
|
|
34
|
+
} | {
|
|
35
|
+
type: "tool_result";
|
|
36
|
+
name: string;
|
|
37
|
+
result: unknown;
|
|
38
|
+
} | {
|
|
39
|
+
type: "validation";
|
|
40
|
+
result: unknown;
|
|
41
|
+
} | {
|
|
42
|
+
type: "error";
|
|
43
|
+
message: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Chat requires an existing Workshop session id (created via New /
|
|
47
|
+
* POST /api/workshop/sessions). Unknown ids return workshop_session_not_found
|
|
48
|
+
* — no create-on-missing.
|
|
49
|
+
*/
|
|
50
|
+
export type WorkshopChatTurnInput = {
|
|
51
|
+
sessionId: string;
|
|
52
|
+
draft: DraftPackage;
|
|
53
|
+
message: string;
|
|
54
|
+
/** @deprecated Ignored — mutations apply immediately (Accept = soft undo). */
|
|
55
|
+
autoApply?: boolean;
|
|
56
|
+
/** Session model override from Workshop chrome. */
|
|
57
|
+
model?: string | null;
|
|
58
|
+
/** Settings default from factory settings /api/settings. */
|
|
59
|
+
settingsDefault?: string | null;
|
|
60
|
+
/**
|
|
61
|
+
* Injected host (tests / fake). When omitted, uses the registry's host
|
|
62
|
+
* (or a process-default Workshop fake Author host).
|
|
63
|
+
*/
|
|
64
|
+
host?: OperatorAgentHost;
|
|
65
|
+
/** Live host-session map; defaults to the process registry. */
|
|
66
|
+
registry?: WorkshopChatSessionRegistry;
|
|
67
|
+
/** Session store root; defaults to `$STAGEFLOW_HOME`. */
|
|
68
|
+
storeRoot?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Mid-turn assistant text callback. Invoked as model deltas arrive (before
|
|
71
|
+
* the turn promise resolves). HTTP uses this to flush NDJSON `delta` frames.
|
|
72
|
+
*/
|
|
73
|
+
onDelta?: (text: string) => void;
|
|
74
|
+
/** Mid-turn tool status. HTTP flushes this as an NDJSON activity frame. */
|
|
75
|
+
onActivity?: (update: WorkshopToolActivityUpdate) => void;
|
|
76
|
+
/** Fired when this turn changes the session pointer. */
|
|
77
|
+
onPointerChange?: (frame: WorkshopPointerChange) => void;
|
|
78
|
+
};
|
|
79
|
+
export type WorkshopChatTurnResult = {
|
|
80
|
+
sessionId: string;
|
|
81
|
+
events: WorkshopChatWireEvent[];
|
|
82
|
+
/** Draft left on the host after this turn. Pinned turns use the build, not the posted body. */
|
|
83
|
+
draft: DraftPackage;
|
|
84
|
+
/**
|
|
85
|
+
* Latest undoable mutation card (already applied), or null after
|
|
86
|
+
* Accept/undo. Name is historical — not a pending gated apply.
|
|
87
|
+
*/
|
|
88
|
+
pending: WorkshopChatProposalPayload | null;
|
|
89
|
+
/** Always false — auto-apply chrome removed; mutations apply immediately. */
|
|
90
|
+
autoApply: boolean;
|
|
91
|
+
model: string;
|
|
92
|
+
/** Build this turn edited. Null when the chat stayed unlinked. */
|
|
93
|
+
buildId: string | null;
|
|
94
|
+
};
|
|
95
|
+
export type WorkshopChatStreamFrame = {
|
|
96
|
+
type: "delta";
|
|
97
|
+
text: string;
|
|
98
|
+
} | ({
|
|
99
|
+
type: "activity";
|
|
100
|
+
} & WorkshopToolActivityUpdate) | {
|
|
101
|
+
type: "pointer-change";
|
|
102
|
+
buildId: string;
|
|
103
|
+
draft: DraftPackage;
|
|
104
|
+
} | {
|
|
105
|
+
type: "event";
|
|
106
|
+
event: WorkshopChatWireEvent;
|
|
107
|
+
} | {
|
|
108
|
+
type: "done";
|
|
109
|
+
sessionId: string;
|
|
110
|
+
events: WorkshopChatWireEvent[];
|
|
111
|
+
draft: DraftPackage;
|
|
112
|
+
pending: WorkshopChatProposalPayload | null;
|
|
113
|
+
autoApply: boolean;
|
|
114
|
+
model: string;
|
|
115
|
+
buildId: string | null;
|
|
116
|
+
};
|
|
117
|
+
export type WorkshopLiveSessionHandle = {
|
|
118
|
+
sessionId: string;
|
|
119
|
+
agentSession: OperatorAgentSession;
|
|
120
|
+
};
|
|
121
|
+
export declare class WorkshopChatSessionRegistry {
|
|
122
|
+
readonly host: OperatorAgentHost;
|
|
123
|
+
private readonly sessions;
|
|
124
|
+
private readonly turnsInFlight;
|
|
125
|
+
private readonly turnChains;
|
|
126
|
+
private readonly pins;
|
|
127
|
+
private readonly liveTurns;
|
|
128
|
+
constructor(host: OperatorAgentHost);
|
|
129
|
+
runExclusive<T>(sessionId: string, fn: () => Promise<T>): Promise<T>;
|
|
130
|
+
bindTurn(sessionId: string, binding: LiveTurnBinding, pinnedBuildId: string | null): void;
|
|
131
|
+
getLiveTurn(sessionId: string): LiveTurnBinding | undefined;
|
|
132
|
+
getPinnedBuildId(sessionId: string): string | null;
|
|
133
|
+
setPinnedBuildId(sessionId: string, buildId: string | null): void;
|
|
134
|
+
clearLive(sessionId: string): void;
|
|
135
|
+
has(sessionId: string): boolean;
|
|
136
|
+
get(sessionId: string): OperatorAgentSession | undefined;
|
|
137
|
+
isTurnInFlight(sessionId: string): boolean;
|
|
138
|
+
beginTurn(sessionId: string): void;
|
|
139
|
+
endTurn(sessionId: string): void;
|
|
140
|
+
/**
|
|
141
|
+
* Interrupt the open host session's in-flight prompt.
|
|
142
|
+
* Returns false when this session has no turn running.
|
|
143
|
+
*/
|
|
144
|
+
abortTurn(sessionId: string): Promise<boolean>;
|
|
145
|
+
/**
|
|
146
|
+
* Reuse the open host session when present; otherwise open a new one.
|
|
147
|
+
* Rebinds the draft argument. Pinned turns pass the stored build draft.
|
|
148
|
+
* Returns whether this call created a new host session (restart / first open).
|
|
149
|
+
*/
|
|
150
|
+
getOrOpen(sessionId: string, draft: DraftPackage): {
|
|
151
|
+
session: OperatorAgentSession;
|
|
152
|
+
created: boolean;
|
|
153
|
+
};
|
|
154
|
+
close(sessionId: string): void;
|
|
155
|
+
clear(): void;
|
|
156
|
+
}
|
|
157
|
+
/** Test helper — drop process-default live sessions between cases. */
|
|
158
|
+
export declare function resetWorkshopChatSessionsForTests(): void;
|
|
159
|
+
export declare function serializeWorkshopProposal(proposal: OperatorAgentProposal, fallbackDraft: DraftPackage): WorkshopChatProposalPayload;
|
|
160
|
+
export declare function toWorkshopChatWireEvent(event: OperatorAgentSessionEvent, fallbackDraft: DraftPackage): WorkshopChatWireEvent;
|
|
161
|
+
/**
|
|
162
|
+
* One Workshop Author turn on a durable Operator Agent Host session.
|
|
163
|
+
* Requires an existing session store record (New / POST sessions first).
|
|
164
|
+
* Does not close the host session after the turn.
|
|
165
|
+
* A pinned build's stored draft is the source of truth. An unlinked turn
|
|
166
|
+
* still binds the client draft, and draft tools fail until a build is pinned.
|
|
167
|
+
* A second turn for the same session waits until this one finishes.
|
|
168
|
+
*/
|
|
169
|
+
export declare function runWorkshopChatTurn(input: WorkshopChatTurnInput): Promise<WorkshopChatTurnResult>;
|
|
170
|
+
/** Stop the in-flight Author prompt and return the draft it left behind. */
|
|
171
|
+
export declare function stopWorkshopChatTurn(registry: WorkshopChatSessionRegistry, sessionId: string): Promise<{
|
|
172
|
+
stopped: boolean;
|
|
173
|
+
draft: DraftPackage | null;
|
|
174
|
+
pending: WorkshopChatProposalPayload | null;
|
|
175
|
+
buildId: string | null;
|
|
176
|
+
}>;
|
|
177
|
+
/** Chunk assistant text for NDJSON stream frames (fake/live coherent turns). */
|
|
178
|
+
export declare function chunkAssistantText(text: string, chunkSize?: number): string[];
|
|
179
|
+
export declare function iterateWorkshopChatStreamFrames(result: WorkshopChatTurnResult, options?: {
|
|
180
|
+
chunkAssistantText?: boolean;
|
|
181
|
+
}): Generator<WorkshopChatStreamFrame>;
|
|
182
|
+
export type WorkshopSessionUndoInput = {
|
|
183
|
+
sessionId: string;
|
|
184
|
+
draft: DraftPackage;
|
|
185
|
+
mutationId?: string;
|
|
186
|
+
host?: OperatorAgentHost;
|
|
187
|
+
registry?: WorkshopChatSessionRegistry;
|
|
188
|
+
storeRoot?: string;
|
|
189
|
+
};
|
|
190
|
+
export type WorkshopSessionUndoResult = {
|
|
191
|
+
ok: true;
|
|
192
|
+
sessionId: string;
|
|
193
|
+
draft: DraftPackage;
|
|
194
|
+
pending: WorkshopChatProposalPayload | null;
|
|
195
|
+
} | {
|
|
196
|
+
ok: false;
|
|
197
|
+
sessionId: string;
|
|
198
|
+
draft: DraftPackage;
|
|
199
|
+
pending: WorkshopChatProposalPayload | null;
|
|
200
|
+
reason: "none" | "id_mismatch" | "conflict";
|
|
201
|
+
notice?: string;
|
|
202
|
+
};
|
|
203
|
+
export type WorkshopSessionAcceptInput = {
|
|
204
|
+
sessionId: string;
|
|
205
|
+
draft: DraftPackage;
|
|
206
|
+
mutationId?: string;
|
|
207
|
+
host?: OperatorAgentHost;
|
|
208
|
+
registry?: WorkshopChatSessionRegistry;
|
|
209
|
+
storeRoot?: string;
|
|
210
|
+
};
|
|
211
|
+
export type WorkshopSessionAcceptResult = {
|
|
212
|
+
ok: true;
|
|
213
|
+
sessionId: string;
|
|
214
|
+
draft: DraftPackage;
|
|
215
|
+
pending: WorkshopChatProposalPayload | null;
|
|
216
|
+
} | {
|
|
217
|
+
ok: false;
|
|
218
|
+
sessionId: string;
|
|
219
|
+
draft: DraftPackage;
|
|
220
|
+
pending: WorkshopChatProposalPayload | null;
|
|
221
|
+
reason: "none" | "id_mismatch" | "conflict";
|
|
222
|
+
notice?: string;
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Soft-undo a mutation on a durable Workshop host session.
|
|
226
|
+
* Rebinds the client draft first (R9), then undoes when fingerprint matches.
|
|
227
|
+
* Fail-closed during an in-flight chat turn: no rebind, conflict.
|
|
228
|
+
*/
|
|
229
|
+
export declare function undoWorkshopSessionMutation(input: WorkshopSessionUndoInput): Promise<WorkshopSessionUndoResult>;
|
|
230
|
+
/** Accept acknowledges a mutation card; draft is already applied. */
|
|
231
|
+
export declare function acceptWorkshopSessionMutation(input: WorkshopSessionAcceptInput): Promise<WorkshopSessionAcceptResult>;
|
|
232
|
+
export { WorkshopSessionStoreError };
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import { createWorkshopDraftContext, createWorkshopOperatorHost, isWorkshopDraftContext, readDraftFromContext, withDraft, WORKSHOP_AUTHOR_PROFILE_ID, } from "../operatorAgent/index.js";
|
|
2
|
+
import { resolveWorkshopModel } from "./modelSettings.js";
|
|
3
|
+
import { getWorkshopBuild, updateWorkshopBuild } from "./buildStore.js";
|
|
4
|
+
import { appendWorkshopSessionMessages, getWorkshopSession, resolveWorkshopSessionStoreRoot, WorkshopSessionStoreError, } from "./sessionStore.js";
|
|
5
|
+
import { bindPinnedBuildContext, enqueueSessionWrite, registerLiveWorkshopSession, resetWorkshopPinStateForTests, unregisterLiveWorkshopSession, } from "./workshopPin.js";
|
|
6
|
+
function markUnlinkedChatContext(current, sessionId, draft) {
|
|
7
|
+
const base = isWorkshopDraftContext(current)
|
|
8
|
+
? { ...current, draft }
|
|
9
|
+
: { draft };
|
|
10
|
+
delete base.buildId;
|
|
11
|
+
base.chatSessionId = sessionId;
|
|
12
|
+
base.draft = draft;
|
|
13
|
+
return base;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* In-memory map of Workshop session id → open OperatorAgentSession.
|
|
17
|
+
* Survives across chat turns until process restart (disk transcript remains).
|
|
18
|
+
*/
|
|
19
|
+
const TURN_IN_FLIGHT_UNDO_NOTICE = "Cannot undo while a chat turn is in progress.";
|
|
20
|
+
export class WorkshopChatSessionRegistry {
|
|
21
|
+
host;
|
|
22
|
+
sessions = new Map();
|
|
23
|
+
turnsInFlight = new Set();
|
|
24
|
+
turnChains = new Map();
|
|
25
|
+
pins = new Map();
|
|
26
|
+
liveTurns = new Map();
|
|
27
|
+
constructor(host) {
|
|
28
|
+
this.host = host;
|
|
29
|
+
}
|
|
30
|
+
runExclusive(sessionId, fn) {
|
|
31
|
+
const prev = this.turnChains.get(sessionId) ?? Promise.resolve();
|
|
32
|
+
const run = prev.then(fn, fn);
|
|
33
|
+
this.turnChains.set(sessionId, run.then(() => undefined, () => undefined));
|
|
34
|
+
return run;
|
|
35
|
+
}
|
|
36
|
+
bindTurn(sessionId, binding, pinnedBuildId) {
|
|
37
|
+
this.liveTurns.set(sessionId, binding);
|
|
38
|
+
this.pins.set(sessionId, pinnedBuildId);
|
|
39
|
+
registerLiveWorkshopSession(sessionId, {
|
|
40
|
+
storeRoot: binding.storeRoot,
|
|
41
|
+
registry: this,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
getLiveTurn(sessionId) {
|
|
45
|
+
return this.liveTurns.get(sessionId);
|
|
46
|
+
}
|
|
47
|
+
getPinnedBuildId(sessionId) {
|
|
48
|
+
return this.pins.get(sessionId) ?? null;
|
|
49
|
+
}
|
|
50
|
+
setPinnedBuildId(sessionId, buildId) {
|
|
51
|
+
this.pins.set(sessionId, buildId);
|
|
52
|
+
}
|
|
53
|
+
clearLive(sessionId) {
|
|
54
|
+
this.liveTurns.delete(sessionId);
|
|
55
|
+
unregisterLiveWorkshopSession(sessionId);
|
|
56
|
+
}
|
|
57
|
+
has(sessionId) {
|
|
58
|
+
return this.sessions.has(sessionId);
|
|
59
|
+
}
|
|
60
|
+
get(sessionId) {
|
|
61
|
+
return this.sessions.get(sessionId)?.agentSession;
|
|
62
|
+
}
|
|
63
|
+
isTurnInFlight(sessionId) {
|
|
64
|
+
return this.turnsInFlight.has(sessionId);
|
|
65
|
+
}
|
|
66
|
+
beginTurn(sessionId) {
|
|
67
|
+
this.turnsInFlight.add(sessionId);
|
|
68
|
+
}
|
|
69
|
+
endTurn(sessionId) {
|
|
70
|
+
this.turnsInFlight.delete(sessionId);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Interrupt the open host session's in-flight prompt.
|
|
74
|
+
* Returns false when this session has no turn running.
|
|
75
|
+
*/
|
|
76
|
+
async abortTurn(sessionId) {
|
|
77
|
+
if (!this.turnsInFlight.has(sessionId))
|
|
78
|
+
return false;
|
|
79
|
+
const session = this.sessions.get(sessionId)?.agentSession;
|
|
80
|
+
if (!session)
|
|
81
|
+
return false;
|
|
82
|
+
await session.abort();
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Reuse the open host session when present; otherwise open a new one.
|
|
87
|
+
* Rebinds the draft argument. Pinned turns pass the stored build draft.
|
|
88
|
+
* Returns whether this call created a new host session (restart / first open).
|
|
89
|
+
*/
|
|
90
|
+
getOrOpen(sessionId, draft) {
|
|
91
|
+
const existing = this.sessions.get(sessionId);
|
|
92
|
+
if (existing) {
|
|
93
|
+
existing.agentSession.setContext(withDraft(existing.agentSession.getContext(), draft));
|
|
94
|
+
return { session: existing.agentSession, created: false };
|
|
95
|
+
}
|
|
96
|
+
const agentSession = this.host.openSession({
|
|
97
|
+
profileId: WORKSHOP_AUTHOR_PROFILE_ID,
|
|
98
|
+
context: createWorkshopDraftContext(draft),
|
|
99
|
+
});
|
|
100
|
+
this.sessions.set(sessionId, { sessionId, agentSession });
|
|
101
|
+
return { session: agentSession, created: true };
|
|
102
|
+
}
|
|
103
|
+
close(sessionId) {
|
|
104
|
+
const handle = this.sessions.get(sessionId);
|
|
105
|
+
if (!handle)
|
|
106
|
+
return;
|
|
107
|
+
handle.agentSession.close();
|
|
108
|
+
this.sessions.delete(sessionId);
|
|
109
|
+
this.turnsInFlight.delete(sessionId);
|
|
110
|
+
}
|
|
111
|
+
clear() {
|
|
112
|
+
for (const handle of this.sessions.values()) {
|
|
113
|
+
handle.agentSession.close();
|
|
114
|
+
}
|
|
115
|
+
this.sessions.clear();
|
|
116
|
+
this.turnsInFlight.clear();
|
|
117
|
+
this.turnChains.clear();
|
|
118
|
+
this.pins.clear();
|
|
119
|
+
this.liveTurns.clear();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
let defaultHost;
|
|
123
|
+
let defaultRegistry;
|
|
124
|
+
function getDefaultRegistry(host) {
|
|
125
|
+
if (host) {
|
|
126
|
+
if (!defaultRegistry || defaultRegistry.host !== host) {
|
|
127
|
+
defaultRegistry?.clear();
|
|
128
|
+
defaultRegistry = new WorkshopChatSessionRegistry(host);
|
|
129
|
+
}
|
|
130
|
+
return defaultRegistry;
|
|
131
|
+
}
|
|
132
|
+
if (!defaultHost) {
|
|
133
|
+
defaultHost = createWorkshopOperatorHost();
|
|
134
|
+
}
|
|
135
|
+
if (!defaultRegistry || defaultRegistry.host !== defaultHost) {
|
|
136
|
+
defaultRegistry?.clear();
|
|
137
|
+
defaultRegistry = new WorkshopChatSessionRegistry(defaultHost);
|
|
138
|
+
}
|
|
139
|
+
return defaultRegistry;
|
|
140
|
+
}
|
|
141
|
+
/** Test helper — drop process-default live sessions between cases. */
|
|
142
|
+
export function resetWorkshopChatSessionsForTests() {
|
|
143
|
+
defaultRegistry?.clear();
|
|
144
|
+
defaultRegistry = undefined;
|
|
145
|
+
defaultHost = undefined;
|
|
146
|
+
resetWorkshopPinStateForTests();
|
|
147
|
+
}
|
|
148
|
+
function isDraftPackage(value) {
|
|
149
|
+
return (value !== null &&
|
|
150
|
+
typeof value === "object" &&
|
|
151
|
+
"pipeline" in value &&
|
|
152
|
+
typeof value.pipeline === "object" &&
|
|
153
|
+
value.pipeline !== null);
|
|
154
|
+
}
|
|
155
|
+
function draftFromContextValue(value, fallback) {
|
|
156
|
+
if (isDraftPackage(value))
|
|
157
|
+
return value;
|
|
158
|
+
if (value !== null &&
|
|
159
|
+
typeof value === "object" &&
|
|
160
|
+
"draft" in value &&
|
|
161
|
+
isDraftPackage(value.draft)) {
|
|
162
|
+
return value.draft;
|
|
163
|
+
}
|
|
164
|
+
return fallback;
|
|
165
|
+
}
|
|
166
|
+
export function serializeWorkshopProposal(proposal, fallbackDraft) {
|
|
167
|
+
// Wire shape for Accept/Reject cards — mutation already applied on the host.
|
|
168
|
+
const nextDraft = draftFromContextValue(proposal.nextContext, fallbackDraft);
|
|
169
|
+
const baseDraft = draftFromContextValue(proposal.baseContext, fallbackDraft);
|
|
170
|
+
return {
|
|
171
|
+
id: proposal.id,
|
|
172
|
+
summary: proposal.summary,
|
|
173
|
+
nextDraft,
|
|
174
|
+
baseDraft,
|
|
175
|
+
baseFingerprint: typeof proposal.baseFingerprint === "string" && proposal.baseFingerprint
|
|
176
|
+
? proposal.baseFingerprint
|
|
177
|
+
: JSON.stringify(baseDraft),
|
|
178
|
+
artifacts: Array.isArray(proposal.artifacts) ? proposal.artifacts : [],
|
|
179
|
+
affectedStageIds: Array.isArray(proposal.affectedStageIds)
|
|
180
|
+
? proposal.affectedStageIds
|
|
181
|
+
: [],
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
export function toWorkshopChatWireEvent(event, fallbackDraft) {
|
|
185
|
+
if (event.type === "proposal") {
|
|
186
|
+
return {
|
|
187
|
+
type: "proposal",
|
|
188
|
+
proposal: serializeWorkshopProposal(event.proposal, fallbackDraft),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
if (event.type === "message") {
|
|
192
|
+
return {
|
|
193
|
+
type: "message",
|
|
194
|
+
role: event.role,
|
|
195
|
+
text: event.text,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (event.type === "tool_result") {
|
|
199
|
+
return {
|
|
200
|
+
type: "tool_result",
|
|
201
|
+
name: event.name,
|
|
202
|
+
result: event.result,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (event.type === "validation") {
|
|
206
|
+
return { type: "validation", result: event.result };
|
|
207
|
+
}
|
|
208
|
+
return { type: "error", message: event.message };
|
|
209
|
+
}
|
|
210
|
+
function transcriptMessagesForTurn(userMessage, events) {
|
|
211
|
+
const messages = [
|
|
212
|
+
{ role: "user", text: userMessage },
|
|
213
|
+
];
|
|
214
|
+
for (const event of events) {
|
|
215
|
+
if (event.type === "message") {
|
|
216
|
+
messages.push({ role: event.role, text: event.text });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return messages;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* One Workshop Author turn on a durable Operator Agent Host session.
|
|
223
|
+
* Requires an existing session store record (New / POST sessions first).
|
|
224
|
+
* Does not close the host session after the turn.
|
|
225
|
+
* A pinned build's stored draft is the source of truth. An unlinked turn
|
|
226
|
+
* still binds the client draft, and draft tools fail until a build is pinned.
|
|
227
|
+
* A second turn for the same session waits until this one finishes.
|
|
228
|
+
*/
|
|
229
|
+
export async function runWorkshopChatTurn(input) {
|
|
230
|
+
const sessionId = typeof input.sessionId === "string" ? input.sessionId.trim() : "";
|
|
231
|
+
if (!sessionId) {
|
|
232
|
+
throw new Error("sessionId is required");
|
|
233
|
+
}
|
|
234
|
+
const message = input.message.trim();
|
|
235
|
+
if (!message) {
|
|
236
|
+
throw new Error("message is required");
|
|
237
|
+
}
|
|
238
|
+
const storeRoot = input.storeRoot ?? resolveWorkshopSessionStoreRoot();
|
|
239
|
+
const model = resolveWorkshopModel({
|
|
240
|
+
sessionOverride: input.model,
|
|
241
|
+
settingsDefault: input.settingsDefault,
|
|
242
|
+
});
|
|
243
|
+
const registry = input.registry ?? getDefaultRegistry(input.host);
|
|
244
|
+
if (input.host && registry.host !== input.host) {
|
|
245
|
+
throw new Error("host does not match workshop chat session registry");
|
|
246
|
+
}
|
|
247
|
+
return registry.runExclusive(sessionId, async () => {
|
|
248
|
+
// Fail closed: chat never creates missing sessions (prefer New → create).
|
|
249
|
+
const storeRecord = getWorkshopSession(storeRoot, sessionId);
|
|
250
|
+
const pinnedBuild = storeRecord.activeBuildId
|
|
251
|
+
? getWorkshopBuild(storeRoot, storeRecord.activeBuildId)
|
|
252
|
+
: null;
|
|
253
|
+
const draftForOpen = pinnedBuild?.draft ?? input.draft;
|
|
254
|
+
const { session: agentSession, created } = registry.getOrOpen(sessionId, draftForOpen);
|
|
255
|
+
if (pinnedBuild) {
|
|
256
|
+
agentSession.setContext(bindPinnedBuildContext(agentSession.getContext(), pinnedBuild, sessionId));
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
agentSession.setContext(markUnlinkedChatContext(agentSession.getContext(), sessionId, draftForOpen));
|
|
260
|
+
}
|
|
261
|
+
registry.bindTurn(sessionId, {
|
|
262
|
+
storeRoot,
|
|
263
|
+
onPointerChange: input.onPointerChange,
|
|
264
|
+
}, pinnedBuild?.id ?? null);
|
|
265
|
+
registry.beginTurn(sessionId);
|
|
266
|
+
let rawEvents;
|
|
267
|
+
let resultBuildId = null;
|
|
268
|
+
try {
|
|
269
|
+
// KTD7: process restart → new host session; replay disk transcript into Pi.
|
|
270
|
+
if (created &&
|
|
271
|
+
storeRecord.transcript.length > 0 &&
|
|
272
|
+
typeof agentSession.prepareRestart === "function") {
|
|
273
|
+
await agentSession.prepareRestart(storeRecord.transcript);
|
|
274
|
+
}
|
|
275
|
+
rawEvents = await agentSession.send(message, {
|
|
276
|
+
onDelta: input.onDelta,
|
|
277
|
+
onActivity: (update) => {
|
|
278
|
+
const buildId = registry.getPinnedBuildId(sessionId);
|
|
279
|
+
input.onActivity?.({
|
|
280
|
+
...update,
|
|
281
|
+
...(buildId ? { buildId } : {}),
|
|
282
|
+
});
|
|
283
|
+
},
|
|
284
|
+
modelId: model,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
finally {
|
|
288
|
+
try {
|
|
289
|
+
resultBuildId = registry.getPinnedBuildId(sessionId);
|
|
290
|
+
if (resultBuildId) {
|
|
291
|
+
updateWorkshopBuild(storeRoot, resultBuildId, {
|
|
292
|
+
draft: readDraftFromContext(agentSession.getContext()),
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
registry.endTurn(sessionId);
|
|
298
|
+
registry.clearLive(sessionId);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const draft = readDraftFromContext(agentSession.getContext());
|
|
302
|
+
const pendingRaw = agentSession.getPendingProposal();
|
|
303
|
+
const events = rawEvents.map((event) => toWorkshopChatWireEvent(event, draft));
|
|
304
|
+
await enqueueSessionWrite(sessionId, () => {
|
|
305
|
+
appendWorkshopSessionMessages(storeRoot, sessionId, transcriptMessagesForTurn(message, events));
|
|
306
|
+
});
|
|
307
|
+
return {
|
|
308
|
+
sessionId,
|
|
309
|
+
events,
|
|
310
|
+
draft,
|
|
311
|
+
pending: pendingRaw
|
|
312
|
+
? serializeWorkshopProposal(pendingRaw, draft)
|
|
313
|
+
: null,
|
|
314
|
+
autoApply: false,
|
|
315
|
+
model,
|
|
316
|
+
buildId: resultBuildId,
|
|
317
|
+
};
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
/** Stop the in-flight Author prompt and return the draft it left behind. */
|
|
321
|
+
export async function stopWorkshopChatTurn(registry, sessionId) {
|
|
322
|
+
const stopped = await registry.abortTurn(sessionId);
|
|
323
|
+
const buildId = registry.getPinnedBuildId(sessionId);
|
|
324
|
+
const session = registry.get(sessionId);
|
|
325
|
+
if (!session) {
|
|
326
|
+
return { stopped, draft: null, pending: null, buildId };
|
|
327
|
+
}
|
|
328
|
+
const draft = readDraftFromContext(session.getContext());
|
|
329
|
+
const pendingRaw = session.getPendingProposal();
|
|
330
|
+
return {
|
|
331
|
+
stopped,
|
|
332
|
+
draft,
|
|
333
|
+
pending: pendingRaw
|
|
334
|
+
? serializeWorkshopProposal(pendingRaw, draft)
|
|
335
|
+
: null,
|
|
336
|
+
buildId,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
/** Chunk assistant text for NDJSON stream frames (fake/live coherent turns). */
|
|
340
|
+
export function chunkAssistantText(text, chunkSize = 28) {
|
|
341
|
+
if (!text)
|
|
342
|
+
return [];
|
|
343
|
+
const size = Math.max(1, chunkSize);
|
|
344
|
+
const chunks = [];
|
|
345
|
+
for (let i = 0; i < text.length; i += size) {
|
|
346
|
+
chunks.push(text.slice(i, i + size));
|
|
347
|
+
}
|
|
348
|
+
return chunks;
|
|
349
|
+
}
|
|
350
|
+
export function* iterateWorkshopChatStreamFrames(result, options) {
|
|
351
|
+
const chunkText = options?.chunkAssistantText !== false;
|
|
352
|
+
for (const event of result.events) {
|
|
353
|
+
if (chunkText &&
|
|
354
|
+
event.type === "message" &&
|
|
355
|
+
event.role === "assistant") {
|
|
356
|
+
for (const text of chunkAssistantText(event.text)) {
|
|
357
|
+
yield { type: "delta", text };
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
yield { type: "event", event };
|
|
361
|
+
}
|
|
362
|
+
yield {
|
|
363
|
+
type: "done",
|
|
364
|
+
sessionId: result.sessionId,
|
|
365
|
+
events: result.events,
|
|
366
|
+
draft: result.draft,
|
|
367
|
+
pending: result.pending,
|
|
368
|
+
autoApply: result.autoApply,
|
|
369
|
+
model: result.model,
|
|
370
|
+
buildId: result.buildId,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function snapshotLiveSession(registry, sessionId, fallbackDraft) {
|
|
374
|
+
const session = registry.get(sessionId);
|
|
375
|
+
if (!session) {
|
|
376
|
+
return { draft: fallbackDraft, pending: null };
|
|
377
|
+
}
|
|
378
|
+
const draft = readDraftFromContext(session.getContext());
|
|
379
|
+
const pendingRaw = session.getPendingProposal();
|
|
380
|
+
return {
|
|
381
|
+
draft,
|
|
382
|
+
pending: pendingRaw
|
|
383
|
+
? serializeWorkshopProposal(pendingRaw, draft)
|
|
384
|
+
: null,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Soft-undo a mutation on a durable Workshop host session.
|
|
389
|
+
* Rebinds the client draft first (R9), then undoes when fingerprint matches.
|
|
390
|
+
* Fail-closed during an in-flight chat turn: no rebind, conflict.
|
|
391
|
+
*/
|
|
392
|
+
export async function undoWorkshopSessionMutation(input) {
|
|
393
|
+
const sessionId = typeof input.sessionId === "string" ? input.sessionId.trim() : "";
|
|
394
|
+
if (!sessionId) {
|
|
395
|
+
throw new Error("sessionId is required");
|
|
396
|
+
}
|
|
397
|
+
const storeRoot = input.storeRoot ?? resolveWorkshopSessionStoreRoot();
|
|
398
|
+
getWorkshopSession(storeRoot, sessionId);
|
|
399
|
+
const registry = input.registry ?? getDefaultRegistry(input.host);
|
|
400
|
+
if (input.host && registry.host !== input.host) {
|
|
401
|
+
throw new Error("host does not match workshop chat session registry");
|
|
402
|
+
}
|
|
403
|
+
if (registry.isTurnInFlight(sessionId)) {
|
|
404
|
+
const snap = snapshotLiveSession(registry, sessionId, input.draft);
|
|
405
|
+
return {
|
|
406
|
+
ok: false,
|
|
407
|
+
sessionId,
|
|
408
|
+
draft: snap.draft,
|
|
409
|
+
pending: snap.pending,
|
|
410
|
+
reason: "conflict",
|
|
411
|
+
notice: TURN_IN_FLIGHT_UNDO_NOTICE,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
const { session } = registry.getOrOpen(sessionId, input.draft);
|
|
415
|
+
const undo = session.undoMutation(input.mutationId);
|
|
416
|
+
const draft = readDraftFromContext(session.getContext());
|
|
417
|
+
const pendingRaw = session.getPendingProposal();
|
|
418
|
+
const pending = pendingRaw
|
|
419
|
+
? serializeWorkshopProposal(pendingRaw, draft)
|
|
420
|
+
: null;
|
|
421
|
+
if (undo.ok) {
|
|
422
|
+
return { ok: true, sessionId, draft, pending };
|
|
423
|
+
}
|
|
424
|
+
return {
|
|
425
|
+
ok: false,
|
|
426
|
+
sessionId,
|
|
427
|
+
draft,
|
|
428
|
+
pending,
|
|
429
|
+
reason: undo.reason,
|
|
430
|
+
...(undo.notice !== undefined ? { notice: undo.notice } : {}),
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
/** Accept acknowledges a mutation card; draft is already applied. */
|
|
434
|
+
export async function acceptWorkshopSessionMutation(input) {
|
|
435
|
+
const sessionId = typeof input.sessionId === "string" ? input.sessionId.trim() : "";
|
|
436
|
+
if (!sessionId) {
|
|
437
|
+
throw new Error("sessionId is required");
|
|
438
|
+
}
|
|
439
|
+
const storeRoot = input.storeRoot ?? resolveWorkshopSessionStoreRoot();
|
|
440
|
+
getWorkshopSession(storeRoot, sessionId);
|
|
441
|
+
const registry = input.registry ?? getDefaultRegistry(input.host);
|
|
442
|
+
if (input.host && registry.host !== input.host) {
|
|
443
|
+
throw new Error("host does not match workshop chat session registry");
|
|
444
|
+
}
|
|
445
|
+
if (registry.isTurnInFlight(sessionId)) {
|
|
446
|
+
const snap = snapshotLiveSession(registry, sessionId, input.draft);
|
|
447
|
+
return {
|
|
448
|
+
ok: false,
|
|
449
|
+
sessionId,
|
|
450
|
+
draft: snap.draft,
|
|
451
|
+
pending: snap.pending,
|
|
452
|
+
reason: "conflict",
|
|
453
|
+
notice: TURN_IN_FLIGHT_UNDO_NOTICE,
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
const { session } = registry.getOrOpen(sessionId, input.draft);
|
|
457
|
+
const accepted = session.acceptProposal(input.mutationId);
|
|
458
|
+
const draft = readDraftFromContext(session.getContext());
|
|
459
|
+
const pendingRaw = session.getPendingProposal();
|
|
460
|
+
const pending = pendingRaw
|
|
461
|
+
? serializeWorkshopProposal(pendingRaw, draft)
|
|
462
|
+
: null;
|
|
463
|
+
if (accepted.ok) {
|
|
464
|
+
return { ok: true, sessionId, draft, pending };
|
|
465
|
+
}
|
|
466
|
+
return {
|
|
467
|
+
ok: false,
|
|
468
|
+
sessionId,
|
|
469
|
+
draft,
|
|
470
|
+
pending,
|
|
471
|
+
reason: accepted.reason,
|
|
472
|
+
...(accepted.notice !== undefined ? { notice: accepted.notice } : {}),
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
export { WorkshopSessionStoreError };
|