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.
Files changed (681) hide show
  1. package/README.md +14 -3
  2. package/builtin-skills/browser/SKILL.md +42 -0
  3. package/dist/a2a/contracts.d.ts +1 -0
  4. package/dist/a2a/contracts.js +1 -0
  5. package/dist/a2a/registry.d.ts +2 -0
  6. package/dist/a2a/registry.js +20 -1
  7. package/dist/a2a/server.d.ts +7 -0
  8. package/dist/a2a/server.js +5 -2
  9. package/dist/a2a/service.d.ts +1 -1
  10. package/dist/a2a/service.js +57 -8
  11. package/dist/a2a/store.d.ts +8 -5
  12. package/dist/a2a/store.js +24 -67
  13. package/dist/agent/activity.d.ts +3 -0
  14. package/dist/agent/bootProviderConfig.d.ts +21 -0
  15. package/dist/agent/bootProviderConfig.js +74 -0
  16. package/dist/agent/claudeAdapter.js +2 -2
  17. package/dist/agent/cursorProvider.d.ts +2 -0
  18. package/dist/agent/cursorProvider.js +30 -5
  19. package/dist/agent/fakeAgent.d.ts +1 -0
  20. package/dist/agent/fakeAgent.js +13 -0
  21. package/dist/agent/piAdapter.d.ts +11 -24
  22. package/dist/agent/piAdapter.js +107 -50
  23. package/dist/agent/piIsolatedMcp.d.ts +2 -0
  24. package/dist/agent/piIsolatedMcp.js +10 -2
  25. package/dist/agent/piSessionFactory.d.ts +38 -0
  26. package/dist/agent/piSessionFactory.js +60 -0
  27. package/dist/agent/port.d.ts +8 -0
  28. package/dist/agent/streamLogRedact.d.ts +7 -1
  29. package/dist/agent/streamLogRedact.js +26 -11
  30. package/dist/browser/anchor.d.ts +27 -0
  31. package/dist/browser/anchor.js +127 -0
  32. package/dist/browser/auditSink.d.ts +38 -0
  33. package/dist/browser/auditSink.js +34 -0
  34. package/dist/browser/browserHost.d.ts +86 -0
  35. package/dist/browser/browserHost.js +7 -0
  36. package/dist/browser/browserSweep.d.ts +14 -0
  37. package/dist/browser/browserSweep.js +54 -0
  38. package/dist/browser/browserTeardown.d.ts +56 -0
  39. package/dist/browser/browserTeardown.js +235 -0
  40. package/dist/browser/fakeRemoteBrowserHost.d.ts +2 -0
  41. package/dist/browser/fakeRemoteBrowserHost.js +34 -0
  42. package/dist/browser/gateHandoff.d.ts +25 -0
  43. package/dist/browser/gateHandoff.js +83 -0
  44. package/dist/browser/humanLogin.d.ts +18 -0
  45. package/dist/browser/humanLogin.js +34 -0
  46. package/dist/browser/keyProvider.d.ts +10 -0
  47. package/dist/browser/keyProvider.js +39 -0
  48. package/dist/browser/localBrowserHost.d.ts +10 -0
  49. package/dist/browser/localBrowserHost.js +152 -0
  50. package/dist/browser/localProfileLock.d.ts +2 -0
  51. package/dist/browser/localProfileLock.js +218 -0
  52. package/dist/browser/localProfileStore.d.ts +5 -0
  53. package/dist/browser/localProfileStore.js +91 -0
  54. package/dist/browser/loginCheck.d.ts +53 -0
  55. package/dist/browser/loginCheck.js +147 -0
  56. package/dist/browser/memoryProfileLock.d.ts +2 -0
  57. package/dist/browser/memoryProfileLock.js +53 -0
  58. package/dist/browser/memoryProfileStore.d.ts +2 -0
  59. package/dist/browser/memoryProfileStore.js +31 -0
  60. package/dist/browser/navigationAudit.d.ts +16 -0
  61. package/dist/browser/navigationAudit.js +53 -0
  62. package/dist/browser/persistedEnv.d.ts +3 -0
  63. package/dist/browser/persistedEnv.js +15 -0
  64. package/dist/browser/profileLock.d.ts +40 -0
  65. package/dist/browser/profileLock.js +10 -0
  66. package/dist/browser/profileStore.d.ts +23 -0
  67. package/dist/browser/profileStore.js +39 -0
  68. package/dist/browser/runLiveness.d.ts +13 -0
  69. package/dist/browser/runLiveness.js +39 -0
  70. package/dist/browser/sitePolicy.d.ts +10 -0
  71. package/dist/browser/sitePolicy.js +61 -0
  72. package/dist/browser/stageBrowserEnv.d.ts +22 -0
  73. package/dist/browser/stageBrowserEnv.js +147 -0
  74. package/dist/browser/stageProfileLock.d.ts +17 -0
  75. package/dist/browser/stageProfileLock.js +39 -0
  76. package/dist/cli/artifactCommand.js +9 -16
  77. package/dist/cli/backupCommand.d.ts +9 -0
  78. package/dist/cli/backupCommand.js +111 -0
  79. package/dist/cli/browserCommand.d.ts +44 -0
  80. package/dist/cli/browserCommand.js +472 -0
  81. package/dist/cli/debugRunCommand.d.ts +10 -0
  82. package/dist/cli/debugRunCommand.js +109 -0
  83. package/dist/cli/doctorCommand.d.ts +32 -0
  84. package/dist/cli/doctorCommand.js +453 -0
  85. package/dist/cli/envelopeCommand.js +9 -2
  86. package/dist/cli/exportAllCommand.d.ts +55 -0
  87. package/dist/cli/exportAllCommand.js +218 -0
  88. package/dist/cli/exportRunCommand.js +23 -21
  89. package/dist/cli/hostClient.d.ts +41 -3
  90. package/dist/cli/hostClient.js +129 -14
  91. package/dist/cli/initCommand.d.ts +1 -0
  92. package/dist/cli/initCommand.js +23 -7
  93. package/dist/cli/initTemplates.d.ts +5 -2
  94. package/dist/cli/initTemplates.js +32 -2
  95. package/dist/cli/resolveSafeOutPath.d.ts +2 -0
  96. package/dist/cli/resolveSafeOutPath.js +40 -0
  97. package/dist/cli/restoreCommand.d.ts +10 -0
  98. package/dist/cli/restoreCommand.js +90 -0
  99. package/dist/cli/runCommand.d.ts +3 -2
  100. package/dist/cli/runCommand.js +93 -11
  101. package/dist/cli/runOutput.d.ts +4 -0
  102. package/dist/cli/runOutput.js +33 -7
  103. package/dist/cli/runStageCommand.d.ts +1 -0
  104. package/dist/cli/runStageCommand.js +44 -25
  105. package/dist/cli/runsCommand.d.ts +1 -1
  106. package/dist/cli/runsCommand.js +168 -10
  107. package/dist/cli/triggerCommand.d.ts +12 -0
  108. package/dist/cli/triggerCommand.js +183 -0
  109. package/dist/cli/validateCommand.d.ts +1 -1
  110. package/dist/cli/validateCommand.js +23 -6
  111. package/dist/cli.js +202 -32
  112. package/dist/config/browseCatalog.d.ts +1 -0
  113. package/dist/config/browseCatalog.js +5 -4
  114. package/dist/config/builtinSkills.d.ts +4 -0
  115. package/dist/config/builtinSkills.js +23 -0
  116. package/dist/config/catalogRelativePath.d.ts +63 -0
  117. package/dist/config/catalogRelativePath.js +126 -0
  118. package/dist/config/configOrigin.d.ts +27 -0
  119. package/dist/config/configOrigin.js +59 -0
  120. package/dist/config/createTrigger.d.ts +27 -0
  121. package/dist/config/createTrigger.js +232 -0
  122. package/dist/config/draftPackage.d.ts +117 -0
  123. package/dist/config/draftPackage.js +550 -0
  124. package/dist/config/ensureCatalogScanRoot.d.ts +16 -0
  125. package/dist/config/ensureCatalogScanRoot.js +73 -0
  126. package/dist/config/hostConfig.d.ts +57 -0
  127. package/dist/config/hostConfig.js +360 -0
  128. package/dist/config/listSkills.d.ts +26 -0
  129. package/dist/config/listSkills.js +206 -5
  130. package/dist/config/loadOutcome.d.ts +7 -1
  131. package/dist/config/loadPipeline.js +39 -2
  132. package/dist/config/loadStage.js +25 -0
  133. package/dist/config/loadStageflowManifest.js +25 -0
  134. package/dist/config/loadTask.d.ts +2 -0
  135. package/dist/config/loadTask.js +57 -18
  136. package/dist/config/loadTrigger.d.ts +9 -0
  137. package/dist/config/loadTrigger.js +120 -0
  138. package/dist/config/materializeStageModels.js +5 -1
  139. package/dist/config/mergePipelineIncludes.d.ts +3 -0
  140. package/dist/config/mergePipelineIncludes.js +19 -0
  141. package/dist/config/migrateYaml.js +6 -11
  142. package/dist/config/multiProjectCatalog.d.ts +32 -0
  143. package/dist/config/multiProjectCatalog.js +150 -0
  144. package/dist/config/normalizePipelineStageEntry.js +27 -1
  145. package/dist/config/parseCompletionContract.js +6 -0
  146. package/dist/config/pipelineStageKeys.js +3 -0
  147. package/dist/config/publishDraftPackage.d.ts +7 -0
  148. package/dist/config/publishDraftPackage.js +25 -0
  149. package/dist/config/resolveCatalogContext.js +1 -1
  150. package/dist/config/resolveCatalogRoots.d.ts +27 -0
  151. package/dist/config/resolveCatalogRoots.js +76 -0
  152. package/dist/config/resolveModel.d.ts +7 -1
  153. package/dist/config/resolveModel.js +11 -1
  154. package/dist/config/resolvePipelineDag.js +1 -1
  155. package/dist/config/resolveStageMcpServers.d.ts +9 -1
  156. package/dist/config/resolveStageMcpServers.js +36 -9
  157. package/dist/config/scanCatalogPaths.d.ts +1 -1
  158. package/dist/config/scanCatalogPaths.js +6 -2
  159. package/dist/config/secretFromEnvOrFile.d.ts +9 -0
  160. package/dist/config/secretFromEnvOrFile.js +34 -0
  161. package/dist/config/seededCatalog.d.ts +11 -0
  162. package/dist/config/seededCatalog.js +29 -0
  163. package/dist/config/stageBrowser.d.ts +12 -0
  164. package/dist/config/stageBrowser.js +118 -0
  165. package/dist/config/toolRequires.d.ts +24 -0
  166. package/dist/config/toolRequires.js +115 -0
  167. package/dist/config/triggerCatalog.d.ts +10 -0
  168. package/dist/config/triggerCatalog.js +37 -0
  169. package/dist/config/validateCatalog.d.ts +17 -3
  170. package/dist/config/validateCatalog.js +223 -3
  171. package/dist/config/validateCompletionContract.js +8 -0
  172. package/dist/diagnostics/checks.d.ts +39 -0
  173. package/dist/diagnostics/checks.js +135 -0
  174. package/dist/envelope/preEmitChecks.d.ts +1 -1
  175. package/dist/envelope/preEmitChecks.js +8 -0
  176. package/dist/errors/codes.d.ts +14 -0
  177. package/dist/errors/codes.js +59 -0
  178. package/dist/git/cache.d.ts +14 -0
  179. package/dist/git/cache.js +150 -0
  180. package/dist/git/credentials.d.ts +9 -0
  181. package/dist/git/credentials.js +88 -0
  182. package/dist/git/errors.d.ts +20 -0
  183. package/dist/git/errors.js +94 -0
  184. package/dist/git/exec.d.ts +16 -0
  185. package/dist/git/exec.js +135 -0
  186. package/dist/git/operations.d.ts +29 -0
  187. package/dist/git/operations.js +153 -0
  188. package/dist/git/version.d.ts +1 -0
  189. package/dist/git/version.js +10 -0
  190. package/dist/logging/audit.d.ts +16 -0
  191. package/dist/logging/audit.js +19 -0
  192. package/dist/logging/commonWords.d.ts +2 -0
  193. package/dist/logging/commonWords.js +13 -0
  194. package/dist/logging/logger.d.ts +49 -0
  195. package/dist/logging/logger.js +193 -0
  196. package/dist/logging/namedSecrets.d.ts +6 -0
  197. package/dist/logging/namedSecrets.js +58 -0
  198. package/dist/logging/redact.d.ts +17 -0
  199. package/dist/logging/redact.js +105 -0
  200. package/dist/mcp/catalogTools.js +492 -81
  201. package/dist/mcp/checkoutTools.d.ts +52 -0
  202. package/dist/mcp/checkoutTools.js +332 -0
  203. package/dist/mcp/controlTools.js +182 -6
  204. package/dist/mcp/deps.d.ts +3 -0
  205. package/dist/mcp/getStartedTool.d.ts +3 -0
  206. package/dist/mcp/getStartedTool.js +62 -0
  207. package/dist/mcp/readArtifact.d.ts +11 -0
  208. package/dist/mcp/readArtifact.js +46 -30
  209. package/dist/mcp/server.js +2 -0
  210. package/dist/mcp/tools.js +6 -0
  211. package/dist/mcp/triggerTools.d.ts +3 -0
  212. package/dist/mcp/triggerTools.js +176 -0
  213. package/dist/net/proxy.d.ts +14 -0
  214. package/dist/net/proxy.js +78 -0
  215. package/dist/operatorAgent/docsRetrieval.d.ts +40 -0
  216. package/dist/operatorAgent/docsRetrieval.js +269 -0
  217. package/dist/operatorAgent/draftContext.d.ts +16 -0
  218. package/dist/operatorAgent/draftContext.js +68 -0
  219. package/dist/operatorAgent/fakeHost.d.ts +39 -0
  220. package/dist/operatorAgent/fakeHost.js +92 -0
  221. package/dist/operatorAgent/host.d.ts +40 -0
  222. package/dist/operatorAgent/host.js +179 -0
  223. package/dist/operatorAgent/index.d.ts +9 -0
  224. package/dist/operatorAgent/index.js +8 -0
  225. package/dist/operatorAgent/piModel.d.ts +80 -0
  226. package/dist/operatorAgent/piModel.js +528 -0
  227. package/dist/operatorAgent/profiles/workshopAuthor.d.ts +23 -0
  228. package/dist/operatorAgent/profiles/workshopAuthor.js +338 -0
  229. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +6 -0
  230. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +103 -0
  231. package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +57 -0
  232. package/dist/operatorAgent/profiles/workshopAuthorTools.js +623 -0
  233. package/dist/operatorAgent/proposals.d.ts +32 -0
  234. package/dist/operatorAgent/proposals.js +144 -0
  235. package/dist/operatorAgent/types.d.ts +128 -0
  236. package/dist/operatorAgent/types.js +1 -0
  237. package/dist/package-meta.d.ts +2 -1
  238. package/dist/package-meta.js +2 -1
  239. package/dist/preflight/bash.d.ts +8 -0
  240. package/dist/preflight/bash.js +34 -0
  241. package/dist/preflight/claudeRoot.d.ts +11 -0
  242. package/dist/preflight/claudeRoot.js +23 -0
  243. package/dist/preflight/mcpCommands.d.ts +8 -0
  244. package/dist/preflight/mcpCommands.js +36 -0
  245. package/dist/preflight/pipelinePreflight.d.ts +40 -0
  246. package/dist/preflight/pipelinePreflight.js +192 -0
  247. package/dist/preflight/tls.d.ts +6 -0
  248. package/dist/preflight/tls.js +18 -0
  249. package/dist/preflight/toolchain.d.ts +45 -0
  250. package/dist/preflight/toolchain.js +219 -0
  251. package/dist/project/findManifestRoot.d.ts +3 -0
  252. package/dist/project/findManifestRoot.js +35 -0
  253. package/dist/project/findProjectRoot.js +3 -4
  254. package/dist/project/globalHome.d.ts +7 -0
  255. package/dist/project/globalHome.js +63 -2
  256. package/dist/project/resolveProjectContext.js +2 -2
  257. package/dist/project/resolveStageflowContext.d.ts +7 -0
  258. package/dist/project/resolveStageflowContext.js +46 -30
  259. package/dist/projection/projectRun.d.ts +2 -1
  260. package/dist/projection/projectRun.js +1 -0
  261. package/dist/runstore/assertTmpdir.d.ts +1 -0
  262. package/dist/runstore/assertTmpdir.js +25 -0
  263. package/dist/runstore/backup.d.ts +52 -0
  264. package/dist/runstore/backup.js +292 -0
  265. package/dist/runstore/createStore.d.ts +18 -1
  266. package/dist/runstore/createStore.js +64 -5
  267. package/dist/runstore/debugBundle.d.ts +60 -0
  268. package/dist/runstore/debugBundle.js +143 -0
  269. package/dist/runstore/diskUsage.d.ts +50 -0
  270. package/dist/runstore/diskUsage.js +214 -0
  271. package/dist/runstore/exportRunPayload.d.ts +8 -0
  272. package/dist/runstore/exportRunPayload.js +23 -0
  273. package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
  274. package/dist/runstore/normalizeCatalogPath.js +10 -0
  275. package/dist/runstore/paths.d.ts +5 -0
  276. package/dist/runstore/paths.js +145 -1
  277. package/dist/runstore/port.d.ts +139 -13
  278. package/dist/runstore/port.js +8 -1
  279. package/dist/runstore/restore.d.ts +81 -0
  280. package/dist/runstore/restore.js +355 -0
  281. package/dist/runstore/retention.d.ts +27 -0
  282. package/dist/runstore/retention.js +74 -0
  283. package/dist/runstore/runManifest.d.ts +146 -0
  284. package/dist/runstore/runManifest.js +288 -0
  285. package/dist/runstore/runProjection.d.ts +3 -1
  286. package/dist/runstore/runProjection.js +63 -1
  287. package/dist/runstore/sqlite/SqliteRunStore.d.ts +35 -3
  288. package/dist/runstore/sqlite/SqliteRunStore.js +442 -219
  289. package/dist/runstore/sqlite/applyStorePragmas.d.ts +39 -0
  290. package/dist/runstore/sqlite/applyStorePragmas.js +145 -0
  291. package/dist/runstore/sqlite/migrations/001-baseline.d.ts +7 -0
  292. package/dist/runstore/sqlite/migrations/001-baseline.js +10 -0
  293. package/dist/runstore/sqlite/migrations/002-repository-binding.d.ts +7 -0
  294. package/dist/runstore/sqlite/migrations/002-repository-binding.js +29 -0
  295. package/dist/runstore/sqlite/migrations/003-run-lifecycle.d.ts +7 -0
  296. package/dist/runstore/sqlite/migrations/003-run-lifecycle.js +28 -0
  297. package/dist/runstore/sqlite/migrations/004-auto-resume-count.d.ts +7 -0
  298. package/dist/runstore/sqlite/migrations/004-auto-resume-count.js +19 -0
  299. package/dist/runstore/sqlite/migrations/005-config-origins.d.ts +7 -0
  300. package/dist/runstore/sqlite/migrations/005-config-origins.js +19 -0
  301. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.d.ts +7 -0
  302. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.js +28 -0
  303. package/dist/runstore/sqlite/migrations/007-projects-registry.d.ts +7 -0
  304. package/dist/runstore/sqlite/migrations/007-projects-registry.js +31 -0
  305. package/dist/runstore/sqlite/migrations/008-triggers-table.d.ts +7 -0
  306. package/dist/runstore/sqlite/migrations/008-triggers-table.js +19 -0
  307. package/dist/runstore/sqlite/migrations/009-trigger-next-run.d.ts +7 -0
  308. package/dist/runstore/sqlite/migrations/009-trigger-next-run.js +19 -0
  309. package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.d.ts +7 -0
  310. package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.js +17 -0
  311. package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
  312. package/dist/runstore/sqlite/migrations/index.js +78 -0
  313. package/dist/runstore/sqlite/schema.d.ts +20 -1
  314. package/dist/runstore/sqlite/schema.js +277 -1
  315. package/dist/runstore/sqlite/storeOpenError.d.ts +6 -0
  316. package/dist/runstore/sqlite/storeOpenError.js +11 -0
  317. package/dist/runstore/sqlite/storeSchemaError.d.ts +5 -0
  318. package/dist/runstore/sqlite/storeSchemaError.js +8 -0
  319. package/dist/runstore/stageExecution.js +3 -0
  320. package/dist/runstore/storeFilesystem.d.ts +32 -0
  321. package/dist/runstore/storeFilesystem.js +148 -0
  322. package/dist/runstore/trackProjection.js +2 -0
  323. package/dist/runstore/workspaceLayout.d.ts +13 -0
  324. package/dist/runstore/workspaceLayout.js +76 -0
  325. package/dist/runtime/answerResume.d.ts +1 -0
  326. package/dist/runtime/answerResume.js +3 -1
  327. package/dist/runtime/completionCheckRunner.d.ts +15 -1
  328. package/dist/runtime/completionCheckRunner.js +67 -7
  329. package/dist/runtime/containerLimits.d.ts +16 -0
  330. package/dist/runtime/containerLimits.js +84 -0
  331. package/dist/runtime/credentialBinding.d.ts +2 -0
  332. package/dist/runtime/credentialBinding.js +3 -0
  333. package/dist/runtime/credentialMaterialisation.d.ts +28 -0
  334. package/dist/runtime/credentialMaterialisation.js +128 -0
  335. package/dist/runtime/emailSource.d.ts +72 -0
  336. package/dist/runtime/emailSource.js +304 -0
  337. package/dist/runtime/gitCheckoutCapability.js +7 -13
  338. package/dist/runtime/githubPollSource.d.ts +86 -0
  339. package/dist/runtime/githubPollSource.js +284 -0
  340. package/dist/runtime/pipelineRunner.d.ts +40 -1
  341. package/dist/runtime/pipelineRunner.js +181 -17
  342. package/dist/runtime/pipelineScheduler.d.ts +17 -0
  343. package/dist/runtime/pipelineScheduler.js +220 -28
  344. package/dist/runtime/reloadRunCatalog.js +6 -1
  345. package/dist/runtime/repositoryMaterialize.d.ts +47 -0
  346. package/dist/runtime/repositoryMaterialize.js +235 -0
  347. package/dist/runtime/resumeTimedOut.d.ts +1 -1
  348. package/dist/runtime/resumeTimedOut.js +5 -2
  349. package/dist/runtime/runChangeBus.js +9 -0
  350. package/dist/runtime/runDeletion.d.ts +7 -0
  351. package/dist/runtime/runDeletion.js +37 -0
  352. package/dist/runtime/runManager.d.ts +169 -4
  353. package/dist/runtime/runManager.js +1748 -83
  354. package/dist/runtime/runRetentionSweep.d.ts +31 -0
  355. package/dist/runtime/runRetentionSweep.js +328 -0
  356. package/dist/runtime/runRetryCoordinator.d.ts +4 -0
  357. package/dist/runtime/runRetryCoordinator.js +20 -2
  358. package/dist/runtime/runSkills.d.ts +40 -0
  359. package/dist/runtime/runSkills.js +173 -0
  360. package/dist/runtime/scheduleSource.d.ts +38 -0
  361. package/dist/runtime/scheduleSource.js +119 -0
  362. package/dist/runtime/settingsFile.d.ts +5 -0
  363. package/dist/runtime/settingsFile.js +61 -54
  364. package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
  365. package/dist/runtime/stageAttemptBootstrap.js +250 -27
  366. package/dist/runtime/stageCacheEnv.d.ts +6 -0
  367. package/dist/runtime/stageCacheEnv.js +34 -0
  368. package/dist/runtime/stageConcurrency.d.ts +2 -1
  369. package/dist/runtime/stageConcurrency.js +4 -2
  370. package/dist/runtime/stageEnvironment.d.ts +38 -0
  371. package/dist/runtime/stageEnvironment.js +194 -0
  372. package/dist/runtime/stageHitl.d.ts +1 -0
  373. package/dist/runtime/stageHitl.js +5 -1
  374. package/dist/runtime/stageProcessLauncher.d.ts +20 -0
  375. package/dist/runtime/stageProcessLauncher.js +236 -41
  376. package/dist/runtime/stageRecovery.d.ts +3 -1
  377. package/dist/runtime/stageRecovery.js +19 -4
  378. package/dist/runtime/stageRoots.d.ts +38 -1
  379. package/dist/runtime/stageRoots.js +118 -0
  380. package/dist/runtime/stageRunner.d.ts +6 -0
  381. package/dist/runtime/stageRunner.js +32 -6
  382. package/dist/runtime/stageSecretDecl.d.ts +9 -0
  383. package/dist/runtime/stageSecretDecl.js +102 -0
  384. package/dist/runtime/stageSecrets.d.ts +40 -0
  385. package/dist/runtime/stageSecrets.js +181 -0
  386. package/dist/runtime/stageStreamLog.d.ts +1 -0
  387. package/dist/runtime/stageStreamLog.js +2 -1
  388. package/dist/runtime/stageWorker.d.ts +3 -2
  389. package/dist/runtime/stageWorker.js +58 -10
  390. package/dist/runtime/stageWorkerProtocol.d.ts +5 -0
  391. package/dist/runtime/stageWorkerProtocol.js +8 -0
  392. package/dist/runtime/startPayload.d.ts +32 -0
  393. package/dist/runtime/startPayload.js +59 -0
  394. package/dist/runtime/taskInput.js +14 -5
  395. package/dist/runtime/triggerCatalog.d.ts +6 -0
  396. package/dist/runtime/triggerCatalog.js +24 -0
  397. package/dist/runtime/triggerEventMatch.d.ts +2 -0
  398. package/dist/runtime/triggerEventMatch.js +6 -0
  399. package/dist/runtime/triggerPort.d.ts +14 -0
  400. package/dist/runtime/triggerPort.js +1 -0
  401. package/dist/runtime/triggerRunner.d.ts +17 -0
  402. package/dist/runtime/triggerRunner.js +89 -0
  403. package/dist/runtime/verifiedStageExecution.d.ts +8 -0
  404. package/dist/runtime/verifiedStageExecution.js +16 -1
  405. package/dist/runtime/webhookSignature.d.ts +1 -0
  406. package/dist/runtime/webhookSignature.js +12 -0
  407. package/dist/runtime/workspaceBinding.d.ts +20 -0
  408. package/dist/runtime/workspaceBinding.js +60 -0
  409. package/dist/server/allowedHosts.d.ts +19 -0
  410. package/dist/server/allowedHosts.js +179 -0
  411. package/dist/server/bootstrap.d.ts +42 -2
  412. package/dist/server/bootstrap.js +273 -5
  413. package/dist/server/controlToken.d.ts +47 -0
  414. package/dist/server/controlToken.js +254 -0
  415. package/dist/server/createHttpHost.d.ts +11 -2
  416. package/dist/server/createHttpHost.js +106 -10
  417. package/dist/server/ensureGlobalService.d.ts +5 -1
  418. package/dist/server/ensureGlobalService.js +35 -1
  419. package/dist/server/healthSurfaces.d.ts +6 -0
  420. package/dist/server/healthSurfaces.js +123 -0
  421. package/dist/server/http.d.ts +27 -1
  422. package/dist/server/http.js +2254 -477
  423. package/dist/server/listenHost.d.ts +5 -0
  424. package/dist/server/listenHost.js +56 -0
  425. package/dist/server/mcpHost.d.ts +10 -1
  426. package/dist/server/mcpHost.js +36 -6
  427. package/dist/server/operatorResults.d.ts +2 -2
  428. package/dist/server/operatorResults.js +40 -29
  429. package/dist/server/requestAuthContext.d.ts +12 -0
  430. package/dist/server/requestAuthContext.js +21 -0
  431. package/dist/server/shutdown.d.ts +69 -0
  432. package/dist/server/shutdown.js +219 -0
  433. package/dist/server/triggerRoutes.d.ts +15 -0
  434. package/dist/server/triggerRoutes.js +268 -0
  435. package/dist/tools/askOperator.d.ts +3 -2
  436. package/dist/types/completion.d.ts +3 -0
  437. package/dist/types/pipeline.d.ts +10 -1
  438. package/dist/types/preEmitCheck.d.ts +7 -0
  439. package/dist/types/stage.d.ts +22 -0
  440. package/dist/types/stageflowManifest.d.ts +3 -0
  441. package/dist/types/task.d.ts +8 -0
  442. package/dist/types/trigger.d.ts +18 -0
  443. package/dist/types/trigger.js +1 -0
  444. package/dist/ui/assets/{index-CSsDued1.css → index-Bv4p1aPK.css} +1 -1
  445. package/dist/ui/assets/index-CntB4bZR.js +133 -0
  446. package/dist/ui/index.html +2 -2
  447. package/dist/workshop/autosave.d.ts +58 -0
  448. package/dist/workshop/autosave.js +222 -0
  449. package/dist/workshop/buildStore.d.ts +79 -0
  450. package/dist/workshop/buildStore.js +326 -0
  451. package/dist/workshop/chatTurn.d.ts +232 -0
  452. package/dist/workshop/chatTurn.js +475 -0
  453. package/dist/workshop/modelSettings.d.ts +18 -0
  454. package/dist/workshop/modelSettings.js +44 -0
  455. package/dist/workshop/sessionStore.d.ts +61 -0
  456. package/dist/workshop/sessionStore.js +254 -0
  457. package/dist/workshop/workshopPin.d.ts +72 -0
  458. package/dist/workshop/workshopPin.js +193 -0
  459. package/examples/README.md +99 -0
  460. package/examples/archify-on-pr/README.md +213 -0
  461. package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +19 -0
  462. package/examples/archify-on-pr/archify-on-pr.task.yaml +19 -0
  463. package/examples/archify-on-pr/author-diagrams.yaml +106 -0
  464. package/examples/archify-on-pr/detect-changes.yaml +89 -0
  465. package/examples/browser-session/README.md +77 -0
  466. package/examples/browser-session/browser-session.pipeline.yaml +50 -0
  467. package/examples/browser-session/browser-session.task.yaml +6 -0
  468. package/examples/browser-session/check-login.yaml +22 -0
  469. package/examples/browser-session/fixture-server.mjs +64 -0
  470. package/examples/browser-session/human-login.yaml +31 -0
  471. package/examples/browser-session/merge.yaml +36 -0
  472. package/examples/browser-session/work-a.yaml +41 -0
  473. package/examples/browser-session/work-b.yaml +41 -0
  474. package/examples/ci-validate/README.md +35 -0
  475. package/examples/ci-validate/check.yaml +13 -0
  476. package/examples/ci-validate/ci-demo.pipeline.yaml +4 -0
  477. package/examples/ci-validate/validate.sh +5 -0
  478. package/examples/compliance-review-demo/README.md +125 -0
  479. package/examples/compliance-review-demo/compliance-review-demo.pipeline.yaml +29 -0
  480. package/examples/compliance-review-demo/connect-account.yaml +47 -0
  481. package/examples/compliance-review-demo/map-to-control.yaml +123 -0
  482. package/examples/compliance-review-demo/poll-bucket-config.yaml +103 -0
  483. package/examples/compliance-review-demo/publish-report.yaml +79 -0
  484. package/examples/compliance-review-demo/review-verdict.yaml +122 -0
  485. package/examples/compliance-review-demo/run-compliance-check.yaml +96 -0
  486. package/examples/compliance-review-demo/store-evidence.yaml +143 -0
  487. package/examples/conditional-fork/README.md +89 -0
  488. package/examples/conditional-fork/branch-a.yaml +13 -0
  489. package/examples/conditional-fork/branch-b.yaml +13 -0
  490. package/examples/conditional-fork/decide.yaml +35 -0
  491. package/examples/conditional-fork/fork-demo.pipeline.yaml +20 -0
  492. package/examples/conditional-fork/fork-demo.task.yaml +8 -0
  493. package/examples/context7-mcp/README.md +42 -0
  494. package/examples/context7-mcp/context7-mcp.pipeline.yaml +15 -0
  495. package/examples/context7-mcp/context7-mcp.task.yaml +4 -0
  496. package/examples/context7-mcp/fetch-docs.yaml +52 -0
  497. package/examples/context7-mcp/resolve-library.yaml +31 -0
  498. package/examples/context7-mcp/write-brief.yaml +52 -0
  499. package/examples/feature-loop/README.md +104 -0
  500. package/examples/feature-loop/address-feedback.yaml +148 -0
  501. package/examples/feature-loop/align.yaml +116 -0
  502. package/examples/feature-loop/decompose.yaml +86 -0
  503. package/examples/feature-loop/default-model-hierarchy.task.yaml +58 -0
  504. package/examples/feature-loop/feature-loop.pipeline.yaml +140 -0
  505. package/examples/feature-loop/feature-loop.task.yaml +25 -0
  506. package/examples/feature-loop/implement.yaml +128 -0
  507. package/examples/feature-loop/plan.yaml +111 -0
  508. package/examples/feature-loop/publish.yaml +167 -0
  509. package/examples/feature-loop/review.yaml +146 -0
  510. package/examples/feature-loop/verify.yaml +106 -0
  511. package/examples/feedback-loop/README.md +72 -0
  512. package/examples/feedback-loop/VERIFY.md +208 -0
  513. package/examples/feedback-loop/continue-only.task.yaml +4 -0
  514. package/examples/feedback-loop/exhaust-require-continue.task.yaml +6 -0
  515. package/examples/feedback-loop/exhaust-wait-human.task.yaml +11 -0
  516. package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +23 -0
  517. package/examples/feedback-loop/feedback-loop.pipeline.yaml +23 -0
  518. package/examples/feedback-loop/feedback-loop.task.yaml +4 -0
  519. package/examples/feedback-loop/implement.yaml +14 -0
  520. package/examples/feedback-loop/plan.yaml +14 -0
  521. package/examples/feedback-loop/review.yaml +15 -0
  522. package/examples/feedback-loop/send-back-once.task.yaml +6 -0
  523. package/examples/feedback-loop/submit.yaml +12 -0
  524. package/examples/generic-fan-in/README.md +151 -0
  525. package/examples/generic-fan-in/clarify.yaml +18 -0
  526. package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +19 -0
  527. package/examples/generic-fan-in/generic-fan-in-accepted.task.yaml +8 -0
  528. package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +18 -0
  529. package/examples/generic-fan-in/generic-fan-in.task.yaml +9 -0
  530. package/examples/generic-fan-in/research.yaml +45 -0
  531. package/examples/generic-fan-in/synthesize.yaml +66 -0
  532. package/examples/generic-fan-in/validation.yaml +45 -0
  533. package/examples/github-release/README.md +78 -0
  534. package/examples/github-release/draft-release-notes.yaml +64 -0
  535. package/examples/github-release/github-release.pipeline.yaml +11 -0
  536. package/examples/github-release/github-release.task.yaml +13 -0
  537. package/examples/github-release/publish-github-release.yaml +64 -0
  538. package/examples/hello-world/README.md +28 -0
  539. package/examples/hello-world/hello.pipeline.yaml +4 -0
  540. package/examples/hello-world/my-task.task.yaml +6 -0
  541. package/examples/hello-world/research.yaml +18 -0
  542. package/examples/mcp-hitl-tour/README.md +113 -0
  543. package/examples/mcp-hitl-tour/draft-angle.yaml +33 -0
  544. package/examples/mcp-hitl-tour/draft-short.yaml +32 -0
  545. package/examples/mcp-hitl-tour/emit-angles.yaml +45 -0
  546. package/examples/mcp-hitl-tour/gather.yaml +31 -0
  547. package/examples/mcp-hitl-tour/intake.yaml +62 -0
  548. package/examples/mcp-hitl-tour/mcp-hitl-tour-exhaust.task.yaml +13 -0
  549. package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +54 -0
  550. package/examples/mcp-hitl-tour/mcp-hitl-tour.task.yaml +16 -0
  551. package/examples/mcp-hitl-tour/polish.yaml +33 -0
  552. package/examples/mcp-hitl-tour/review.yaml +17 -0
  553. package/examples/mcp-hitl-tour/ship.yaml +25 -0
  554. package/examples/oss-issue-contribution/README.md +218 -0
  555. package/examples/oss-issue-contribution/oss-address-review-feedback.yaml +117 -0
  556. package/examples/oss-issue-contribution/oss-approve-contribution.yaml +181 -0
  557. package/examples/oss-issue-contribution/oss-approve-plan.yaml +111 -0
  558. package/examples/oss-issue-contribution/oss-explain-fix.yaml +108 -0
  559. package/examples/oss-issue-contribution/oss-explain-issue.yaml +114 -0
  560. package/examples/oss-issue-contribution/oss-implement-source-fix.yaml +171 -0
  561. package/examples/oss-issue-contribution/oss-investigate-area.yaml +116 -0
  562. package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +125 -0
  563. package/examples/oss-issue-contribution/oss-issue-intake.yaml +106 -0
  564. package/examples/oss-issue-contribution/oss-plan-investigation.yaml +112 -0
  565. package/examples/oss-issue-contribution/oss-plan-review.yaml +109 -0
  566. package/examples/oss-issue-contribution/oss-reproduce-issue.yaml +140 -0
  567. package/examples/oss-issue-contribution/oss-review-change.yaml +107 -0
  568. package/examples/oss-issue-contribution/oss-verify-fix.yaml +130 -0
  569. package/examples/oss-issue-contribution/oss-write-regression-test.yaml +135 -0
  570. package/examples/oss-issue-contribution/pi-7629.task.yaml +79 -0
  571. package/examples/oss-issue-contribution/pi-8919.task.yaml +75 -0
  572. package/examples/oss-issue-contribution/pydantic-ai-7971.task.yaml +53 -0
  573. package/examples/oss-quick-fix/README.md +65 -0
  574. package/examples/oss-quick-fix/implement-fix.yaml +84 -0
  575. package/examples/oss-quick-fix/oss-quick-fix.pipeline.yaml +35 -0
  576. package/examples/oss-quick-fix/oss-quick-fix.task.yaml +19 -0
  577. package/examples/oss-quick-fix/ship-fix.yaml +81 -0
  578. package/examples/oss-quick-fix/understand-issue.yaml +67 -0
  579. package/examples/oss-quick-fix/verify-fix.yaml +73 -0
  580. package/examples/plan-review/README.md +37 -0
  581. package/examples/plan-review/plan-review-followup.yaml +13 -0
  582. package/examples/plan-review/plan-review.pipeline.yaml +9 -0
  583. package/examples/plan-review/plan-review.task.yaml +9 -0
  584. package/examples/plan-review/plan-review.yaml +25 -0
  585. package/examples/playwright-mcp/README.md +39 -0
  586. package/examples/playwright-mcp/playwright-mcp.pipeline.yaml +5 -0
  587. package/examples/playwright-mcp/playwright-mcp.task.yaml +4 -0
  588. package/examples/playwright-mcp/screenshot.yaml +40 -0
  589. package/examples/retry-tour/README.md +75 -0
  590. package/examples/retry-tour/retry-tour.pipeline.yaml +122 -0
  591. package/examples/retry-tour/retry-tour.task.yaml +9 -0
  592. package/examples/route-if-tour/README.md +202 -0
  593. package/examples/route-if-tour/route-if-tour.pipeline.yaml +950 -0
  594. package/examples/route-if-tour/route-if-tour.task.yaml +4 -0
  595. package/examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml +168 -0
  596. package/examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml +44 -0
  597. package/examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml +28 -0
  598. package/examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml +27 -0
  599. package/examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml +110 -0
  600. package/examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml +82 -0
  601. package/examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml +82 -0
  602. package/examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml +77 -0
  603. package/examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml +102 -0
  604. package/examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml +23 -0
  605. package/examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml +37 -0
  606. package/examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml +138 -0
  607. package/examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml +84 -0
  608. package/examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml +50 -0
  609. package/examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml +37 -0
  610. package/examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml +65 -0
  611. package/examples/route-wiring-smoke-test/17-if-join.pipeline.yaml +80 -0
  612. package/examples/route-wiring-smoke-test/README.md +377 -0
  613. package/examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml +26 -0
  614. package/examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml +25 -0
  615. package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml +30 -0
  616. package/examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml +24 -0
  617. package/examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml +35 -0
  618. package/examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml +37 -0
  619. package/examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml +27 -0
  620. package/examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml +42 -0
  621. package/examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml +26 -0
  622. package/examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml +55 -0
  623. package/examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml +51 -0
  624. package/examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml +35 -0
  625. package/examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml +15 -0
  626. package/examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml +15 -0
  627. package/examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml +33 -0
  628. package/examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml +51 -0
  629. package/examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml +55 -0
  630. package/examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml +36 -0
  631. package/examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml +42 -0
  632. package/examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml +33 -0
  633. package/examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml +32 -0
  634. package/examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml +31 -0
  635. package/examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml +33 -0
  636. package/examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml +36 -0
  637. package/examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml +63 -0
  638. package/examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml +46 -0
  639. package/examples/route-wiring-smoke-test/smoke-test.task.yaml +4 -0
  640. package/examples/route-wiring-smoke-test/stages/branch-a.yaml +12 -0
  641. package/examples/route-wiring-smoke-test/stages/branch-b.yaml +12 -0
  642. package/examples/route-wiring-smoke-test/stages/decide.yaml +12 -0
  643. package/examples/route-wiring-smoke-test/stages/finish.yaml +12 -0
  644. package/examples/ship-feature/README.md +190 -0
  645. package/examples/ship-feature/feat-address-feedback.yaml +119 -0
  646. package/examples/ship-feature/feat-implement.yaml +180 -0
  647. package/examples/ship-feature/feat-plan.yaml +120 -0
  648. package/examples/ship-feature/feat-review.yaml +109 -0
  649. package/examples/ship-feature/feat-ship.yaml +203 -0
  650. package/examples/ship-feature/ship-feature.pipeline.yaml +44 -0
  651. package/examples/ship-feature/ship-feature.task.yaml +78 -0
  652. package/examples/stage-mcp/README.md +145 -0
  653. package/examples/stage-mcp/echo-mcp.mjs +20 -0
  654. package/examples/stage-mcp/stage-mcp-dead.pipeline.yaml +5 -0
  655. package/examples/stage-mcp/stage-mcp-dead.task.yaml +3 -0
  656. package/examples/stage-mcp/stage-mcp-missing-var.pipeline.yaml +5 -0
  657. package/examples/stage-mcp/stage-mcp-missing-var.task.yaml +3 -0
  658. package/examples/stage-mcp/stage-mcp.pipeline.yaml +5 -0
  659. package/examples/stage-mcp/stage-mcp.task.yaml +4 -0
  660. package/examples/stage-mcp/use-echo.yaml +20 -0
  661. package/examples/stageflow.yaml +51 -0
  662. package/examples/verify-tour/README.md +80 -0
  663. package/examples/verify-tour/verify-tour.pipeline.yaml +162 -0
  664. package/examples/verify-tour/verify-tour.task.yaml +11 -0
  665. package/package.json +9 -1
  666. package/skills/stageflow/SKILL.md +6 -6
  667. package/skills/stageflow/references/control-surface.md +13 -5
  668. package/skills/stageflow/scripts/detect-host.mjs +14 -1
  669. package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
  670. package/skills/stageflow-author/SKILL.md +4 -3
  671. package/skills/stageflow-author/references/catalog-mapping.md +16 -0
  672. package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
  673. package/skills/stageflow-author/references/stage-prompt-template.md +4 -4
  674. package/skills/stageflow-run/SKILL.md +22 -12
  675. package/skills/stageflow-run/references/mcp-call.md +9 -1
  676. package/skills/stageflow-run/references/task-and-pipeline-selection.md +19 -6
  677. package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
  678. package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
  679. package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
  680. package/skills/stageflow-setup/SKILL.md +51 -8
  681. package/dist/ui/assets/index-Da5EHU6M.js +0 -119
