stageflow 0.25.0 → 0.27.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 (501) hide show
  1. package/README.md +10 -3
  2. package/dist/a2a/contracts.d.ts +1 -0
  3. package/dist/a2a/contracts.js +1 -0
  4. package/dist/a2a/registry.d.ts +2 -0
  5. package/dist/a2a/registry.js +20 -1
  6. package/dist/a2a/server.d.ts +7 -0
  7. package/dist/a2a/server.js +5 -2
  8. package/dist/a2a/service.d.ts +1 -1
  9. package/dist/a2a/service.js +57 -8
  10. package/dist/a2a/store.d.ts +8 -5
  11. package/dist/a2a/store.js +24 -67
  12. package/dist/agent/activity.d.ts +3 -0
  13. package/dist/agent/bootProviderConfig.d.ts +21 -0
  14. package/dist/agent/bootProviderConfig.js +74 -0
  15. package/dist/agent/piAdapter.d.ts +9 -1
  16. package/dist/agent/piAdapter.js +58 -3
  17. package/dist/agent/piIsolatedMcp.d.ts +2 -0
  18. package/dist/agent/piIsolatedMcp.js +10 -2
  19. package/dist/agent/port.d.ts +6 -0
  20. package/dist/agent/streamLogRedact.d.ts +1 -1
  21. package/dist/agent/streamLogRedact.js +4 -11
  22. package/dist/cli/artifactCommand.js +9 -16
  23. package/dist/cli/backupCommand.d.ts +9 -0
  24. package/dist/cli/backupCommand.js +111 -0
  25. package/dist/cli/debugRunCommand.d.ts +10 -0
  26. package/dist/cli/debugRunCommand.js +109 -0
  27. package/dist/cli/doctorCommand.d.ts +32 -0
  28. package/dist/cli/doctorCommand.js +453 -0
  29. package/dist/cli/envelopeCommand.js +9 -2
  30. package/dist/cli/exportAllCommand.d.ts +55 -0
  31. package/dist/cli/exportAllCommand.js +218 -0
  32. package/dist/cli/exportRunCommand.js +23 -21
  33. package/dist/cli/hostClient.d.ts +21 -3
  34. package/dist/cli/hostClient.js +93 -12
  35. package/dist/cli/initTemplates.d.ts +1 -1
  36. package/dist/cli/initTemplates.js +8 -1
  37. package/dist/cli/resolveSafeOutPath.d.ts +2 -0
  38. package/dist/cli/resolveSafeOutPath.js +40 -0
  39. package/dist/cli/restoreCommand.d.ts +10 -0
  40. package/dist/cli/restoreCommand.js +90 -0
  41. package/dist/cli/runCommand.d.ts +3 -2
  42. package/dist/cli/runCommand.js +93 -11
  43. package/dist/cli/runOutput.d.ts +4 -0
  44. package/dist/cli/runOutput.js +33 -7
  45. package/dist/cli/runStageCommand.d.ts +1 -0
  46. package/dist/cli/runStageCommand.js +44 -25
  47. package/dist/cli/runsCommand.d.ts +1 -1
  48. package/dist/cli/runsCommand.js +162 -8
  49. package/dist/cli.js +171 -30
  50. package/dist/config/catalogRelativePath.d.ts +62 -0
  51. package/dist/config/catalogRelativePath.js +118 -0
  52. package/dist/config/configOrigin.d.ts +27 -0
  53. package/dist/config/configOrigin.js +59 -0
  54. package/dist/config/hostConfig.d.ts +55 -0
  55. package/dist/config/hostConfig.js +333 -0
  56. package/dist/config/listSkills.d.ts +26 -0
  57. package/dist/config/listSkills.js +190 -3
  58. package/dist/config/loadOutcome.d.ts +1 -1
  59. package/dist/config/loadPipeline.js +23 -2
  60. package/dist/config/loadStage.js +18 -0
  61. package/dist/config/loadTask.d.ts +2 -0
  62. package/dist/config/loadTask.js +57 -18
  63. package/dist/config/materializeStageModels.js +5 -1
  64. package/dist/config/mergePipelineIncludes.d.ts +3 -0
  65. package/dist/config/mergePipelineIncludes.js +19 -0
  66. package/dist/config/migrateYaml.js +6 -11
  67. package/dist/config/multiProjectCatalog.d.ts +30 -0
  68. package/dist/config/multiProjectCatalog.js +142 -0
  69. package/dist/config/normalizePipelineStageEntry.js +20 -1
  70. package/dist/config/pipelineStageKeys.js +2 -0
  71. package/dist/config/resolveCatalogRoots.d.ts +27 -0
  72. package/dist/config/resolveCatalogRoots.js +76 -0
  73. package/dist/config/resolveModel.d.ts +7 -1
  74. package/dist/config/resolveModel.js +11 -1
  75. package/dist/config/resolveStageMcpServers.d.ts +9 -1
  76. package/dist/config/resolveStageMcpServers.js +36 -9
  77. package/dist/config/secretFromEnvOrFile.d.ts +9 -0
  78. package/dist/config/secretFromEnvOrFile.js +34 -0
  79. package/dist/config/seededCatalog.d.ts +11 -0
  80. package/dist/config/seededCatalog.js +29 -0
  81. package/dist/config/toolRequires.d.ts +24 -0
  82. package/dist/config/toolRequires.js +115 -0
  83. package/dist/config/validateCatalog.d.ts +5 -1
  84. package/dist/config/validateCatalog.js +140 -1
  85. package/dist/diagnostics/checks.d.ts +39 -0
  86. package/dist/diagnostics/checks.js +135 -0
  87. package/dist/errors/codes.d.ts +14 -0
  88. package/dist/errors/codes.js +59 -0
  89. package/dist/git/cache.d.ts +14 -0
  90. package/dist/git/cache.js +150 -0
  91. package/dist/git/credentials.d.ts +9 -0
  92. package/dist/git/credentials.js +88 -0
  93. package/dist/git/errors.d.ts +20 -0
  94. package/dist/git/errors.js +94 -0
  95. package/dist/git/exec.d.ts +16 -0
  96. package/dist/git/exec.js +135 -0
  97. package/dist/git/operations.d.ts +29 -0
  98. package/dist/git/operations.js +153 -0
  99. package/dist/git/version.d.ts +1 -0
  100. package/dist/git/version.js +10 -0
  101. package/dist/logging/audit.d.ts +16 -0
  102. package/dist/logging/audit.js +19 -0
  103. package/dist/logging/commonWords.d.ts +2 -0
  104. package/dist/logging/commonWords.js +13 -0
  105. package/dist/logging/logger.d.ts +49 -0
  106. package/dist/logging/logger.js +193 -0
  107. package/dist/logging/namedSecrets.d.ts +6 -0
  108. package/dist/logging/namedSecrets.js +58 -0
  109. package/dist/logging/redact.d.ts +13 -0
  110. package/dist/logging/redact.js +88 -0
  111. package/dist/mcp/catalogTools.js +456 -80
  112. package/dist/mcp/checkoutTools.d.ts +52 -0
  113. package/dist/mcp/checkoutTools.js +332 -0
  114. package/dist/mcp/controlTools.js +179 -5
  115. package/dist/mcp/deps.d.ts +1 -0
  116. package/dist/mcp/getStartedTool.d.ts +3 -0
  117. package/dist/mcp/getStartedTool.js +62 -0
  118. package/dist/mcp/readArtifact.d.ts +11 -0
  119. package/dist/mcp/readArtifact.js +46 -30
  120. package/dist/mcp/server.js +1 -0
  121. package/dist/mcp/tools.js +4 -0
  122. package/dist/net/proxy.d.ts +14 -0
  123. package/dist/net/proxy.js +78 -0
  124. package/dist/package-meta.d.ts +2 -1
  125. package/dist/package-meta.js +2 -1
  126. package/dist/preflight/bash.d.ts +8 -0
  127. package/dist/preflight/bash.js +34 -0
  128. package/dist/preflight/claudeRoot.d.ts +11 -0
  129. package/dist/preflight/claudeRoot.js +23 -0
  130. package/dist/preflight/mcpCommands.d.ts +8 -0
  131. package/dist/preflight/mcpCommands.js +36 -0
  132. package/dist/preflight/pipelinePreflight.d.ts +40 -0
  133. package/dist/preflight/pipelinePreflight.js +192 -0
  134. package/dist/preflight/tls.d.ts +6 -0
  135. package/dist/preflight/tls.js +18 -0
  136. package/dist/preflight/toolchain.d.ts +45 -0
  137. package/dist/preflight/toolchain.js +219 -0
  138. package/dist/project/findProjectRoot.js +3 -4
  139. package/dist/project/globalHome.d.ts +7 -0
  140. package/dist/project/globalHome.js +63 -2
  141. package/dist/project/resolveProjectContext.js +2 -2
  142. package/dist/project/resolveStageflowContext.js +2 -2
  143. package/dist/projection/projectRun.d.ts +2 -1
  144. package/dist/projection/projectRun.js +1 -0
  145. package/dist/runstore/assertTmpdir.d.ts +1 -0
  146. package/dist/runstore/assertTmpdir.js +21 -0
  147. package/dist/runstore/backup.d.ts +52 -0
  148. package/dist/runstore/backup.js +292 -0
  149. package/dist/runstore/createStore.d.ts +18 -1
  150. package/dist/runstore/createStore.js +64 -5
  151. package/dist/runstore/debugBundle.d.ts +60 -0
  152. package/dist/runstore/debugBundle.js +143 -0
  153. package/dist/runstore/diskUsage.d.ts +50 -0
  154. package/dist/runstore/diskUsage.js +214 -0
  155. package/dist/runstore/exportRunPayload.d.ts +8 -0
  156. package/dist/runstore/exportRunPayload.js +23 -0
  157. package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
  158. package/dist/runstore/normalizeCatalogPath.js +10 -0
  159. package/dist/runstore/paths.d.ts +5 -0
  160. package/dist/runstore/paths.js +145 -1
  161. package/dist/runstore/port.d.ts +111 -13
  162. package/dist/runstore/port.js +8 -1
  163. package/dist/runstore/restore.d.ts +81 -0
  164. package/dist/runstore/restore.js +355 -0
  165. package/dist/runstore/retention.d.ts +27 -0
  166. package/dist/runstore/retention.js +74 -0
  167. package/dist/runstore/runManifest.d.ts +146 -0
  168. package/dist/runstore/runManifest.js +288 -0
  169. package/dist/runstore/runProjection.d.ts +3 -1
  170. package/dist/runstore/runProjection.js +63 -1
  171. package/dist/runstore/sqlite/SqliteRunStore.d.ts +28 -3
  172. package/dist/runstore/sqlite/SqliteRunStore.js +352 -219
  173. package/dist/runstore/sqlite/applyStorePragmas.d.ts +39 -0
  174. package/dist/runstore/sqlite/applyStorePragmas.js +145 -0
  175. package/dist/runstore/sqlite/migrations/001-baseline.d.ts +7 -0
  176. package/dist/runstore/sqlite/migrations/001-baseline.js +10 -0
  177. package/dist/runstore/sqlite/migrations/002-repository-binding.d.ts +7 -0
  178. package/dist/runstore/sqlite/migrations/002-repository-binding.js +29 -0
  179. package/dist/runstore/sqlite/migrations/003-run-lifecycle.d.ts +7 -0
  180. package/dist/runstore/sqlite/migrations/003-run-lifecycle.js +28 -0
  181. package/dist/runstore/sqlite/migrations/004-auto-resume-count.d.ts +7 -0
  182. package/dist/runstore/sqlite/migrations/004-auto-resume-count.js +19 -0
  183. package/dist/runstore/sqlite/migrations/005-config-origins.d.ts +7 -0
  184. package/dist/runstore/sqlite/migrations/005-config-origins.js +19 -0
  185. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.d.ts +7 -0
  186. package/dist/runstore/sqlite/migrations/006-pipeline-body-and-caller.js +28 -0
  187. package/dist/runstore/sqlite/migrations/007-projects-registry.d.ts +7 -0
  188. package/dist/runstore/sqlite/migrations/007-projects-registry.js +31 -0
  189. package/dist/runstore/sqlite/migrations/index.d.ts +21 -0
  190. package/dist/runstore/sqlite/migrations/index.js +72 -0
  191. package/dist/runstore/sqlite/schema.d.ts +20 -1
  192. package/dist/runstore/sqlite/schema.js +277 -1
  193. package/dist/runstore/sqlite/storeOpenError.d.ts +6 -0
  194. package/dist/runstore/sqlite/storeOpenError.js +11 -0
  195. package/dist/runstore/sqlite/storeSchemaError.d.ts +5 -0
  196. package/dist/runstore/sqlite/storeSchemaError.js +8 -0
  197. package/dist/runstore/stageExecution.js +3 -0
  198. package/dist/runstore/storeFilesystem.d.ts +32 -0
  199. package/dist/runstore/storeFilesystem.js +148 -0
  200. package/dist/runstore/trackProjection.js +2 -0
  201. package/dist/runstore/workspaceLayout.d.ts +13 -0
  202. package/dist/runstore/workspaceLayout.js +76 -0
  203. package/dist/runtime/completionCheckRunner.d.ts +3 -0
  204. package/dist/runtime/completionCheckRunner.js +45 -7
  205. package/dist/runtime/containerLimits.d.ts +16 -0
  206. package/dist/runtime/containerLimits.js +84 -0
  207. package/dist/runtime/credentialMaterialisation.d.ts +28 -0
  208. package/dist/runtime/credentialMaterialisation.js +128 -0
  209. package/dist/runtime/gitCheckoutCapability.js +7 -13
  210. package/dist/runtime/pipelineRunner.d.ts +36 -1
  211. package/dist/runtime/pipelineRunner.js +178 -17
  212. package/dist/runtime/pipelineScheduler.d.ts +15 -0
  213. package/dist/runtime/pipelineScheduler.js +135 -27
  214. package/dist/runtime/reloadRunCatalog.js +6 -1
  215. package/dist/runtime/repositoryMaterialize.d.ts +47 -0
  216. package/dist/runtime/repositoryMaterialize.js +235 -0
  217. package/dist/runtime/resumeTimedOut.d.ts +1 -1
  218. package/dist/runtime/resumeTimedOut.js +5 -2
  219. package/dist/runtime/runChangeBus.js +9 -0
  220. package/dist/runtime/runDeletion.d.ts +7 -0
  221. package/dist/runtime/runDeletion.js +37 -0
  222. package/dist/runtime/runManager.d.ts +158 -4
  223. package/dist/runtime/runManager.js +1596 -79
  224. package/dist/runtime/runRetentionSweep.d.ts +31 -0
  225. package/dist/runtime/runRetentionSweep.js +328 -0
  226. package/dist/runtime/runRetryCoordinator.d.ts +2 -0
  227. package/dist/runtime/runRetryCoordinator.js +19 -2
  228. package/dist/runtime/runSkills.d.ts +40 -0
  229. package/dist/runtime/runSkills.js +173 -0
  230. package/dist/runtime/stageAttemptBootstrap.d.ts +5 -1
  231. package/dist/runtime/stageAttemptBootstrap.js +195 -24
  232. package/dist/runtime/stageCacheEnv.d.ts +6 -0
  233. package/dist/runtime/stageCacheEnv.js +34 -0
  234. package/dist/runtime/stageConcurrency.d.ts +2 -1
  235. package/dist/runtime/stageConcurrency.js +4 -2
  236. package/dist/runtime/stageEnvironment.d.ts +38 -0
  237. package/dist/runtime/stageEnvironment.js +193 -0
  238. package/dist/runtime/stageProcessLauncher.d.ts +18 -0
  239. package/dist/runtime/stageProcessLauncher.js +194 -38
  240. package/dist/runtime/stageRecovery.d.ts +3 -1
  241. package/dist/runtime/stageRecovery.js +19 -4
  242. package/dist/runtime/stageRoots.d.ts +38 -1
  243. package/dist/runtime/stageRoots.js +118 -0
  244. package/dist/runtime/stageRunner.d.ts +1 -0
  245. package/dist/runtime/stageRunner.js +3 -1
  246. package/dist/runtime/stageSecretDecl.d.ts +9 -0
  247. package/dist/runtime/stageSecretDecl.js +102 -0
  248. package/dist/runtime/stageSecrets.d.ts +40 -0
  249. package/dist/runtime/stageSecrets.js +181 -0
  250. package/dist/runtime/stageWorker.d.ts +3 -2
  251. package/dist/runtime/stageWorker.js +58 -10
  252. package/dist/runtime/stageWorkerProtocol.d.ts +5 -0
  253. package/dist/runtime/stageWorkerProtocol.js +8 -0
  254. package/dist/runtime/startPayload.d.ts +32 -0
  255. package/dist/runtime/startPayload.js +59 -0
  256. package/dist/runtime/taskInput.js +14 -5
  257. package/dist/runtime/verifiedStageExecution.d.ts +1 -0
  258. package/dist/runtime/verifiedStageExecution.js +2 -1
  259. package/dist/runtime/workspaceBinding.d.ts +20 -0
  260. package/dist/runtime/workspaceBinding.js +60 -0
  261. package/dist/server/allowedHosts.d.ts +19 -0
  262. package/dist/server/allowedHosts.js +179 -0
  263. package/dist/server/bootstrap.d.ts +36 -2
  264. package/dist/server/bootstrap.js +209 -5
  265. package/dist/server/controlToken.d.ts +47 -0
  266. package/dist/server/controlToken.js +241 -0
  267. package/dist/server/createHttpHost.d.ts +11 -2
  268. package/dist/server/createHttpHost.js +103 -10
  269. package/dist/server/ensureGlobalService.d.ts +5 -1
  270. package/dist/server/ensureGlobalService.js +35 -1
  271. package/dist/server/healthSurfaces.d.ts +6 -0
  272. package/dist/server/healthSurfaces.js +98 -0
  273. package/dist/server/http.d.ts +12 -1
  274. package/dist/server/http.js +1085 -485
  275. package/dist/server/listenHost.d.ts +5 -0
  276. package/dist/server/listenHost.js +56 -0
  277. package/dist/server/mcpHost.d.ts +10 -1
  278. package/dist/server/mcpHost.js +36 -6
  279. package/dist/server/operatorResults.d.ts +2 -2
  280. package/dist/server/operatorResults.js +40 -29
  281. package/dist/server/requestAuthContext.d.ts +12 -0
  282. package/dist/server/requestAuthContext.js +21 -0
  283. package/dist/server/shutdown.d.ts +69 -0
  284. package/dist/server/shutdown.js +219 -0
  285. package/dist/types/pipeline.d.ts +7 -0
  286. package/dist/types/stage.d.ts +8 -0
  287. package/dist/types/task.d.ts +8 -0
  288. package/dist/ui/assets/index-B6hlSXXn.js +120 -0
  289. package/dist/ui/index.html +1 -1
  290. package/examples/README.md +98 -0
  291. package/examples/archify-on-pr/README.md +213 -0
  292. package/examples/archify-on-pr/archify-on-pr.pipeline.yaml +19 -0
  293. package/examples/archify-on-pr/archify-on-pr.task.yaml +19 -0
  294. package/examples/archify-on-pr/author-diagrams.yaml +106 -0
  295. package/examples/archify-on-pr/detect-changes.yaml +89 -0
  296. package/examples/ci-validate/README.md +35 -0
  297. package/examples/ci-validate/check.yaml +13 -0
  298. package/examples/ci-validate/ci-demo.pipeline.yaml +4 -0
  299. package/examples/ci-validate/validate.sh +5 -0
  300. package/examples/compliance-review-demo/README.md +125 -0
  301. package/examples/compliance-review-demo/compliance-review-demo.pipeline.yaml +29 -0
  302. package/examples/compliance-review-demo/connect-account.yaml +47 -0
  303. package/examples/compliance-review-demo/map-to-control.yaml +123 -0
  304. package/examples/compliance-review-demo/poll-bucket-config.yaml +103 -0
  305. package/examples/compliance-review-demo/publish-report.yaml +79 -0
  306. package/examples/compliance-review-demo/review-verdict.yaml +122 -0
  307. package/examples/compliance-review-demo/run-compliance-check.yaml +96 -0
  308. package/examples/compliance-review-demo/store-evidence.yaml +143 -0
  309. package/examples/conditional-fork/README.md +89 -0
  310. package/examples/conditional-fork/branch-a.yaml +13 -0
  311. package/examples/conditional-fork/branch-b.yaml +13 -0
  312. package/examples/conditional-fork/decide.yaml +35 -0
  313. package/examples/conditional-fork/fork-demo.pipeline.yaml +20 -0
  314. package/examples/conditional-fork/fork-demo.task.yaml +8 -0
  315. package/examples/context7-mcp/README.md +42 -0
  316. package/examples/context7-mcp/context7-mcp.pipeline.yaml +15 -0
  317. package/examples/context7-mcp/context7-mcp.task.yaml +4 -0
  318. package/examples/context7-mcp/fetch-docs.yaml +52 -0
  319. package/examples/context7-mcp/resolve-library.yaml +31 -0
  320. package/examples/context7-mcp/write-brief.yaml +52 -0
  321. package/examples/feature-loop/README.md +104 -0
  322. package/examples/feature-loop/address-feedback.yaml +148 -0
  323. package/examples/feature-loop/align.yaml +116 -0
  324. package/examples/feature-loop/decompose.yaml +86 -0
  325. package/examples/feature-loop/default-model-hierarchy.task.yaml +58 -0
  326. package/examples/feature-loop/feature-loop.pipeline.yaml +140 -0
  327. package/examples/feature-loop/feature-loop.task.yaml +25 -0
  328. package/examples/feature-loop/implement.yaml +128 -0
  329. package/examples/feature-loop/plan.yaml +111 -0
  330. package/examples/feature-loop/publish.yaml +167 -0
  331. package/examples/feature-loop/review.yaml +146 -0
  332. package/examples/feature-loop/verify.yaml +106 -0
  333. package/examples/feedback-loop/README.md +72 -0
  334. package/examples/feedback-loop/VERIFY.md +208 -0
  335. package/examples/feedback-loop/continue-only.task.yaml +4 -0
  336. package/examples/feedback-loop/exhaust-require-continue.task.yaml +6 -0
  337. package/examples/feedback-loop/exhaust-wait-human.task.yaml +11 -0
  338. package/examples/feedback-loop/feedback-loop-wait-human.pipeline.yaml +23 -0
  339. package/examples/feedback-loop/feedback-loop.pipeline.yaml +23 -0
  340. package/examples/feedback-loop/feedback-loop.task.yaml +4 -0
  341. package/examples/feedback-loop/implement.yaml +14 -0
  342. package/examples/feedback-loop/plan.yaml +14 -0
  343. package/examples/feedback-loop/review.yaml +15 -0
  344. package/examples/feedback-loop/send-back-once.task.yaml +6 -0
  345. package/examples/feedback-loop/submit.yaml +12 -0
  346. package/examples/generic-fan-in/README.md +151 -0
  347. package/examples/generic-fan-in/clarify.yaml +18 -0
  348. package/examples/generic-fan-in/generic-fan-in-accepted.pipeline.yaml +19 -0
  349. package/examples/generic-fan-in/generic-fan-in-accepted.task.yaml +8 -0
  350. package/examples/generic-fan-in/generic-fan-in.pipeline.yaml +18 -0
  351. package/examples/generic-fan-in/generic-fan-in.task.yaml +9 -0
  352. package/examples/generic-fan-in/research.yaml +45 -0
  353. package/examples/generic-fan-in/synthesize.yaml +66 -0
  354. package/examples/generic-fan-in/validation.yaml +45 -0
  355. package/examples/github-release/README.md +78 -0
  356. package/examples/github-release/draft-release-notes.yaml +64 -0
  357. package/examples/github-release/github-release.pipeline.yaml +11 -0
  358. package/examples/github-release/github-release.task.yaml +13 -0
  359. package/examples/github-release/publish-github-release.yaml +64 -0
  360. package/examples/hello-world/README.md +28 -0
  361. package/examples/hello-world/hello.pipeline.yaml +4 -0
  362. package/examples/hello-world/my-task.task.yaml +6 -0
  363. package/examples/hello-world/research.yaml +18 -0
  364. package/examples/mcp-hitl-tour/README.md +113 -0
  365. package/examples/mcp-hitl-tour/draft-angle.yaml +33 -0
  366. package/examples/mcp-hitl-tour/draft-short.yaml +32 -0
  367. package/examples/mcp-hitl-tour/emit-angles.yaml +45 -0
  368. package/examples/mcp-hitl-tour/gather.yaml +31 -0
  369. package/examples/mcp-hitl-tour/intake.yaml +62 -0
  370. package/examples/mcp-hitl-tour/mcp-hitl-tour-exhaust.task.yaml +13 -0
  371. package/examples/mcp-hitl-tour/mcp-hitl-tour.pipeline.yaml +54 -0
  372. package/examples/mcp-hitl-tour/mcp-hitl-tour.task.yaml +16 -0
  373. package/examples/mcp-hitl-tour/polish.yaml +33 -0
  374. package/examples/mcp-hitl-tour/review.yaml +17 -0
  375. package/examples/mcp-hitl-tour/ship.yaml +25 -0
  376. package/examples/oss-issue-contribution/README.md +218 -0
  377. package/examples/oss-issue-contribution/oss-address-review-feedback.yaml +117 -0
  378. package/examples/oss-issue-contribution/oss-approve-contribution.yaml +181 -0
  379. package/examples/oss-issue-contribution/oss-approve-plan.yaml +111 -0
  380. package/examples/oss-issue-contribution/oss-explain-fix.yaml +108 -0
  381. package/examples/oss-issue-contribution/oss-explain-issue.yaml +114 -0
  382. package/examples/oss-issue-contribution/oss-implement-source-fix.yaml +171 -0
  383. package/examples/oss-issue-contribution/oss-investigate-area.yaml +116 -0
  384. package/examples/oss-issue-contribution/oss-issue-contribution.pipeline.yaml +125 -0
  385. package/examples/oss-issue-contribution/oss-issue-intake.yaml +106 -0
  386. package/examples/oss-issue-contribution/oss-plan-investigation.yaml +112 -0
  387. package/examples/oss-issue-contribution/oss-plan-review.yaml +109 -0
  388. package/examples/oss-issue-contribution/oss-reproduce-issue.yaml +140 -0
  389. package/examples/oss-issue-contribution/oss-review-change.yaml +107 -0
  390. package/examples/oss-issue-contribution/oss-verify-fix.yaml +130 -0
  391. package/examples/oss-issue-contribution/oss-write-regression-test.yaml +135 -0
  392. package/examples/oss-issue-contribution/pi-7629.task.yaml +79 -0
  393. package/examples/oss-issue-contribution/pi-8919.task.yaml +75 -0
  394. package/examples/oss-issue-contribution/pydantic-ai-7971.task.yaml +53 -0
  395. package/examples/oss-quick-fix/README.md +65 -0
  396. package/examples/oss-quick-fix/implement-fix.yaml +84 -0
  397. package/examples/oss-quick-fix/oss-quick-fix.pipeline.yaml +35 -0
  398. package/examples/oss-quick-fix/oss-quick-fix.task.yaml +19 -0
  399. package/examples/oss-quick-fix/ship-fix.yaml +81 -0
  400. package/examples/oss-quick-fix/understand-issue.yaml +67 -0
  401. package/examples/oss-quick-fix/verify-fix.yaml +73 -0
  402. package/examples/plan-review/README.md +37 -0
  403. package/examples/plan-review/plan-review-followup.yaml +13 -0
  404. package/examples/plan-review/plan-review.pipeline.yaml +9 -0
  405. package/examples/plan-review/plan-review.task.yaml +9 -0
  406. package/examples/plan-review/plan-review.yaml +25 -0
  407. package/examples/playwright-mcp/README.md +39 -0
  408. package/examples/playwright-mcp/playwright-mcp.pipeline.yaml +5 -0
  409. package/examples/playwright-mcp/playwright-mcp.task.yaml +4 -0
  410. package/examples/playwright-mcp/screenshot.yaml +40 -0
  411. package/examples/retry-tour/README.md +75 -0
  412. package/examples/retry-tour/retry-tour.pipeline.yaml +122 -0
  413. package/examples/retry-tour/retry-tour.task.yaml +9 -0
  414. package/examples/route-if-tour/README.md +202 -0
  415. package/examples/route-if-tour/route-if-tour.pipeline.yaml +950 -0
  416. package/examples/route-if-tour/route-if-tour.task.yaml +4 -0
  417. package/examples/route-wiring-smoke-test/01-core-routing.pipeline.yaml +168 -0
  418. package/examples/route-wiring-smoke-test/02-on-gating.pipeline.yaml +44 -0
  419. package/examples/route-wiring-smoke-test/03-two-entry-points.pipeline.yaml +28 -0
  420. package/examples/route-wiring-smoke-test/04-entry-false-equivalent-to-omitted.pipeline.yaml +27 -0
  421. package/examples/route-wiring-smoke-test/05-fork-choice.pipeline.yaml +110 -0
  422. package/examples/route-wiring-smoke-test/06-fan-out-fan-in.pipeline.yaml +82 -0
  423. package/examples/route-wiring-smoke-test/07-loop-human-decision.pipeline.yaml +82 -0
  424. package/examples/route-wiring-smoke-test/08-skip-fallback-and-multi-on-gate.pipeline.yaml +77 -0
  425. package/examples/route-wiring-smoke-test/09-multi-loop-targets.pipeline.yaml +102 -0
  426. package/examples/route-wiring-smoke-test/10-uses-dialect-fork.pipeline.yaml +23 -0
  427. package/examples/route-wiring-smoke-test/11-sequential-io-handoff.pipeline.yaml +37 -0
  428. package/examples/route-wiring-smoke-test/12-complex-io-schemas.pipeline.yaml +138 -0
  429. package/examples/route-wiring-smoke-test/13-ref-io-handoff.pipeline.yaml +84 -0
  430. package/examples/route-wiring-smoke-test/14-if-eq-gating.pipeline.yaml +50 -0
  431. package/examples/route-wiring-smoke-test/15-if-all-gated.pipeline.yaml +37 -0
  432. package/examples/route-wiring-smoke-test/16-if-composition.pipeline.yaml +65 -0
  433. package/examples/route-wiring-smoke-test/17-if-join.pipeline.yaml +80 -0
  434. package/examples/route-wiring-smoke-test/README.md +377 -0
  435. package/examples/route-wiring-smoke-test/rejected/01-reject-legacy-needs.pipeline.yaml +26 -0
  436. package/examples/route-wiring-smoke-test/rejected/02-reject-legacy-fork.pipeline.yaml +25 -0
  437. package/examples/route-wiring-smoke-test/rejected/03-reject-legacy-feedback-loop.pipeline.yaml +30 -0
  438. package/examples/route-wiring-smoke-test/rejected/04-reject-missing-entry.pipeline.yaml +24 -0
  439. package/examples/route-wiring-smoke-test/rejected/05-reject-unreachable.pipeline.yaml +35 -0
  440. package/examples/route-wiring-smoke-test/rejected/06-reject-allow-none-without-route-select.pipeline.yaml +37 -0
  441. package/examples/route-wiring-smoke-test/rejected/07-reject-cycle.pipeline.yaml +27 -0
  442. package/examples/route-wiring-smoke-test/rejected/08-reject-loop-non-ancestor.pipeline.yaml +42 -0
  443. package/examples/route-wiring-smoke-test/rejected/09-reject-route-select-leaf.pipeline.yaml +26 -0
  444. package/examples/route-wiring-smoke-test/rejected/12-reject-loop-replay-unsafe.pipeline.yaml +55 -0
  445. package/examples/route-wiring-smoke-test/rejected/13-reject-multiple-loop-entries.pipeline.yaml +51 -0
  446. package/examples/route-wiring-smoke-test/rejected/14-reject-duplicate-stage-id.pipeline.yaml +35 -0
  447. package/examples/route-wiring-smoke-test/rejected/15-reject-unknown-route-target.pipeline.yaml +15 -0
  448. package/examples/route-wiring-smoke-test/rejected/16-reject-malformed-route-item.pipeline.yaml +15 -0
  449. package/examples/route-wiring-smoke-test/rejected/17-reject-io-incompatible.pipeline.yaml +33 -0
  450. package/examples/route-wiring-smoke-test/rejected/18-reject-nested-io.pipeline.yaml +51 -0
  451. package/examples/route-wiring-smoke-test/rejected/19-reject-array-item-io.pipeline.yaml +55 -0
  452. package/examples/route-wiring-smoke-test/rejected/20-reject-closed-io.pipeline.yaml +36 -0
  453. package/examples/route-wiring-smoke-test/rejected/21-reject-ref-io.pipeline.yaml +42 -0
  454. package/examples/route-wiring-smoke-test/rejected/22-reject-if-unknown-field.pipeline.yaml +33 -0
  455. package/examples/route-wiring-smoke-test/rejected/23-reject-if-optional-field.pipeline.yaml +32 -0
  456. package/examples/route-wiring-smoke-test/rejected/24-reject-if-empty-all.pipeline.yaml +31 -0
  457. package/examples/route-wiring-smoke-test/rejected/25-reject-if-gt-on-string.pipeline.yaml +33 -0
  458. package/examples/route-wiring-smoke-test/rejected/26-reject-if-optional-nested.pipeline.yaml +36 -0
  459. package/examples/route-wiring-smoke-test/rejected/27-reject-if-on-loop.pipeline.yaml +63 -0
  460. package/examples/route-wiring-smoke-test/rejected/29-reject-if-on-failed.pipeline.yaml +46 -0
  461. package/examples/route-wiring-smoke-test/smoke-test.task.yaml +4 -0
  462. package/examples/route-wiring-smoke-test/stages/branch-a.yaml +12 -0
  463. package/examples/route-wiring-smoke-test/stages/branch-b.yaml +12 -0
  464. package/examples/route-wiring-smoke-test/stages/decide.yaml +12 -0
  465. package/examples/route-wiring-smoke-test/stages/finish.yaml +12 -0
  466. package/examples/ship-feature/README.md +190 -0
  467. package/examples/ship-feature/feat-address-feedback.yaml +119 -0
  468. package/examples/ship-feature/feat-implement.yaml +180 -0
  469. package/examples/ship-feature/feat-plan.yaml +120 -0
  470. package/examples/ship-feature/feat-review.yaml +109 -0
  471. package/examples/ship-feature/feat-ship.yaml +203 -0
  472. package/examples/ship-feature/ship-feature.pipeline.yaml +44 -0
  473. package/examples/ship-feature/ship-feature.task.yaml +78 -0
  474. package/examples/stage-mcp/README.md +144 -0
  475. package/examples/stage-mcp/echo-mcp.mjs +20 -0
  476. package/examples/stage-mcp/stage-mcp-dead.pipeline.yaml +5 -0
  477. package/examples/stage-mcp/stage-mcp-dead.task.yaml +3 -0
  478. package/examples/stage-mcp/stage-mcp-missing-var.pipeline.yaml +5 -0
  479. package/examples/stage-mcp/stage-mcp-missing-var.task.yaml +3 -0
  480. package/examples/stage-mcp/stage-mcp.pipeline.yaml +5 -0
  481. package/examples/stage-mcp/stage-mcp.task.yaml +4 -0
  482. package/examples/stage-mcp/use-echo.yaml +20 -0
  483. package/examples/verify-tour/README.md +80 -0
  484. package/examples/verify-tour/verify-tour.pipeline.yaml +162 -0
  485. package/examples/verify-tour/verify-tour.task.yaml +11 -0
  486. package/package.json +5 -1
  487. package/skills/stageflow/SKILL.md +6 -6
  488. package/skills/stageflow/references/control-surface.md +11 -5
  489. package/skills/stageflow/scripts/detect-host.mjs +14 -1
  490. package/skills/stageflow/scripts/detect-host.test.mjs +29 -1
  491. package/skills/stageflow-author/SKILL.md +4 -3
  492. package/skills/stageflow-author/references/catalog-mapping.md +16 -0
  493. package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
  494. package/skills/stageflow-run/SKILL.md +20 -12
  495. package/skills/stageflow-run/references/mcp-call.md +9 -1
  496. package/skills/stageflow-run/references/task-and-pipeline-selection.md +16 -5
  497. package/skills/stageflow-run/scripts/mcp-call.mjs +46 -6
  498. package/skills/stageflow-run/scripts/mcp-call.test.mjs +64 -0
  499. package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -0
  500. package/skills/stageflow-setup/SKILL.md +40 -8
  501. package/dist/ui/assets/index-Da5EHU6M.js +0 -119
