stageflow 0.35.0 → 0.39.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 (320) hide show
  1. package/README.md +18 -8
  2. package/dist/agent/claudeAdapter.js +12 -0
  3. package/dist/agent/piAdapter.d.ts +9 -1
  4. package/dist/agent/piAdapter.js +30 -2
  5. package/dist/agent/piIsolatedMcp.js +14 -2
  6. package/dist/agent/piIsolatedMcpProbe.d.ts +5 -1
  7. package/dist/agent/piIsolatedMcpProbe.js +16 -30
  8. package/dist/agent/port.d.ts +7 -0
  9. package/dist/agents/agentId.d.ts +8 -0
  10. package/dist/agents/agentId.js +27 -0
  11. package/dist/agents/approvalBroker.d.ts +16 -0
  12. package/dist/agents/approvalBroker.js +45 -0
  13. package/dist/agents/authorChat.d.ts +19 -0
  14. package/dist/agents/authorChat.js +63 -0
  15. package/dist/agents/chatTurn.d.ts +23 -0
  16. package/dist/agents/chatTurn.js +77 -0
  17. package/dist/agents/communications/agentmail.d.ts +19 -0
  18. package/dist/agents/communications/agentmail.js +46 -0
  19. package/dist/agents/communications/agentmailListener.d.ts +59 -0
  20. package/dist/agents/communications/agentmailListener.js +183 -0
  21. package/dist/agents/communications/allowlist.d.ts +10 -0
  22. package/dist/agents/communications/allowlist.js +36 -0
  23. package/dist/agents/communications/channelConnections.d.ts +3 -0
  24. package/dist/agents/communications/channelConnections.js +51 -0
  25. package/dist/agents/communications/delivery.d.ts +53 -0
  26. package/dist/agents/communications/delivery.js +142 -0
  27. package/dist/agents/communications/email.d.ts +26 -0
  28. package/dist/agents/communications/email.js +20 -0
  29. package/dist/agents/communications/identity.d.ts +13 -0
  30. package/dist/agents/communications/identity.js +18 -0
  31. package/dist/agents/communications/imessageListener.d.ts +41 -0
  32. package/dist/agents/communications/imessageListener.js +92 -0
  33. package/dist/agents/communications/inbound.d.ts +63 -0
  34. package/dist/agents/communications/inbound.js +143 -0
  35. package/dist/agents/communications/listener.d.ts +36 -0
  36. package/dist/agents/communications/listener.js +38 -0
  37. package/dist/agents/communications/photon.d.ts +19 -0
  38. package/dist/agents/communications/photon.js +38 -0
  39. package/dist/agents/communications/port.d.ts +27 -0
  40. package/dist/agents/communications/port.js +6 -0
  41. package/dist/agents/communications/slack.d.ts +28 -0
  42. package/dist/agents/communications/slack.js +65 -0
  43. package/dist/agents/communications/supervisor.d.ts +36 -0
  44. package/dist/agents/communications/supervisor.js +96 -0
  45. package/dist/agents/communications/telegram.d.ts +19 -0
  46. package/dist/agents/communications/telegram.js +52 -0
  47. package/dist/agents/definitionSummary.d.ts +13 -0
  48. package/dist/agents/definitionSummary.js +91 -0
  49. package/dist/agents/delegate.d.ts +3 -0
  50. package/dist/agents/delegate.js +8 -0
  51. package/dist/agents/errors.d.ts +10 -0
  52. package/dist/agents/errors.js +32 -0
  53. package/dist/agents/guardrails.d.ts +24 -0
  54. package/dist/agents/guardrails.js +39 -0
  55. package/dist/agents/historyFit.d.ts +10 -0
  56. package/dist/agents/historyFit.js +26 -0
  57. package/dist/agents/hostContext.d.ts +54 -0
  58. package/dist/agents/hostContext.js +156 -0
  59. package/dist/agents/ledgers.d.ts +29 -0
  60. package/dist/agents/ledgers.js +31 -0
  61. package/dist/agents/lineDiff.d.ts +12 -0
  62. package/dist/agents/lineDiff.js +46 -0
  63. package/dist/agents/ndjson.d.ts +9 -0
  64. package/dist/agents/ndjson.js +47 -0
  65. package/dist/agents/otlpExport.d.ts +9 -0
  66. package/dist/agents/otlpExport.js +58 -0
  67. package/dist/agents/otlpSink.d.ts +7 -0
  68. package/dist/agents/otlpSink.js +23 -0
  69. package/dist/agents/policy.d.ts +31 -0
  70. package/dist/agents/policy.js +84 -0
  71. package/dist/agents/projectRoot.d.ts +5 -0
  72. package/dist/agents/projectRoot.js +15 -0
  73. package/dist/agents/runtime/piRuntime.d.ts +52 -0
  74. package/dist/agents/runtime/piRuntime.js +474 -0
  75. package/dist/agents/runtime/types.d.ts +77 -0
  76. package/dist/agents/runtime/types.js +26 -0
  77. package/dist/agents/sandbox.d.ts +17 -0
  78. package/dist/agents/sandbox.js +10 -0
  79. package/dist/agents/scheduleSource.d.ts +32 -0
  80. package/dist/agents/scheduleSource.js +100 -0
  81. package/dist/agents/service.d.ts +298 -0
  82. package/dist/agents/service.js +1105 -0
  83. package/dist/agents/sessions.d.ts +38 -0
  84. package/dist/agents/sessions.js +321 -0
  85. package/dist/agents/store.d.ts +277 -0
  86. package/dist/agents/store.js +643 -0
  87. package/dist/agents/trace.d.ts +27 -0
  88. package/dist/agents/trace.js +29 -0
  89. package/dist/agents/turnLifecycle.d.ts +72 -0
  90. package/dist/agents/turnLifecycle.js +157 -0
  91. package/dist/agents/webChat/publicChat.d.ts +36 -0
  92. package/dist/agents/webChat/publicChat.js +290 -0
  93. package/dist/agents/webChat/rateLimit.d.ts +15 -0
  94. package/dist/agents/webChat/rateLimit.js +33 -0
  95. package/dist/agents/webChat/slug.d.ts +2 -0
  96. package/dist/agents/webChat/slug.js +9 -0
  97. package/dist/channels/config.d.ts +11 -0
  98. package/dist/channels/config.js +95 -0
  99. package/dist/channels/configWriter.d.ts +40 -0
  100. package/dist/channels/configWriter.js +148 -0
  101. package/dist/channels/connectionEdits.d.ts +34 -0
  102. package/dist/channels/connectionEdits.js +53 -0
  103. package/dist/channels/errorInfo.d.ts +18 -0
  104. package/dist/channels/errorInfo.js +71 -0
  105. package/dist/channels/errors.d.ts +12 -0
  106. package/dist/channels/errors.js +13 -0
  107. package/dist/channels/health.d.ts +41 -0
  108. package/dist/channels/health.js +99 -0
  109. package/dist/channels/host.d.ts +55 -0
  110. package/dist/channels/host.js +185 -0
  111. package/dist/channels/http.d.ts +31 -0
  112. package/dist/channels/http.js +79 -0
  113. package/dist/channels/index.d.ts +10 -0
  114. package/dist/channels/index.js +9 -0
  115. package/dist/channels/ledger.d.ts +37 -0
  116. package/dist/channels/ledger.js +95 -0
  117. package/dist/channels/providers/agentmail.d.ts +26 -0
  118. package/dist/channels/providers/agentmail.js +94 -0
  119. package/dist/channels/providers/kit.d.ts +40 -0
  120. package/dist/channels/providers/kit.js +78 -0
  121. package/dist/channels/providers/photonImessage.d.ts +45 -0
  122. package/dist/channels/providers/photonImessage.js +188 -0
  123. package/dist/channels/providers/photonWhatsapp.d.ts +49 -0
  124. package/dist/channels/providers/photonWhatsapp.js +146 -0
  125. package/dist/channels/providers/slack.d.ts +25 -0
  126. package/dist/channels/providers/slack.js +102 -0
  127. package/dist/channels/providers/telegram.d.ts +21 -0
  128. package/dist/channels/providers/telegram.js +101 -0
  129. package/dist/channels/providers.d.ts +5 -0
  130. package/dist/channels/providers.js +22 -0
  131. package/dist/channels/registry.d.ts +54 -0
  132. package/dist/channels/registry.js +186 -0
  133. package/dist/channels/secretStore.d.ts +21 -0
  134. package/dist/channels/secretStore.js +75 -0
  135. package/dist/channels/secrets.d.ts +15 -0
  136. package/dist/channels/secrets.js +50 -0
  137. package/dist/channels/service.d.ts +54 -0
  138. package/dist/channels/service.js +307 -0
  139. package/dist/channels/stageChannels.d.ts +45 -0
  140. package/dist/channels/stageChannels.js +110 -0
  141. package/dist/channels/types.d.ts +169 -0
  142. package/dist/channels/types.js +1 -0
  143. package/dist/cli/agentsCommand.d.ts +14 -0
  144. package/dist/cli/agentsCommand.js +291 -0
  145. package/dist/cli/doctorCommand.js +3 -1
  146. package/dist/cli.js +9 -0
  147. package/dist/config/browseCatalog.js +4 -11
  148. package/dist/config/draftPackage.d.ts +2 -0
  149. package/dist/config/draftPackage.js +8 -0
  150. package/dist/config/hostConfig.js +8 -0
  151. package/dist/config/loadAgent.d.ts +266 -0
  152. package/dist/config/loadAgent.js +374 -0
  153. package/dist/config/loadPipeline.js +31 -4
  154. package/dist/config/loadStage.js +15 -0
  155. package/dist/config/mcpHostCatalog.d.ts +50 -0
  156. package/dist/config/mcpHostCatalog.js +405 -0
  157. package/dist/config/mcpOAuth.d.ts +37 -0
  158. package/dist/config/mcpOAuth.js +263 -0
  159. package/dist/config/mcpRedaction.d.ts +42 -0
  160. package/dist/config/mcpRedaction.js +314 -0
  161. package/dist/config/mcpToolCache.d.ts +20 -0
  162. package/dist/config/mcpToolCache.js +43 -0
  163. package/dist/config/mergePipelineIncludes.d.ts +5 -0
  164. package/dist/config/mergePipelineIncludes.js +52 -0
  165. package/dist/config/pipelineStageKeys.js +1 -0
  166. package/dist/config/resolveStageMcpServers.d.ts +35 -3
  167. package/dist/config/resolveStageMcpServers.js +124 -9
  168. package/dist/config/validateCatalog.d.ts +4 -1
  169. package/dist/config/validateCatalog.js +45 -1
  170. package/dist/errors/codes.d.ts +1 -1
  171. package/dist/errors/codes.js +1 -0
  172. package/dist/mcp/agentTools.d.ts +8 -0
  173. package/dist/mcp/agentTools.js +132 -0
  174. package/dist/mcp/catalogTools.js +7 -9
  175. package/dist/mcp/deps.d.ts +6 -0
  176. package/dist/mcp/pipelineAuthorSupport.d.ts +19 -0
  177. package/dist/mcp/pipelineAuthorSupport.js +10 -0
  178. package/dist/mcp/pipelineAuthorTools.d.ts +8 -0
  179. package/dist/mcp/pipelineAuthorTools.js +109 -0
  180. package/dist/mcp/server.js +5 -0
  181. package/dist/mcp/tools.js +4 -0
  182. package/dist/mcp/triggerTools.js +32 -0
  183. package/dist/memory/access.d.ts +36 -0
  184. package/dist/memory/access.js +116 -0
  185. package/dist/memory/agentIssues.d.ts +3 -0
  186. package/dist/memory/agentIssues.js +23 -0
  187. package/dist/memory/bashDeny.d.ts +6 -0
  188. package/dist/memory/bashDeny.js +35 -0
  189. package/dist/memory/host.d.ts +51 -0
  190. package/dist/memory/host.js +394 -0
  191. package/dist/memory/ids.d.ts +15 -0
  192. package/dist/memory/ids.js +31 -0
  193. package/dist/memory/worker.d.ts +1 -0
  194. package/dist/memory/worker.js +84 -0
  195. package/dist/models/catalog.d.ts +113 -0
  196. package/dist/models/catalog.js +238 -0
  197. package/dist/models/response.d.ts +29 -0
  198. package/dist/models/response.js +25 -0
  199. package/dist/operatorAgent/agentAuthorContext.d.ts +17 -0
  200. package/dist/operatorAgent/agentAuthorContext.js +32 -0
  201. package/dist/operatorAgent/fakeHost.js +2 -0
  202. package/dist/operatorAgent/host.js +6 -3
  203. package/dist/operatorAgent/index.d.ts +4 -0
  204. package/dist/operatorAgent/index.js +4 -0
  205. package/dist/operatorAgent/piModel.js +2 -0
  206. package/dist/operatorAgent/profiles/agentAuthor.d.ts +11 -0
  207. package/dist/operatorAgent/profiles/agentAuthor.js +192 -0
  208. package/dist/operatorAgent/profiles/agentAuthorPlaybook.d.ts +1 -0
  209. package/dist/operatorAgent/profiles/agentAuthorPlaybook.js +29 -0
  210. package/dist/operatorAgent/profiles/workshopAuthor.js +2 -2
  211. package/dist/operatorAgent/profiles/workshopAuthorTools.js +3 -3
  212. package/dist/operatorAgent/proposals.d.ts +1 -0
  213. package/dist/operatorAgent/proposals.js +23 -2
  214. package/dist/package-meta.d.ts +1 -1
  215. package/dist/package-meta.js +1 -1
  216. package/dist/preflight/channelChecks.d.ts +17 -0
  217. package/dist/preflight/channelChecks.js +106 -0
  218. package/dist/preflight/pipelinePreflight.d.ts +9 -2
  219. package/dist/preflight/pipelinePreflight.js +10 -1
  220. package/dist/runstore/createStore.d.ts +2 -0
  221. package/dist/runstore/createStore.js +8 -0
  222. package/dist/runstore/overviewSummary.d.ts +56 -0
  223. package/dist/runstore/overviewSummary.js +134 -0
  224. package/dist/runstore/port.d.ts +3 -0
  225. package/dist/runstore/sqlite/SqliteRunStore.d.ts +2 -0
  226. package/dist/runstore/sqlite/SqliteRunStore.js +18 -0
  227. package/dist/runstore/sqlite/migrations/013-agents.d.ts +12 -0
  228. package/dist/runstore/sqlite/migrations/013-agents.js +156 -0
  229. package/dist/runstore/sqlite/migrations/014-agent-deliveries.d.ts +11 -0
  230. package/dist/runstore/sqlite/migrations/014-agent-deliveries.js +32 -0
  231. package/dist/runstore/sqlite/migrations/index.js +4 -0
  232. package/dist/runtime/pipelineRunner.js +3 -1
  233. package/dist/runtime/repositoryMaterialize.d.ts +1 -1
  234. package/dist/runtime/runManager.js +4 -1
  235. package/dist/runtime/stageAttemptBootstrap.js +31 -1
  236. package/dist/runtime/stageEnvironment.d.ts +2 -0
  237. package/dist/runtime/stageEnvironment.js +6 -1
  238. package/dist/runtime/stageProcessLauncher.js +54 -1
  239. package/dist/runtime/stageSecrets.d.ts +6 -1
  240. package/dist/runtime/stageSecrets.js +34 -1
  241. package/dist/server/agentAuthorRoutes.d.ts +5 -0
  242. package/dist/server/agentAuthorRoutes.js +64 -0
  243. package/dist/server/agentRoutes.d.ts +5 -0
  244. package/dist/server/agentRoutes.js +323 -0
  245. package/dist/server/bootstrap.d.ts +11 -0
  246. package/dist/server/bootstrap.js +40 -10
  247. package/dist/server/channelRoutes.d.ts +9 -0
  248. package/dist/server/channelRoutes.js +88 -0
  249. package/dist/server/controlToken.js +8 -0
  250. package/dist/server/http.d.ts +8 -1
  251. package/dist/server/http.js +183 -20
  252. package/dist/server/mcpHost.js +1 -0
  253. package/dist/server/memoryRoutes.d.ts +5 -0
  254. package/dist/server/memoryRoutes.js +146 -0
  255. package/dist/server/projectMcpRoutes.d.ts +1 -0
  256. package/dist/server/projectMcpRoutes.js +241 -3
  257. package/dist/toolkit/guard.d.ts +27 -0
  258. package/dist/toolkit/guard.js +98 -0
  259. package/dist/toolkit/index.d.ts +48 -0
  260. package/dist/toolkit/index.js +82 -0
  261. package/dist/toolkit/meta.d.ts +36 -0
  262. package/dist/toolkit/meta.js +117 -0
  263. package/dist/toolkit/profiles.d.ts +13 -0
  264. package/dist/toolkit/profiles.js +25 -0
  265. package/dist/toolkit/record.d.ts +15 -0
  266. package/dist/toolkit/record.js +17 -0
  267. package/dist/tools/memoryTools.d.ts +95 -0
  268. package/dist/tools/memoryTools.js +179 -0
  269. package/dist/tools/sendMessage.d.ts +21 -0
  270. package/dist/tools/sendMessage.js +25 -0
  271. package/dist/types/pipeline.d.ts +7 -1
  272. package/dist/types/stage.d.ts +15 -0
  273. package/dist/ui/assets/AssistantRuntimeProvider-CsiPFhCT.js +9 -0
  274. package/dist/ui/assets/MarkdownText-D7tYaIFO.js +29 -0
  275. package/dist/ui/assets/ReadonlyStore-BfXqHykm.js +6 -0
  276. package/dist/ui/assets/Tooltip-DrpoRRNi.js +1 -0
  277. package/dist/ui/assets/chat-BbLukq9W.js +5 -0
  278. package/dist/ui/assets/chat-zIZU_bP1.css +2 -0
  279. package/dist/ui/assets/jsx-runtime-iVoFAvQ_.js +1 -0
  280. package/dist/ui/assets/{index-CIPbbBUi.css → main-BFo79krC.css} +1 -1
  281. package/dist/ui/assets/main-CijYMeM0.js +259 -0
  282. package/dist/ui/chat.html +25 -0
  283. package/dist/ui/index.html +6 -2
  284. package/dist/workshop/modelSettings.d.ts +2 -2
  285. package/dist/workshop/modelSettings.js +5 -11
  286. package/examples/README.md +1 -0
  287. package/examples/channels-smoke/README.md +23 -0
  288. package/examples/channels-smoke/channels-smoke.pipeline.yaml +11 -0
  289. package/examples/channels-smoke/channels-smoke.task.yaml +3 -0
  290. package/examples/channels-smoke/send-email.yaml +32 -0
  291. package/examples/channels-smoke/send-text.yaml +31 -0
  292. package/examples/github-release/README.md +1 -1
  293. package/examples/memory/README.md +99 -0
  294. package/examples/memory/desk-outage.task.yaml +15 -0
  295. package/examples/memory/desk-refund.task.yaml +15 -0
  296. package/examples/memory/desk-revisit-outage.task.yaml +11 -0
  297. package/examples/memory/desk-revisit.pipeline.yaml +123 -0
  298. package/examples/memory/desk.pipeline.yaml +192 -0
  299. package/examples/memory/file-card.pipeline.yaml +39 -0
  300. package/examples/memory/file-ledger.task.yaml +22 -0
  301. package/examples/memory/file-release.task.yaml +24 -0
  302. package/examples/memory/file-rich.pipeline.yaml +40 -0
  303. package/examples/memory/file-ticket.task.yaml +7 -0
  304. package/examples/memory/file-timeline.task.yaml +28 -0
  305. package/examples/memory/find-card.pipeline.yaml +46 -0
  306. package/examples/memory/find-ticket.task.yaml +7 -0
  307. package/examples/memory/missing.pipeline.yaml +16 -0
  308. package/examples/memory/recall.pipeline.yaml +24 -0
  309. package/examples/memory/recall.task.yaml +5 -0
  310. package/examples/memory/remember-ada.task.yaml +6 -0
  311. package/examples/memory/remember-grace.task.yaml +6 -0
  312. package/examples/memory/remember.pipeline.yaml +58 -0
  313. package/examples/memory/stageflow.yaml +12 -0
  314. package/examples/memory/update-card.pipeline.yaml +43 -0
  315. package/examples/memory/update-ledger.task.yaml +23 -0
  316. package/examples/memory/update-rich.pipeline.yaml +44 -0
  317. package/examples/memory/update-ticket.task.yaml +7 -0
  318. package/examples/stage-mcp/README.md +1 -1
  319. package/package.json +9 -3
  320. package/dist/ui/assets/index-BoFPkKFg.js +0 -256
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ import { type EnsureGlobalServiceResult } from "../server/ensureGlobalService.js";
2
+ export declare const AGENTS_USAGE = "Usage:\n sf agents list [--json]\n sf agents get <id> [--json]\n sf agents validate <file.agent.yaml> [--json]\n sf agents enable <id> [--json]\n sf agents disable <id> [--json]\n sf agents history <id> [--json]\n sf agents restore <id> <revision> --base <current revision> [--json]\n sf agents sessions <id> [--status <status>] [--json]\n sf agents session <id> <sessionId> [--json]\n sf agents chat <id> --message <text> [--session <sessionId>] [--json]\n sf agents approve <id> <sessionId> [--json]\n sf agents deny <id> <sessionId> [--json]\n\nrestore needs --base: the revision you looked at. If the agent has moved on since, the restore is refused instead of\noverwriting a newer edit. Run it without --base to see the current revision.\n\nTalks to the running Stageflow Host for the project in the current directory.";
3
+ export type AgentsCommandIo = {
4
+ log: (line: string) => void;
5
+ error: (line: string) => void;
6
+ write: (chunk: string) => void;
7
+ };
8
+ export declare function runAgentsCommand(args: string[], options?: {
9
+ io?: Partial<AgentsCommandIo>;
10
+ cwd?: string;
11
+ projectRoot?: string;
12
+ hostBaseUrl?: string;
13
+ ensureService?: () => Promise<EnsureGlobalServiceResult>;
14
+ }): Promise<number>;
@@ -0,0 +1,291 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { resolveStageflowContext } from "../project/resolveStageflowContext.js";
5
+ import { clientAuthorizationHeaders } from "../server/controlToken.js";
6
+ import { ensureGlobalService, hostBaseUrl } from "../server/ensureGlobalService.js";
7
+ export const AGENTS_USAGE = `Usage:
8
+ sf agents list [--json]
9
+ sf agents get <id> [--json]
10
+ sf agents validate <file.agent.yaml> [--json]
11
+ sf agents enable <id> [--json]
12
+ sf agents disable <id> [--json]
13
+ sf agents history <id> [--json]
14
+ sf agents restore <id> <revision> --base <current revision> [--json]
15
+ sf agents sessions <id> [--status <status>] [--json]
16
+ sf agents session <id> <sessionId> [--json]
17
+ sf agents chat <id> --message <text> [--session <sessionId>] [--json]
18
+ sf agents approve <id> <sessionId> [--json]
19
+ sf agents deny <id> <sessionId> [--json]
20
+
21
+ restore needs --base: the revision you looked at. If the agent has moved on since, the restore is refused instead of
22
+ overwriting a newer edit. Run it without --base to see the current revision.
23
+
24
+ Talks to the running Stageflow Host for the project in the current directory.`;
25
+ const defaultIo = {
26
+ log: (line) => console.log(line),
27
+ error: (line) => console.error(line),
28
+ write: (chunk) => process.stdout.write(chunk),
29
+ };
30
+ const FLAGS_WITH_VALUE = new Set(["--message", "--session", "--status", "--base"]);
31
+ function parseArgs(args) {
32
+ const parsed = { help: false, json: false, positional: [] };
33
+ for (let index = 0; index < args.length; index += 1) {
34
+ const arg = args[index];
35
+ if (arg === "--help" || arg === "-h")
36
+ parsed.help = true;
37
+ else if (arg === "--json")
38
+ parsed.json = true;
39
+ else if (FLAGS_WITH_VALUE.has(arg)) {
40
+ const value = args[++index];
41
+ if (value === undefined || value.length === 0)
42
+ throw new Error(`Missing value for ${arg}`);
43
+ if (arg === "--message")
44
+ parsed.message = value;
45
+ else if (arg === "--session")
46
+ parsed.session = value;
47
+ else if (arg === "--base")
48
+ parsed.base = value;
49
+ else
50
+ parsed.status = value;
51
+ }
52
+ else if (arg.startsWith("-"))
53
+ throw new Error(`Unknown flag: ${arg}`);
54
+ else if (parsed.subcommand === undefined)
55
+ parsed.subcommand = arg;
56
+ else
57
+ parsed.positional.push(arg);
58
+ }
59
+ return parsed;
60
+ }
61
+ class HostError extends Error {
62
+ code;
63
+ issues;
64
+ constructor(code, message, issues = []) {
65
+ super(message);
66
+ this.code = code;
67
+ this.issues = issues;
68
+ }
69
+ }
70
+ function hostClient(base, projectRoot) {
71
+ const withRoot = (urlPath) => {
72
+ const url = new URL(urlPath, base);
73
+ url.searchParams.set("project_root", projectRoot);
74
+ return url;
75
+ };
76
+ const fail = async (res) => {
77
+ const body = (await res.json().catch(() => ({})));
78
+ throw new HostError(body.code ?? `http_${res.status}`, body.message ?? body.code ?? `Host returned ${res.status}`, body.issues);
79
+ };
80
+ return {
81
+ async get(urlPath) {
82
+ const res = await fetch(withRoot(urlPath), { headers: clientAuthorizationHeaders("GET") });
83
+ if (!res.ok)
84
+ await fail(res);
85
+ return res.json();
86
+ },
87
+ async post(urlPath, body) {
88
+ const res = await fetch(withRoot(urlPath), {
89
+ method: "POST",
90
+ headers: { "Content-Type": "application/json", ...clientAuthorizationHeaders("POST") },
91
+ body: JSON.stringify(body ?? {}),
92
+ });
93
+ if (!res.ok)
94
+ await fail(res);
95
+ return res.json();
96
+ },
97
+ async stream(urlPath, body, onFrame) {
98
+ const res = await fetch(withRoot(urlPath), {
99
+ method: "POST",
100
+ headers: {
101
+ "Content-Type": "application/json",
102
+ Accept: "application/x-ndjson",
103
+ ...clientAuthorizationHeaders("POST"),
104
+ },
105
+ body: JSON.stringify(body),
106
+ });
107
+ if (!res.ok || !res.body)
108
+ await fail(res);
109
+ const decoder = new TextDecoder();
110
+ let buffered = "";
111
+ for await (const chunk of res.body) {
112
+ buffered += decoder.decode(chunk, { stream: true });
113
+ let newline = buffered.indexOf("\n");
114
+ while (newline >= 0) {
115
+ const line = buffered.slice(0, newline).trim();
116
+ buffered = buffered.slice(newline + 1);
117
+ if (line)
118
+ onFrame(JSON.parse(line));
119
+ newline = buffered.indexOf("\n");
120
+ }
121
+ }
122
+ },
123
+ };
124
+ }
125
+ export async function runAgentsCommand(args, options = {}) {
126
+ const io = { ...defaultIo, ...options.io };
127
+ let parsed;
128
+ try {
129
+ parsed = parseArgs(args);
130
+ }
131
+ catch (error) {
132
+ io.error(error instanceof Error ? error.message : String(error));
133
+ io.error(AGENTS_USAGE);
134
+ return 1;
135
+ }
136
+ if (parsed.help || !parsed.subcommand) {
137
+ io.error(AGENTS_USAGE);
138
+ return parsed.help ? 0 : 1;
139
+ }
140
+ const need = (count, what) => {
141
+ if (parsed.positional.length !== count)
142
+ throw new HostError("usage", `${parsed.subcommand} needs ${what}`);
143
+ return parsed.positional;
144
+ };
145
+ const print = (value, human) => (parsed.json ? io.log(JSON.stringify(value, null, 2)) : human());
146
+ try {
147
+ const cwd = options.cwd ?? process.cwd();
148
+ const projectRoot = options.projectRoot ?? (await resolveStageflowContext(cwd)).projectRoot;
149
+ const ensured = await (options.ensureService ?? (() => ensureGlobalService()))();
150
+ if (!ensured.ok)
151
+ throw new HostError("host.unavailable", ensured.message);
152
+ const client = hostClient(options.hostBaseUrl ?? hostBaseUrl(), projectRoot);
153
+ const agentPath = (id, tail = "") => `/api/agents/${encodeURIComponent(id)}${tail}`;
154
+ switch (parsed.subcommand) {
155
+ case "list": {
156
+ need(0, "no arguments");
157
+ const { agents } = await client.get("/api/agents");
158
+ print({ agents }, () => {
159
+ for (const agent of agents) {
160
+ const state = agent.issues.length > 0 ? "invalid" : agent.enabled ? "enabled" : "disabled";
161
+ io.log(`${agent.id}\tv${agent.revision}\t${state}\t${agent.name}`);
162
+ }
163
+ });
164
+ return 0;
165
+ }
166
+ case "get": {
167
+ const [id] = need(1, "<id>");
168
+ const detail = await client.get(agentPath(id));
169
+ print(detail, () => io.log(detail.yaml ?? "(no valid revision)"));
170
+ return 0;
171
+ }
172
+ case "validate": {
173
+ const [file] = need(1, "<file.agent.yaml>");
174
+ const definition = parseYaml(await readFile(path.resolve(cwd, file), "utf8"));
175
+ const result = await client.post("/api/agents/validate", { definition });
176
+ print(result, () => {
177
+ for (const issue of result.issues)
178
+ io.error(`error ${issue.path || "(file)"}: ${issue.message}`);
179
+ for (const warning of result.warnings)
180
+ io.error(`warning ${warning.path}: ${warning.message}`);
181
+ if (result.issues.length === 0)
182
+ io.log("valid");
183
+ });
184
+ return result.issues.length === 0 ? 0 : 1;
185
+ }
186
+ case "enable":
187
+ case "disable": {
188
+ const [id] = need(1, "<id>");
189
+ const detail = await client.post(agentPath(id, `/${parsed.subcommand}`));
190
+ print(detail, () => io.log(`${id} ${parsed.subcommand}d (v${detail.agent.revision})`));
191
+ return 0;
192
+ }
193
+ case "history": {
194
+ const [id] = need(1, "<id>");
195
+ const { revisions } = await client.get(agentPath(id, "/revisions"));
196
+ print({ revisions }, () => {
197
+ for (const row of revisions)
198
+ io.log(`v${row.revision}\t${row.createdAt}\t${row.source}\t${row.summary ?? ""}`);
199
+ });
200
+ return 0;
201
+ }
202
+ case "restore": {
203
+ const [id, raw] = need(2, "<id> <revision>");
204
+ const revision = Number(raw);
205
+ if (!Number.isInteger(revision) || revision < 1)
206
+ throw new HostError("usage", "revision must be a positive integer");
207
+ if (parsed.base === undefined) {
208
+ // The lock only means something if the caller names the revision they saw; reading it here and echoing it back would not.
209
+ const current = await client.get(agentPath(id));
210
+ throw new HostError("usage", `restore needs --base: ${id} is at v${current.agent.revision}. Pass --base ${current.agent.revision} to restore v${revision} over it`);
211
+ }
212
+ const baseRevision = Number(parsed.base);
213
+ if (!Number.isInteger(baseRevision) || baseRevision < 1)
214
+ throw new HostError("usage", "--base must be a positive integer");
215
+ const detail = await client.post(agentPath(id, `/revisions/${revision}/restore`), { baseRevision });
216
+ print(detail, () => io.log(`${id} restored v${revision} as v${detail.agent.revision}`));
217
+ return 0;
218
+ }
219
+ case "sessions": {
220
+ const [id] = need(1, "<id>");
221
+ const query = parsed.status ? `?status=${encodeURIComponent(parsed.status)}` : "";
222
+ const page = await client.get(agentPath(id, `/sessions${query}`));
223
+ print(page, () => {
224
+ for (const row of page.sessions)
225
+ io.log(`${row.id}\t${row.status}\t${row.source}\t${row.updatedAt}\t${row.title ?? ""}`);
226
+ });
227
+ return 0;
228
+ }
229
+ case "session": {
230
+ const [id, sessionId] = need(2, "<id> <sessionId>");
231
+ const detail = await client.get(agentPath(id, `/sessions/${encodeURIComponent(sessionId)}`));
232
+ print(detail, () => {
233
+ for (const message of detail.messages)
234
+ io.log(`${message.author ?? message.role}: ${message.text}\n`);
235
+ });
236
+ return 0;
237
+ }
238
+ case "chat": {
239
+ const [id] = need(1, "<id>");
240
+ if (!parsed.message)
241
+ throw new HostError("usage", "chat needs --message");
242
+ let failure;
243
+ let done;
244
+ await client.stream(agentPath(id, "/chat"), { message: parsed.message, ...(parsed.session ? { sessionId: parsed.session } : {}) }, (frame) => {
245
+ if (frame.type === "delta" && !parsed.json)
246
+ io.write(String(frame.text));
247
+ else if (frame.type === "session" && !parsed.json)
248
+ io.error(`session ${String(frame.sessionId)}`);
249
+ else if (frame.type === "done")
250
+ done = frame.session;
251
+ else if (frame.type === "error")
252
+ failure = new HostError(String(frame.code), String(frame.message ?? frame.code));
253
+ });
254
+ if (failure)
255
+ throw failure;
256
+ // A stream that ends with neither a result nor an error was cut off: not a success.
257
+ if (done === undefined)
258
+ throw new HostError("agent.stream_closed", "The Host closed the connection before the reply finished");
259
+ if (parsed.json)
260
+ io.log(JSON.stringify(done, null, 2));
261
+ else
262
+ io.write("\n");
263
+ return 0;
264
+ }
265
+ case "approve":
266
+ case "deny": {
267
+ const [id, sessionId] = need(2, "<id> <sessionId>");
268
+ const result = await client.post(agentPath(id, `/sessions/${encodeURIComponent(sessionId)}/approval/${parsed.subcommand}`));
269
+ print(result, () => io.log(`${parsed.subcommand === "approve" ? "Approved" : "Denied"} ${result.approval.tool}`));
270
+ return 0;
271
+ }
272
+ default:
273
+ throw new HostError("usage", `Unknown subcommand: ${parsed.subcommand}`);
274
+ }
275
+ }
276
+ catch (error) {
277
+ if (error instanceof HostError) {
278
+ if (parsed.json)
279
+ io.log(JSON.stringify({ code: error.code, message: error.message, issues: error.issues }, null, 2));
280
+ else {
281
+ io.error(error.message);
282
+ for (const issue of error.issues)
283
+ io.error(` ${issue.path || "(file)"}: ${issue.message}`);
284
+ }
285
+ if (error.code === "usage")
286
+ io.error(AGENTS_USAGE);
287
+ return 1;
288
+ }
289
+ throw error;
290
+ }
291
+ }
@@ -293,7 +293,9 @@ function preflightToDoctorChecks(preflight, strict) {
293
293
  ? `toolchain:${c.tool ?? i}`
294
294
  : c.kind === "secret"
295
295
  ? `secret:${c.secret ?? i}`
296
- : `mcp:${c.server ?? c.stageId ?? i}`;
296
+ : c.kind === "channel"
297
+ ? `channel:${c.connection ?? i}`
298
+ : `mcp:${c.server ?? c.stageId ?? i}`;
297
299
  let status = "pass";
298
300
  if (c.status === "ok") {
299
301
  status = "pass";
package/dist/cli.js CHANGED
@@ -18,6 +18,7 @@ import { PROVIDERS_USAGE, runProvidersCommand } from "./cli/providersCommand.js"
18
18
  import { RUN_USAGE, runRunCommand } from "./cli/runCommand.js";
19
19
  import { RUN_STAGE_USAGE, runRunStageCommand } from "./cli/runStageCommand.js";
20
20
  import { RUNS_USAGE, runRunsCommand } from "./cli/runsCommand.js";
21
+ import { AGENTS_USAGE, runAgentsCommand } from "./cli/agentsCommand.js";
21
22
  import { TRIGGER_USAGE, runTriggerCommand } from "./cli/triggerCommand.js";
22
23
  import { resolveOperatorCatalog } from "./cli/operatorCatalog.js";
23
24
  import { SKILLS_USAGE, runSkillsCommand } from "./cli/skillsCommand.js";
@@ -124,6 +125,8 @@ ${RUNS_USAGE}
124
125
 
125
126
  ${TRIGGER_USAGE}
126
127
 
128
+ ${AGENTS_USAGE}
129
+
127
130
  ${PROVIDERS_USAGE}
128
131
 
129
132
  ${SKILLS_USAGE}
@@ -165,6 +168,7 @@ function parseArgs(argv) {
165
168
  command === "export" ||
166
169
  command === "runs" ||
167
170
  command === "trigger" ||
171
+ command === "agents" ||
168
172
  command === "skills" ||
169
173
  command === "browser") {
170
174
  return { help: false, command };
@@ -491,6 +495,11 @@ async function main(argv) {
491
495
  cwd: ctx.invocationCwd,
492
496
  });
493
497
  }
498
+ if (parsed.command === "agents") {
499
+ return runAgentsCommand(argv.slice(3), {
500
+ cwd: ctx.invocationCwd,
501
+ });
502
+ }
494
503
  if (parsed.command === "providers") {
495
504
  return runProvidersCommand(argv.slice(3), ctx.invocationCwd);
496
505
  }
@@ -3,11 +3,6 @@ import { loadPipeline } from "./loadPipeline.js";
3
3
  import { loadTask } from "./loadTask.js";
4
4
  import { resolveStageflowContext, } from "../project/resolveStageflowContext.js";
5
5
  import { scanCatalogPaths } from "./scanCatalogPaths.js";
6
- const BAKED_MODEL_IDS = [
7
- "anthropic/claude-sonnet-4-5",
8
- "cursor/auto",
9
- "cursor/composer-2-5",
10
- ];
11
6
  function repoRelPath(projectRoot, absPath) {
12
7
  return path.relative(projectRoot, absPath).replace(/\\/g, "/");
13
8
  }
@@ -30,9 +25,6 @@ function mapStageListing(stage, source, projectRoot) {
30
25
  }
31
26
  return listing;
32
27
  }