@@ -1,16 +1,40 @@
1
- import { resolveSkillByName } from "../config/listSkills.js";
1
+ import { bindingKindForOrigin, catalogOrSeededOrigin, decideWorkspaceConfigTrust, } from "../config/configOrigin.js";
2
+ import { loginCheckPromptBlock, readStageLoginCheck, } from "../browser/loginCheck.js";
3
+ import { humanLoginPromptBlock, isHumanLoginStage } from "../browser/humanLogin.js";
4
+ import { BROWSER_SKILL_NAME, resolveBuiltinSkillFile, } from "../config/builtinSkills.js";
5
+ import { resolveSkillByName, } from "../config/listSkills.js";
6
+ import { loadHostConfig } from "../config/hostConfig.js";
7
+ import { defaultSeededRoots } from "../config/seededCatalog.js";
8
+ import { readFileSync } from "node:fs";
2
9
  import { mkdir } from "node:fs/promises";
3
- import { MCP_CATALOG_FILENAME, STAGEFLOW_STAGE_ARTIFACTS_DIR_ENV, StageMcpError, resolveStageMcpServers, stampStagePromptArtifactsDir, } from "../config/resolveStageMcpServers.js";
10
+ import { runSkillsDir } from "./runSkills.js";
11
+ import { MCP_CATALOG_FILENAME, STAGEFLOW_STAGE_ARTIFACTS_DIR_ENV, StageMcpError, mcpCatalogExists, mcpCatalogPath, resolveStageMcpServers, stampStagePromptArtifactsDir, } from "../config/resolveStageMcpServers.js";
4
12
  import { attemptArtifactsDir, attemptStreamLogPath } from "../runstore/workspaceLayout.js";
