stageflow 0.27.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.
Files changed (261) hide show
  1. package/README.md +4 -0
  2. package/builtin-skills/browser/SKILL.md +42 -0
  3. package/dist/agent/claudeAdapter.js +2 -2
  4. package/dist/agent/cursorProvider.d.ts +2 -0
  5. package/dist/agent/cursorProvider.js +30 -5
  6. package/dist/agent/fakeAgent.d.ts +1 -0
  7. package/dist/agent/fakeAgent.js +13 -0
  8. package/dist/agent/piAdapter.d.ts +3 -24
  9. package/dist/agent/piAdapter.js +49 -47
  10. package/dist/agent/piSessionFactory.d.ts +38 -0
  11. package/dist/agent/piSessionFactory.js +60 -0
  12. package/dist/agent/port.d.ts +2 -0
  13. package/dist/agent/streamLogRedact.d.ts +6 -0
  14. package/dist/agent/streamLogRedact.js +23 -1
  15. package/dist/browser/anchor.d.ts +27 -0
  16. package/dist/browser/anchor.js +127 -0
  17. package/dist/browser/auditSink.d.ts +38 -0
  18. package/dist/browser/auditSink.js +34 -0
  19. package/dist/browser/browserHost.d.ts +86 -0
  20. package/dist/browser/browserHost.js +7 -0
  21. package/dist/browser/browserSweep.d.ts +14 -0
  22. package/dist/browser/browserSweep.js +54 -0
  23. package/dist/browser/browserTeardown.d.ts +56 -0
  24. package/dist/browser/browserTeardown.js +235 -0
  25. package/dist/browser/fakeRemoteBrowserHost.d.ts +2 -0
  26. package/dist/browser/fakeRemoteBrowserHost.js +34 -0
  27. package/dist/browser/gateHandoff.d.ts +25 -0
  28. package/dist/browser/gateHandoff.js +83 -0
  29. package/dist/browser/humanLogin.d.ts +18 -0
  30. package/dist/browser/humanLogin.js +34 -0
  31. package/dist/browser/keyProvider.d.ts +10 -0
  32. package/dist/browser/keyProvider.js +39 -0
  33. package/dist/browser/localBrowserHost.d.ts +10 -0
  34. package/dist/browser/localBrowserHost.js +152 -0
  35. package/dist/browser/localProfileLock.d.ts +2 -0
  36. package/dist/browser/localProfileLock.js +218 -0
  37. package/dist/browser/localProfileStore.d.ts +5 -0
  38. package/dist/browser/localProfileStore.js +91 -0
  39. package/dist/browser/loginCheck.d.ts +53 -0
  40. package/dist/browser/loginCheck.js +147 -0
  41. package/dist/browser/memoryProfileLock.d.ts +2 -0
  42. package/dist/browser/memoryProfileLock.js +53 -0
  43. package/dist/browser/memoryProfileStore.d.ts +2 -0
  44. package/dist/browser/memoryProfileStore.js +31 -0
  45. package/dist/browser/navigationAudit.d.ts +16 -0
  46. package/dist/browser/navigationAudit.js +53 -0
  47. package/dist/browser/persistedEnv.d.ts +3 -0
  48. package/dist/browser/persistedEnv.js +15 -0
  49. package/dist/browser/profileLock.d.ts +40 -0
  50. package/dist/browser/profileLock.js +10 -0
  51. package/dist/browser/profileStore.d.ts +23 -0
  52. package/dist/browser/profileStore.js +39 -0
  53. package/dist/browser/runLiveness.d.ts +13 -0
  54. package/dist/browser/runLiveness.js +39 -0
  55. package/dist/browser/sitePolicy.d.ts +10 -0
  56. package/dist/browser/sitePolicy.js +61 -0
  57. package/dist/browser/stageBrowserEnv.d.ts +22 -0
  58. package/dist/browser/stageBrowserEnv.js +147 -0
  59. package/dist/browser/stageProfileLock.d.ts +17 -0
  60. package/dist/browser/stageProfileLock.js +39 -0
  61. package/dist/cli/browserCommand.d.ts +44 -0
  62. package/dist/cli/browserCommand.js +472 -0
  63. package/dist/cli/hostClient.d.ts +20 -0
  64. package/dist/cli/hostClient.js +36 -2
  65. package/dist/cli/initCommand.d.ts +1 -0
  66. package/dist/cli/initCommand.js +23 -7
  67. package/dist/cli/initTemplates.d.ts +5 -2
  68. package/dist/cli/initTemplates.js +25 -2
  69. package/dist/cli/runsCommand.js +6 -2
  70. package/dist/cli/triggerCommand.d.ts +12 -0
  71. package/dist/cli/triggerCommand.js +183 -0
  72. package/dist/cli/validateCommand.d.ts +1 -1
  73. package/dist/cli/validateCommand.js +23 -6
  74. package/dist/cli.js +31 -2
  75. package/dist/config/browseCatalog.d.ts +1 -0
  76. package/dist/config/browseCatalog.js +5 -4
  77. package/dist/config/builtinSkills.d.ts +4 -0
  78. package/dist/config/builtinSkills.js +23 -0
  79. package/dist/config/catalogRelativePath.d.ts +1 -0
  80. package/dist/config/catalogRelativePath.js +10 -2
  81. package/dist/config/createTrigger.d.ts +27 -0
  82. package/dist/config/createTrigger.js +232 -0
  83. package/dist/config/draftPackage.d.ts +117 -0
  84. package/dist/config/draftPackage.js +550 -0
  85. package/dist/config/ensureCatalogScanRoot.d.ts +16 -0
  86. package/dist/config/ensureCatalogScanRoot.js +73 -0
  87. package/dist/config/hostConfig.d.ts +2 -0
  88. package/dist/config/hostConfig.js +27 -0
  89. package/dist/config/listSkills.d.ts +2 -2
  90. package/dist/config/listSkills.js +17 -3
  91. package/dist/config/loadOutcome.d.ts +6 -0
  92. package/dist/config/loadPipeline.js +16 -0
  93. package/dist/config/loadStage.js +7 -0
  94. package/dist/config/loadStageflowManifest.js +25 -0
  95. package/dist/config/loadTrigger.d.ts +9 -0
  96. package/dist/config/loadTrigger.js +120 -0
  97. package/dist/config/multiProjectCatalog.d.ts +2 -0
  98. package/dist/config/multiProjectCatalog.js +26 -18
  99. package/dist/config/normalizePipelineStageEntry.js +8 -1
  100. package/dist/config/parseCompletionContract.js +6 -0
  101. package/dist/config/pipelineStageKeys.js +1 -0
  102. package/dist/config/publishDraftPackage.d.ts +7 -0
  103. package/dist/config/publishDraftPackage.js +25 -0
  104. package/dist/config/resolveCatalogContext.js +1 -1
  105. package/dist/config/resolvePipelineDag.js +1 -1
  106. package/dist/config/scanCatalogPaths.d.ts +1 -1
  107. package/dist/config/scanCatalogPaths.js +6 -2
  108. package/dist/config/stageBrowser.d.ts +12 -0
  109. package/dist/config/stageBrowser.js +118 -0
  110. package/dist/config/triggerCatalog.d.ts +10 -0
  111. package/dist/config/triggerCatalog.js +37 -0
  112. package/dist/config/validateCatalog.d.ts +13 -3
  113. package/dist/config/validateCatalog.js +83 -2
  114. package/dist/config/validateCompletionContract.js +8 -0
  115. package/dist/envelope/preEmitChecks.d.ts +1 -1
  116. package/dist/envelope/preEmitChecks.js +8 -0
  117. package/dist/logging/redact.d.ts +4 -0
  118. package/dist/logging/redact.js +17 -0
  119. package/dist/mcp/catalogTools.js +43 -8
  120. package/dist/mcp/controlTools.js +3 -1
  121. package/dist/mcp/deps.d.ts +2 -0
  122. package/dist/mcp/server.js +1 -0
  123. package/dist/mcp/tools.js +2 -0
  124. package/dist/mcp/triggerTools.d.ts +3 -0
  125. package/dist/mcp/triggerTools.js +176 -0
  126. package/dist/operatorAgent/docsRetrieval.d.ts +40 -0
  127. package/dist/operatorAgent/docsRetrieval.js +269 -0
  128. package/dist/operatorAgent/draftContext.d.ts +16 -0
  129. package/dist/operatorAgent/draftContext.js +68 -0
  130. package/dist/operatorAgent/fakeHost.d.ts +39 -0
  131. package/dist/operatorAgent/fakeHost.js +92 -0
  132. package/dist/operatorAgent/host.d.ts +40 -0
  133. package/dist/operatorAgent/host.js +179 -0
  134. package/dist/operatorAgent/index.d.ts +9 -0
  135. package/dist/operatorAgent/index.js +8 -0
  136. package/dist/operatorAgent/piModel.d.ts +80 -0
  137. package/dist/operatorAgent/piModel.js +528 -0
  138. package/dist/operatorAgent/profiles/workshopAuthor.d.ts +23 -0
  139. package/dist/operatorAgent/profiles/workshopAuthor.js +338 -0
  140. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +6 -0
  141. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +103 -0
  142. package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +57 -0
  143. package/dist/operatorAgent/profiles/workshopAuthorTools.js +623 -0
  144. package/dist/operatorAgent/proposals.d.ts +32 -0
  145. package/dist/operatorAgent/proposals.js +144 -0
  146. package/dist/operatorAgent/types.d.ts +128 -0
  147. package/dist/operatorAgent/types.js +1 -0
  148. package/dist/package-meta.d.ts +1 -1
  149. package/dist/package-meta.js +1 -1
  150. package/dist/project/findManifestRoot.d.ts +3 -0
  151. package/dist/project/findManifestRoot.js +35 -0
  152. package/dist/project/resolveStageflowContext.d.ts +7 -0
  153. package/dist/project/resolveStageflowContext.js +44 -28
  154. package/dist/runstore/assertTmpdir.js +6 -2
  155. package/dist/runstore/port.d.ts +28 -0
  156. package/dist/runstore/sqlite/SqliteRunStore.d.ts +8 -1
  157. package/dist/runstore/sqlite/SqliteRunStore.js +90 -0
  158. package/dist/runstore/sqlite/migrations/008-triggers-table.d.ts +7 -0
  159. package/dist/runstore/sqlite/migrations/008-triggers-table.js +19 -0
  160. package/dist/runstore/sqlite/migrations/009-trigger-next-run.d.ts +7 -0
  161. package/dist/runstore/sqlite/migrations/009-trigger-next-run.js +19 -0
  162. package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.d.ts +7 -0
  163. package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.js +17 -0
  164. package/dist/runstore/sqlite/migrations/index.js +6 -0
  165. package/dist/runtime/answerResume.d.ts +1 -0
  166. package/dist/runtime/answerResume.js +3 -1
  167. package/dist/runtime/completionCheckRunner.d.ts +12 -1
  168. package/dist/runtime/completionCheckRunner.js +22 -0
  169. package/dist/runtime/credentialBinding.d.ts +2 -0
  170. package/dist/runtime/credentialBinding.js +3 -0
  171. package/dist/runtime/emailSource.d.ts +72 -0
  172. package/dist/runtime/emailSource.js +304 -0
  173. package/dist/runtime/githubPollSource.d.ts +86 -0
  174. package/dist/runtime/githubPollSource.js +284 -0
  175. package/dist/runtime/pipelineRunner.d.ts +4 -0
  176. package/dist/runtime/pipelineRunner.js +3 -0
  177. package/dist/runtime/pipelineScheduler.d.ts +2 -0
  178. package/dist/runtime/pipelineScheduler.js +85 -1
  179. package/dist/runtime/repositoryMaterialize.d.ts +1 -1
  180. package/dist/runtime/runManager.d.ts +11 -0
  181. package/dist/runtime/runManager.js +149 -1
  182. package/dist/runtime/runRetryCoordinator.d.ts +2 -0
  183. package/dist/runtime/runRetryCoordinator.js +1 -0
  184. package/dist/runtime/scheduleSource.d.ts +38 -0
  185. package/dist/runtime/scheduleSource.js +119 -0
  186. package/dist/runtime/settingsFile.d.ts +5 -0
  187. package/dist/runtime/settingsFile.js +61 -54
  188. package/dist/runtime/stageAttemptBootstrap.js +55 -3
  189. package/dist/runtime/stageEnvironment.js +1 -0
  190. package/dist/runtime/stageHitl.d.ts +1 -0
  191. package/dist/runtime/stageHitl.js +5 -1
  192. package/dist/runtime/stageProcessLauncher.d.ts +2 -0
  193. package/dist/runtime/stageProcessLauncher.js +44 -5
  194. package/dist/runtime/stageRunner.d.ts +5 -0
  195. package/dist/runtime/stageRunner.js +30 -6
  196. package/dist/runtime/stageStreamLog.d.ts +1 -0
  197. package/dist/runtime/stageStreamLog.js +2 -1
  198. package/dist/runtime/triggerCatalog.d.ts +6 -0
  199. package/dist/runtime/triggerCatalog.js +24 -0
  200. package/dist/runtime/triggerEventMatch.d.ts +2 -0
  201. package/dist/runtime/triggerEventMatch.js +6 -0
  202. package/dist/runtime/triggerPort.d.ts +14 -0
  203. package/dist/runtime/triggerPort.js +1 -0
  204. package/dist/runtime/triggerRunner.d.ts +17 -0
  205. package/dist/runtime/triggerRunner.js +89 -0
  206. package/dist/runtime/verifiedStageExecution.d.ts +7 -0
  207. package/dist/runtime/verifiedStageExecution.js +14 -0
  208. package/dist/runtime/webhookSignature.d.ts +1 -0
  209. package/dist/runtime/webhookSignature.js +12 -0
  210. package/dist/server/bootstrap.d.ts +6 -0
  211. package/dist/server/bootstrap.js +64 -0
  212. package/dist/server/controlToken.js +13 -0
  213. package/dist/server/createHttpHost.js +3 -0
  214. package/dist/server/healthSurfaces.js +31 -6
  215. package/dist/server/http.d.ts +15 -0
  216. package/dist/server/http.js +1251 -74
  217. package/dist/server/requestAuthContext.d.ts +1 -1
  218. package/dist/server/triggerRoutes.d.ts +15 -0
  219. package/dist/server/triggerRoutes.js +268 -0
  220. package/dist/tools/askOperator.d.ts +3 -2
  221. package/dist/types/completion.d.ts +3 -0
  222. package/dist/types/pipeline.d.ts +3 -1
  223. package/dist/types/preEmitCheck.d.ts +7 -0
  224. package/dist/types/stage.d.ts +14 -0
  225. package/dist/types/stageflowManifest.d.ts +3 -0
  226. package/dist/types/trigger.d.ts +18 -0
  227. package/dist/types/trigger.js +1 -0
  228. package/dist/ui/assets/{index-CSsDued1.css → index-Bv4p1aPK.css} +1 -1
  229. package/dist/ui/assets/index-CntB4bZR.js +133 -0
  230. package/dist/ui/index.html +2 -2
  231. package/dist/workshop/autosave.d.ts +58 -0
  232. package/dist/workshop/autosave.js +222 -0
  233. package/dist/workshop/buildStore.d.ts +79 -0
  234. package/dist/workshop/buildStore.js +326 -0
  235. package/dist/workshop/chatTurn.d.ts +232 -0
  236. package/dist/workshop/chatTurn.js +475 -0
  237. package/dist/workshop/modelSettings.d.ts +18 -0
  238. package/dist/workshop/modelSettings.js +44 -0
  239. package/dist/workshop/sessionStore.d.ts +61 -0
  240. package/dist/workshop/sessionStore.js +254 -0
  241. package/dist/workshop/workshopPin.d.ts +72 -0
  242. package/dist/workshop/workshopPin.js +193 -0
  243. package/examples/README.md +2 -1
  244. package/examples/browser-session/README.md +77 -0
  245. package/examples/browser-session/browser-session.pipeline.yaml +50 -0
  246. package/examples/browser-session/browser-session.task.yaml +6 -0
  247. package/examples/browser-session/check-login.yaml +22 -0
  248. package/examples/browser-session/fixture-server.mjs +64 -0
  249. package/examples/browser-session/human-login.yaml +31 -0
  250. package/examples/browser-session/merge.yaml +36 -0
  251. package/examples/browser-session/work-a.yaml +41 -0
  252. package/examples/browser-session/work-b.yaml +41 -0
  253. package/examples/stage-mcp/README.md +3 -2
  254. package/examples/stageflow.yaml +51 -0
  255. package/package.json +5 -1
  256. package/skills/stageflow/references/control-surface.md +3 -1
  257. package/skills/stageflow-author/references/stage-prompt-template.md +4 -4
  258. package/skills/stageflow-run/SKILL.md +2 -0
  259. package/skills/stageflow-run/references/task-and-pipeline-selection.md +3 -1
  260. package/skills/stageflow-setup/SKILL.md +11 -0
  261. package/dist/ui/assets/index-B6hlSXXn.js +0 -120