33
- function bakedModels() {
34
- return [...BAKED_MODEL_IDS].sort((a, b) => a.localeCompare(b));
35
- }
36
28
  function catalogReadyFromStageflow(ctx) {
37
29
  return ctx.manifestStatus === "ok" && ctx.manifest !== null;
38
30
  }
@@ -106,8 +98,9 @@ async function listPipelinesFromManifest(projectRoot, manifest, warnings) {
106
98
  });
107
99
  return listings;
108
100
  }
101
+ /** Model ids the project's pipelines already use. The provider catalog (src/models) owns the choosable list. */
109
102
  async function listModelsFromManifest(projectRoot, manifest) {
110
- const models = new Set(BAKED_MODEL_IDS);
103
+ const models = new Set();
111
104
  const filePaths = await scanCatalogPaths(manifest, "pipeline");
112
105
  for (const filePath of filePaths) {
113
106
  try {
@@ -139,7 +132,7 @@ export async function browseCatalog(invocationCwd) {
139
132
  ...base,
140
133
  pipelines: [],
141
134
  tasks: [],
142
- models: bakedModels(),
135
+ models: [],
143
136
  warnings: [],
144
137
  };
145
138
  }
@@ -171,7 +164,7 @@ export async function listTasksForContext(ctx) {
171
164
  }
172
165
  export async function listModelsForContext(ctx) {
173
166
  if (!catalogReady(ctx)) {
174
- return bakedModels();
167
+ return [];
175
168
  }
176
169
  return listModelsFromManifest(ctx.projectRoot, ctx.manifest);
177
170
  }
@@ -12,6 +12,8 @@ export type DraftPackage = {
12
12
  model?: unknown;
13
13
  schemas?: unknown;
14
14
  requires?: unknown;
15
+ channels?: unknown;
16
+ memories?: unknown;
15
17
  };
16
18
  stages?: DraftStageArtifact[];
17
19
  task?: {
@@ -77,6 +77,10 @@ function pipelineDocument(pipeline) {
77
77
  doc.schemas = pipeline.schemas;
78
78
  if (pipeline.requires !== undefined)
79
79
  doc.requires = pipeline.requires;
80
+ if (pipeline.channels !== undefined)
81
+ doc.channels = pipeline.channels;
82
+ if (pipeline.memories !== undefined)
83
+ doc.memories = pipeline.memories;
80
84
  return doc;
81
85
  }
82
86
  function resolveDirectory(projectRoot, directory) {
@@ -164,6 +168,8 @@ export async function validateDraftPackage(draft, options = {}) {
164
168
  ...(draft.pipeline.requires !== undefined
165
169
  ? { requires: draft.pipeline.requires }
166
170
  : {}),
171
+ ...(draft.pipeline.channels !== undefined ? { channels: draft.pipeline.channels } : {}),
172
+ ...(draft.pipeline.memories !== undefined ? { memories: draft.pipeline.memories } : {}),
167
173
  };
168
174
  const result = await loadPipelineValidated(inline, {
169
175
  cwd,
@@ -716,6 +722,8 @@ export async function loadDraftPackage(projectRoot, pipelineRelPath, options = {
716
722
  ...(raw.model !== undefined ? { model: raw.model } : {}),
717
723
  ...(raw.schemas !== undefined ? { schemas: raw.schemas } : {}),
718
724
  ...(raw.requires !== undefined ? { requires: raw.requires } : {}),
725
+ ...(raw.channels !== undefined ? { channels: raw.channels } : {}),
726
+ ...(raw.memories !== undefined ? { memories: raw.memories } : {}),
719
727
  },
720
728
  ...(stageArtifacts.length > 0 ? { stages: stageArtifacts } : {}),
721
729
  };
@@ -18,6 +18,7 @@ export class HostConfigError extends Error {
18
18
  export const KNOWN_STAGEFLOW_ENV_KEYS = new Set([
19
19
  "STAGEFLOW_HOME",
20
20
  "STAGEFLOW_CREDENTIAL_HOME",
21
+ "STAGEFLOW_CONNECTIONS_FILE",
21
22
  "STAGEFLOW_BIND",
22
23
  "STAGEFLOW_ALLOW_UNAUTHENTICATED_BIND",
23
24
  "STAGEFLOW_ALLOWED_HOSTS",
@@ -68,6 +69,13 @@ export const KNOWN_STAGEFLOW_ENV_KEYS = new Set([
68
69
  "STAGEFLOW_SECRET_REGISTRY",
69
70
  "STAGEFLOW_BUILD_SHA",
70
71
  "STAGEFLOW_TRIGGER_TICK_INTERVAL_MS",
72
+ "STAGEFLOW_AGENT_SCHEDULE_TICK_INTERVAL_MS",
73
+ "STAGEFLOW_AGENT_SESSION_IDLE_MINUTES",
74
+ "STAGEFLOW_AGENT_STALL_SECONDS",
75
+ "STAGEFLOW_AGENT_CHANNEL_LISTENERS",
76
+ "STAGEFLOW_AGENTS_ALLOW_CURSOR_NATIVE_TOOLS",
77
+ "STAGEFLOW_PUBLIC_CHAT_ORIGINS",
78
+ "STAGEFLOW_MCP_ENV_ALLOW",
71
79
  "STAGEFLOW_GITHUB_POLL_INTERVAL_MS",
72
80
  ]);
73
81
  const KNOWN_ENV_PREFIXES = [