13
+ import { redactBrowserActivityEvent, redactBrowserSecrets, } from "../agent/streamLogRedact.js";
5
14
  import { createStageStreamLogWriter, } from "./stageStreamLog.js";
6
15
  import { resolveCloneEmitContext, resolveForkEmitContext } from "../config/resolveForkEmitContext.js";
7
16
  import { createAttemptQaTrailReader } from "../hitl/qaTrail.js";
17
+ import { collectMcpEnvNamedSecrets, patchRunManifest, redactMcpServers, sha256Digest, withSkillEntry, withStageMcpServers, withStageResolvedModel, } from "../runstore/runManifest.js";
18
+ import { getNamedSecrets, registerNamedSecrets, } from "../logging/namedSecrets.js";
8
19
  import { assertPriorInputPayload, payloadInstanceMismatch, } from "../envelope/payloadSchema.js";
9
20
  import { buildCompletedEnvelopesFromRun, resolvePriorEnvelope, } from "./envelopeRouting.js";
10
21
  import { assignment } from "./cloneSchedule.js";
11
22
  import { resumeSessionFilePath } from "./stageAttemptContext.js";
12
- import { buildStageRoots, rootsForStageWorker, withResolvedAuthPath, } from "./stageRoots.js";
13
- async function resolveStageSkillForRun(stage, catalog) {
23
+ import { bindingKindFromMeta, buildStageRoots, rootsForStageWorker, withResolvedAuthPath, } from "./stageRoots.js";
24
+ function resolveTrustWorkspaceConfig(explicit) {
25
+ if (explicit !== undefined)
26
+ return explicit;
27
+ try {
28
+ return loadHostConfig().trustWorkspaceConfig;
29
+ }
30
+ catch {
31
+ return [];
32
+ }
33
+ }
34
+ function seededRootPaths() {
35
+ return defaultSeededRoots().map((root) => root.path);
36
+ }
37
+ async function resolveStageSkillForRun(stage, catalog, options) {
14
38
  const name = stage.skill;
15
39
  if (name === undefined)
16
40
  return { ok: true };
@@ -20,55 +44,235 @@ async function resolveStageSkillForRun(stage, catalog) {
20
44
  const resolved = await resolveSkillByName(name, {
21
45
  cwd: catalog.cwd ?? process.cwd(),
22
46
  agentDir: catalog.agentDir,
47
+ runSkillsDir: runSkillsDir(options.workspaceDir),
48
+ ...(options.checkoutRoot !== undefined
49
+ ? { checkoutRoot: options.checkoutRoot }
50
+ : {}),
23
51
  });
24
52
  if (!resolved) {
25
53
  return { ok: false, reason: `Skill "${name}" is not installed` };
26
54
  }
27
- return { ok: true, skillFilePath: resolved.filePath };
55
+ if (resolved.origin === "checkout") {
56
+ const decision = decideWorkspaceConfigTrust({
57
+ bindingKind: bindingKindForOrigin(options.bindingKind),
58
+ projectRoot: options.factoryCwd ?? options.checkoutRoot ?? "",
59
+ trustWorkspaceConfig: options.trustWorkspaceConfig,
60
+ source: "workspace",
61
+ });
62
+ if (!decision.allow) {
63
+ return {
64
+ ok: false,
65
+ reason: decision.code ?? "untrusted_config_origin",
66
+ };
67
+ }
68
+ }
69
+ return {
70
+ ok: true,
71
+ skillFilePath: resolved.filePath,
72
+ skillOrigin: resolved.origin,
73
+ };
74
+ }
75
+ /** Browser stages get the `browser` skill (run > checkout > host > built-in). A missing skill is not an error. */
76
+ async function resolveBrowserSkillFile(stage, catalog, options) {
77
+ if (stage.browser === undefined || stage.skill === BROWSER_SKILL_NAME) {
78
+ return undefined;
79
+ }
80
+ const resolved = await resolveStageSkillForRun({ skill: BROWSER_SKILL_NAME }, catalog, options);
81
+ if (resolved.ok && resolved.skillFilePath !== undefined) {
82
+ return resolved.skillFilePath;
83
+ }
84
+ return resolveBuiltinSkillFile(BROWSER_SKILL_NAME);
28
85
  }
29
- async function resolveAttemptMcpServers(allowlist, factoryCwd, artifactsDir) {
86
+ async function resolveAttemptMcpServers(allowlist, factoryCwd, artifactsDir, options) {
30
87
  const names = allowlist ?? [];
31
88
  if (names.length === 0)
32
- return undefined;
33
- if (factoryCwd === undefined) {
34
- throw new StageMcpError(`MCP catalog "${MCP_CATALOG_FILENAME}" is missing`, "missing_catalog");
89
+ return { servers: undefined, origins: [] };
90
+ const env = {
91
+ ...(options.stageEnv ?? {}),
92
+ [STAGEFLOW_STAGE_ARTIFACTS_DIR_ENV]: artifactsDir,
93
+ };
94
+ const stageIdOpt = options.stageId !== undefined ? { stageId: options.stageId } : {};
95
+ const bindingKind = bindingKindForOrigin(options.bindingKind);
96
+ if (factoryCwd !== undefined && (await mcpCatalogExists(factoryCwd))) {
97
+ await mkdir(artifactsDir, { recursive: true });
98
+ const resolved = await resolveStageMcpServers({
99
+ projectRoot: factoryCwd,
100
+ allowlist: names,
101
+ env,
102
+ bindingKind,
103
+ trustWorkspaceConfig: options.trustWorkspaceConfig,
104
+ ...stageIdOpt,
105
+ });
106
+ const origin = catalogOrSeededOrigin(factoryCwd, seededRootPaths());
107
+ const catalogPath = mcpCatalogPath(factoryCwd);
108
+ return {
109
+ servers: Object.keys(resolved).length > 0 ? resolved : undefined,
110
+ origins: names.map((name) => ({
111
+ name,
112
+ origin,
113
+ path: catalogPath,
114
+ })),
115
+ };
35
116
  }
36
- await mkdir(artifactsDir, { recursive: true });
37
- const resolved = await resolveStageMcpServers({
38
- projectRoot: factoryCwd,
39
- allowlist: names,
40
- env: {
41
- ...process.env,
42
- [STAGEFLOW_STAGE_ARTIFACTS_DIR_ENV]: artifactsDir,
43
- },
44
- });
45
- return Object.keys(resolved).length > 0 ? resolved : undefined;
117
+ const checkoutRoot = options.checkoutRoot;
118
+ if (checkoutRoot !== undefined &&
119
+ checkoutRoot !== factoryCwd &&
120
+ (await mcpCatalogExists(checkoutRoot))) {
121
+ await mkdir(artifactsDir, { recursive: true });
122
+ const resolved = await resolveStageMcpServers({
123
+ projectRoot: checkoutRoot,
124
+ allowlist: names,
125
+ env,
126
+ bindingKind,
127
+ trustWorkspaceConfig: options.trustWorkspaceConfig,
128
+ trustProjectRoot: factoryCwd ?? checkoutRoot,
129
+ workspaceSourced: true,
130
+ ...stageIdOpt,
131
+ });
132
+ const catalogPath = mcpCatalogPath(checkoutRoot);
133
+ return {
134
+ servers: Object.keys(resolved).length > 0 ? resolved : undefined,
135
+ origins: names.map((name) => ({
136
+ name,
137
+ origin: "workspace",
138
+ path: catalogPath,
139
+ })),
140
+ };
141
+ }
142
+ throw new StageMcpError(`MCP catalog "${MCP_CATALOG_FILENAME}" is missing`, "missing_catalog");
46
143
  }
47
- async function openStageWithOperatorCatalog(agent, input, catalog, factoryCwd, artifactsDir) {
48
- const skill = await resolveStageSkillForRun(input.stage, catalog);
144
+ function verifyCommandOrigins(dag, stageId, pipelinePath, factoryCwd) {
145
+ const completion = dag.nodes.find((node) => node.id === stageId)?.completion;
146
+ const origin = catalogOrSeededOrigin(factoryCwd, seededRootPaths());
147
+ const records = [];
148
+ for (const check of completion?.checks ?? []) {
149
+ if (check.type !== "command")
150
+ continue;
151
+ records.push({
152
+ name: check.id,
153
+ origin,
154
+ ...(pipelinePath !== undefined ? { path: pipelinePath } : {}),
155
+ });
156
+ }
157
+ return records;
158
+ }
159
+ async function openStageWithOperatorCatalog(agent, input, catalog, factoryCwd, artifactsDir, resolveOptions) {
160
+ const skill = await resolveStageSkillForRun(input.stage, catalog, {
161
+ bindingKind: resolveOptions.bindingKind,
162
+ checkoutRoot: resolveOptions.checkoutRoot,
163
+ factoryCwd,
164
+ trustWorkspaceConfig: resolveOptions.trustWorkspaceConfig,
165
+ workspaceDir: resolveOptions.workspaceDir,
166
+ });
49
167
  if (!skill.ok)
50
168
  return skill;
169
+ const browserSkillFilePath = await resolveBrowserSkillFile(input.stage, catalog, {
170
+ bindingKind: resolveOptions.bindingKind,
171
+ checkoutRoot: resolveOptions.checkoutRoot,
172
+ factoryCwd,
173
+ trustWorkspaceConfig: resolveOptions.trustWorkspaceConfig,
174
+ workspaceDir: resolveOptions.workspaceDir,
175
+ });
51
176
  let resolvedMcpServers;
177
+ const origins = [];
52
178
  try {
53
- resolvedMcpServers = await resolveAttemptMcpServers(input.stage.mcp, factoryCwd, artifactsDir);
179
+ const mcp = await resolveAttemptMcpServers(input.stage.mcp, factoryCwd, artifactsDir, {
180
+ checkoutRoot: resolveOptions.checkoutRoot,
181
+ bindingKind: resolveOptions.bindingKind,
182
+ trustWorkspaceConfig: resolveOptions.trustWorkspaceConfig,
183
+ stageEnv: resolveOptions.stageEnv,
184
+ stageId: input.stageId,
185
+ });
186
+ resolvedMcpServers = mcp.servers;
187
+ origins.push(...mcp.origins);
54
188
  }
55
189
  catch (err) {
56
190
  if (err instanceof StageMcpError) {
57
- return { ok: false, reason: err.message };
191
+ return {
192
+ ok: false,
193
+ reason: err.code === "untrusted_config_origin" ? err.code : err.message,
194
+ };
58
195
  }
59
196
  throw err;
60
197
  }
198
+ origins.push(...verifyCommandOrigins(resolveOptions.dag, input.stageId ?? input.stage.id, resolveOptions.pipelinePath, factoryCwd));
199
+ if (origins.length > 0) {
200
+ await resolveOptions.store.appendConfigOrigins(resolveOptions.runId, origins);
201
+ }
202
+ const stageIdForManifest = input.stageId ?? input.stage.id;
203
+ if (resolvedMcpServers !== undefined) {
204
+ const mcpSecrets = collectMcpEnvNamedSecrets(resolvedMcpServers);
205
+ if (mcpSecrets.length > 0) {
206
+ registerNamedSecrets(mcpSecrets);
207
+ }
208
+ const originMap = new Map(origins
209
+ .filter((o) => o.name.length > 0)
210
+ .map((o) => [o.name, o.origin]));
211
+ const mcpServers = redactMcpServers(resolvedMcpServers, [...getNamedSecrets(), ...mcpSecrets], originMap);
212
+ await patchRunManifest(resolveOptions.store, resolveOptions.runId, (m) => withStageMcpServers(m, stageIdForManifest, mcpServers), [...getNamedSecrets(), ...mcpSecrets]).catch(() => null);
213
+ }
214
+ if (skill.skillOrigin !== undefined && skill.skillFilePath !== undefined) {
215
+ const skillName = input.stage.skill;
216
+ if (skillName !== undefined) {
217
+ let digest;
218
+ try {
219
+ digest = sha256Digest(readFileSync(skill.skillFilePath));
220
+ }
221
+ catch {
222
+ digest = sha256Digest(skill.skillFilePath);
223
+ }
224
+ await patchRunManifest(resolveOptions.store, resolveOptions.runId, (m) => withSkillEntry(m, {
225
+ name: skillName,
226
+ origin: skill.skillOrigin,
227
+ digest,
228
+ files: ["SKILL.md"],
229
+ })).catch(() => null);
230
+ }
231
+ }
232
+ let loginCheck;
233
+ const humanLogin = isHumanLoginStage(resolveOptions.dag, input.stage.id, input.stage.browser);
234
+ if (input.stage.browser?.check !== undefined && !humanLogin) {
235
+ loginCheck = await readStageLoginCheck(resolveOptions.workspaceDir, stageIdForManifest);
236
+ if (loginCheck === undefined) {
237
+ return { ok: false, reason: "browser login check result is missing" };
238
+ }
239
+ }
61
240
  try {
62
241
  const handle = agent.openStage({
63
242
  ...input,
64
243
  stage: {
65
244
  ...input.stage,
66
- system_prompt: stampStagePromptArtifactsDir(input.stage.system_prompt, artifactsDir),
245
+ system_prompt: `${stampStagePromptArtifactsDir(input.stage.system_prompt, artifactsDir)}${loginCheck !== undefined ? `\n\n${loginCheckPromptBlock(loginCheck)}` : ""}${humanLogin ? `\n\n${humanLoginPromptBlock(input.stage.browser?.login_url ?? input.stage.browser?.check?.url)}` : ""}`,
246
+ ...(loginCheck !== undefined
247
+ ? {
248
+ pre_emit_checks: [
249
+ ...(input.stage.pre_emit_checks ?? []),
250
+ {
251
+ id: "browser_login_check",
252
+ type: "browser_login_check",
253
+ state: loginCheck.state,
254
+ logged_in: loginCheck.logged_in,
255
+ url: loginCheck.url,
256
+ },
257
+ ],
258
+ }
259
+ : {}),
67
260
  },
68
261
  ...(skill.skillFilePath !== undefined
69
262
  ? { skillFilePath: skill.skillFilePath }
70
263
  : {}),
264
+ ...(browserSkillFilePath !== undefined
265
+ ? { browserSkillFilePath }
266
+ : {}),
71
267
  ...(resolvedMcpServers !== undefined ? { resolvedMcpServers } : {}),
268
+ onResolvedModel: async (info) => {
269
+ await patchRunManifest(resolveOptions.store, resolveOptions.runId, (m) => withStageResolvedModel(m, info.stageId, {
270
+ model: info.model,
271
+ ...(info.thinkingLevel !== undefined
272
+ ? { thinkingLevel: info.thinkingLevel }
273
+ : {}),
274
+ })).catch(() => null);
275
+ },
72
276
  });
73
277
  return { ok: true, handle };
74
278
  }
@@ -200,7 +404,10 @@ export async function openStageAttempt(input) {
200
404
  return priorInput;
201
405
  const roots = resolveAttemptRoots(input, stageId);
202
406
  const attempt = input.attemptCtx?.attempt ?? 1;
203
- const streamWriter = (input.streamLogWriterFactory ?? createStageStreamLogWriter)(attemptStreamLogPath(input.workspaceDir, stageId, attempt));
407
+ const streamLogPath = attemptStreamLogPath(input.workspaceDir, stageId, attempt);
408
+ const streamWriter = input.streamLogWriterFactory
409
+ ? input.streamLogWriterFactory(streamLogPath)
410
+ : createStageStreamLogWriter(streamLogPath, input.stage.browser !== undefined ? { redact: redactBrowserSecrets } : {});
204
411
  const resumeToken = input.resumeToken ??
205
412
  resumeSessionFilePath(input.workspaceDir, stageId, attempt);
206
413
  const forkEmitContext = resolveForkEmitContext(input.dag, definitionId);
@@ -219,6 +426,9 @@ export async function openStageAttempt(input) {
219
426
  : runtimeNode?.feedback_loop;
220
427
  const repairContext = await repairContextForAttempt(input, stageId, attempt);
221
428
  const readQaTrail = createAttemptQaTrailReader(input.store, input.runId, stageId, attempt);
429
+ const meta = await input.store.readRunMeta(input.runId);
430
+ const bindingKind = input.bindingKind ?? bindingKindFromMeta(meta);
431
+ const trustWorkspaceConfig = resolveTrustWorkspaceConfig(input.trustWorkspaceConfig);
222
432
  const opened = await openStageWithOperatorCatalog(input.agent, {
223
433
  roots,
224
434
  stage: input.stage,
@@ -234,7 +444,9 @@ export async function openStageAttempt(input) {
234
444
  resumeToken,
235
445
  ...(input.sessionMode !== undefined ? { sessionMode: input.sessionMode } : {}),
236
446
  onActivity: (event) => {
237
- input.onActivity?.(event);
447
+ input.onActivity?.(input.stage.browser !== undefined
448
+ ? redactBrowserActivityEvent(event)
449
+ : event);
238
450
  void streamWriter.flush();
239
451
  },
240
452
  onAssistantTextDelta: streamWriter.onDelta,
@@ -250,7 +462,17 @@ export async function openStageAttempt(input) {
250
462
  ...(input.stage.timeout_ms !== undefined
251
463
  ? { timeoutMs: input.stage.timeout_ms }
252
464
  : {}),
253
- }, input.operatorCatalog, input.factoryCwd, attemptArtifactsDir(input.workspaceDir, stageId, attempt));
465
+ }, input.operatorCatalog, input.factoryCwd, attemptArtifactsDir(input.workspaceDir, stageId, attempt), {
466
+ checkoutRoot: input.checkoutRoot ?? meta.checkout_root,
467
+ bindingKind,
468
+ trustWorkspaceConfig,
469
+ stageEnv: input.stageEnv,
470
+ store: input.store,
471
+ runId: input.runId,
472
+ pipelinePath: meta.pipeline_path,
473
+ dag: input.dag,
474
+ workspaceDir: input.workspaceDir,
475
+ });
254
476
  if (!opened.ok)
255
477
  return opened;
256
478
  return {
@@ -258,5 +480,6 @@ export async function openStageAttempt(input) {
258
480
  handle: opened.handle,
259
481
  roots,
260
482
  prior: priorResult.prior,
483
+ ...(input.stageEnv !== undefined ? { stageEnv: input.stageEnv } : {}),
261
484
  };
262
485
  }
@@ -0,0 +1,6 @@
1
+ export declare function stageflowCacheRoot(home?: string): string;
2
+ /** Compute cache env vars without creating directories (lazy create is separate). */
3
+ export declare function computeCacheEnvVars(home?: string): Record<string, string>;
4
+ /** Lazily create shared cache directories at first stage launch. */
5
+ export declare function ensureStageCacheDirs(home?: string): Record<string, string>;
6
+ export declare function resetStageCacheDirsForTests(): void;
@@ -0,0 +1,34 @@
1
+ import { mkdirSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { globalStageflowHome } from "../project/globalHome.js";
4
+ export function stageflowCacheRoot(home = globalStageflowHome()) {
5
+ return path.join(home, "cache");
6
+ }
7
+ /** Compute cache env vars without creating directories (lazy create is separate). */
8
+ export function computeCacheEnvVars(home = globalStageflowHome()) {
9
+ const cache = stageflowCacheRoot(home);
10
+ return {
11
+ STAGEFLOW_CACHE: cache,
12
+ npm_config_cache: path.join(cache, "npm"),
13
+ PNPM_STORE_DIR: path.join(cache, "pnpm"),
14
+ YARN_CACHE_FOLDER: path.join(cache, "yarn"),
15
+ UV_CACHE_DIR: path.join(cache, "uv"),
16
+ GOMODCACHE: path.join(cache, "go", "mod"),
17
+ CARGO_HOME: path.join(cache, "cargo"),
18
+ };
19
+ }
20
+ let cacheEnsured = false;
21
+ /** Lazily create shared cache directories at first stage launch. */
22
+ export function ensureStageCacheDirs(home = globalStageflowHome()) {
23
+ const vars = computeCacheEnvVars(home);
24
+ if (!cacheEnsured) {
25
+ for (const value of Object.values(vars)) {
26
+ mkdirSync(value, { recursive: true });
27
+ }
28
+ cacheEnsured = true;
29
+ }
30
+ return vars;
31
+ }
32
+ export function resetStageCacheDirsForTests() {
33
+ cacheEnsured = false;
34
+ }
@@ -1,7 +1,8 @@
1
1
  export declare const UNLIMITED_CONCURRENCY: number;
2
2
  export declare const DEFAULT_MAX_ACTIVE_STAGES_PER_RUN: number;
3
3
  export declare const MAX_ACTIVE_STAGES_PER_RUN_ENV = "STAGEFLOW_MAX_ACTIVE_STAGES_PER_RUN";
4
- export declare const DEFAULT_MAX_ACTIVE_STAGE_PROCESSES: number;
4
+ /** Fallback when cgroup is absent; finite so waitForCapacity is exercised. */
5
+ export declare const DEFAULT_MAX_ACTIVE_STAGE_PROCESSES = 4;
5
6
  export declare const MAX_ACTIVE_STAGE_PROCESSES_ENV = "STAGEFLOW_MAX_ACTIVE_STAGE_PROCESSES";
6
7
  export declare const STAGE_EXECUTION_ENV = "STAGEFLOW_STAGE_EXECUTION";
7
8
  export type StageExecutionMode = "process" | "inprocess";
@@ -1,7 +1,9 @@
1
+ import { getContainerLimits } from "./containerLimits.js";
1
2
  export const UNLIMITED_CONCURRENCY = Number.POSITIVE_INFINITY;
2
3
  export const DEFAULT_MAX_ACTIVE_STAGES_PER_RUN = UNLIMITED_CONCURRENCY;
3
4
  export const MAX_ACTIVE_STAGES_PER_RUN_ENV = "STAGEFLOW_MAX_ACTIVE_STAGES_PER_RUN";
4
- export const DEFAULT_MAX_ACTIVE_STAGE_PROCESSES = UNLIMITED_CONCURRENCY;
5
+ /** Fallback when cgroup is absent; finite so waitForCapacity is exercised. */
6
+ export const DEFAULT_MAX_ACTIVE_STAGE_PROCESSES = 4;
5
7
  export const MAX_ACTIVE_STAGE_PROCESSES_ENV = "STAGEFLOW_MAX_ACTIVE_STAGE_PROCESSES";
6
8
  export const STAGE_EXECUTION_ENV = "STAGEFLOW_STAGE_EXECUTION";
7
9
  export function readStageExecutionMode(env = process.env, override) {
@@ -41,7 +43,7 @@ export function readMaxActiveStageProcesses(env = process.env, override) {
41
43
  }
42
44
  const raw = env[MAX_ACTIVE_STAGE_PROCESSES_ENV];
43
45
  if (raw === undefined || raw.trim() === "") {
44
- return DEFAULT_MAX_ACTIVE_STAGE_PROCESSES;
46
+ return getContainerLimits().maxActiveStageProcesses;
45
47
  }
46
48
  const n = Number.parseInt(raw, 10);
47
49
  if (!Number.isFinite(n) || n < 1) {
@@ -0,0 +1,38 @@
1
+ export declare const STAGE_ENV_PASSTHROUGH = "STAGEFLOW_STAGE_ENV_PASSTHROUGH";
2
+ export declare const STAGE_ENV_ALLOW = "STAGEFLOW_STAGE_ENV_ALLOW";
3
+ /** Names copied from Host when present (exact-name allowlist; no prefix wildcards). */
4
+ export declare const STAGE_ENV_ALLOWLIST: readonly string[];
5
+ /** Never grantable — even via secrets `as: env`. */
6
+ export declare const FOREVER_DENIED_SECRET_NAMES: ReadonlySet<string>;
7
+ /** Blocked from ambient / ALLOW / PASSTHROUGH; `as: env` grants may still inject. */
8
+ export declare const AMBIENT_BLOCKED_ENV_NAMES: ReadonlySet<string>;
9
+ /** Full denylist surface for docs and health (union of forever + ambient-blocked). */
10
+ export declare const STAGE_ENV_DENYLIST: readonly string[];
11
+ export type ResolvedStageGrants = {
12
+ env: Record<string, string>;
13
+ registeredSecretNames: readonly string[];
14
+ declaredSecretNames: readonly string[];
15
+ };
16
+ export type BuildStageEnvironmentInput = {
17
+ hostEnv: NodeJS.ProcessEnv;
18
+ runVars?: Record<string, string>;
19
+ cacheVars?: Record<string, string>;
20
+ grants?: ResolvedStageGrants;
21
+ /** Per-attempt empty HOME (KTD7). When set, overrides Host HOME. */
22
+ attemptHome?: string;
23
+ /** Package version for PASSTHROUGH deprecation text. */
24
+ packageVersion?: string;
25
+ };
26
+ export type BuildStageEnvironmentResult = {
27
+ env: Record<string, string>;
28
+ warnings: string[];
29
+ passthroughActive: boolean;
30
+ };
31
+ export declare function isForeverDeniedSecret(name: string): boolean;
32
+ export declare function isAmbientBlockedEnv(name: string): boolean;
33
+ /**
34
+ * Construct the stage child environment. Exact-name allowlist only — never a
35
+ * raw spread of Host env, and never a STAGEFLOW_* prefix passthrough.
36
+ */
37
+ export declare function buildStageEnvironment(input: BuildStageEnvironmentInput): BuildStageEnvironmentResult;
38
+ export declare function envNameSet(env: Record<string, string>): Set<string>;
@@ -0,0 +1,194 @@
1
+ import { SF_STAGE_WORKER } from "./stageWorkerProtocol.js";
2
+ export const STAGE_ENV_PASSTHROUGH = "STAGEFLOW_STAGE_ENV_PASSTHROUGH";
3
+ export const STAGE_ENV_ALLOW = "STAGEFLOW_STAGE_ENV_ALLOW";
4
+ /** Names copied from Host when present (exact-name allowlist; no prefix wildcards). */
5
+ export const STAGE_ENV_ALLOWLIST = [
6
+ "PATH",
7
+ "USER",
8
+ "LOGNAME",
9
+ "SHELL",
10
+ "LANG",
11
+ "LC_ALL",
12
+ "LC_CTYPE",
13
+ "TZ",
14
+ "TERM",
15
+ "TMPDIR",
16
+ "TMP",
17
+ "TEMP",
18
+ "NODE_EXTRA_CA_CERTS",
19
+ "SSL_CERT_FILE",
20
+ "SSL_CERT_DIR",
21
+ "HTTP_PROXY",
22
+ "HTTPS_PROXY",
23
+ "NO_PROXY",
24
+ "http_proxy",
25
+ "https_proxy",
26
+ "no_proxy",
27
+ "STAGEFLOW_HOME",
28
+ "STAGEFLOW_CURSOR_EXTENSION",
29
+ ];
30
+ const PROVIDER_AND_CLOUD_NAMES = [
31
+ "ANTHROPIC_API_KEY",
32
+ "OPENAI_API_KEY",
33
+ "OPENAI_API_KEY_FILE",
34
+ "GOOGLE_API_KEY",
35
+ "GEMINI_API_KEY",
36
+ "GROQ_API_KEY",
37
+ "MISTRAL_API_KEY",
38
+ "DEEPSEEK_API_KEY",
39
+ "TOGETHER_API_KEY",
40
+ "FIREWORKS_API_KEY",
41
+ "PERPLEXITY_API_KEY",
42
+ "XAI_API_KEY",
43
+ "COHERE_API_KEY",
44
+ "OPENROUTER_API_KEY",
45
+ "AZURE_OPENAI_API_KEY",
46
+ "AWS_ACCESS_KEY_ID",
47
+ "AWS_SECRET_ACCESS_KEY",
48
+ "AWS_SESSION_TOKEN",
49
+ "AWS_SECURITY_TOKEN",
50
+ "AWS_PROFILE",
51
+ "AWS_DEFAULT_REGION",
52
+ "AWS_REGION",
53
+ "GOOGLE_APPLICATION_CREDENTIALS",
54
+ "GCLOUD_PROJECT",
55
+ "AZURE_CLIENT_SECRET",
56
+ "AZURE_TENANT_ID",
57
+ "AZURE_CLIENT_ID",
58
+ "NPM_TOKEN",
59
+ "NODE_AUTH_TOKEN",
60
+ "SSH_AUTH_SOCK",
61
+ "SSH_AGENT_PID",
62
+ "GITHUB_TOKEN",
63
+ "GH_TOKEN",
64
+ "GITHUB_TOKEN_FILE",
65
+ "GH_TOKEN_FILE",
66
+ ];
67
+ /** Never grantable — even via secrets `as: env`. */
68
+ export const FOREVER_DENIED_SECRET_NAMES = new Set([
69
+ "STAGEFLOW_CONTROL_TOKEN",
70
+ "STAGEFLOW_CONTROL_TOKEN_FILE",
71
+ "STAGEFLOW_READ_TOKEN",
72
+ "STAGEFLOW_READ_TOKEN_FILE",
73
+ ]);
74
+ /** Blocked from ambient / ALLOW / PASSTHROUGH; `as: env` grants may still inject. */
75
+ export const AMBIENT_BLOCKED_ENV_NAMES = new Set([
76
+ ...FOREVER_DENIED_SECRET_NAMES,
77
+ ...PROVIDER_AND_CLOUD_NAMES,
78
+ ]);
79
+ /** Full denylist surface for docs and health (union of forever + ambient-blocked). */
80
+ export const STAGE_ENV_DENYLIST = [
81
+ ...FOREVER_DENIED_SECRET_NAMES,
82
+ ...PROVIDER_AND_CLOUD_NAMES,
83
+ ];
84
+ function copyDefined(out, hostEnv, names) {
85
+ for (const name of names) {
86
+ const value = hostEnv[name];
87
+ if (value !== undefined && value !== "") {
88
+ out[name] = value;
89
+ }
90
+ }
91
+ }
92
+ export function isForeverDeniedSecret(name) {
93
+ if (FOREVER_DENIED_SECRET_NAMES.has(name))
94
+ return true;
95
+ return name.startsWith("STAGEFLOW_CONTROL_TOKEN_");
96
+ }
97
+ export function isAmbientBlockedEnv(name) {
98
+ return isForeverDeniedSecret(name) || AMBIENT_BLOCKED_ENV_NAMES.has(name);
99
+ }
100
+ function stripForeverDenied(env) {
101
+ const out = {};
102
+ for (const [key, value] of Object.entries(env)) {
103
+ if (value === undefined)
104
+ continue;
105
+ if (isForeverDeniedSecret(key))
106
+ continue;
107
+ out[key] = value;
108
+ }
109
+ return out;
110
+ }
111
+ function parseAllowList(raw) {
112
+ if (raw === undefined || raw.trim() === "")
113
+ return [];
114
+ return raw
115
+ .split(",")
116
+ .map((s) => s.trim())
117
+ .filter((s) => s.length > 0);
118
+ }
119
+ function passthroughDeprecationTarget(version) {
120
+ const parts = version.split(".").map((p) => Number.parseInt(p, 10));
121
+ const major = Number.isFinite(parts[0]) ? parts[0] : 0;
122
+ const minor = Number.isFinite(parts[1]) ? parts[1] : 0;
123
+ return `${major}.${minor + 2}.0`;
124
+ }
125
+ /**
126
+ * Construct the stage child environment. Exact-name allowlist only — never a
127
+ * raw spread of Host env, and never a STAGEFLOW_* prefix passthrough.
128
+ */
129
+ export function buildStageEnvironment(input) {
130
+ const hostEnv = input.hostEnv;
131
+ const warnings = [];
132
+ const grants = input.grants ?? {
133
+ env: {},
134
+ registeredSecretNames: [],
135
+ declaredSecretNames: [],
136
+ };
137
+ const declared = new Set(grants.declaredSecretNames);
138
+ const registered = new Set(grants.registeredSecretNames);
139
+ const env = {};
140
+ copyDefined(env, hostEnv, STAGE_ENV_ALLOWLIST);
141
+ if (input.cacheVars) {
142
+ Object.assign(env, input.cacheVars);
143
+ }
144
+ if (input.runVars) {
145
+ Object.assign(env, input.runVars);
146
+ }
147
+ const allowNames = parseAllowList(hostEnv[STAGE_ENV_ALLOW]);
148
+ for (const name of allowNames) {
149
+ if (AMBIENT_BLOCKED_ENV_NAMES.has(name))
150
+ continue;
151
+ const value = hostEnv[name];
152
+ if (value !== undefined) {
153
+ env[name] = value;
154
+ }
155
+ }
156
+ const passthroughRaw = hostEnv[STAGE_ENV_PASSTHROUGH]?.trim();
157
+ const passthroughActive = passthroughRaw === "all";
158
+ if (passthroughActive) {
159
+ const version = input.packageVersion ?? "0.24.0";
160
+ const removeBy = passthroughDeprecationTarget(version);
161
+ warnings.push(`${STAGE_ENV_PASSTHROUGH}=all is deprecated and will be removed in ${removeBy}; prefer ${STAGE_ENV_ALLOW} or stage secrets:`);
162
+ for (const [key, value] of Object.entries(hostEnv)) {
163
+ if (value === undefined)
164
+ continue;
165
+ if (AMBIENT_BLOCKED_ENV_NAMES.has(key))
166
+ continue;
167
+ if (registered.has(key) && !declared.has(key))
168
+ continue;
169
+ if (key.endsWith("_FILE") &&
170
+ registered.has(key.slice(0, -"_FILE".length)) &&
171
+ !declared.has(key.slice(0, -"_FILE".length))) {
172
+ continue;
173
+ }
174
+ if (Object.hasOwn(env, key))
175
+ continue;
176
+ env[key] = value;
177
+ }
178
+ }
179
+ // Grants after ambient so explicit `as: env` can inject ambient-blocked names
180
+ // (e.g. GITHUB_TOKEN). Forever-denied names are stripped below.
181
+ Object.assign(env, grants.env);
182
+ if (input.attemptHome !== undefined) {
183
+ env.HOME = input.attemptHome;
184
+ }
185
+ env[SF_STAGE_WORKER] = "1";
186
+ return {
187
+ env: stripForeverDenied(env),
188
+ warnings,
189
+ passthroughActive,
190
+ };
191
+ }
192
+ export function envNameSet(env) {
193
+ return new Set(Object.keys(env));
194
+ }
@@ -4,6 +4,7 @@ import { type StageAttemptContext } from "./stageAttemptContext.js";
4
4
  import { type AskOperatorPrompt } from "../tools/askOperator.js";
5
5
  export type DeliverAnswerResult = {
6
6
  ok: true;
7
+ verification?: "failed_retrying";
7
8
  } | {
8
9
  ok: false;
9
10
  reason: string;