stageflow 0.40.0 → 0.44.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 (519) hide show
  1. package/README.md +15 -4
  2. package/dist/agent/activity.d.ts +18 -0
  3. package/dist/agent/claudeAdapter.js +7 -0
  4. package/dist/agent/claudeTools.d.ts +27 -18
  5. package/dist/agent/claudeTools.js +54 -15
  6. package/dist/agent/compactionEvents.d.ts +34 -0
  7. package/dist/agent/compactionEvents.js +37 -0
  8. package/dist/agent/openRouterRouting.d.ts +7 -0
  9. package/dist/agent/openRouterRouting.js +23 -0
  10. package/dist/agent/piAdapter.d.ts +6 -0
  11. package/dist/agent/piAdapter.js +128 -27
  12. package/dist/agent/piSettings.d.ts +7 -0
  13. package/dist/agent/piSettings.js +9 -0
  14. package/dist/agent/sandboxPiTools.d.ts +3 -1
  15. package/dist/agent/sandboxPiTools.js +8 -2
  16. package/dist/agent/stageTurnDriver.d.ts +11 -2
  17. package/dist/agent/stageTurnDriver.js +45 -4
  18. package/dist/agent/toolOutputBudget.d.ts +15 -1
  19. package/dist/agent/toolOutputBudget.js +18 -0
  20. package/dist/agent/toolOutputBudgetExtension.d.ts +2 -0
  21. package/dist/agent/toolOutputBudgetExtension.js +40 -3
  22. package/dist/agents/authorChat.d.ts +5 -0
  23. package/dist/agents/authorChat.js +120 -12
  24. package/dist/agents/authorSessionStore.d.ts +38 -0
  25. package/dist/agents/authorSessionStore.js +167 -0
  26. package/dist/agents/chatTurn.d.ts +2 -0
  27. package/dist/agents/chatTurn.js +17 -1
  28. package/dist/agents/errors.d.ts +1 -1
  29. package/dist/agents/errors.js +1 -0
  30. package/dist/agents/evalGate.d.ts +61 -0
  31. package/dist/agents/evalGate.js +103 -0
  32. package/dist/agents/evalSession.d.ts +26 -0
  33. package/dist/agents/evalSession.js +29 -0
  34. package/dist/agents/hostContext.d.ts +4 -1
  35. package/dist/agents/hostContext.js +4 -1
  36. package/dist/agents/runtime/piRuntime.d.ts +6 -2
  37. package/dist/agents/runtime/piRuntime.js +50 -16
  38. package/dist/agents/runtime/types.d.ts +3 -1
  39. package/dist/agents/service.d.ts +27 -2
  40. package/dist/agents/service.js +91 -15
  41. package/dist/agents/sessions.d.ts +8 -0
  42. package/dist/agents/sessions.js +53 -11
  43. package/dist/agents/store.d.ts +14 -3
  44. package/dist/agents/store.js +45 -7
  45. package/dist/agents/toolRisk.d.ts +21 -0
  46. package/dist/agents/toolRisk.js +50 -0
  47. package/dist/cli/doctorCommand.js +26 -0
  48. package/dist/cli/evalCommand.d.ts +20 -0
  49. package/dist/cli/evalCommand.js +720 -0
  50. package/dist/cli/exportAllCommand.js +1 -1
  51. package/dist/cli/hostClient.d.ts +60 -0
  52. package/dist/cli/hostClient.js +71 -0
  53. package/dist/cli/validateOutput.d.ts +2 -2
  54. package/dist/cli/validateOutput.js +2 -2
  55. package/dist/cli.js +10 -0
  56. package/dist/compaction/directives.d.ts +18 -0
  57. package/dist/compaction/directives.js +119 -0
  58. package/dist/compaction/extension.d.ts +20 -0
  59. package/dist/compaction/extension.js +78 -0
  60. package/dist/compaction/mask.d.ts +18 -0
  61. package/dist/compaction/mask.js +155 -0
  62. package/dist/compaction/pin.d.ts +21 -0
  63. package/dist/compaction/pin.js +270 -0
  64. package/dist/compaction/scrub.d.ts +7 -0
  65. package/dist/compaction/scrub.js +26 -0
  66. package/dist/compaction/sessionWiring.d.ts +22 -0
  67. package/dist/compaction/sessionWiring.js +26 -0
  68. package/dist/compaction/summarize.d.ts +79 -0
  69. package/dist/compaction/summarize.js +171 -0
  70. package/dist/compaction/toolPolicy.d.ts +3 -0
  71. package/dist/compaction/toolPolicy.js +33 -0
  72. package/dist/compaction/types.d.ts +45 -0
  73. package/dist/compaction/types.js +7 -0
  74. package/dist/compaction/workingState.d.ts +56 -0
  75. package/dist/compaction/workingState.js +198 -0
  76. package/dist/config/atomicWrite.d.ts +15 -0
  77. package/dist/config/atomicWrite.js +43 -0
  78. package/dist/config/browseCatalog.d.ts +2 -0
  79. package/dist/config/browseCatalog.js +4 -2
  80. package/dist/config/createPipeline.js +2 -0
  81. package/dist/config/createTrigger.js +7 -1
  82. package/dist/config/csv.d.ts +9 -0
  83. package/dist/config/csv.js +81 -0
  84. package/dist/config/datasetAgentCheck.d.ts +18 -0
  85. package/dist/config/datasetAgentCheck.js +109 -0
  86. package/dist/config/datasetCandidates.d.ts +22 -0
  87. package/dist/config/datasetCandidates.js +86 -0
  88. package/dist/config/datasetFromSessions.d.ts +34 -0
  89. package/dist/config/datasetFromSessions.js +105 -0
  90. package/dist/config/datasetHash.d.ts +1 -0
  91. package/dist/config/datasetHash.js +4 -0
  92. package/dist/config/datasetImport.d.ts +21 -0
  93. package/dist/config/datasetImport.js +120 -0
  94. package/dist/config/datasetStageCheck.d.ts +9 -0
  95. package/dist/config/datasetStageCheck.js +17 -0
  96. package/dist/config/datasetTypes.d.ts +27 -0
  97. package/dist/config/datasetTypes.js +1 -0
  98. package/dist/config/ensureCatalogScanRoot.d.ts +4 -1
  99. package/dist/config/ensureCatalogScanRoot.js +8 -6
  100. package/dist/config/evalCatalog.d.ts +22 -0
  101. package/dist/config/evalCatalog.js +95 -0
  102. package/dist/config/evalWriteRoots.d.ts +17 -0
  103. package/dist/config/evalWriteRoots.js +109 -0
  104. package/dist/config/githubTriggerAction.d.ts +8 -0
  105. package/dist/config/githubTriggerAction.js +29 -0
  106. package/dist/config/hostConfig.js +3 -0
  107. package/dist/config/installEvalSample.d.ts +34 -0
  108. package/dist/config/installEvalSample.js +182 -0
  109. package/dist/config/loadDataset.d.ts +16 -0
  110. package/dist/config/loadDataset.js +318 -0
  111. package/dist/config/loadEval.d.ts +32 -0
  112. package/dist/config/loadEval.js +1103 -0
  113. package/dist/config/loadOutcome.d.ts +5 -0
  114. package/dist/config/loadStageflowManifest.js +64 -0
  115. package/dist/config/pipelineNeeds.d.ts +2 -0
  116. package/dist/config/pipelineNeeds.js +16 -3
  117. package/dist/config/pipelineRoute.js +5 -4
  118. package/dist/config/resolveAgentTarget.d.ts +32 -0
  119. package/dist/config/resolveAgentTarget.js +118 -0
  120. package/dist/config/resolveEvalTarget.d.ts +21 -0
  121. package/dist/config/resolveEvalTarget.js +89 -0
  122. package/dist/config/scanCatalogPaths.d.ts +1 -1
  123. package/dist/config/scanCatalogPaths.js +17 -5
  124. package/dist/config/validateCatalog.d.ts +2 -2
  125. package/dist/config/validateCatalog.js +21 -1
  126. package/dist/config/validateEval.d.ts +36 -0
  127. package/dist/config/validateEval.js +446 -0
  128. package/dist/config/writeDataset.d.ts +54 -0
  129. package/dist/config/writeDataset.js +186 -0
  130. package/dist/config/writeEval.d.ts +25 -0
  131. package/dist/config/writeEval.js +398 -0
  132. package/dist/diagnostics/checks.js +1 -1
  133. package/dist/envelope/assertEmittedArtifacts.d.ts +12 -0
  134. package/dist/envelope/assertEmittedArtifacts.js +43 -0
  135. package/dist/envelope/preEmitChecks.d.ts +3 -0
  136. package/dist/evals/agentDiff.d.ts +13 -0
  137. package/dist/evals/agentDiff.js +11 -0
  138. package/dist/evals/canonical.d.ts +3 -0
  139. package/dist/evals/canonical.js +24 -0
  140. package/dist/evals/caseTask.d.ts +3 -0
  141. package/dist/evals/caseTask.js +9 -0
  142. package/dist/evals/compare.d.ts +94 -0
  143. package/dist/evals/compare.js +201 -0
  144. package/dist/evals/constants.d.ts +62 -0
  145. package/dist/evals/constants.js +97 -0
  146. package/dist/evals/engine/FakeEngine.d.ts +33 -0
  147. package/dist/evals/engine/FakeEngine.js +177 -0
  148. package/dist/evals/engine/index.d.ts +9 -0
  149. package/dist/evals/engine/index.js +19 -0
  150. package/dist/evals/engine/promptfoo/PromptfooEngine.d.ts +52 -0
  151. package/dist/evals/engine/promptfoo/PromptfooEngine.js +312 -0
  152. package/dist/evals/engine/promptfoo/errors.d.ts +5 -0
  153. package/dist/evals/engine/promptfoo/errors.js +8 -0
  154. package/dist/evals/engine/promptfoo/generate.d.ts +30 -0
  155. package/dist/evals/engine/promptfoo/generate.js +345 -0
  156. package/dist/evals/engine/promptfoo/guard.d.ts +10 -0
  157. package/dist/evals/engine/promptfoo/guard.js +116 -0
  158. package/dist/evals/engine/promptfoo/install.d.ts +17 -0
  159. package/dist/evals/engine/promptfoo/install.js +73 -0
  160. package/dist/evals/engine/promptfoo/judgeProviders.d.ts +2 -0
  161. package/dist/evals/engine/promptfoo/judgeProviders.js +9 -0
  162. package/dist/evals/engine/promptfoo/judgeServices.d.ts +6 -0
  163. package/dist/evals/engine/promptfoo/judgeServices.js +41 -0
  164. package/dist/evals/engine/promptfoo/locate.d.ts +21 -0
  165. package/dist/evals/engine/promptfoo/locate.js +68 -0
  166. package/dist/evals/engine/promptfoo/nodeVersion.d.ts +7 -0
  167. package/dist/evals/engine/promptfoo/nodeVersion.js +14 -0
  168. package/dist/evals/engine/promptfoo/normalize.d.ts +66 -0
  169. package/dist/evals/engine/promptfoo/normalize.js +261 -0
  170. package/dist/evals/engine/promptfoo/pinned.d.ts +5 -0
  171. package/dist/evals/engine/promptfoo/pinned.js +5 -0
  172. package/dist/evals/engine/promptfoo/rubricPrompt.d.ts +14 -0
  173. package/dist/evals/engine/promptfoo/rubricPrompt.js +105 -0
  174. package/dist/evals/engine/promptfoo/runTokens.d.ts +18 -0
  175. package/dist/evals/engine/promptfoo/runTokens.js +31 -0
  176. package/dist/evals/engine/promptfoo/status.d.ts +13 -0
  177. package/dist/evals/engine/promptfoo/status.js +16 -0
  178. package/dist/evals/estimate.d.ts +56 -0
  179. package/dist/evals/estimate.js +66 -0
  180. package/dist/evals/graders/codeGrader.d.ts +6 -0
  181. package/dist/evals/graders/codeGrader.js +85 -0
  182. package/dist/evals/graders/conversationCheckGrader.d.ts +6 -0
  183. package/dist/evals/graders/conversationCheckGrader.js +62 -0
  184. package/dist/evals/graders/fieldGrader.d.ts +11 -0
  185. package/dist/evals/graders/fieldGrader.js +117 -0
  186. package/dist/evals/graders/goal.d.ts +3 -0
  187. package/dist/evals/graders/goal.js +14 -0
  188. package/dist/evals/graders/index.d.ts +18 -0
  189. package/dist/evals/graders/index.js +34 -0
  190. package/dist/evals/graders/notApplicable.d.ts +5 -0
  191. package/dist/evals/graders/notApplicable.js +9 -0
  192. package/dist/evals/graders/path.d.ts +26 -0
  193. package/dist/evals/graders/path.js +75 -0
  194. package/dist/evals/graders/referenceGrader.d.ts +5 -0
  195. package/dist/evals/graders/referenceGrader.js +59 -0
  196. package/dist/evals/graders/schemaGrader.d.ts +5 -0
  197. package/dist/evals/graders/schemaGrader.js +29 -0
  198. package/dist/evals/graders/subject.d.ts +6 -0
  199. package/dist/evals/graders/subject.js +33 -0
  200. package/dist/evals/graders/toolCallsGrader.d.ts +6 -0
  201. package/dist/evals/graders/toolCallsGrader.js +100 -0
  202. package/dist/evals/graders/transcript.d.ts +12 -0
  203. package/dist/evals/graders/transcript.js +57 -0
  204. package/dist/evals/graders/types.d.ts +20 -0
  205. package/dist/evals/graders/types.js +1 -0
  206. package/dist/evals/judgeProviders.d.ts +16 -0
  207. package/dist/evals/judgeProviders.js +27 -0
  208. package/dist/evals/lineDiff.d.ts +5 -0
  209. package/dist/evals/lineDiff.js +34 -0
  210. package/dist/evals/listStatus.d.ts +31 -0
  211. package/dist/evals/listStatus.js +48 -0
  212. package/dist/evals/manager.d.ts +187 -0
  213. package/dist/evals/manager.js +795 -0
  214. package/dist/evals/plan.d.ts +65 -0
  215. package/dist/evals/plan.js +621 -0
  216. package/dist/evals/planInternalAgent.d.ts +19 -0
  217. package/dist/evals/planInternalAgent.js +205 -0
  218. package/dist/evals/providerKeys.d.ts +1 -0
  219. package/dist/evals/providerKeys.js +21 -0
  220. package/dist/evals/read/agentTargets.d.ts +37 -0
  221. package/dist/evals/read/agentTargets.js +101 -0
  222. package/dist/evals/read/api.d.ts +208 -0
  223. package/dist/evals/read/api.js +363 -0
  224. package/dist/evals/read/compare.d.ts +4 -0
  225. package/dist/evals/read/compare.js +39 -0
  226. package/dist/evals/read/datasets.d.ts +105 -0
  227. package/dist/evals/read/datasets.js +318 -0
  228. package/dist/evals/read/list.d.ts +66 -0
  229. package/dist/evals/read/list.js +182 -0
  230. package/dist/evals/read/results.d.ts +46 -0
  231. package/dist/evals/read/results.js +107 -0
  232. package/dist/evals/read/runs.d.ts +154 -0
  233. package/dist/evals/read/runs.js +295 -0
  234. package/dist/evals/read/suggestions.d.ts +43 -0
  235. package/dist/evals/read/suggestions.js +73 -0
  236. package/dist/evals/runner/FakeAgentBackend.d.ts +40 -0
  237. package/dist/evals/runner/FakeAgentBackend.js +82 -0
  238. package/dist/evals/runner/agentCaseRunner.d.ts +24 -0
  239. package/dist/evals/runner/agentCaseRunner.js +388 -0
  240. package/dist/evals/runner/caseRunner.d.ts +8 -0
  241. package/dist/evals/runner/caseRunner.js +28 -0
  242. package/dist/evals/runner/conversationSubject.d.ts +18 -0
  243. package/dist/evals/runner/conversationSubject.js +123 -0
  244. package/dist/evals/runner/internalAgentCaseRunner.d.ts +6 -0
  245. package/dist/evals/runner/internalAgentCaseRunner.js +250 -0
  246. package/dist/evals/runner/simulatorModel.d.ts +51 -0
  247. package/dist/evals/runner/simulatorModel.js +58 -0
  248. package/dist/evals/runner/simulatorPrompt.d.ts +29 -0
  249. package/dist/evals/runner/simulatorPrompt.js +59 -0
  250. package/dist/evals/runner/stageCaseRunner.d.ts +30 -0
  251. package/dist/evals/runner/stageCaseRunner.js +279 -0
  252. package/dist/evals/runner/userDriver.d.ts +71 -0
  253. package/dist/evals/runner/userDriver.js +104 -0
  254. package/dist/evals/scoring.d.ts +34 -0
  255. package/dist/evals/scoring.js +67 -0
  256. package/dist/evals/snapshot.d.ts +191 -0
  257. package/dist/evals/snapshot.js +70 -0
  258. package/dist/evals/stageDiff.d.ts +8 -0
  259. package/dist/evals/stageDiff.js +48 -0
  260. package/dist/evals/stats.d.ts +95 -0
  261. package/dist/evals/stats.js +220 -0
  262. package/dist/evals/statsAdapter.d.ts +4 -0
  263. package/dist/evals/statsAdapter.js +30 -0
  264. package/dist/evals/statsTypes.d.ts +51 -0
  265. package/dist/evals/statsTypes.js +18 -0
  266. package/dist/evals/storeError.d.ts +5 -0
  267. package/dist/evals/storeError.js +8 -0
  268. package/dist/evals/storeTypes.d.ts +207 -0
  269. package/dist/evals/storeTypes.js +1 -0
  270. package/dist/evals/tTable.d.ts +3 -0
  271. package/dist/evals/tTable.js +15 -0
  272. package/dist/evals/triage/constants.d.ts +26 -0
  273. package/dist/evals/triage/constants.js +33 -0
  274. package/dist/evals/triage/credentials.d.ts +13 -0
  275. package/dist/evals/triage/credentials.js +20 -0
  276. package/dist/evals/triage/jevClassifier.d.ts +14 -0
  277. package/dist/evals/triage/jevClassifier.js +124 -0
  278. package/dist/evals/triage/judgeClassifier.d.ts +10 -0
  279. package/dist/evals/triage/judgeClassifier.js +76 -0
  280. package/dist/evals/triage/prompts.d.ts +16 -0
  281. package/dist/evals/triage/prompts.js +64 -0
  282. package/dist/evals/triage/service.d.ts +79 -0
  283. package/dist/evals/triage/service.js +217 -0
  284. package/dist/evals/triage/stateBuilder.d.ts +19 -0
  285. package/dist/evals/triage/stateBuilder.js +125 -0
  286. package/dist/evals/triage/types.d.ts +60 -0
  287. package/dist/evals/triage/types.js +8 -0
  288. package/dist/evals/types.d.ts +357 -0
  289. package/dist/evals/types.js +4 -0
  290. package/dist/guide/cardContract.d.ts +133 -0
  291. package/dist/guide/cardContract.js +156 -0
  292. package/dist/guide/chat.d.ts +45 -0
  293. package/dist/guide/chat.js +378 -0
  294. package/dist/guide/knowledge/index.d.ts +14 -0
  295. package/dist/guide/knowledge/index.js +109 -0
  296. package/dist/guide/knowledge/topics/agents.d.ts +2 -0
  297. package/dist/guide/knowledge/topics/agents.js +58 -0
  298. package/dist/guide/knowledge/topics/bestPractices.d.ts +2 -0
  299. package/dist/guide/knowledge/topics/bestPractices.js +67 -0
  300. package/dist/guide/knowledge/topics/connections.d.ts +2 -0
  301. package/dist/guide/knowledge/topics/connections.js +66 -0
  302. package/dist/guide/knowledge/topics/consoleMap.d.ts +2 -0
  303. package/dist/guide/knowledge/topics/consoleMap.js +55 -0
  304. package/dist/guide/knowledge/topics/evals.d.ts +2 -0
  305. package/dist/guide/knowledge/topics/evals.js +72 -0
  306. package/dist/guide/knowledge/topics/limitations.d.ts +2 -0
  307. package/dist/guide/knowledge/topics/limitations.js +84 -0
  308. package/dist/guide/knowledge/topics/mcpSkillsBrowser.d.ts +2 -0
  309. package/dist/guide/knowledge/topics/mcpSkillsBrowser.js +57 -0
  310. package/dist/guide/knowledge/topics/memories.d.ts +2 -0
  311. package/dist/guide/knowledge/topics/memories.js +63 -0
  312. package/dist/guide/knowledge/topics/modelsAndProviders.d.ts +2 -0
  313. package/dist/guide/knowledge/topics/modelsAndProviders.js +56 -0
  314. package/dist/guide/knowledge/topics/overview.d.ts +2 -0
  315. package/dist/guide/knowledge/topics/overview.js +56 -0
  316. package/dist/guide/knowledge/topics/pipelines.d.ts +2 -0
  317. package/dist/guide/knowledge/topics/pipelines.js +93 -0
  318. package/dist/guide/knowledge/topics/stages.d.ts +2 -0
  319. package/dist/guide/knowledge/topics/stages.js +54 -0
  320. package/dist/guide/knowledge/topics/tasks.d.ts +2 -0
  321. package/dist/guide/knowledge/topics/tasks.js +52 -0
  322. package/dist/guide/knowledge/topics/triggers.d.ts +2 -0
  323. package/dist/guide/knowledge/topics/triggers.js +68 -0
  324. package/dist/guide/knowledge/topics/troubleshooting.d.ts +2 -0
  325. package/dist/guide/knowledge/topics/troubleshooting.js +85 -0
  326. package/dist/guide/knowledgeTools.d.ts +2 -0
  327. package/dist/guide/knowledgeTools.js +56 -0
  328. package/dist/guide/showUi.d.ts +6 -0
  329. package/dist/guide/showUi.js +546 -0
  330. package/dist/guide/threadStore.d.ts +48 -0
  331. package/dist/guide/threadStore.js +189 -0
  332. package/dist/guide/writeRoot.d.ts +11 -0
  333. package/dist/guide/writeRoot.js +70 -0
  334. package/dist/hosted/translate.js +2 -0
  335. package/dist/mcp/agentTools.js +12 -0
  336. package/dist/mcp/catalogTools.js +18 -20
  337. package/dist/mcp/catalogWriteTools.d.ts +8 -0
  338. package/dist/mcp/catalogWriteTools.js +225 -0
  339. package/dist/mcp/connectionTools.d.ts +3 -0
  340. package/dist/mcp/connectionTools.js +85 -0
  341. package/dist/mcp/controlTools.js +34 -1
  342. package/dist/mcp/deps.d.ts +16 -0
  343. package/dist/mcp/evalTools.d.ts +3 -0
  344. package/dist/mcp/evalTools.js +943 -0
  345. package/dist/mcp/memoryHostTools.d.ts +3 -0
  346. package/dist/mcp/memoryHostTools.js +72 -0
  347. package/dist/mcp/pipelineAuthorTools.js +14 -1
  348. package/dist/mcp/server.js +6 -0
  349. package/dist/mcp/tools.js +8 -0
  350. package/dist/mcp/triggerTools.js +77 -31
  351. package/dist/models/response.d.ts +7 -2
  352. package/dist/models/response.js +6 -1
  353. package/dist/operatorAgent/agentAuthorContext.d.ts +1 -1
  354. package/dist/operatorAgent/agentAuthorContext.js +1 -1
  355. package/dist/operatorAgent/evalGate.d.ts +22 -0
  356. package/dist/operatorAgent/evalGate.js +77 -0
  357. package/dist/operatorAgent/fakeHost.js +10 -2
  358. package/dist/operatorAgent/host.js +18 -2
  359. package/dist/operatorAgent/index.d.ts +1 -0
  360. package/dist/operatorAgent/index.js +1 -0
  361. package/dist/operatorAgent/internalAgents.d.ts +11 -0
  362. package/dist/operatorAgent/internalAgents.js +13 -0
  363. package/dist/operatorAgent/piModel.d.ts +5 -1
  364. package/dist/operatorAgent/piModel.js +32 -14
  365. package/dist/operatorAgent/profiles/agentAuthor.d.ts +3 -1
  366. package/dist/operatorAgent/profiles/agentAuthor.js +201 -32
  367. package/dist/operatorAgent/profiles/agentAuthorPlaybook.d.ts +1 -1
  368. package/dist/operatorAgent/profiles/agentAuthorPlaybook.js +48 -15
  369. package/dist/operatorAgent/profiles/authorReadable.d.ts +2 -0
  370. package/dist/operatorAgent/profiles/authorReadable.js +26 -0
  371. package/dist/operatorAgent/profiles/guideConfirm.d.ts +21 -0
  372. package/dist/operatorAgent/profiles/guideConfirm.js +100 -0
  373. package/dist/operatorAgent/profiles/guideTools.d.ts +7 -0
  374. package/dist/operatorAgent/profiles/guideTools.js +123 -0
  375. package/dist/operatorAgent/profiles/stageflowGuide.d.ts +7 -0
  376. package/dist/operatorAgent/profiles/stageflowGuide.js +132 -0
  377. package/dist/operatorAgent/profiles/workshopAuthor.js +23 -0
  378. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +1 -1
  379. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +9 -1
  380. package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +2 -0
  381. package/dist/operatorAgent/profiles/workshopAuthorTools.js +197 -9
  382. package/dist/operatorAgent/types.d.ts +23 -0
  383. package/dist/package-meta.d.ts +1 -1
  384. package/dist/package-meta.js +1 -1
  385. package/dist/runstore/port.d.ts +43 -0
  386. package/dist/runstore/retention.d.ts +2 -1
  387. package/dist/runstore/retention.js +3 -7
  388. package/dist/runstore/runStatusClock.d.ts +17 -0
  389. package/dist/runstore/runStatusClock.js +19 -0
  390. package/dist/runstore/sqlite/SqliteRunStore.d.ts +29 -0
  391. package/dist/runstore/sqlite/SqliteRunStore.js +144 -50
  392. package/dist/runstore/sqlite/evalStore.d.ts +20 -0
  393. package/dist/runstore/sqlite/evalStore.js +541 -0
  394. package/dist/runstore/sqlite/migrations/015-evals.d.ts +12 -0
  395. package/dist/runstore/sqlite/migrations/015-evals.js +157 -0
  396. package/dist/runstore/sqlite/migrations/016-eval-subject-ref.d.ts +12 -0
  397. package/dist/runstore/sqlite/migrations/016-eval-subject-ref.js +20 -0
  398. package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.d.ts +11 -0
  399. package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.js +36 -0
  400. package/dist/runstore/sqlite/migrations/index.js +6 -0
  401. package/dist/runstore/sqlite/suggestionStore.d.ts +14 -0
  402. package/dist/runstore/sqlite/suggestionStore.js +132 -0
  403. package/dist/runstore/workspaceLayout.js +6 -1
  404. package/dist/runtime/artifactDiskInspect.d.ts +14 -0
  405. package/dist/runtime/artifactDiskInspect.js +52 -0
  406. package/dist/runtime/artifactPath.d.ts +24 -0
  407. package/dist/runtime/artifactPath.js +84 -0
  408. package/dist/runtime/completionCheckRunner.js +15 -43
  409. package/dist/runtime/githubPollSource.d.ts +22 -4
  410. package/dist/runtime/githubPollSource.js +93 -8
  411. package/dist/runtime/pipelineRunner.d.ts +2 -1
  412. package/dist/runtime/pipelineRunner.js +2 -0
  413. package/dist/runtime/priorArtifactGrants.d.ts +8 -0
  414. package/dist/runtime/priorArtifactGrants.js +105 -0
  415. package/dist/runtime/runActionEligibility.d.ts +46 -0
  416. package/dist/runtime/runActionEligibility.js +123 -0
  417. package/dist/runtime/runManager.d.ts +6 -2
  418. package/dist/runtime/runManager.js +60 -16
  419. package/dist/runtime/runRetentionSweep.js +2 -2
  420. package/dist/runtime/runRetryCoordinator.d.ts +2 -14
  421. package/dist/runtime/runRetryCoordinator.js +3 -67
  422. package/dist/runtime/sandboxContainer.d.ts +7 -0
  423. package/dist/runtime/sandboxContainer.js +48 -6
  424. package/dist/runtime/sandboxDesk.d.ts +2 -1
  425. package/dist/runtime/sandboxDesk.js +11 -12
  426. package/dist/runtime/stageEnvironment.js +1 -0
  427. package/dist/runtime/stageRoots.d.ts +12 -0
  428. package/dist/runtime/stageSandbox.d.ts +2 -1
  429. package/dist/runtime/stageSandbox.js +18 -2
  430. package/dist/runtime/stageWorker.js +20 -0
  431. package/dist/server/agentAuthorRoutes.js +59 -1
  432. package/dist/server/bootstrap.d.ts +13 -0
  433. package/dist/server/bootstrap.js +69 -0
  434. package/dist/server/controlToken.js +3 -0
  435. package/dist/server/evalInternalRoutes.d.ts +14 -0
  436. package/dist/server/evalInternalRoutes.js +87 -0
  437. package/dist/server/evalRouteContext.d.ts +46 -0
  438. package/dist/server/evalRouteContext.js +43 -0
  439. package/dist/server/evalRoutes.d.ts +5 -0
  440. package/dist/server/evalRoutes.js +1456 -0
  441. package/dist/server/evalTriageRoutes.d.ts +2 -0
  442. package/dist/server/evalTriageRoutes.js +95 -0
  443. package/dist/server/guideRoutes.d.ts +5 -0
  444. package/dist/server/guideRoutes.js +166 -0
  445. package/dist/server/http.d.ts +15 -0
  446. package/dist/server/http.js +67 -3
  447. package/dist/server/internalAgentRoutes.d.ts +6 -0
  448. package/dist/server/internalAgentRoutes.js +12 -0
  449. package/dist/server/mcpHost.js +5 -0
  450. package/dist/toolkit/meta.d.ts +1 -1
  451. package/dist/toolkit/meta.js +53 -0
  452. package/dist/toolkit/profiles.d.ts +5 -0
  453. package/dist/toolkit/profiles.js +13 -1
  454. package/dist/tools/askOperator.js +2 -1
  455. package/dist/tools/emitStageEnvelope.d.ts +17 -16
  456. package/dist/tools/emitStageEnvelope.js +46 -32
  457. package/dist/tools/stageToolNames.d.ts +4 -0
  458. package/dist/tools/stageToolNames.js +4 -0
  459. package/dist/tools/workingState.d.ts +40 -0
  460. package/dist/tools/workingState.js +108 -0
  461. package/dist/tools/writeStageArtifact.d.ts +0 -9
  462. package/dist/tools/writeStageArtifact.js +2 -1
  463. package/dist/types/stageflowManifest.d.ts +6 -0
  464. package/dist/ui/assets/{MarkdownText-D7tYaIFO.js → MarkdownText-S5C_vemc.js} +2 -2
  465. package/dist/ui/assets/adapters-C0l4ruiR.js +17 -0
  466. package/dist/ui/assets/chat-CjnsmvqR.js +2 -0
  467. package/dist/ui/assets/chat-DFDd4UjS.css +2 -0
  468. package/dist/ui/assets/{main-BFo79krC.css → main-Del1GeLf.css} +1 -1
  469. package/dist/ui/assets/main-_yXVqcW9.js +277 -0
  470. package/dist/ui/chat.html +3 -4
  471. package/dist/ui/index.html +3 -4
  472. package/dist/workshop/chatTurn.js +1 -1
  473. package/dist/workshop/workshopPin.d.ts +3 -3
  474. package/dist/workshop/workshopPin.js +16 -15
  475. package/examples/README.md +2 -0
  476. package/examples/compaction-stress/README.md +30 -0
  477. package/examples/compaction-stress/check-run.mjs +53 -0
  478. package/examples/compaction-stress/collect-evidence.yaml +60 -0
  479. package/examples/compaction-stress/compaction-stress.pipeline.yaml +141 -0
  480. package/examples/compaction-stress/compaction-stress.task.yaml +15 -0
  481. package/examples/compaction-stress/generate-evidence.mjs +110 -0
  482. package/examples/compaction-stress/root-cause.yaml +26 -0
  483. package/examples/compaction-stress/stageflow.yaml +9 -0
  484. package/examples/compaction-stress/write-postmortem.yaml +40 -0
  485. package/examples/document-policy-review/README.md +35 -0
  486. package/examples/document-policy-review/agents/compliance.agent.yaml +42 -0
  487. package/examples/document-policy-review/documents/acme-vendor-sow.md +15 -0
  488. package/examples/document-policy-review/documents/support-runbook.md +13 -0
  489. package/examples/document-policy-review/policies/acceptable-use.md +13 -0
  490. package/examples/document-policy-review/policies/data-handling.md +17 -0
  491. package/examples/document-policy-review/policies/vendor-security.md +17 -0
  492. package/examples/evals/README.md +141 -0
  493. package/examples/evals/critique-sample.dataset.jsonl +8 -0
  494. package/examples/evals/critique-sample.eval.yaml +34 -0
  495. package/examples/evals/critique-sample.task.yaml +4 -0
  496. package/examples/evals/eval-sample.pipeline.yaml +35 -0
  497. package/examples/evals/guide-behavior.dataset.jsonl +15 -0
  498. package/examples/evals/guide-behavior.eval.yaml +35 -0
  499. package/examples/evals/guide-depth.dataset.jsonl +35 -0
  500. package/examples/evals/guide-depth.eval.yaml +169 -0
  501. package/examples/evals/support-sample.agent.yaml +20 -0
  502. package/examples/evals/support-sample.dataset.jsonl +6 -0
  503. package/examples/evals/support-sample.eval.yaml +38 -0
  504. package/examples/memory/evals/guide-behavior.dataset.jsonl +15 -0
  505. package/examples/memory/evals/guide-behavior.eval.yaml +35 -0
  506. package/examples/memory/evals/guide-depth.dataset.jsonl +35 -0
  507. package/examples/memory/evals/guide-depth.eval.yaml +169 -0
  508. package/examples/stageflow.yaml +6 -0
  509. package/package.json +1 -1
  510. package/skills/stageflow/SKILL.md +5 -2
  511. package/skills/stageflow/references/control-surface.md +4 -2
  512. package/skills/stageflow/references/evals.md +68 -0
  513. package/skills/stageflow-author/SKILL.md +4 -0
  514. package/skills/stageflow-run/SKILL.md +4 -0
  515. package/dist/ui/assets/AssistantRuntimeProvider-CsiPFhCT.js +0 -9
  516. package/dist/ui/assets/ReadonlyStore-BfXqHykm.js +0 -6
  517. package/dist/ui/assets/chat-BbLukq9W.js +0 -5
  518. package/dist/ui/assets/chat-zIZU_bP1.css +0 -2
  519. package/dist/ui/assets/main-CijYMeM0.js +0 -259