@@ -45,6 +45,12 @@ export type StageflowHostBootstrap = {
45
45
  /** Periodic retention GC handle when enabled; already `.unref()`'d. */
46
46
  gcInterval?: NodeJS.Timeout;
47
47
  stopGcInterval: () => void;
48
+ /** Stops the schedule-trigger tick loop started at boot. */
49
+ stopScheduleSource: () => void;
50
+ /** Stops the GitHub poll-trigger loop started at boot. */
51
+ stopGithubPollSource: () => void;
52
+ /** Stops the email-trigger IMAP/IDLE listeners started at boot. */
53
+ stopEmailSource: () => void;
48
54
  /** Filesystem classification for `$STAGEFLOW_HOME` (Slot 8). */
49
55
  storeFilesystem?: StoreFilesystemClassification;
50
56
  /**
@@ -12,6 +12,10 @@ import { assertStoreFilesystemSupported } from "../runstore/storeFilesystem.js";
12
12
  import { assertStoreQuickCheck, isSqliteCorruptError, maybeCheckpointResidualWal, rethrowAsStoreIntegrityFailed, } from "../runstore/sqlite/applyStorePragmas.js";
13
13
  import { RunManager } from "../runtime/runManager.js";
14
14
  import { PI_CODING_AGENT_DIR_ENV } from "../runtime/stageRoots.js";
15
+ import { ScheduleSource, triggerTickIntervalMsFromEnv, } from "../runtime/scheduleSource.js";
16
+ import { GithubPollSource, githubPollIntervalMsFromEnv, } from "../runtime/githubPollSource.js";
17
+ import { EmailSource } from "../runtime/emailSource.js";
18
+ import { fireTrigger } from "../runtime/triggerRunner.js";
15
19
  import { createRunChangeBus, getRunChangeBusFromWrappedStore, isRunStoreWrapped, wrapRunStoreWithChangeBus, } from "../runtime/runChangeBus.js";
16
20
  import { createMcpHttpHandler, resolveMcpStateless, } from "../mcp/server.js";
17
21
  import { loadHostConfig, } from "../config/hostConfig.js";
@@ -149,6 +153,9 @@ export async function bootstrapStageflowHost(options) {
149
153
  close: async () => { },
150
154
  },
151
155
  stopGcInterval: () => { },
156
+ stopScheduleSource: () => { },
157
+ stopGithubPollSource: () => { },
158
+ stopEmailSource: () => { },
152
159
  storeFilesystem,
153
160
  serveBlocked,
154
161
  ...(hostConfig !== undefined ? { hostConfig } : {}),
@@ -231,6 +238,7 @@ export async function bootstrapStageflowHost(options) {
231
238
  });
232
239
  await manager.attachWaitingStages();
233
240
  await manager.reconcileOrphanedStages();
241
+ await manager.sweepBrowserSessions().catch(() => undefined);
234
242
  await manager.autoResumeInterruptedStages();
235
243
  await manager.resumeStalledSchedules();
236
244
  await manager.reenqueuePersistedQueuedRuns();
@@ -240,6 +248,58 @@ export async function bootstrapStageflowHost(options) {
240
248
  if (gcInterval !== undefined)
241
249
  clearInterval(gcInterval);
242
250
  };
251
+ const scheduleSource = new ScheduleSource({
252
+ store,
253
+ cwd,
254
+ intervalMs: triggerTickIntervalMsFromEnv(env),
255
+ logError: (message) => bootLog.error("trigger.schedule_source_failed", message),
256
+ });
257
+ const onTriggerFire = async (event) => {
258
+ try {
259
+ const result = await fireTrigger(event.triggerId, store, manager, {
260
+ cwd,
261
+ task: event.task,
262
+ });
263
+ if (!result.ok) {
264
+ bootLog.error("trigger.fire_failed", `trigger "${event.triggerId}" fire failed: ${result.reason}`);
265
+ }
266
+ }
267
+ catch (err) {
268
+ bootLog.error("trigger.fire_failed", `trigger "${event.triggerId}" fire threw: ${err instanceof Error ? err.message : String(err)}`);
269
+ }
270
+ };
271
+ try {
272
+ // Boot-time catch-up: fire once for any schedule trigger whose next_run_at
273
+ // already passed while the Host was down, then reschedule from now —
274
+ // before starting the periodic ticker so this pass never races it.
275
+ await scheduleSource.tick(onTriggerFire);
276
+ }
277
+ catch (err) {
278
+ bootLog.error("trigger.schedule_catchup_failed", `boot catch-up tick failed: ${err instanceof Error ? err.message : String(err)}`);
279
+ }
280
+ await scheduleSource.start(onTriggerFire);
281
+ const stopScheduleSource = () => {
282
+ void scheduleSource.stop();
283
+ };
284
+ const githubPollSource = new GithubPollSource({
285
+ store,
286
+ cwd,
287
+ intervalMs: githubPollIntervalMsFromEnv(env),
288
+ logError: (message) => bootLog.error("trigger.github_poll_source_failed", message),
289
+ });
290
+ await githubPollSource.start(onTriggerFire);
291
+ const stopGithubPollSource = () => {
292
+ void githubPollSource.stop();
293
+ };
294
+ const emailSource = new EmailSource({
295
+ store,
296
+ cwd,
297
+ logError: (message) => bootLog.error("trigger.email_source_failed", message),
298
+ });
299
+ await emailSource.start(onTriggerFire);
300
+ const stopEmailSource = () => {
301
+ void emailSource.stop();
302
+ };
243
303
  const mcpStateless = resolveMcpStateless({
244
304
  mcpStateless: options.mcpStateless,
245
305
  });
@@ -251,6 +311,7 @@ export async function bootstrapStageflowHost(options) {
251
311
  runChangeBus,
252
312
  providerAuthContext: options.providerAuthContext,
253
313
  projectRoot: rootDir,
314
+ ...(providerBoot !== undefined ? { providerBoot } : {}),
254
315
  }, { mcpStateless });
255
316
  return {
256
317
  a2a: await createA2aHost({
@@ -274,6 +335,9 @@ export async function bootstrapStageflowHost(options) {
274
335
  ...(providerBoot !== undefined ? { providerBoot } : {}),
275
336
  ...(gcInterval !== undefined ? { gcInterval } : {}),
276
337
  stopGcInterval,
338
+ stopScheduleSource,
339
+ stopGithubPollSource,
340
+ stopEmailSource,
277
341
  storeFilesystem,
278
342
  };
279
343
  }
@@ -158,11 +158,24 @@ export class BindRefusedError extends Error {
158
158
  this.name = "BindRefusedError";
159
159
  }
160
160
  }
161
+ /**
162
+ * `POST /api/triggers/:id/webhook` is exempt from bearer auth: an external
163
+ * webhook sender can't present Stageflow's own control token, and the route
164
+ * authenticates the request itself via per-trigger HMAC signature
165
+ * verification instead. It still goes through `assertAllowedHttpAccess`
166
+ * (loopback/allowed-hosts gating) the same as every other `/api/*` route —
167
+ * only the bearer-token requirement is carved out here.
168
+ */
169
+ function isTriggerWebhookRoute(method, pathname) {
170
+ return method === "POST" && /^\/api\/triggers\/[^/]+\/webhook$/.test(pathname);
171
+ }
161
172
  export function requiredScopeFor(method, pathname) {
162
173
  if (pathname === "/mcp")
163
174
  return "drive";
164
175
  if (!pathname.startsWith("/api/"))
165
176
  return null;
177
+ if (isTriggerWebhookRoute(method, pathname))
178
+ return null;
166
179
  if (pathname === "/api/backup" || pathname.startsWith("/api/backup/")) {
167
180
  return "drive";
168
181
  }
@@ -135,6 +135,9 @@ export async function createHttpHost(options) {
135
135
  server.maxConnections = maxConnections;
136
136
  server.on("close", () => {
137
137
  boot.stopGcInterval();
138
+ boot.stopScheduleSource();
139
+ boot.stopGithubPollSource();
140
+ boot.stopEmailSource();
138
141
  void boot.mcpHandler.close();
139
142
  });
140
143
  await new Promise((resolve, reject) => {
@@ -1,3 +1,4 @@
1
+ import { getAuthStatus, } from "../agent/providerAuth.js";
1
2
  import { PACKAGE_VERSION, BUILD_SHA } from "../package-meta.js";
2
3
  import { globalStageflowHome } from "../project/globalHome.js";
3
4
  import { redactHostConfig } from "../config/hostConfig.js";
@@ -6,6 +7,31 @@ import { json } from "./createHttpHost.js";
6
7
  import { livezBody, probeGitVersion, readSchemaHealth, runReadyzChecks, } from "../diagnostics/checks.js";
7
8
  import { buildEgressHealth } from "../net/proxy.js";
8
9
  import { toolchainHealthMap } from "../preflight/toolchain.js";
10
+ function bootProvidersSnapshot(providerBoot) {
11
+ return providerBoot
12
+ ? {
13
+ configured: providerBoot.configured,
14
+ failures: providerBoot.failures,
15
+ }
16
+ : { configured: [], failures: [] };
17
+ }
18
+ async function providersLiveSummary(cwd, authCtx) {
19
+ const note = "Live auth inspect — prefer list_providers / sf providers status. boot_providers is Host boot env only and may be empty when CLI credentials are configured.";
20
+ if (authCtx === undefined) {
21
+ return { configured: [], note };
22
+ }
23
+ try {
24
+ const status = await getAuthStatus(cwd, undefined, authCtx);
25
+ const rows = Array.isArray(status) ? status : [status];
26
+ return {
27
+ configured: rows.filter((r) => r.configured).map((r) => r.providerId),
28
+ note,
29
+ };
30
+ }
31
+ catch {
32
+ return { configured: [], note };
33
+ }
34
+ }
9
35
  export function handleLivez(_req, res) {
10
36
  json(res, 200, livezBody());
11
37
  }
@@ -54,6 +80,8 @@ export async function buildRichHealthPayload(boot) {
54
80
  store: boot.store,
55
81
  bootCwd: boot.cwd,
56
82
  });
83
+ const boot_providers = bootProvidersSnapshot(boot.providerBoot);
84
+ const providers_live = await providersLiveSummary(boot.cwd, boot.providerAuthContext);
57
85
  const payload = {
58
86
  ...capacity,
59
87
  capacity: {
@@ -78,12 +106,9 @@ export async function buildRichHealthPayload(boot) {
78
106
  kind: r.kind,
79
107
  read_only: r.read_only,
80
108
  })),
81
- providers: boot.providerBoot
82
- ? {
83
- configured: boot.providerBoot.configured,
84
- failures: boot.providerBoot.failures,
85
- }
86
- : { configured: [], failures: [] },
109
+ boot_providers,
110
+ providers_live,
111
+ providers: boot_providers,
87
112
  };
88
113
  if (boot.hostConfig) {
89
114
  payload.config = redactHostConfig(boot.hostConfig);
@@ -1,5 +1,7 @@
1
1
  import type { AgentPort } from "../agent/port.js";
2
2
  import { type ProviderAuthContext } from "../agent/providerAuth.js";
3
+ import { WorkshopChatSessionRegistry } from "../workshop/chatTurn.js";
4
+ import { type OperatorAgentHost } from "../operatorAgent/index.js";
3
5
  import type { RunStoreKind } from "../runstore/createStore.js";
4
6
  import type { RunStore } from "../runstore/port.js";
5
7
  import type { RunManager } from "../runtime/runManager.js";
@@ -24,6 +26,8 @@ export type UiServerOptions = {
24
26
  runChangeBus?: RunChangeBus;
25
27
  allowedHosts?: AllowedHosts;
26
28
  controlTokens?: ControlTokens;
29
+ /** Optional Workshop Operator Agent Host (fake in tests). */
30
+ workshopOperatorHost?: OperatorAgentHost;
27
31
  };
28
32
  export declare function defaultUiDistDir(): string;
29
33
  export type OperatorRouteDeps = {
@@ -39,6 +43,17 @@ export type OperatorRouteDeps = {
39
43
  controlTokens?: ControlTokens;
40
44
  /** Live shutdown controller; set after listen so restore can beginDrain. */
41
45
  getShutdown?: () => import("./shutdown.js").ShutdownController | undefined;
46
+ /**
47
+ * Optional Operator Agent Host for Workshop chat (tests inject the fake host).
48
+ * Distinct from stage-execution AgentPort. Defaults to live Pi Workshop Author
49
+ * (fake remains available via createWorkshopOperatorHost / test injection).
50
+ */
51
+ workshopOperatorHost?: OperatorAgentHost;
52
+ /**
53
+ * Optional durable Workshop chat registry (host sessions keyed by session id).
54
+ * Defaults to a registry owned by this route surface.
55
+ */
56
+ workshopChatRegistry?: WorkshopChatSessionRegistry;
42
57
  };
43
58
  /**
44
59
  * The full operator-console route surface: REST API (runs, stages,