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
@@ -0,0 +1,52 @@
1
+ import type { McpServer } from "@modelcontextprotocol/server";
2
+ import type { RunMeta, RunStore } from "../runstore/port.js";
3
+ import type { McpToolDeps } from "./deps.js";
4
+ export declare const CHECKOUT_CHANGES_CAP = 500;
5
+ export declare const DEFAULT_DIFF_MAX_BYTES = 262144;
6
+ export type CheckoutChangeStatus = "added" | "untracked" | "modified" | "deleted";
7
+ export type CheckoutChangeEntry = {
8
+ path: string;
9
+ status: CheckoutChangeStatus;
10
+ };
11
+ export type CheckoutVisibilityCode = "run_not_bound" | "checkout_reclaimed" | "not_a_git_repository";
12
+ export type CheckoutVisibilityError = {
13
+ ok: false;
14
+ code: CheckoutVisibilityCode;
15
+ error: string;
16
+ status: number;
17
+ };
18
+ export type BoundCheckout = {
19
+ ok: true;
20
+ runId: string;
21
+ meta: RunMeta;
22
+ checkoutRoot: string;
23
+ isGit: boolean;
24
+ };
25
+ export declare function resolveBoundCheckout(store: RunStore, runId: string): Promise<BoundCheckout | CheckoutVisibilityError>;
26
+ export declare function parseStatusPorcelainZ(output: string): CheckoutChangeEntry[];
27
+ export declare function listCheckoutChanges(store: RunStore, runId: string): Promise<{
28
+ ok: true;
29
+ changes: CheckoutChangeEntry[];
30
+ truncated: boolean;
31
+ } | CheckoutVisibilityError>;
32
+ export type GetRunDiffInput = {
33
+ mode?: "stat" | "patch";
34
+ path?: string;
35
+ maxBytes?: number;
36
+ };
37
+ export type GetRunDiffSuccess = {
38
+ ok: true;
39
+ mode: "stat" | "patch";
40
+ base_sha: string;
41
+ base_source: "resolved_sha" | "HEAD";
42
+ content: string;
43
+ truncated: boolean;
44
+ untracked: string[];
45
+ };
46
+ export declare function getRunDiff(store: RunStore, runId: string, input?: GetRunDiffInput): Promise<GetRunDiffSuccess | CheckoutVisibilityError>;
47
+ export declare function readCheckoutFileBytes(store: RunStore, runId: string, relativePath: string): Promise<{
48
+ ok: true;
49
+ bytes: Buffer;
50
+ path: string;
51
+ } | CheckoutVisibilityError>;
52
+ export declare function registerCheckoutTools(server: McpServer, deps: McpToolDeps): void;
@@ -0,0 +1,332 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync } from "node:fs";
3
+ import { lstat, readdir, readFile, readlink } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { z } from "zod";
6
+ import { diff, lsFilesOthersZ, revParse, statusPorcelainZ, } from "../git/operations.js";
7
+ import { projectRunBindingDetail } from "../runstore/runProjection.js";
8
+ import { mapStoreLookupError } from "../server/operatorResults.js";
9
+ import { assertSafeRunId, CHECKOUT_PATH_MESSAGES, classifyArtifactContent, resolveContainedRelativePath, } from "./readArtifact.js";
10
+ import { imageResult, textResult } from "./toolResults.js";
11
+ export const CHECKOUT_CHANGES_CAP = 500;
12
+ export const DEFAULT_DIFF_MAX_BYTES = 262_144;
13
+ async function detectGitCheckout(root) {
14
+ try {
15
+ const inside = await revParse(root, ["--is-inside-work-tree"]);
16
+ return inside === "true";
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ export async function resolveBoundCheckout(store, runId) {
23
+ assertSafeRunId(runId);
24
+ let meta;
25
+ try {
26
+ meta = await store.readRunMeta(runId);
27
+ }
28
+ catch (err) {
29
+ const mapped = mapStoreLookupError(err, { policy: "run" });
30
+ throw new Error(mapped.error);
31
+ }
32
+ const binding = projectRunBindingDetail(meta);
33
+ if (binding.kind === "unbound") {
34
+ return {
35
+ ok: false,
36
+ code: "run_not_bound",
37
+ error: "run is not bound to a checkout",
38
+ status: 400,
39
+ };
40
+ }
41
+ const checkoutRoot = meta.checkout_root?.trim();
42
+ if (!checkoutRoot) {
43
+ return {
44
+ ok: false,
45
+ code: "checkout_reclaimed",
46
+ error: "checkout has been reclaimed",
47
+ status: 404,
48
+ };
49
+ }
50
+ if (!existsSync(checkoutRoot)) {
51
+ return {
52
+ ok: false,
53
+ code: "checkout_reclaimed",
54
+ error: "checkout has been reclaimed",
55
+ status: 404,
56
+ };
57
+ }
58
+ const isGit = await detectGitCheckout(checkoutRoot);
59
+ return { ok: true, runId, meta, checkoutRoot, isGit };
60
+ }
61
+ function nulSplit(output) {
62
+ return output.split("\0").filter((part) => part.length > 0);
63
+ }
64
+ export function parseStatusPorcelainZ(output) {
65
+ const parts = nulSplit(output);
66
+ const changes = [];
67
+ for (let i = 0; i < parts.length; i += 1) {
68
+ const entry = parts[i];
69
+ if (entry.length < 3)
70
+ continue;
71
+ const xy = entry.slice(0, 2);
72
+ const firstPath = entry.slice(3);
73
+ const isRenameOrCopy = xy[0] === "R" || xy[0] === "C";
74
+ let filePath = firstPath;
75
+ if (isRenameOrCopy) {
76
+ const next = parts[i + 1];
77
+ if (next !== undefined) {
78
+ filePath = next;
79
+ i += 1;
80
+ }
81
+ }
82
+ if (xy === "??") {
83
+ changes.push({ path: filePath, status: "untracked" });
84
+ continue;
85
+ }
86
+ if (xy === "!!")
87
+ continue;
88
+ if (xy.includes("D") && !isRenameOrCopy) {
89
+ changes.push({ path: filePath, status: "deleted" });
90
+ continue;
91
+ }
92
+ if (xy[0] === "A" || xy[1] === "A" || isRenameOrCopy) {
93
+ changes.push({ path: filePath, status: "added" });
94
+ continue;
95
+ }
96
+ changes.push({ path: filePath, status: "modified" });
97
+ }
98
+ return changes;
99
+ }
100
+ function capChanges(changes) {
101
+ if (changes.length <= CHECKOUT_CHANGES_CAP) {
102
+ return { changes, truncated: false };
103
+ }
104
+ return {
105
+ changes: changes.slice(0, CHECKOUT_CHANGES_CAP),
106
+ truncated: true,
107
+ };
108
+ }
109
+ async function fingerprintFile(root, relativePath) {
110
+ const target = path.join(root, relativePath);
111
+ try {
112
+ const stats = await lstat(target);
113
+ if (stats.isSymbolicLink()) {
114
+ const targetPath = await readlink(target);
115
+ return `link:${createHash("sha256").update(targetPath).digest("hex")}`;
116
+ }
117
+ if (!stats.isFile())
118
+ return `other:${stats.mode}:${stats.size}`;
119
+ const contents = await readFile(target);
120
+ return `file:${createHash("sha256").update(contents).digest("hex")}`;
121
+ }
122
+ catch (error) {
123
+ if (error.code === "ENOENT")
124
+ return "missing";
125
+ throw error;
126
+ }
127
+ }
128
+ async function listNonGitFiles(root, relativeDir = "") {
129
+ const absDir = relativeDir ? path.join(root, relativeDir) : root;
130
+ let entries;
131
+ try {
132
+ entries = await readdir(absDir, { withFileTypes: true });
133
+ }
134
+ catch (error) {
135
+ if (error.code === "ENOENT")
136
+ return [];
137
+ throw error;
138
+ }
139
+ const files = [];
140
+ for (const entry of entries) {
141
+ if (entry.name === ".pi-agent" || entry.name === ".git")
142
+ continue;
143
+ const rel = relativeDir ? path.join(relativeDir, entry.name) : entry.name;
144
+ if (entry.name === "auth.json")
145
+ continue;
146
+ if (entry.isSymbolicLink() || entry.isFile()) {
147
+ files.push(rel.split(path.sep).join("/"));
148
+ continue;
149
+ }
150
+ if (entry.isDirectory()) {
151
+ files.push(...(await listNonGitFiles(root, rel)));
152
+ }
153
+ }
154
+ return files;
155
+ }
156
+ async function listNonGitChanges(checkoutRoot) {
157
+ const files = (await listNonGitFiles(checkoutRoot)).sort();
158
+ const changes = [];
159
+ for (const file of files) {
160
+ const fingerprint = await fingerprintFile(checkoutRoot, file);
161
+ if (fingerprint === "missing")
162
+ continue;
163
+ changes.push({ path: file, status: "untracked" });
164
+ if (changes.length > CHECKOUT_CHANGES_CAP)
165
+ break;
166
+ }
167
+ return capChanges(changes);
168
+ }
169
+ export async function listCheckoutChanges(store, runId) {
170
+ const bound = await resolveBoundCheckout(store, runId);
171
+ if (!bound.ok)
172
+ return bound;
173
+ if (!bound.isGit) {
174
+ const listed = await listNonGitChanges(bound.checkoutRoot);
175
+ return { ok: true, ...listed };
176
+ }
177
+ const porcelain = await statusPorcelainZ(bound.checkoutRoot);
178
+ return { ok: true, ...capChanges(parseStatusPorcelainZ(porcelain)) };
179
+ }
180
+ export async function getRunDiff(store, runId, input = {}) {
181
+ const bound = await resolveBoundCheckout(store, runId);
182
+ if (!bound.ok)
183
+ return bound;
184
+ if (!bound.isGit) {
185
+ return {
186
+ ok: false,
187
+ code: "not_a_git_repository",
188
+ error: "checkout is not a git repository",
189
+ status: 400,
190
+ };
191
+ }
192
+ const mode = input.mode ?? "stat";
193
+ const maxBytes = typeof input.maxBytes === "number" && Number.isFinite(input.maxBytes)
194
+ ? Math.max(0, Math.floor(input.maxBytes))
195
+ : DEFAULT_DIFF_MAX_BYTES;
196
+ let baseSha = bound.meta.resolved_sha?.trim() || undefined;
197
+ let baseSource = "resolved_sha";
198
+ if (!baseSha) {
199
+ baseSha = await revParse(bound.checkoutRoot, ["HEAD"]);
200
+ baseSource = "HEAD";
201
+ }
202
+ const pathArgs = input.path !== undefined && input.path.trim().length > 0
203
+ ? ["--", input.path]
204
+ : ["--"];
205
+ const diffArgs = mode === "patch"
206
+ ? ["--patch", "--no-color", baseSha, ...pathArgs]
207
+ : ["--stat", baseSha, ...pathArgs];
208
+ let content = await diff(bound.checkoutRoot, diffArgs);
209
+ const othersRaw = await lsFilesOthersZ(bound.checkoutRoot);
210
+ let untracked = nulSplit(othersRaw);
211
+ if (input.path !== undefined && input.path.trim().length > 0) {
212
+ const filter = input.path.replace(/\\/g, "/");
213
+ untracked = untracked.filter((file) => file === filter || file.startsWith(`${filter}/`));
214
+ }
215
+ let truncated = false;
216
+ if (mode === "patch" && content.length > maxBytes) {
217
+ content = content.slice(0, maxBytes);
218
+ truncated = true;
219
+ }
220
+ if (untracked.length > CHECKOUT_CHANGES_CAP) {
221
+ untracked = untracked.slice(0, CHECKOUT_CHANGES_CAP);
222
+ truncated = true;
223
+ }
224
+ return {
225
+ ok: true,
226
+ mode,
227
+ base_sha: baseSha,
228
+ base_source: baseSource,
229
+ content,
230
+ truncated,
231
+ untracked,
232
+ };
233
+ }
234
+ export async function readCheckoutFileBytes(store, runId, relativePath) {
235
+ const bound = await resolveBoundCheckout(store, runId);
236
+ if (!bound.ok)
237
+ return bound;
238
+ const realPath = await resolveContainedRelativePath(bound.checkoutRoot, relativePath, CHECKOUT_PATH_MESSAGES);
239
+ return { ok: true, bytes: await readFile(realPath), path: relativePath };
240
+ }
241
+ function visibilityErrorResult(err) {
242
+ return textResult({ error: err.error, code: err.code, status: err.status }, true);
243
+ }
244
+ export function registerCheckoutTools(server, deps) {
245
+ const { store } = deps;
246
+ server.registerTool("list_checkout_changes", {
247
+ description: "List dirty/untracked paths in the run's bound checkout. Repository and git path bindings use git status; non-git path bindings use filesystem fingerprints. Unbound → run_not_bound; reclaimed checkout → checkout_reclaimed. Caps at 500 entries with truncated: true.",
248
+ inputSchema: z.object({
249
+ runId: z.string(),
250
+ }),
251
+ }, async ({ runId }) => {
252
+ try {
253
+ const result = await listCheckoutChanges(store, runId);
254
+ if (!result.ok)
255
+ return visibilityErrorResult(result);
256
+ return textResult({
257
+ runId,
258
+ changes: result.changes,
259
+ truncated: result.truncated,
260
+ });
261
+ }
262
+ catch (err) {
263
+ const mapped = mapStoreLookupError(err, { policy: "run" });
264
+ return textResult({ error: mapped.error, status: mapped.status }, true);
265
+ }
266
+ });
267
+ server.registerTool("get_run_diff", {
268
+ description: "Diff the run's bound git checkout against its recorded base SHA (resolved_sha). mode defaults to stat; patch enforces maxBytes (default 262144) with truncated: true. Unbound → run_not_bound; non-git path → not_a_git_repository; reclaimed → checkout_reclaimed.",
269
+ inputSchema: z.object({
270
+ runId: z.string(),
271
+ mode: z.enum(["stat", "patch"]).optional(),
272
+ path: z.string().optional(),
273
+ maxBytes: z.number().optional(),
274
+ }),
275
+ }, async ({ runId, mode, path: filterPath, maxBytes }) => {
276
+ try {
277
+ const result = await getRunDiff(store, runId, {
278
+ mode,
279
+ path: filterPath,
280
+ maxBytes,
281
+ });
282
+ if (!result.ok)
283
+ return visibilityErrorResult(result);
284
+ return textResult({
285
+ runId,
286
+ mode: result.mode,
287
+ base_sha: result.base_sha,
288
+ base_source: result.base_source,
289
+ content: result.content,
290
+ truncated: result.truncated,
291
+ untracked: result.untracked,
292
+ });
293
+ }
294
+ catch (err) {
295
+ const mapped = mapStoreLookupError(err, { policy: "run" });
296
+ return textResult({ error: mapped.error, status: mapped.status }, true);
297
+ }
298
+ });
299
+ server.registerTool("read_checkout_file", {
300
+ description: "Read a file from the run's bound checkout by relative path (contained under checkout_root). Same deny-list as read_artifact (.pi-agent, auth.json, traversal). Images return an MCP image block; UTF-8 returns JSON { runId, path, content }.",
301
+ inputSchema: z.object({
302
+ runId: z.string(),
303
+ path: z.string(),
304
+ }),
305
+ }, async ({ runId, path: relativePath }) => {
306
+ try {
307
+ const result = await readCheckoutFileBytes(store, runId, relativePath);
308
+ if (!result.ok)
309
+ return visibilityErrorResult(result);
310
+ const classified = classifyArtifactContent(relativePath, result.bytes);
311
+ if (classified.kind === "image") {
312
+ return imageResult(classified.mimeType, result.bytes, {
313
+ runId,
314
+ path: relativePath,
315
+ mimeType: classified.mimeType,
316
+ });
317
+ }
318
+ if (classified.kind === "utf8") {
319
+ return textResult({
320
+ runId,
321
+ path: relativePath,
322
+ content: result.bytes.toString("utf8"),
323
+ });
324
+ }
325
+ return textResult({ error: "Checkout file is not valid UTF-8 text", status: 400 }, true);
326
+ }
327
+ catch (err) {
328
+ const mapped = mapStoreLookupError(err, { policy: "artifact" });
329
+ return textResult({ error: mapped.error, status: mapped.status }, true);
330
+ }
331
+ });
332
+ }
@@ -1,13 +1,17 @@
1
1
  import path from "node:path";
2
2
  import { z } from "zod";
3
+ import { writeAudit } from "../logging/audit.js";
4
+ import { logger as rootLogger } from "../logging/logger.js";
3
5
  import { findProjectRoot } from "../project/findProjectRoot.js";
4
6
  import { mapRetryStageFailure, mapStartFailure, mapStoreLookupError, } from "../server/operatorResults.js";
7
+ import { callerIdFromRequestAuth, getRequestAuth, } from "../server/requestAuthContext.js";
5
8
  import { attemptStreamLogPath } from "../runstore/workspaceLayout.js";
6
9
  import { parseAskOperatorAnswer } from "../tools/askOperator.js";
7
10
  import { readStreamLogTail } from "./tailStreamLog.js";
8
11
  import { textResult } from "./toolResults.js";
9
12
  import { projectWaitingGates } from "./waitingGates.js";
10
13
  import { readStageVerificationHistory } from "../runstore/verificationHistory.js";
14
+ const auditLog = rootLogger.child({ component: "audit" });
11
15
  export function registerControlTools(server, deps) {
12
16
  const { manager, store, cwd } = deps;
13
17
  server.registerTool("list_waiting", {
@@ -51,13 +55,36 @@ export function registerControlTools(server, deps) {
51
55
  }
52
56
  catch (err) {
53
57
  const message = err instanceof Error ? err.message : String(err);
58
+ writeAudit(auditLog, {
59
+ caller_id: callerIdFromRequestAuth(),
60
+ surface: getRequestAuth()?.surface ?? "mcp",
61
+ action: "answer_gate",
62
+ target_run_id: runId,
63
+ outcome: "error",
64
+ });
54
65
  return textResult({ error: message, status: 400 }, true);
55
66
  }
56
67
  const result = await manager.deliverAnswer(runId, stageId, parsed);
57
68
  if (!result.ok) {
69
+ writeAudit(auditLog, {
70
+ caller_id: callerIdFromRequestAuth(),
71
+ surface: getRequestAuth()?.surface ?? "mcp",
72
+ action: "answer_gate",
73
+ target_run_id: runId,
74
+ outcome: "error",
75
+ });
58
76
  return textResult({ error: result.reason, status: result.status }, true);
59
77
  }
60
- return textResult({ ok: true });
78
+ writeAudit(auditLog, {
79
+ caller_id: callerIdFromRequestAuth(),
80
+ surface: getRequestAuth()?.surface ?? "mcp",
81
+ action: "answer_gate",
82
+ target_run_id: runId,
83
+ outcome: "ok",
84
+ });
85
+ return textResult(result.verification !== undefined
86
+ ? { ok: true, verification: result.verification }
87
+ : { ok: true });
61
88
  });
62
89
  server.registerTool("decide_feedback_loop", {
63
90
  description: "Resolve a feedback-loop wait_for_human decision (extend, continue, or abandon). Same semantics as POST /api/runs/:id/stages/:stageId/feedback-decision.",
@@ -233,8 +260,23 @@ export function registerControlTools(server, deps) {
233
260
  }, async ({ runId, stageId }) => {
234
261
  const result = await manager.retryStage(runId, stageId);
235
262
  if (!result.ok) {
263
+ writeAudit(auditLog, {
264
+ caller_id: callerIdFromRequestAuth(),
265
+ surface: getRequestAuth()?.surface ?? "mcp",
266
+ action: "retry_stage",
267
+ target_run_id: runId,
268
+ outcome: "error",
269
+ ...(result.code !== undefined ? { error_code: result.code } : {}),
270
+ });
236
271
  return textResult({ ...mapRetryStageFailure(result), status: result.status }, true);
237
272
  }
273
+ writeAudit(auditLog, {
274
+ caller_id: callerIdFromRequestAuth(),
275
+ surface: getRequestAuth()?.surface ?? "mcp",
276
+ action: "retry_stage",
277
+ target_run_id: runId,
278
+ outcome: "ok",
279
+ });
238
280
  return textResult({
239
281
  runId: result.runId,
240
282
  stageId: result.stageId,
@@ -242,7 +284,7 @@ export function registerControlTools(server, deps) {
242
284
  });
243
285
  });
244
286
  server.registerTool("resume_stage", {
245
- description: "Resume a stage that failed because it timed out, continuing the same attempt/session (same as POST .../resume). Does not start a new attempt — use retry_stage to start over.",
287
+ description: "Resume an interrupted stage or a stage that failed because it timed out, continuing the same attempt/session (same as POST .../resume). Does not start a new attempt — use retry_stage to start over.",
246
288
  inputSchema: z.object({
247
289
  runId: z.string(),
248
290
  stageId: z.string(),
@@ -250,8 +292,23 @@ export function registerControlTools(server, deps) {
250
292
  }, async ({ runId, stageId }) => {
251
293
  const result = await manager.resumeTimedOutStage(runId, stageId);
252
294
  if (!result.ok) {
295
+ writeAudit(auditLog, {
296
+ caller_id: callerIdFromRequestAuth(),
297
+ surface: getRequestAuth()?.surface ?? "mcp",
298
+ action: "resume_stage",
299
+ target_run_id: runId,
300
+ outcome: "error",
301
+ ...(result.code !== undefined ? { error_code: result.code } : {}),
302
+ });
253
303
  return textResult({ ...mapRetryStageFailure(result), status: result.status }, true);
254
304
  }
305
+ writeAudit(auditLog, {
306
+ caller_id: callerIdFromRequestAuth(),
307
+ surface: getRequestAuth()?.surface ?? "mcp",
308
+ action: "resume_stage",
309
+ target_run_id: runId,
310
+ outcome: "ok",
311
+ });
255
312
  return textResult({
256
313
  runId: result.runId,
257
314
  stageId: result.stageId,
@@ -259,7 +316,7 @@ export function registerControlTools(server, deps) {
259
316
  });
260
317
  });
261
318
  server.registerTool("abandon_stage", {
262
- description: "Abandon a running stage (marks it failed/interrupted). Does not dismiss HITL — waiting stages return 409; answer them with answer_gate. There is no run-level cancel tool.",
319
+ description: "Abandon a running stage (marks it failed). Does not dismiss HITL — waiting stages return 409; answer them with answer_gate. Prefer cancel_run to stop an entire run.",
263
320
  inputSchema: z.object({
264
321
  runId: z.string(),
265
322
  stageId: z.string(),
@@ -268,27 +325,146 @@ export function registerControlTools(server, deps) {
268
325
  const result = await manager.abandonStage(runId, stageId);
269
326
  if (!result.ok) {
270
327
  const fail = result;
328
+ writeAudit(auditLog, {
329
+ caller_id: callerIdFromRequestAuth(),
330
+ surface: getRequestAuth()?.surface ?? "mcp",
331
+ action: "abandon_stage",
332
+ target_run_id: runId,
333
+ outcome: "error",
334
+ });
271
335
  return textResult({ error: fail.reason, status: fail.status }, true);
272
336
  }
337
+ writeAudit(auditLog, {
338
+ caller_id: callerIdFromRequestAuth(),
339
+ surface: getRequestAuth()?.surface ?? "mcp",
340
+ action: "abandon_stage",
341
+ target_run_id: runId,
342
+ outcome: "ok",
343
+ });
273
344
  return textResult({
274
345
  ok: true,
275
346
  runId: result.runId,
276
347
  stageId: result.stageId,
277
348
  });
278
349
  });
350
+ server.registerTool("cancel_run", {
351
+ description: "Cancel a non-terminal run (marks it cancelled, terminalizes pending/running/waiting stages, releases the checkout lease). Signals live stage workers via process-group kill (SIGTERM, then SIGKILL escalation) so agent grandchildren are included. Reason is required free-text and stored on the run as cancel_reason.",
352
+ inputSchema: z.object({
353
+ runId: z.string(),
354
+ reason: z.string().min(1),
355
+ }),
356
+ }, async ({ runId, reason }) => {
357
+ const result = await manager.cancelRun(runId, reason);
358
+ if (!result.ok) {
359
+ const fail = result;
360
+ writeAudit(auditLog, {
361
+ caller_id: callerIdFromRequestAuth(),
362
+ surface: getRequestAuth()?.surface ?? "mcp",
363
+ action: "cancel_run",
364
+ target_run_id: runId,
365
+ outcome: "error",
366
+ });
367
+ return textResult({ error: fail.reason, status: fail.status }, true);
368
+ }
369
+ writeAudit(auditLog, {
370
+ caller_id: callerIdFromRequestAuth(),
371
+ surface: getRequestAuth()?.surface ?? "mcp",
372
+ action: "cancel_run",
373
+ target_run_id: runId,
374
+ outcome: "ok",
375
+ });
376
+ return textResult({
377
+ ok: true,
378
+ runId: result.runId,
379
+ });
380
+ });
381
+ server.registerTool("delete_run", {
382
+ description: "Hard-delete a terminal run (store rows, workspace, worktree, run branch, and A2A tasks/artifacts). Active runs (created/queued/running) require force: true, which cancels first then deletes. Irreversible.",
383
+ inputSchema: z.object({
384
+ runId: z.string(),
385
+ force: z.boolean().optional(),
386
+ }),
387
+ }, async ({ runId, force }) => {
388
+ const result = await manager.deleteRun(runId, {
389
+ force,
390
+ channel: "mcp",
391
+ });
392
+ if (!result.ok) {
393
+ const fail = result;
394
+ writeAudit(auditLog, {
395
+ caller_id: callerIdFromRequestAuth(),
396
+ surface: getRequestAuth()?.surface ?? "mcp",
397
+ action: "delete_run",
398
+ target_run_id: runId,
399
+ outcome: "error",
400
+ });
401
+ return textResult({ error: fail.reason, status: fail.status }, true);
402
+ }
403
+ writeAudit(auditLog, {
404
+ caller_id: callerIdFromRequestAuth(),
405
+ surface: getRequestAuth()?.surface ?? "mcp",
406
+ action: "delete_run",
407
+ target_run_id: runId,
408
+ outcome: "ok",
409
+ });
410
+ return textResult({
411
+ ok: true,
412
+ runId: result.runId,
413
+ });
414
+ });
415
+ server.registerTool("gc_runs", {
416
+ description: "Run retention GC (SLIM then PURGE then bare-cache eviction). Default execute: false is dry-run (report candidates only). execute: true is irreversible bulk reclaim — slimmed/purged runIds and evicted bare caches are returned in the report.",
417
+ inputSchema: z.object({
418
+ execute: z.boolean().optional(),
419
+ }),
420
+ }, async ({ execute }) => {
421
+ const result = await manager.gcRuns({
422
+ execute: execute === true,
423
+ channel: "mcp",
424
+ });
425
+ if (!result.ok) {
426
+ const fail = result;
427
+ return textResult({ error: fail.reason, status: fail.status }, true);
428
+ }
429
+ return textResult({
430
+ slimmed: result.slimmed,
431
+ purged: result.purged,
432
+ bareCachesEvicted: result.bareCachesEvicted,
433
+ });
434
+ });
279
435
  server.registerTool("rerun", {
280
- description: "Start a new run from a completed or failed run's pipeline/task locators. Returns { runId } for the new run.",
436
+ description: "Start a new run from a completed or failed run's pipeline/task locators. Optional pinned: true replays the prior resolved_sha for repository bindings. Returns { runId } for the new run.",
281
437
  inputSchema: z.object({
282
438
  runId: z.string(),
439
+ pinned: z.boolean().optional(),
283
440
  }),
284
- }, async ({ runId }) => {
285
- const result = await manager.rerun(runId);
441
+ }, async ({ runId, pinned }) => {
442
+ const callerId = callerIdFromRequestAuth();
443
+ const result = await manager.rerun(runId, {
444
+ ...(pinned !== undefined ? { pinned } : {}),
445
+ callerId,
446
+ });
286
447
  if (!result.ok) {
448
+ writeAudit(auditLog, {
449
+ caller_id: callerId,
450
+ surface: getRequestAuth()?.surface ?? "mcp",
451
+ action: "rerun",
452
+ target_run_id: runId,
453
+ outcome: "error",
454
+ ...(result.code !== undefined ? { error_code: result.code } : {}),
455
+ });
287
456
  return textResult({
288
457
  ...mapStartFailure(result),
289
458
  ...(result.status !== undefined ? { status: result.status } : {}),
290
459
  }, true);
291
460
  }
461
+ writeAudit(auditLog, {
462
+ caller_id: callerId,
463
+ surface: getRequestAuth()?.surface ?? "mcp",
464
+ action: "rerun",
465
+ target_run_id: result.runId,
466
+ outcome: "ok",
467
+ });
292
468
  return textResult({ runId: result.runId });
293
469
  });
294
470
  }
@@ -1,3 +1,4 @@
1
+ import type { BootProviderResult } from "../agent/bootProviderConfig.js";
1
2
  import type { ProviderAuthContext } from "../agent/providerAuth.js";
2
3
  import type { RunStore } from "../runstore/port.js";
3
4
  import type { RunChangeBus } from "../runtime/runChangeBus.js";
@@ -6,8 +7,10 @@ export type McpToolDeps = {
6
7
  manager: RunManager;
7
8
  store: RunStore;
8
9
  cwd: string;
10
+ agentDir?: string;
9
11
  providerAuthContext?: ProviderAuthContext;
10
12
  projectRoot?: string;
13
+ providerBoot?: BootProviderResult;
11
14
  };
12
15
  export type McpHttpDeps = McpToolDeps & {
13
16
  runChangeBus: RunChangeBus;
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/server";
2
+ import type { McpToolDeps } from "./deps.js";
3
+ export declare function registerGetStartedTool(server: McpServer, deps: McpToolDeps): void;