@@ -8,10 +8,11 @@
8
8
  */
9
9
  import { mkdir } from "node:fs/promises";
10
10
  import path from "node:path";
11
- import { defineTool, ModelRuntime, resolveCliModel, SessionManager, SettingsManager, } from "@earendil-works/pi-coding-agent";
12
- import { Type } from "typebox";
11
+ import { defineTool, ModelRuntime, resolveCliModel, SessionManager, } from "@earendil-works/pi-coding-agent";
13
12
  import { createPiAgentSession, createSealedResourceLoader, resolveWorkshopToolNames, } from "../agent/piSessionFactory.js";
14
- import { bindCursorApiKey, cursorBridgePrompt } from "../agent/cursorProvider.js";
13
+ import { createPiSettingsManager } from "../agent/piSettings.js";
14
+ import { createSessionContextWiring } from "../compaction/sessionWiring.js";
15
+ import { bindCursorApiKey, cursorBridgePrompt, isCursorModelRef } from "../agent/cursorProvider.js";
15
16
  import { findProviderSupport } from "../agent/providerSupport.js";
16
17
  import "../agent/cursorProvider.js";
17
18
  import { logger as rootLogger } from "../logging/logger.js";
@@ -19,7 +20,8 @@ import { globalStageflowHome } from "../project/globalHome.js";
19
20
  import { isUsableAuthFile, resolveCredentialBinding, } from "../runtime/credentialBinding.js";