@@ -0,0 +1,135 @@
1
+ import { execFile, execFileSync } from "node:child_process";
2
+ import { classifyGitFailure, GitError, redactGitText, } from "./errors.js";
3
+ const DEFAULT_TIMEOUT_MS = 30_000;
4
+ const DEFAULT_MAX_BUFFER = 16 * 1024 * 1024;
5
+ function buildEnv(extra) {
6
+ return {
7
+ ...process.env,
8
+ ...extra,
9
+ GIT_TERMINAL_PROMPT: "0",
10
+ };
11
+ }
12
+ function toErrorMessage(code) {
13
+ switch (code) {
14
+ case "auth_failed":
15
+ return "git authentication failed";
16
+ case "ref_not_found":
17
+ return "git ref not found";
18
+ case "repo_not_found":
19
+ return "git repository not found";
20
+ case "network":
21
+ return "git network error";
22
+ case "disk_full":
23
+ return "git disk full";
24
+ case "git_missing":
25
+ return "git binary not found";
26
+ case "timeout":
27
+ return "git command timed out";
28
+ default:
29
+ return "git command failed";
30
+ }
31
+ }
32
+ function fail(options) {
33
+ const stderr = redactGitText(options.stderrRaw, options.env);
34
+ const code = classifyGitFailure({
35
+ stderr: options.stderrRaw,
36
+ exitCode: options.exitCode,
37
+ errno: options.errno,
38
+ timedOut: options.timedOut,
39
+ });
40
+ throw new GitError(toErrorMessage(code), {
41
+ code,
42
+ argv: options.argv,
43
+ stderr,
44
+ exitCode: options.exitCode,
45
+ });
46
+ }
47
+ function normalizeStderr(stderr) {
48
+ if (Buffer.isBuffer(stderr))
49
+ return stderr.toString("utf8").trim();
50
+ if (typeof stderr === "string")
51
+ return stderr.trim();
52
+ return "";
53
+ }
54
+ export function runGitSync(options) {
55
+ const gitBin = options.gitBin ?? "git";
56
+ const argv = [gitBin, ...options.args];
57
+ const env = buildEnv(options.env);
58
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
59
+ try {
60
+ const stdout = execFileSync(gitBin, options.args, {
61
+ cwd: options.cwd,
62
+ env,
63
+ encoding: "utf8",
64
+ timeout: timeoutMs,
65
+ maxBuffer: options.maxBuffer ?? DEFAULT_MAX_BUFFER,
66
+ stdio: ["ignore", "pipe", "pipe"],
67
+ });
68
+ return { stdout, stderr: "", exitCode: 0 };
69
+ }
70
+ catch (error) {
71
+ const err = error;
72
+ const timedOut = err.killed === true ||
73
+ err.signal === "SIGTERM" ||
74
+ (typeof err.message === "string" && /TIMEDOUT|timed out/i.test(err.message));
75
+ fail({
76
+ argv,
77
+ stderrRaw: normalizeStderr(err.stderr) || (timedOut ? "git command timed out" : err.message),
78
+ exitCode: typeof err.status === "number" ? err.status : null,
79
+ errno: err.code ?? null,
80
+ timedOut,
81
+ env,
82
+ });
83
+ }
84
+ }
85
+ export function runGit(options) {
86
+ const gitBin = options.gitBin ?? "git";
87
+ const argv = [gitBin, ...options.args];
88
+ const env = buildEnv(options.env);
89
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
90
+ return new Promise((resolve, reject) => {
91
+ execFile(gitBin, options.args, {
92
+ cwd: options.cwd,
93
+ env,
94
+ encoding: "utf8",
95
+ timeout: timeoutMs,
96
+ maxBuffer: options.maxBuffer ?? DEFAULT_MAX_BUFFER,
97
+ signal: options.signal,
98
+ killSignal: "SIGTERM",
99
+ }, (error, stdout, stderr) => {
100
+ if (!error) {
101
+ resolve({
102
+ stdout: typeof stdout === "string" ? stdout : String(stdout ?? ""),
103
+ stderr: normalizeStderr(stderr),
104
+ exitCode: 0,
105
+ });
106
+ return;
107
+ }
108
+ const err = error;
109
+ const timedOut = err.killed === true ||
110
+ err.signal === "SIGTERM" ||
111
+ err.code === "ETIMEDOUT" ||
112
+ (typeof err.message === "string" && /TIMEDOUT|timed out/i.test(err.message));
113
+ const errno = typeof err.code === "string" ? err.code : null;
114
+ const exitCode = typeof err.status === "number"
115
+ ? err.status
116
+ : typeof err.code === "number"
117
+ ? err.code
118
+ : null;
119
+ try {
120
+ fail({
121
+ argv,
122
+ stderrRaw: normalizeStderr(stderr) ||
123
+ (timedOut ? "git command timed out" : err.message),
124
+ exitCode,
125
+ errno,
126
+ timedOut,
127
+ env,
128
+ });
129
+ }
130
+ catch (gitError) {
131
+ reject(gitError);
132
+ }
133
+ });
134
+ });
135
+ }
@@ -0,0 +1,29 @@
1
+ export type GitCallOptions = {
2
+ env?: NodeJS.ProcessEnv;
3
+ gitBin?: string;
4
+ signal?: AbortSignal;
5
+ };
6
+ export declare const BARE_ORIGIN_FETCH_HEADS = "+refs/heads/*:refs/remotes/origin/*";
7
+ export declare const BARE_ORIGIN_FETCH_TAGS = "+refs/tags/*:refs/tags/*";
8
+ export declare function configureBareOriginFetch(repoDir: string, opts?: GitCallOptions): Promise<void>;
9
+ export declare function pruneNonStageflowLocalHeads(repoDir: string, opts?: GitCallOptions): Promise<void>;
10
+ export declare function cloneBare(url: string, dest: string, opts?: GitCallOptions): Promise<void>;
11
+ export declare function fetch(repoDir: string, refspecs?: string[], opts?: GitCallOptions): Promise<void>;
12
+ export declare function remoteUpdate(repoDir: string, opts?: GitCallOptions): Promise<void>;
13
+ export declare function resolveRef(repoDir: string, ref: string, opts?: GitCallOptions): Promise<string>;
14
+ export declare function catFileCommit(repoDir: string, sha: string, opts?: GitCallOptions): Promise<boolean>;
15
+ export declare function worktreeAdd(repoDir: string, input: {
16
+ worktreePath: string;
17
+ branch: string;
18
+ startPoint: string;
19
+ }, opts?: GitCallOptions): Promise<void>;
20
+ export declare function worktreeRemove(repoDir: string, worktreePath: string, opts?: GitCallOptions): Promise<void>;
21
+ export declare function worktreePrune(repoDir: string, opts?: GitCallOptions): Promise<void>;
22
+ export declare function deleteBranch(repoDir: string, branch: string, opts?: GitCallOptions): Promise<void>;
23
+ export declare function revParse(repoDir: string, args: string[], opts?: GitCallOptions): Promise<string>;
24
+ export declare function diff(repoDir: string, args?: string[], opts?: GitCallOptions): Promise<string>;
25
+ export declare function statusPorcelain(repoDir: string, pathspec?: string, opts?: GitCallOptions): string;
26
+ export declare function statusPorcelainZ(repoDir: string, opts?: GitCallOptions): Promise<string>;
27
+ export declare function lsFilesOthersZ(repoDir: string, opts?: GitCallOptions): Promise<string>;
28
+ export declare function checkRefFormat(branchName: string, opts?: GitCallOptions): Promise<boolean>;
29
+ export declare function revParseSync(cwd: string, args: string[], opts?: GitCallOptions): string;
@@ -0,0 +1,153 @@
1
+ import { GitError } from "./errors.js";
2
+ import { runGit, runGitSync } from "./exec.js";
3
+ const TIMEOUT = {
4
+ resolve: 30_000,
5
+ worktree: 120_000,
6
+ fetch: 300_000,
7
+ clone: 900_000,
8
+ default: 30_000,
9
+ };
10
+ const FULL_SHA_RE = /^[0-9a-f]{40}$/i;
11
+ function baseOpts(cwd, args, timeoutMs, opts) {
12
+ return {
13
+ cwd,
14
+ args,
15
+ timeoutMs,
16
+ env: opts?.env,
17
+ gitBin: opts?.gitBin,
18
+ signal: opts?.signal,
19
+ };
20
+ }
21
+ export const BARE_ORIGIN_FETCH_HEADS = "+refs/heads/*:refs/remotes/origin/*";
22
+ export const BARE_ORIGIN_FETCH_TAGS = "+refs/tags/*:refs/tags/*";
23
+ export async function configureBareOriginFetch(repoDir, opts) {
24
+ try {
25
+ await runGit(baseOpts(repoDir, ["config", "--unset", "remote.origin.mirror"], TIMEOUT.default, opts));
26
+ }
27
+ catch {
28
+ // unset fails when the key is absent
29
+ }
30
+ try {
31
+ await runGit(baseOpts(repoDir, ["config", "--unset-all", "remote.origin.fetch"], TIMEOUT.default, opts));
32
+ }
33
+ catch {
34
+ // unset-all fails when the key is absent
35
+ }
36
+ await runGit(baseOpts(repoDir, ["config", "--add", "remote.origin.fetch", BARE_ORIGIN_FETCH_HEADS], TIMEOUT.default, opts));
37
+ await runGit(baseOpts(repoDir, ["config", "--add", "remote.origin.fetch", BARE_ORIGIN_FETCH_TAGS], TIMEOUT.default, opts));
38
+ }
39
+ export async function pruneNonStageflowLocalHeads(repoDir, opts) {
40
+ const listed = await runGit(baseOpts(repoDir, ["for-each-ref", "--format=%(refname)", "refs/heads/"], TIMEOUT.default, opts));
41
+ const refs = listed.stdout
42
+ .split("\n")
43
+ .map((line) => line.trim())
44
+ .filter((line) => line.length > 0);
45
+ for (const ref of refs) {
46
+ if (ref === "refs/heads/stageflow" || ref.startsWith("refs/heads/stageflow/")) {
47
+ continue;
48
+ }
49
+ try {
50
+ await runGit(baseOpts(repoDir, ["update-ref", "-d", ref], TIMEOUT.default, opts));
51
+ }
52
+ catch {
53
+ // best-effort prune under heal lock
54
+ }
55
+ }
56
+ }
57
+ export async function cloneBare(url, dest, opts) {
58
+ await runGit(baseOpts(undefined, ["clone", "--bare", url, dest], TIMEOUT.clone, opts));
59
+ await configureBareOriginFetch(dest, opts);
60
+ }
61
+ export async function fetch(repoDir, refspecs = [], opts) {
62
+ await runGit(baseOpts(repoDir, ["fetch", "--prune", "origin", ...refspecs], TIMEOUT.fetch, opts));
63
+ }
64
+ export async function remoteUpdate(repoDir, opts) {
65
+ await runGit(baseOpts(repoDir, ["remote", "update", "--prune"], TIMEOUT.fetch, opts));
66
+ }
67
+ async function revParseCommit(repoDir, ref, opts) {
68
+ const result = await runGit(baseOpts(repoDir, ["rev-parse", "--verify", "--end-of-options", `${ref}^{commit}`], TIMEOUT.resolve, opts));
69
+ return result.stdout.trim();
70
+ }
71
+ async function tryRevParseCommit(repoDir, ref, opts) {
72
+ try {
73
+ return await revParseCommit(repoDir, ref, opts);
74
+ }
75
+ catch (err) {
76
+ if (err instanceof GitError && err.code === "ref_not_found") {
77
+ return null;
78
+ }
79
+ throw err;
80
+ }
81
+ }
82
+ export async function resolveRef(repoDir, ref, opts) {
83
+ if (FULL_SHA_RE.test(ref) || ref.startsWith("refs/")) {
84
+ return revParseCommit(repoDir, ref, opts);
85
+ }
86
+ const candidates = [
87
+ `refs/remotes/origin/${ref}`,
88
+ `origin/${ref}`,
89
+ `refs/tags/${ref}`,
90
+ ];
91
+ for (const candidate of candidates) {
92
+ const sha = await tryRevParseCommit(repoDir, candidate, opts);
93
+ if (sha !== null)
94
+ return sha;
95
+ }
96
+ return revParseCommit(repoDir, candidates[0], opts);
97
+ }
98
+ export async function catFileCommit(repoDir, sha, opts) {
99
+ try {
100
+ await runGit(baseOpts(repoDir, ["cat-file", "-e", `${sha}^{commit}`], TIMEOUT.resolve, opts));
101
+ return true;
102
+ }
103
+ catch {
104
+ return false;
105
+ }
106
+ }
107
+ export async function worktreeAdd(repoDir, input, opts) {
108
+ await runGit(baseOpts(repoDir, ["worktree", "add", "-b", input.branch, input.worktreePath, input.startPoint], TIMEOUT.worktree, opts));
109
+ }
110
+ export async function worktreeRemove(repoDir, worktreePath, opts) {
111
+ await runGit(baseOpts(repoDir, ["worktree", "remove", "--force", worktreePath], TIMEOUT.worktree, opts));
112
+ }
113
+ export async function worktreePrune(repoDir, opts) {
114
+ await runGit(baseOpts(repoDir, ["worktree", "prune"], TIMEOUT.worktree, opts));
115
+ }
116
+ export async function deleteBranch(repoDir, branch, opts) {
117
+ await runGit(baseOpts(repoDir, ["branch", "-D", branch], TIMEOUT.default, opts));
118
+ }
119
+ export async function revParse(repoDir, args, opts) {
120
+ const result = await runGit(baseOpts(repoDir, ["rev-parse", ...args], TIMEOUT.resolve, opts));
121
+ return result.stdout.trim();
122
+ }
123
+ export async function diff(repoDir, args = [], opts) {
124
+ const result = await runGit(baseOpts(repoDir, ["diff", ...args], TIMEOUT.default, opts));
125
+ return result.stdout;
126
+ }
127
+ export function statusPorcelain(repoDir, pathspec, opts) {
128
+ const args = ["status", "--porcelain"];
129
+ if (pathspec !== undefined) {
130
+ args.push("--", pathspec);
131
+ }
132
+ return runGitSync(baseOpts(repoDir, args, TIMEOUT.default, opts)).stdout;
133
+ }
134
+ export async function statusPorcelainZ(repoDir, opts) {
135
+ const result = await runGit(baseOpts(repoDir, ["status", "--porcelain=v1", "-z", "--untracked-files=all"], TIMEOUT.default, opts));
136
+ return result.stdout;
137
+ }
138
+ export async function lsFilesOthersZ(repoDir, opts) {
139
+ const result = await runGit(baseOpts(repoDir, ["ls-files", "--others", "--exclude-standard", "-z"], TIMEOUT.default, opts));
140
+ return result.stdout;
141
+ }
142
+ export async function checkRefFormat(branchName, opts) {
143
+ try {
144
+ await runGit(baseOpts(undefined, ["check-ref-format", "--branch", branchName], TIMEOUT.resolve, opts));
145
+ return true;
146
+ }
147
+ catch {
148
+ return false;
149
+ }
150
+ }
151
+ export function revParseSync(cwd, args, opts) {
152
+ return runGitSync(baseOpts(cwd, ["rev-parse", ...args], TIMEOUT.resolve, opts)).stdout.trim();
153
+ }
@@ -0,0 +1 @@
1
+ export declare function gitVersion(gitBin?: string): Promise<string>;
@@ -0,0 +1,10 @@
1
+ import { runGit } from "./exec.js";
2
+ export async function gitVersion(gitBin = "git") {
3
+ const result = await runGit({
4
+ gitBin,
5
+ args: ["version"],
6
+ timeoutMs: 5_000,
7
+ });
8
+ const match = result.stdout.match(/git version\s+(\S+)/i);
9
+ return match?.[1] ?? result.stdout.trim();
10
+ }
@@ -0,0 +1,16 @@
1
+ import type { Logger } from "./logger.js";
2
+ import type { CallerSurface } from "../server/requestAuthContext.js";
3
+ export type AuditOutcome = "ok" | "error";
4
+ export type AuditRecord = {
5
+ caller_id: string | null;
6
+ surface: CallerSurface;
7
+ action: string;
8
+ target_run_id?: string;
9
+ outcome: AuditOutcome;
10
+ error_code?: string;
11
+ };
12
+ /**
13
+ * Append-only mutating-call audit on the Slot 4 JSON logger.
14
+ * Allowlisted fields only — never Authorization, pipeline_body, or skills.
15
+ */
16
+ export declare function writeAudit(log: Logger, record: AuditRecord): void;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Append-only mutating-call audit on the Slot 4 JSON logger.
3
+ * Allowlisted fields only — never Authorization, pipeline_body, or skills.
4
+ */
5
+ export function writeAudit(log, record) {
6
+ const fields = {
7
+ caller_id: record.caller_id,
8
+ surface: record.surface,
9
+ action: record.action,
10
+ outcome: record.outcome,
11
+ };
12
+ if (record.target_run_id !== undefined) {
13
+ fields.target_run_id = record.target_run_id;
14
+ }
15
+ if (record.error_code !== undefined) {
16
+ fields.error_code = record.error_code;
17
+ }
18
+ log.info("audit", `${record.action} ${record.outcome}`, fields);
19
+ }
@@ -0,0 +1,2 @@
1
+ /** Common words that must not be value-redacted even if length ≥ 8. */
2
+ export declare const COMMON_WORDS: ReadonlySet<string>;
@@ -0,0 +1,13 @@
1
+ /** Common words that must not be value-redacted even if length ≥ 8. */
2
+ export const COMMON_WORDS = new Set([
3
+ "password",
4
+ "username",
5
+ "localhost",
6
+ "127.0.0.1",
7
+ "true",
8
+ "false",
9
+ "undefined",
10
+ "development",
11
+ "production",
12
+ "staging",
13
+ ]);
@@ -0,0 +1,49 @@
1
+ export type LogLevel = "debug" | "info" | "warn" | "error";
2
+ export type LogFormat = "json" | "pretty";
3
+ export type LoggerBindings = {
4
+ component?: string;
5
+ run_id?: string;
6
+ stage_id?: string;
7
+ attempt?: number;
8
+ };
9
+ export type LogFields = Record<string, unknown>;
10
+ export type LogRecord = {
11
+ ts: string;
12
+ level: LogLevel;
13
+ event: string;
14
+ msg: string;
15
+ component?: string;
16
+ run_id?: string;
17
+ stage_id?: string;
18
+ attempt?: number;
19
+ truncated?: boolean;
20
+ original_bytes?: number;
21
+ } & LogFields;
22
+ export type Logger = {
23
+ debug(event: string, msg: string, fields?: LogFields): void;
24
+ info(event: string, msg: string, fields?: LogFields): void;
25
+ warn(event: string, msg: string, fields?: LogFields): void;
26
+ error(event: string, msg: string, fields?: LogFields): void;
27
+ child(bindings: LoggerBindings): Logger;
28
+ };
29
+ export declare const LOG_FORMAT_ENV = "STAGEFLOW_LOG_FORMAT";
30
+ export declare const LOG_LEVEL_ENV = "STAGEFLOW_LOG_LEVEL";
31
+ export declare const LOG_MAX_LINE_BYTES_ENV = "STAGEFLOW_LOG_MAX_LINE_BYTES";
32
+ export declare const DEFAULT_LOG_LEVEL: LogLevel;
33
+ export declare const DEFAULT_LOG_MAX_LINE_BYTES = 8192;
34
+ export type CreateLoggerOptions = {
35
+ env?: Record<string, string | undefined>;
36
+ stdoutIsTTY?: boolean;
37
+ format?: LogFormat;
38
+ level?: LogLevel;
39
+ maxLineBytes?: number;
40
+ knownSecrets?: readonly string[];
41
+ bindings?: LoggerBindings;
42
+ write?: (line: string) => void;
43
+ now?: () => Date;
44
+ };
45
+ export declare function resolveLogFormat(env?: Record<string, string | undefined>, stdoutIsTTY?: boolean): LogFormat;
46
+ export declare function resolveLogLevel(env?: Record<string, string | undefined>): LogLevel;
47
+ export declare function resolveLogMaxLineBytes(env?: Record<string, string | undefined>): number;
48
+ export declare function createLogger(options?: CreateLoggerOptions): Logger;
49
+ export declare const logger: Logger;
@@ -0,0 +1,193 @@
1
+ import { redact } from "./redact.js";
2
+ import { getNamedSecrets } from "./namedSecrets.js";
3
+ export const LOG_FORMAT_ENV = "STAGEFLOW_LOG_FORMAT";
4
+ export const LOG_LEVEL_ENV = "STAGEFLOW_LOG_LEVEL";
5
+ export const LOG_MAX_LINE_BYTES_ENV = "STAGEFLOW_LOG_MAX_LINE_BYTES";
6
+ export const DEFAULT_LOG_LEVEL = "info";
7
+ export const DEFAULT_LOG_MAX_LINE_BYTES = 8192;
8
+ const LEVEL_RANK = {
9
+ debug: 10,
10
+ info: 20,
11
+ warn: 30,
12
+ error: 40,
13
+ };
14
+ export function resolveLogFormat(env = process.env, stdoutIsTTY = Boolean(process.stdout.isTTY)) {
15
+ const raw = env[LOG_FORMAT_ENV]?.trim().toLowerCase();
16
+ if (raw === "json" || raw === "pretty")
17
+ return raw;
18
+ return stdoutIsTTY ? "pretty" : "json";
19
+ }
20
+ export function resolveLogLevel(env = process.env) {
21
+ const raw = env[LOG_LEVEL_ENV]?.trim().toLowerCase();
22
+ if (raw === "debug" || raw === "info" || raw === "warn" || raw === "error") {
23
+ return raw;
24
+ }
25
+ return DEFAULT_LOG_LEVEL;
26
+ }
27
+ export function resolveLogMaxLineBytes(env = process.env) {
28
+ const raw = env[LOG_MAX_LINE_BYTES_ENV];
29
+ if (raw === undefined || raw.trim() === "")
30
+ return DEFAULT_LOG_MAX_LINE_BYTES;
31
+ const n = Number.parseInt(raw, 10);
32
+ if (!Number.isFinite(n) || n < 64)
33
+ return DEFAULT_LOG_MAX_LINE_BYTES;
34
+ return n;
35
+ }
36
+ function formatPretty(record) {
37
+ const parts = [
38
+ record.ts,
39
+ record.level.toUpperCase(),
40
+ record.component !== undefined ? `[${record.component}]` : undefined,
41
+ `${record.event}:`,
42
+ record.msg,
43
+ ].filter((part) => part !== undefined && part !== "");
44
+ const correlation = [];
45
+ if (record.run_id !== undefined)
46
+ correlation.push(`run_id=${record.run_id}`);
47
+ if (record.stage_id !== undefined) {
48
+ correlation.push(`stage_id=${record.stage_id}`);
49
+ }
50
+ if (record.attempt !== undefined) {
51
+ correlation.push(`attempt=${record.attempt}`);
52
+ }
53
+ if (record.truncated === true)
54
+ correlation.push("truncated=true");
55
+ const reserved = new Set([
56
+ "ts",
57
+ "level",
58
+ "event",
59
+ "msg",
60
+ "component",
61
+ "run_id",
62
+ "stage_id",
63
+ "attempt",
64
+ "truncated",
65
+ "original_bytes",
66
+ ]);
67
+ for (const [key, value] of Object.entries(record)) {
68
+ if (reserved.has(key))
69
+ continue;
70
+ if (value === undefined)
71
+ continue;
72
+ correlation.push(`${key}=${typeof value === "string" ? value : JSON.stringify(value)}`);
73
+ }
74
+ return correlation.length > 0
75
+ ? `${parts.join(" ")} ${correlation.join(" ")}`
76
+ : parts.join(" ");
77
+ }
78
+ function serializeRecord(record, format, maxLineBytes) {
79
+ if (format === "pretty") {
80
+ let line = formatPretty(record);
81
+ const bytes = Buffer.byteLength(line, "utf8");
82
+ if (bytes <= maxLineBytes)
83
+ return line;
84
+ const overhead = bytes - Buffer.byteLength(record.msg, "utf8");
85
+ const msgBudget = Math.max(0, maxLineBytes - overhead - 1);
86
+ const truncatedMsg = Buffer.from(record.msg, "utf8")
87
+ .subarray(0, msgBudget)
88
+ .toString("utf8");
89
+ return formatPretty({
90
+ ...record,
91
+ msg: truncatedMsg,
92
+ truncated: true,
93
+ original_bytes: bytes,
94
+ });
95
+ }
96
+ let payload = { ...record };
97
+ let line = JSON.stringify(payload);
98
+ let bytes = Buffer.byteLength(line, "utf8");
99
+ if (bytes <= maxLineBytes)
100
+ return line;
101
+ const originalBytes = bytes;
102
+ let lo = 0;
103
+ let hi = Buffer.byteLength(record.msg, "utf8");
104
+ let bestMsg = "";
105
+ while (lo <= hi) {
106
+ const mid = Math.floor((lo + hi) / 2);
107
+ const candidateMsg = Buffer.from(record.msg, "utf8")
108
+ .subarray(0, mid)
109
+ .toString("utf8");
110
+ payload = {
111
+ ...record,
112
+ msg: candidateMsg,
113
+ truncated: true,
114
+ original_bytes: originalBytes,
115
+ };
116
+ line = JSON.stringify(payload);
117
+ bytes = Buffer.byteLength(line, "utf8");
118
+ if (bytes <= maxLineBytes) {
119
+ bestMsg = candidateMsg;
120
+ lo = mid + 1;
121
+ }
122
+ else {
123
+ hi = mid - 1;
124
+ }
125
+ }
126
+ return JSON.stringify({
127
+ ...record,
128
+ msg: bestMsg,
129
+ truncated: true,
130
+ original_bytes: originalBytes,
131
+ });
132
+ }
133
+ export function createLogger(options = {}) {
134
+ const env = options.env ?? process.env;
135
+ const format = options.format ??
136
+ resolveLogFormat(env, options.stdoutIsTTY ?? Boolean(process.stdout.isTTY));
137
+ const level = options.level ?? resolveLogLevel(env);
138
+ const maxLineBytes = options.maxLineBytes ?? resolveLogMaxLineBytes(env);
139
+ const knownSecrets = options.knownSecrets ?? [];
140
+ const bindings = options.bindings ?? {};
141
+ const write = options.write ??
142
+ ((line) => {
143
+ process.stdout.write(`${line}\n`);
144
+ });
145
+ const now = options.now ?? (() => new Date());
146
+ const emit = (recordLevel, event, msg, fields) => {
147
+ if (LEVEL_RANK[recordLevel] < LEVEL_RANK[level])
148
+ return;
149
+ const record = {
150
+ ts: now().toISOString(),
151
+ level: recordLevel,
152
+ event,
153
+ msg,
154
+ ...bindings,
155
+ ...fields,
156
+ };
157
+ const redacted = redact(record, {
158
+ knownSecrets,
159
+ namedSecrets: getNamedSecrets(),
160
+ });
161
+ write(serializeRecord(redacted, format, maxLineBytes));
162
+ };
163
+ const logger = {
164
+ debug(event, msg, fields) {
165
+ emit("debug", event, msg, fields);
166
+ },
167
+ info(event, msg, fields) {
168
+ emit("info", event, msg, fields);
169
+ },
170
+ warn(event, msg, fields) {
171
+ emit("warn", event, msg, fields);
172
+ },
173
+ error(event, msg, fields) {
174
+ emit("error", event, msg, fields);
175
+ },
176
+ child(childBindings) {
177
+ return createLogger({
178
+ env,
179
+ format,
180
+ level,
181
+ maxLineBytes,
182
+ knownSecrets,
183
+ write,
184
+ now,
185
+ bindings: { ...bindings, ...childBindings },
186
+ });
187
+ },
188
+ };
189
+ return logger;
190
+ }
191
+ export const logger = createLogger({
192
+ bindings: { component: "host" },
193
+ });
@@ -0,0 +1,6 @@
1
+ import type { NamedSecret } from "../logging/redact.js";
2
+ export declare const REDACTION_SECRETS_FILENAME = "redaction-secrets.json";
3
+ export declare function registerNamedSecrets(secrets: readonly NamedSecret[]): void;
4
+ export declare function clearNamedSecretsForTests(): void;
5
+ export declare function getNamedSecrets(): readonly NamedSecret[];
6
+ export declare function loadNamedSecretsFromAttemptDir(attemptDir: string): void;