20
21
  import { resolveWorkshopModel } from "../workshop/modelSettings.js";
21
22
  import { createOperatorAgentHost, invokeProfileTool, } from "./host.js";
22
- import { createAgentAuthorProfile } from "./profiles/agentAuthor.js";
23
+ import { AGENT_AUTHOR_PROFILE_ID, agentAuthorBridgeHint, createAgentAuthorProfile, formatAgentAuthorTurnPrompt, } from "./profiles/agentAuthor.js";
24
+ import { createStageflowGuideProfile } from "./profiles/stageflowGuide.js";
23
25
  import { createWorkshopAuthorProfile, } from "./profiles/workshopAuthor.js";
24
26
  import { readDraftFromContext } from "./draftContext.js";
25
27
  export function sessionNeedsExtensionReload(loaded, needed) {
@@ -37,7 +39,6 @@ function extensionPathsForModel(modelId) {
37
39
  return [];
38
40
  return prepared.extensionPaths;
39
41
  }
40
- const FLEX_PARAMS = Type.Object({}, { additionalProperties: true });
41
42
  const workshopLog = rootLogger.child({ component: "workshop" });
42
43
  export function workshopToolLogFields(args, result) {
43
44
  const body = args.body;
@@ -106,7 +107,8 @@ function buildWorkshopCustomTools(profileTools, getProfile, getTools, onToolResu
106
107
  name: tool.name,
107
108
  label: tool.name,
108
109
  description: tool.description,
109
- parameters: FLEX_PARAMS,
110
+ parameters: tool.parameters,
111
+ constrainedSampling: { type: "json_schema", strict: "prefer" },
110
112
  execute: async (_toolCallId, params) => {
111
113
  const args = params !== null && typeof params === "object" && !Array.isArray(params)
112
114
  ? params
@@ -119,6 +121,7 @@ function buildWorkshopCustomTools(profileTools, getProfile, getTools, onToolResu
119
121
  reportActivity({
120
122
  ...workshopToolActivity(callId, tool.name, "start", args),
121
123
  ...(pinnedBuildId ? { buildId: pinnedBuildId } : {}),
124
+ args,
122
125
  });
123
126
  const result = await invokeProfileTool(getProfile(), tool.name, args, getTools());
124
127
  const fields = workshopToolLogFields(args, result);
@@ -136,6 +139,7 @@ function buildWorkshopCustomTools(profileTools, getProfile, getTools, onToolResu
136
139
  ...update,
137
140
  draft,
138
141
  ...(doneBuildId ? { buildId: doneBuildId } : {}),
142
+ result: result.content,
139
143
  });
140
144
  }
141
145
  else {
@@ -225,14 +229,14 @@ async function openDefaultPiSession(input) {
225
229
  authPath: input.authPath,
226
230
  modelsPath: path.join(path.dirname(input.authPath), "models.json"),
227
231
  });
228
- const settingsManager = SettingsManager.inMemory({
229
- compaction: { enabled: false },
230
- });
232
+ const settingsManager = createPiSettingsManager();
233
+ const contextWiring = createSessionContextWiring({ workingState: true });
231
234
  const loader = createSealedResourceLoader({
232
235
  cwd: input.cwd,
233
236
  agentDir: input.agentDir,
234
237
  settingsManager,
235
- systemPrompt: input.systemPrompt,
238
+ systemPrompt: contextWiring.guidance ? `${input.systemPrompt}\n\n${contextWiring.guidance}` : input.systemPrompt,
239
+ extensionFactories: contextWiring.extensions,
236
240
  ...(additionalExtensionPaths.length > 0
237
241
  ? { additionalExtensionPaths }
238
242
  : {}),
@@ -257,7 +261,7 @@ async function openDefaultPiSession(input) {
257
261
  sessionManager,
258
262
  settingsManager,
259
263
  resourceLoader: loader,
260
- tools: input.toolNames,
264
+ tools: [...input.toolNames, ...contextWiring.toolNames],
261
265
  customTools: input.customTools,
262
266
  });
263
267
  session = created.session;
@@ -434,7 +438,7 @@ export function createPiOperatorAgentModel(options) {
434
438
  syncAgentMessages(state.handle.session, state.handle.sessionManager);
435
439
  state.replayed = true;
436
440
  },
437
- async complete({ profile, message, tools, onDelta, onActivity, modelId }) {
441
+ async complete({ profile, message, contextSnapshot, tools, onDelta, onActivity, modelId }) {
438
442
  let state;
439
443
  try {
440
444
  state = await ensureBound(profile, tools, modelId);
@@ -472,8 +476,21 @@ export function createPiOperatorAgentModel(options) {
472
476
  }
473
477
  }
474
478
  });
479
+ const toolNames = profile.tools.map((tool) => tool.name);
480
+ let prompt = message;
481
+ if (profile.id === AGENT_AUTHOR_PROFILE_ID) {
482
+ prompt = formatAgentAuthorTurnPrompt(message, contextSnapshot);
483
+ prompt = `${prompt}\n\n${agentAuthorBridgeHint(toolNames)}`;
484
+ if (modelId && isCursorModelRef(modelId) && toolNames.length > 0) {
485
+ const aliasLines = toolNames.map((name) => `- pi__${name} (playbook name: ${name})`);
486
+ prompt = `${prompt}\n${aliasLines.join("\n")}`;
487
+ }
488
+ }
489
+ else {
490
+ prompt = cursorBridgePrompt(prompt, modelId, toolNames);
491
+ }
475
492
  try {
476
- await state.handle.session.prompt(cursorBridgePrompt(message, modelId, profile.tools.map((tool) => tool.name)));
493
+ await state.handle.session.prompt(prompt);
477
494
  }
478
495
  catch (err) {
479
496
  unsubscribe();
@@ -529,7 +546,7 @@ export function createPiOperatorAgentModel(options) {
529
546
  return model;
530
547
  }
531
548
  export function createLiveWorkshopOperatorHost(options) {
532
- const { cwd, agentDir, authPath, model, settingsDefault, profileDefault, piSessionDir, openPiSession, resolveModelId, retriever, projectRoot, } = options;
549
+ const { cwd, agentDir, authPath, model, settingsDefault, profileDefault, piSessionDir, openPiSession, resolveModelId, retriever, projectRoot, guideDeps, } = options;
533
550
  return createOperatorAgentHost(createPiOperatorAgentModel({
534
551
  cwd,
535
552
  ...(agentDir !== undefined ? { agentDir } : {}),
@@ -546,5 +563,6 @@ export function createLiveWorkshopOperatorHost(options) {
546
563
  ...(projectRoot !== undefined ? { projectRoot } : {}),
547
564
  }),
548
565
  createAgentAuthorProfile(),
566
+ createStageflowGuideProfile(guideDeps),
549
567
  ]);
550
568
  }
@@ -1,9 +1,11 @@
1
1
  import { type AgentAuthorContext, type AgentAuthorDraft } from "../agentAuthorContext.js";
2
2
  import type { OperatorAgentProfile } from "../types.js";
3
3
  export declare const AGENT_AUTHOR_PROFILE_ID = "agent-author";
4
+ export declare function formatAgentAuthorTurnPrompt(message: string, contextSnapshot: unknown): string;
5
+ export declare function agentAuthorBridgeHint(toolNames: readonly string[]): string;
4
6
  /** Objects merge key by key; arrays and scalars replace; `null` removes the key. */
5
7
  export declare function mergeDraftPatch(draft: AgentAuthorDraft, patch: Record<string, unknown>): AgentAuthorDraft;
6
- export declare const AGENT_AUTHOR_TOOL_NAMES: readonly ["read_project_file", "list_project_files", "list_mcp_servers", "update_agent_draft"];
8
+ export declare const AGENT_AUTHOR_TOOL_NAMES: readonly ["read_agent_draft", "read_project_file", "list_project_files", "list_mcp_servers", "list_author_catalog", "update_agent_draft"];
7
9
  export declare function createAgentAuthorProfile(): OperatorAgentProfile;
8
10
  export declare function createAgentAuthorContext(input: {
9
11
  projectRoot: string;
@@ -1,11 +1,47 @@
1
1
  import { readdir, readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { Type } from "typebox";
4
+ import { parse as parseYaml } from "yaml";
3
5
  import { agentAuthorContextAdapter, emptyAgentAuthorDraft, isAgentAuthorContext, readAgentAuthorDraft, } from "../agentAuthorContext.js";
4
- import { AGENT_ID_PATTERN, parseAgentDefinition } from "../../config/loadAgent.js";
6
+ import { slugAgentId } from "../../agents/agentId.js";
7
+ import { parseAgentDefinition } from "../../config/loadAgent.js";
5
8
  import { listProjectMcpCatalog } from "../../config/resolveStageMcpServers.js";
6
9
  import { AGENT_AUTHOR_PLAYBOOK } from "./agentAuthorPlaybook.js";
10
+ import { authorReadRefusal } from "./authorReadable.js";
11
+ import { connectionsFilePath } from "../../channels/registry.js";
12
+ import { loadConnectionsFile } from "../../channels/config.js";
13
+ import { listSkills } from "../../config/listSkills.js";
14
+ import { globalStageflowHome } from "../../project/globalHome.js";
7
15
  export const AGENT_AUTHOR_PROFILE_ID = "agent-author";
8
16
  const MAX_READ_CHARS = 32_000;
17
+ const closed = { additionalProperties: false };
18
+ const emptyParams = Type.Object({}, closed);
19
+ /** Known top-level AgentDefinition fields; nested values stay Unknown (Workshop pattern). */
20
+ const agentDraftPatchFields = {
21
+ id: Type.Optional(Type.Unknown()),
22
+ name: Type.Optional(Type.Unknown()),
23
+ description: Type.Optional(Type.Unknown()),
24
+ greeting: Type.Optional(Type.Unknown()),
25
+ enabled: Type.Optional(Type.Unknown()),
26
+ instructions: Type.Optional(Type.Unknown()),
27
+ project_context: Type.Optional(Type.Unknown()),
28
+ execution: Type.Optional(Type.Unknown()),
29
+ model: Type.Optional(Type.Unknown()),
30
+ tools: Type.Optional(Type.Unknown()),
31
+ approvals: Type.Optional(Type.Unknown()),
32
+ sub_agents: Type.Optional(Type.Unknown()),
33
+ sub_agent_depth: Type.Optional(Type.Unknown()),
34
+ guardrails: Type.Optional(Type.Unknown()),
35
+ evals: Type.Optional(Type.Unknown()),
36
+ observability: Type.Optional(Type.Unknown()),
37
+ channel: Type.Optional(Type.Unknown()),
38
+ memories: Type.Optional(Type.Unknown()),
39
+ web_chat: Type.Optional(Type.Unknown()),
40
+ schedule: Type.Optional(Type.Unknown()),
41
+ limits: Type.Optional(Type.Unknown()),
42
+ };
43
+ const agentDraftPatchObject = Type.Object(agentDraftPatchFields, closed);
44
+ const AGENT_DRAFT_PATCH_KEYS = new Set(Object.keys(agentDraftPatchFields));
9
45
  let proposalSeq = 0;
10
46
  function nextProposalId() {
11
47
  proposalSeq += 1;
@@ -38,6 +74,74 @@ function stringArg(args, key) {
38
74
  function isPlainObject(value) {
39
75
  return value !== null && typeof value === "object" && !Array.isArray(value);
40
76
  }
77
+ function coercePlainObject(value) {
78
+ if (isPlainObject(value))
79
+ return value;
80
+ if (typeof value !== "string")
81
+ return null;
82
+ const trimmed = value.trim();
83
+ if (!trimmed)
84
+ return null;
85
+ try {
86
+ const parsed = JSON.parse(trimmed);
87
+ if (isPlainObject(parsed))
88
+ return parsed;
89
+ }
90
+ catch {
91
+ /* not JSON */
92
+ }
93
+ try {
94
+ const parsed = parseYaml(trimmed);
95
+ if (isPlainObject(parsed))
96
+ return parsed;
97
+ }
98
+ catch {
99
+ /* not YAML */
100
+ }
101
+ return null;
102
+ }
103
+ export function formatAgentAuthorTurnPrompt(message, contextSnapshot) {
104
+ const draft = readAgentAuthorDraft(contextSnapshot);
105
+ const draftJson = JSON.stringify(draft, null, 2);
106
+ return [
107
+ "Current agent draft JSON. Ask until the job is clear. Call update_agent_draft only when you draft or revise; do not reply with YAML instead:",
108
+ draftJson,
109
+ "",
110
+ "Operator message:",
111
+ message.trim(),
112
+ ].join("\n");
113
+ }
114
+ export function agentAuthorBridgeHint(toolNames) {
115
+ return [
116
+ "Agent author: a thin first request is not a spec. Ask what you still need, or offer one suggestion when the answer is vague. Do not call update_agent_draft until they confirm the job or tell you to go ahead.",
117
+ "When you do change the draft, call update_agent_draft before you finish. Chat YAML does not update the panel.",
118
+ "You may read only docs/, policies/, AGENTS.md, and README.md. Do not grant a connection, MCP server, or skill that list_author_catalog or list_mcp_servers did not return. Do not set tools.browser.",
119
+ `Tools: ${toolNames.join(", ")}`,
120
+ ].join("\n");
121
+ }
122
+ function unknownPatchKeys(patch) {
123
+ return Object.keys(patch).filter((key) => !AGENT_DRAFT_PATCH_KEYS.has(key));
124
+ }
125
+ /** Thin adapter: object / YAML-string `patch`, or flat known fields. Rejects unknown keys after coerce. */
126
+ function patchFromToolArgs(args) {
127
+ let patch = coercePlainObject(args.patch);
128
+ if (!patch) {
129
+ const { summary: _summary, patch: _patch, ...rest } = args;
130
+ if (Object.keys(rest).length === 0)
131
+ return { ok: false, error: "patch must be an object (JSON or YAML)" };
132
+ patch = coercePlainObject(rest) ?? (isPlainObject(rest) ? rest : null);
133
+ }
134
+ if (!patch)
135
+ return { ok: false, error: "patch must be an object (JSON or YAML)" };
136
+ const unknown = unknownPatchKeys(patch);
137
+ if (unknown.length > 0) {
138
+ return {
139
+ ok: false,
140
+ error: `unknown patch field${unknown.length === 1 ? "" : "s"}: ${unknown.join(", ")}`,
141
+ };
142
+ }
143
+ return { ok: true, patch };
144
+ }
41
145
  /** Objects merge key by key; arrays and scalars replace; `null` removes the key. */
42
146
  export function mergeDraftPatch(draft, patch) {
43
147
  const next = structuredClone(draft);
@@ -52,19 +156,10 @@ export function mergeDraftPatch(draft, patch) {
52
156
  }
53
157
  return next;
54
158
  }
55
- function slugId(name) {
56
- const slug = name
57
- .trim()
58
- .toLowerCase()
59
- .replace(/[^a-z0-9]+/g, "_")
60
- .replace(/^_+|_+$/g, "")
61
- .replace(/^[^a-z]+/, "")
62
- .slice(0, 64);
63
- return AGENT_ID_PATTERN.test(slug) ? slug : "";
64
- }
65
159
  const readProjectFile = {
66
160
  name: "read_project_file",
67
161
  description: "Read a text file inside the operator project. Relative path only. Refuses .git, node_modules, and paths outside the project. Does not write.",
162
+ parameters: Type.Object({ path: Type.String({ minLength: 1 }) }, closed),
68
163
  async handler(args, ctx) {
69
164
  const root = projectRootOf(ctx);
70
165
  const rel = stringArg(args, "path")?.trim();
@@ -75,6 +170,9 @@ const readProjectFile = {
75
170
  const rejected = rejectEscape(root, rel);
76
171
  if (rejected)
77
172
  return { ok: false, content: null, error: rejected };
173
+ const docsOnly = authorReadRefusal(rel);
174
+ if (docsOnly)
175
+ return { ok: false, content: null, error: docsOnly };
78
176
  try {
79
177
  const bytes = await readFile(path.resolve(root, rel));
80
178
  if (bytes.includes(0))
@@ -95,35 +193,67 @@ const readProjectFile = {
95
193
  };
96
194
  const listProjectFiles = {
97
195
  name: "list_project_files",
98
- description: "List readable project files: AGENTS.md when present, and YAML files under agents/. Does not write.",
196
+ description: "List documentation the author may read: docs/ and policies/ (.md and .txt), plus AGENTS.md and README.md at the project root. Does not list source code.",
197
+ parameters: emptyParams,
99
198
  async handler(_args, ctx) {
100
199
  const root = projectRootOf(ctx);
101
200
  if (!root)
102
201
  return { ok: false, content: null, error: "project root is not set" };
103
202
  const files = [];
104
- try {
105
- await readFile(path.join(root, "AGENTS.md"));
106
- files.push("AGENTS.md");
107
- }
108
- catch {
109
- /* absent */
203
+ for (const name of ["AGENTS.md", "README.md"]) {
204
+ try {
205
+ await readFile(path.join(root, name));
206
+ files.push(name);
207
+ }
208
+ catch {
209
+ /* absent */
210
+ }
110
211
  }
111
- try {
112
- const entries = await readdir(path.join(root, "agents"), { withFileTypes: true });
212
+ async function walk(rel) {
213
+ let entries;
214
+ try {
215
+ entries = await readdir(path.join(root, rel), { withFileTypes: true });
216
+ }
217
+ catch {
218
+ return;
219
+ }
113
220
  for (const entry of entries) {
114
- if (entry.isFile() && /\.ya?ml$/i.test(entry.name))
115
- files.push(`agents/${entry.name}`);
221
+ if (entry.name.startsWith(".") || entry.name === "node_modules")
222
+ continue;
223
+ const child = `${rel}/${entry.name}`;
224
+ if (entry.isDirectory())
225
+ await walk(child);
226
+ else if (!authorReadRefusal(child))
227
+ files.push(child);
116
228
  }
117
229
  }
118
- catch {
119
- /* no agents dir */
120
- }
230
+ await walk("docs");
231
+ await walk("policies");
232
+ files.sort();
121
233
  return { ok: true, content: { files } };
122
234
  },
123
235
  };
236
+ const readAgentDraft = {
237
+ name: "read_agent_draft",
238
+ description: "Read the current unsaved agent draft (agents/<id>.agent.yaml shape). Use before update_agent_draft when you need the latest fields.",
239
+ parameters: emptyParams,
240
+ handler(_args, ctx) {
241
+ const draft = readAgentAuthorDraft(ctx.getContext());
242
+ const context = ctx.getContext();
243
+ const projectRoot = isAgentAuthorContext(context) ? context.projectRoot : undefined;
244
+ return {
245
+ ok: true,
246
+ content: {
247
+ ...(projectRoot ? { projectRoot } : {}),
248
+ draft,
249
+ },
250
+ };
251
+ },
252
+ };
124
253
  const listMcpServers = {
125
254
  name: "list_mcp_servers",
126
255
  description: "List MCP server names declared in the project's .mcp.json. Use these names under tools.mcp. Does not connect.",
256
+ parameters: emptyParams,
127
257
  async handler(_args, ctx) {
128
258
  const root = projectRootOf(ctx);
129
259
  if (!root)
@@ -132,6 +262,33 @@ const listMcpServers = {
132
262
  return { ok: true, content: { status: catalog.status, servers: catalog.servers.map((server) => server.name) } };
133
263
  },
134
264
  };
265
+ const listAuthorCatalog = {
266
+ name: "list_author_catalog",
267
+ description: "List host connections (id and provider only) and installed skill names. No secrets. Use these ids in channel.connection_id and tools.skills. If a name is not listed, do not grant it.",
268
+ parameters: emptyParams,
269
+ async handler(_args, ctx) {
270
+ const root = projectRootOf(ctx);
271
+ if (!root)
272
+ return { ok: false, content: null, error: "project root is not set" };
273
+ let connections = [];
274
+ try {
275
+ const loaded = loadConnectionsFile(connectionsFilePath(root));
276
+ connections = loaded.connections.map((entry) => ({ id: entry.id, provider: entry.provider }));
277
+ }
278
+ catch {
279
+ connections = [];
280
+ }
281
+ let skills = [];
282
+ try {
283
+ const catalog = await listSkills({ cwd: root, agentDir: path.join(globalStageflowHome(), "workshop", "agent") });
284
+ skills = catalog.skills.map((skill) => skill.name);
285
+ }
286
+ catch {
287
+ skills = [];
288
+ }
289
+ return { ok: true, content: { connections, skills } };
290
+ },
291
+ };
135
292
  const updateAgentDraft = {
136
293
  name: "update_agent_draft",
137
294
  description: [
@@ -139,15 +296,20 @@ const updateAgentDraft = {
139
296
  "patch uses the agent YAML schema: objects merge key by key, arrays replace, null removes a key.",
140
297
  "The result lists validation issues; fix them in a follow-up patch. Does not write YAML.",
141
298
  ].join(" "),
299
+ parameters: Type.Object({
300
+ patch: agentDraftPatchObject,
301
+ summary: Type.Optional(Type.String()),
302
+ }, closed),
142
303
  handler(args, ctx) {
143
- const patch = args.patch;
144
- if (!isPlainObject(patch))
145
- return { ok: false, content: null, error: "patch must be an object" };
304
+ const parsedPatch = patchFromToolArgs(args);
305
+ if (!parsedPatch.ok)
306
+ return { ok: false, content: null, error: parsedPatch.error };
307
+ const patch = parsedPatch.patch;
146
308
  const currentContext = ctx.getContext();
147
309
  const current = readAgentAuthorDraft(currentContext);
148
310
  const next = mergeDraftPatch(current, patch);
149
311
  if (typeof next.name === "string" && next.name.trim() && !(typeof next.id === "string" && next.id.trim())) {
150
- const id = slugId(next.name);
312
+ const id = slugAgentId(next.name);
151
313
  if (id)
152
314
  next.id = id;
153
315
  }
@@ -172,14 +334,21 @@ const updateAgentDraft = {
172
334
  };
173
335
  },
174
336
  };
175
- export const AGENT_AUTHOR_TOOL_NAMES = ["read_project_file", "list_project_files", "list_mcp_servers", "update_agent_draft"];
337
+ export const AGENT_AUTHOR_TOOL_NAMES = [
338
+ "read_agent_draft",
339
+ "read_project_file",
340
+ "list_project_files",
341
+ "list_mcp_servers",
342
+ "list_author_catalog",
343
+ "update_agent_draft",
344
+ ];
176
345
  export function createAgentAuthorProfile() {
177
346
  return {
178
347
  id: AGENT_AUTHOR_PROFILE_ID,
179
348
  title: "Agent author",
180
349
  playbook: AGENT_AUTHOR_PLAYBOOK,
181
- greeting: "What should this agent do?",
182
- tools: [readProjectFile, listProjectFiles, listMcpServers, updateAgentDraft],
350
+ greeting: "Who is this agent for, and what does a good result look like? I'll ask a few questions before I fill the config.",
351
+ tools: [readAgentDraft, readProjectFile, listProjectFiles, listMcpServers, listAuthorCatalog, updateAgentDraft],
183
352
  contextAdapter: agentAuthorContextAdapter(),
184
353
  };
185
354
  }
@@ -1 +1 @@
1
- export declare const AGENT_AUTHOR_PLAYBOOK = "You are the Stageflow Agent author. You draft one sealed project agent with the operator. You are not a task runner, and you do not write files.\n\n## How you talk\n- Short turns, plain words, present tense. One to four sentences.\n- Do not narrate tool names. Say what changed in the config.\n- The config panel shows the draft. The operator can edit it directly; your next patch builds on what they changed.\n\n## Tools\n- read_project_file and list_project_files are read-only. Use them when the operator points at the project, an existing agent file, or AGENTS.md.\n- list_mcp_servers names the servers in .mcp.json. Only grant MCP servers that exist there; if the operator wants one that isn't there, say so.\n- update_agent_draft applies a patch to the draft immediately. Call it as soon as you know enough. Do not wait for Keep. If it reports issues, fix them with another patch.\n- Never use bash, write, or edit. Save is the operator's button, not a tool.\n\n## The draft (agents/<id>.agent.yaml schema)\n- id (snake_case, starts with a letter; derived from name when omitted), name, description, greeting, instructions (required).\n- model: { backend: pi | claude, id?: \"provider/model\", thinking: low | medium | high }. Leave id out to use the project default unless they name one, and say so.\n- tools: { builtin: [read | write | shell] (whole groups), builtin_tools: [read | grep | find | ls | write | edit | bash] (single tools), stageflow: { groups: [...], tools: [...] }, mcp: { <server>: [tool names] or [\"*\"] }, skills: [names], browser: bool }.\n- approvals: { ask_first: [tool ids], approvers: { operators: bool, channel_ids: [] }, timeout_minutes, on_timeout: skip | deny }.\n Tool ids: builtin names (read, grep, find, ls, write, edit, bash), \"<server>.<tool>\" for MCP, \"agent:<id>\" for sub-agents. ask_first may only name granted tools.\n- sub_agents: [agent ids], observability: { capture: off | metadata | full }, limits: { session_minutes, max_turns, cost_usd | null, long_context: summarize | truncate }, guardrails: { block_patterns: [JavaScript regex] }, schedule: { cron, timezone?, message? }.\n\n## Defaults\n- A new agent saves disabled and starts sealed: read only. Write and shell stay off unless the job needs them.\n- Anything that sends, posts, writes, merges or deletes goes in approvals.ask_first.\n- Capture stays metadata unless they ask for full content.\n\n## After an edit\n- One sentence on what the agent will do now. Mention any assumption or open question. Do not paste YAML unless they ask.\n";
1
+ export declare const AGENT_AUTHOR_PLAYBOOK = "You are the Stageflow Agent author. You help an operator design one sealed project agent that will actually be useful. You are not a task runner, and you do not write files.\n\nA first message is a starting point, not a spec. Your job is to understand the use case before you fill the config.\n\n## How you talk\n- Short turns, plain words, present tense.\n- Two or three questions a turn. Do not dump a questionnaire.\n- Do not narrate tool names.\n- The config panel shows the draft. The operator can edit it directly; your next patch builds on what they changed.\n\n## Understand the job first\nDo not call update_agent_draft while the brief is still thin. Asking questions is a complete turn.\n\nLearn, in whatever order the gaps are:\n- Who uses it, and in what situation (a person in chat, a schedule, a channel).\n- What a good result looks like, and what a bad one looks like.\n- What it may read, and what it may change.\n- What it must never do without asking.\n- Where the source of truth lives. You may read only documentation: docs/, policies/, AGENTS.md, and README.md (.md and .txt). You cannot read source code. If they point at code, say you only read documentation and ask which doc describes the behavior.\n\nUse what they already said. Ask only what would change the draft.\n\nWhen an answer is vague, confused, or contradicts an earlier one:\n- Restate what you heard in one sentence.\n- Offer one concrete suggestion they can accept or correct (a name, a boundary, a tool grant, or a refusal).\n- Ask which part is wrong.\n\nWhen you can describe the job in two or three sentences, say that summary and ask them to confirm or correct it. Do not draft before they confirm, unless they tell you to go ahead anyway.\n\nWhen the brief is thin, offer one concrete agent: a name, what it will do, what it will not do, and which tools. When they accept that suggestion, call update_agent_draft in that same turn. Do not wait for another question.\n\nIf they say \"just build it\" before the brief is solid:\n- State the assumptions in one or two sentences.\n- Offer the narrowest useful version.\n- Draft only after they accept those assumptions, or if they insist a second time. Name every assumption in the reply after you draft.\n\n## When you draft\n- Call update_agent_draft in that turn. Chat text does not update the panel. Do not paste YAML unless they ask to see it.\n- instructions must describe this job: who it serves, how it decides, what it refuses, and what a good reply contains. Do not write a generic \"be helpful\" prompt.\n- Grant only the tools the job needs. A new agent stays sealed: read only, until the job needs write or shell.\n- Anything that sends, posts, writes, merges, or deletes goes in approvals.ask_first.\n- Leave model.id unset unless they name a model, and say you did that.\n- Capture stays metadata unless they ask for full content.\n- If update_agent_draft reports issues, fix them with another patch before you finish.\n\nAfter the patch, one sentence on what the agent will do. Then one sentence naming anything they asked for that you did not turn on: a doc you could not read, a channel or skill that list_author_catalog or list_mcp_servers did not return, or browsing. Do not set tools.browser. Do not invent a connection id, MCP server, or skill name.\n\n## Tools\n- read_agent_draft returns the current unsaved draft JSON. Each turn also includes that draft in the operator message.\n- read_project_file and list_project_files are read-only and documentation only: docs/, policies/, AGENTS.md, and README.md, and only .md or .txt. A refused path means you tell them you cannot read code or other files.\n- list_mcp_servers names the servers in .mcp.json. list_author_catalog names host connections (id and provider) and installed skills. Grant only names those tools return. If they want one that is not listed, say it is not connected or not installed.\n- update_agent_draft applies a patch of known agent fields immediately. Objects merge key by key, arrays replace, null removes a key. Unknown fields are rejected. Do not wait for Keep.\n- Never use bash, write, or edit. Save is the operator's button, not a tool.\n\n## The draft (agents/<id>.agent.yaml schema)\n- id (snake_case, starts with a letter; derived from name when omitted), name, description, greeting, instructions (required).\n- model: { backend: pi | claude, id?: \"provider/model\", thinking: low | medium | high }.\n- tools: { builtin: [read | write | shell] (whole groups), builtin_tools: [read | grep | find | ls | write | edit | bash] (single tools), stageflow: { groups: [...], tools: [...] }, mcp: { <server>: [tool names] or [\"*\"] }, skills: [names], browser: bool }.\n- approvals: { ask_first: [tool ids], approvers: { operators: bool, channel_ids: [] }, timeout_minutes, on_timeout: skip | deny }.\n Tool ids: builtin names (read, grep, find, ls, write, edit, bash), \"<server>.<tool>\" for MCP, \"agent:<id>\" for sub-agents. ask_first may only name granted tools.\n- sub_agents: [agent ids], observability: { capture: off | metadata | full }, limits: { session_minutes, max_turns, cost_usd | null, long_context: summarize | truncate }, guardrails: { block_patterns: [JavaScript regex] }, schedule: { cron, timezone?, message? }.\n";
@@ -1,29 +1,62 @@
1
- export const AGENT_AUTHOR_PLAYBOOK = `You are the Stageflow Agent author. You draft one sealed project agent with the operator. You are not a task runner, and you do not write files.
1
+ export const AGENT_AUTHOR_PLAYBOOK = `You are the Stageflow Agent author. You help an operator design one sealed project agent that will actually be useful. You are not a task runner, and you do not write files.
2
+
3
+ A first message is a starting point, not a spec. Your job is to understand the use case before you fill the config.
2
4
 
3
5
  ## How you talk
4
- - Short turns, plain words, present tense. One to four sentences.
5
- - Do not narrate tool names. Say what changed in the config.
6
+ - Short turns, plain words, present tense.
7
+ - Two or three questions a turn. Do not dump a questionnaire.
8
+ - Do not narrate tool names.
6
9
  - The config panel shows the draft. The operator can edit it directly; your next patch builds on what they changed.
7
10
 
11
+ ## Understand the job first
12
+ Do not call update_agent_draft while the brief is still thin. Asking questions is a complete turn.
13
+
14
+ Learn, in whatever order the gaps are:
15
+ - Who uses it, and in what situation (a person in chat, a schedule, a channel).
16
+ - What a good result looks like, and what a bad one looks like.
17
+ - What it may read, and what it may change.
18
+ - What it must never do without asking.
19
+ - Where the source of truth lives. You may read only documentation: docs/, policies/, AGENTS.md, and README.md (.md and .txt). You cannot read source code. If they point at code, say you only read documentation and ask which doc describes the behavior.
20
+
21
+ Use what they already said. Ask only what would change the draft.
22
+
23
+ When an answer is vague, confused, or contradicts an earlier one:
24
+ - Restate what you heard in one sentence.
25
+ - Offer one concrete suggestion they can accept or correct (a name, a boundary, a tool grant, or a refusal).
26
+ - Ask which part is wrong.
27
+
28
+ When you can describe the job in two or three sentences, say that summary and ask them to confirm or correct it. Do not draft before they confirm, unless they tell you to go ahead anyway.
29
+
30
+ When the brief is thin, offer one concrete agent: a name, what it will do, what it will not do, and which tools. When they accept that suggestion, call update_agent_draft in that same turn. Do not wait for another question.
31
+
32
+ If they say "just build it" before the brief is solid:
33
+ - State the assumptions in one or two sentences.
34
+ - Offer the narrowest useful version.
35
+ - Draft only after they accept those assumptions, or if they insist a second time. Name every assumption in the reply after you draft.
36
+
37
+ ## When you draft
38
+ - Call update_agent_draft in that turn. Chat text does not update the panel. Do not paste YAML unless they ask to see it.
39
+ - instructions must describe this job: who it serves, how it decides, what it refuses, and what a good reply contains. Do not write a generic "be helpful" prompt.
40
+ - Grant only the tools the job needs. A new agent stays sealed: read only, until the job needs write or shell.
41
+ - Anything that sends, posts, writes, merges, or deletes goes in approvals.ask_first.
42
+ - Leave model.id unset unless they name a model, and say you did that.
43
+ - Capture stays metadata unless they ask for full content.
44
+ - If update_agent_draft reports issues, fix them with another patch before you finish.
45
+
46
+ After the patch, one sentence on what the agent will do. Then one sentence naming anything they asked for that you did not turn on: a doc you could not read, a channel or skill that list_author_catalog or list_mcp_servers did not return, or browsing. Do not set tools.browser. Do not invent a connection id, MCP server, or skill name.
47
+
8
48
  ## Tools
9
- - read_project_file and list_project_files are read-only. Use them when the operator points at the project, an existing agent file, or AGENTS.md.
10
- - list_mcp_servers names the servers in .mcp.json. Only grant MCP servers that exist there; if the operator wants one that isn't there, say so.
11
- - update_agent_draft applies a patch to the draft immediately. Call it as soon as you know enough. Do not wait for Keep. If it reports issues, fix them with another patch.
49
+ - read_agent_draft returns the current unsaved draft JSON. Each turn also includes that draft in the operator message.
50
+ - read_project_file and list_project_files are read-only and documentation only: docs/, policies/, AGENTS.md, and README.md, and only .md or .txt. A refused path means you tell them you cannot read code or other files.
51
+ - list_mcp_servers names the servers in .mcp.json. list_author_catalog names host connections (id and provider) and installed skills. Grant only names those tools return. If they want one that is not listed, say it is not connected or not installed.
52
+ - update_agent_draft applies a patch of known agent fields immediately. Objects merge key by key, arrays replace, null removes a key. Unknown fields are rejected. Do not wait for Keep.
12
53
  - Never use bash, write, or edit. Save is the operator's button, not a tool.
13
54
 
14
55
  ## The draft (agents/<id>.agent.yaml schema)
15
56
  - id (snake_case, starts with a letter; derived from name when omitted), name, description, greeting, instructions (required).
16
- - model: { backend: pi | claude, id?: "provider/model", thinking: low | medium | high }. Leave id out to use the project default unless they name one, and say so.
57
+ - model: { backend: pi | claude, id?: "provider/model", thinking: low | medium | high }.
17
58
  - tools: { builtin: [read | write | shell] (whole groups), builtin_tools: [read | grep | find | ls | write | edit | bash] (single tools), stageflow: { groups: [...], tools: [...] }, mcp: { <server>: [tool names] or ["*"] }, skills: [names], browser: bool }.
18
59
  - approvals: { ask_first: [tool ids], approvers: { operators: bool, channel_ids: [] }, timeout_minutes, on_timeout: skip | deny }.
19
60
  Tool ids: builtin names (read, grep, find, ls, write, edit, bash), "<server>.<tool>" for MCP, "agent:<id>" for sub-agents. ask_first may only name granted tools.
20
61
  - sub_agents: [agent ids], observability: { capture: off | metadata | full }, limits: { session_minutes, max_turns, cost_usd | null, long_context: summarize | truncate }, guardrails: { block_patterns: [JavaScript regex] }, schedule: { cron, timezone?, message? }.
21
-
22
- ## Defaults
23
- - A new agent saves disabled and starts sealed: read only. Write and shell stay off unless the job needs them.
24
- - Anything that sends, posts, writes, merges or deletes goes in approvals.ask_first.
25
- - Capture stays metadata unless they ask for full content.
26
-
27
- ## After an edit
28
- - One sentence on what the agent will do now. Mention any assumption or open question. Do not paste YAML unless they ask.
29
62
  `;
@@ -0,0 +1,2 @@
1
+ /** Relative project path the agent author may read. Null when it is documentation. */
2
+ export declare function authorReadRefusal(rel: string): string | null;
@@ -0,0 +1,26 @@
1
+ const DOC_ROOTS = new Set(["docs", "policies"]);
2
+ const ROOT_FILES = new Set(["AGENTS.md", "README.md"]);
3
+ /** Relative project path the agent author may read. Null when it is documentation. */
4
+ export function authorReadRefusal(rel) {
5
+ const normalized = rel.replace(/\\/g, "/").replace(/^\.\//, "");
6
+ if (!normalized || normalized.startsWith("/") || normalized.split("/").includes("..")) {
7
+ return "path is outside the readable project surface";
8
+ }
9
+ const segments = normalized.split("/").filter(Boolean);
10
+ if (segments.some((part) => part === ".git" || part === "node_modules" || part.startsWith("."))) {
11
+ return "path is outside the readable project surface";
12
+ }
13
+ if (ROOT_FILES.has(normalized))
14
+ return null;
15
+ const [head, ...rest] = segments;
16
+ if (!head || !DOC_ROOTS.has(head)) {
17
+ return "only documentation under docs/ and policies/, plus AGENTS.md and README.md, can be read";
18
+ }
19
+ if (rest.length === 0)
20
+ return "path must be a documentation file";
21
+ const base = rest[rest.length - 1] ?? "";
22
+ if (!base.endsWith(".md") && !base.endsWith(".txt")) {
23
+ return "only .md and .txt documentation can be read";
24
+ }
25
+ return null;
26
+ }
@@ -0,0 +1,21 @@
1
+ import type { OperatorAgentTool, OperatorAgentToolContext, OperatorAgentToolResult } from "../types.js";
2
+ export declare const CONFIRM_ACTION_TOOL = "confirm_action";
3
+ export declare const GUIDE_CONFIRMED_TOOLS: ReadonlySet<string>;
4
+ type Confirmation = {
5
+ id: string;
6
+ tool: string;
7
+ summary: string;
8
+ turn: number;
9
+ };
10
+ export type GuideSessionContext = {
11
+ kind: "stageflow_guide";
12
+ turn: number;
13
+ confirmations: Confirmation[];
14
+ };
15
+ export declare function guideContextOf(value: unknown): GuideSessionContext;
16
+ /** Call once per person message, before the session sees it. */
17
+ export declare function advanceGuideTurn(value: unknown): GuideSessionContext;
18
+ export declare function createConfirmActionTool(): OperatorAgentTool;
19
+ /** Consumes a confirmation issued in an earlier turn for this tool. */
20
+ export declare function checkGuideConfirmation(tool: string, args: Record<string, unknown>, ctx: OperatorAgentToolContext): OperatorAgentToolResult | null;
21
+ export {};