@yanlinglabs/winter-agent-runtime 0.0.27

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 (311) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +41 -0
  3. package/README.md +64 -0
  4. package/dist/checkpoint/file-history.d.ts +81 -0
  5. package/dist/checkpoint/rewind.d.ts +55 -0
  6. package/dist/checkpoint/seam.d.ts +47 -0
  7. package/dist/checkpoint/sink.d.ts +66 -0
  8. package/dist/commands/builtins-listing.d.ts +40 -0
  9. package/dist/commands/resolver.d.ts +103 -0
  10. package/dist/commands/seam.d.ts +53 -0
  11. package/dist/compaction/controller.d.ts +23 -0
  12. package/dist/compaction/retention.d.ts +35 -0
  13. package/dist/compaction/seam.d.ts +115 -0
  14. package/dist/compaction/summarizer.d.ts +79 -0
  15. package/dist/context/agent-listing.d.ts +39 -0
  16. package/dist/context/assembler.d.ts +46 -0
  17. package/dist/context/attachments.d.ts +104 -0
  18. package/dist/context/dynamic-sections.d.ts +31 -0
  19. package/dist/context/git-fixture.d.ts +18 -0
  20. package/dist/context/git-status.d.ts +16 -0
  21. package/dist/context/imports.d.ts +22 -0
  22. package/dist/context/injection.d.ts +53 -0
  23. package/dist/context/memory-key.d.ts +46 -0
  24. package/dist/context/memory.d.ts +28 -0
  25. package/dist/context/minimal-prompt.d.ts +5 -0
  26. package/dist/context/output-styles.d.ts +68 -0
  27. package/dist/context/plan-mode.d.ts +29 -0
  28. package/dist/context/request-layout.d.ts +138 -0
  29. package/dist/context/rules.d.ts +63 -0
  30. package/dist/context/seam.d.ts +136 -0
  31. package/dist/context/tool-epoch.d.ts +118 -0
  32. package/dist/context/winter-code-preset.d.ts +39 -0
  33. package/dist/context/winter-md.d.ts +81 -0
  34. package/dist/embedded-host.d.ts +48 -0
  35. package/dist/embedded-host.js +155 -0
  36. package/dist/embedded-protocol.d.ts +44 -0
  37. package/dist/embedded-worker.d.ts +1 -0
  38. package/dist/embedded-worker.js +74 -0
  39. package/dist/embedded.d.ts +34 -0
  40. package/dist/embedded.js +9 -0
  41. package/dist/engine.d.ts +1298 -0
  42. package/dist/hooks/additional-context.d.ts +21 -0
  43. package/dist/hooks/bounds.d.ts +6 -0
  44. package/dist/hooks/bridge-invoker.d.ts +3 -0
  45. package/dist/hooks/command-invoker.d.ts +52 -0
  46. package/dist/hooks/from-config.d.ts +31 -0
  47. package/dist/hooks/hook-stage.d.ts +25 -0
  48. package/dist/hooks/input-validator.d.ts +6 -0
  49. package/dist/hooks/reducer.d.ts +74 -0
  50. package/dist/hooks/registry.d.ts +33 -0
  51. package/dist/hooks/runner.d.ts +105 -0
  52. package/dist/index-584yahed.js +6037 -0
  53. package/dist/index-97t2rmtf.js +42 -0
  54. package/dist/index-9qgkpv56.js +27183 -0
  55. package/dist/index-bef62z3r.js +437 -0
  56. package/dist/index-rkhh0457.js +187 -0
  57. package/dist/index.d.ts +37 -0
  58. package/dist/index.js +353 -0
  59. package/dist/main.d.ts +1 -0
  60. package/dist/mcp/client.d.ts +105 -0
  61. package/dist/mcp/control-seam.d.ts +25 -0
  62. package/dist/mcp/control.d.ts +5 -0
  63. package/dist/mcp/elicitation.d.ts +35 -0
  64. package/dist/mcp/env.d.ts +12 -0
  65. package/dist/mcp/lifecycle.d.ts +142 -0
  66. package/dist/mcp/output-cap.d.ts +15 -0
  67. package/dist/mcp/state.d.ts +24 -0
  68. package/dist/mcp/test-fixtures.d.ts +88 -0
  69. package/dist/mcp/transports/__fixtures__/stdio-server.d.ts +1 -0
  70. package/dist/mcp/transports/http.d.ts +5 -0
  71. package/dist/mcp/transports/sdk.d.ts +5 -0
  72. package/dist/mcp/transports/sse.d.ts +3 -0
  73. package/dist/mcp/transports/stdio.d.ts +35 -0
  74. package/dist/mcp/winter-server.d.ts +2 -0
  75. package/dist/messaging/reference-adapter.d.ts +88 -0
  76. package/dist/messaging/router.d.ts +8 -0
  77. package/dist/paths/project-dir-name.d.ts +2 -0
  78. package/dist/paths/temp.d.ts +25 -0
  79. package/dist/permissions/approvals.d.ts +107 -0
  80. package/dist/permissions/auto/caches.d.ts +53 -0
  81. package/dist/permissions/auto/config.d.ts +37 -0
  82. package/dist/permissions/auto/engine.d.ts +74 -0
  83. package/dist/permissions/auto/envelope.d.ts +45 -0
  84. package/dist/permissions/auto/inheritance.d.ts +27 -0
  85. package/dist/permissions/edit-recognition.d.ts +30 -0
  86. package/dist/permissions/evaluator.d.ts +284 -0
  87. package/dist/permissions/file-rules.d.ts +384 -0
  88. package/dist/permissions/grammar.d.ts +113 -0
  89. package/dist/permissions/paths.d.ts +32 -0
  90. package/dist/permissions/policy-state.d.ts +64 -0
  91. package/dist/permissions/prompt-stage.d.ts +3 -0
  92. package/dist/permissions/protected.d.ts +54 -0
  93. package/dist/permissions/ruleset.d.ts +134 -0
  94. package/dist/permissions/shell-structure.d.ts +41 -0
  95. package/dist/plugins/bundle.d.ts +100 -0
  96. package/dist/plugins/installed.d.ts +30 -0
  97. package/dist/plugins/loader.d.ts +56 -0
  98. package/dist/plugins/manifest.d.ts +115 -0
  99. package/dist/production-wiring.d.ts +340 -0
  100. package/dist/protocol/channel.d.ts +22 -0
  101. package/dist/provider/advisor-route.d.ts +47 -0
  102. package/dist/provider/bridge.d.ts +124 -0
  103. package/dist/provider/classifier/model-classifier.d.ts +82 -0
  104. package/dist/provider/classifier/prompt.d.ts +62 -0
  105. package/dist/provider/classifier/verdict-schema.d.ts +83 -0
  106. package/dist/provider/credential-api.d.ts +160 -0
  107. package/dist/provider/family-listing.d.ts +27 -0
  108. package/dist/provider/first-party.d.ts +4 -0
  109. package/dist/provider/keychain-store.d.ts +59 -0
  110. package/dist/provider/lean-prompt.d.ts +7 -0
  111. package/dist/provider/mock.d.ts +55 -0
  112. package/dist/provider/scenario-fake.d.ts +96 -0
  113. package/dist/provider/selection.d.ts +115 -0
  114. package/dist/provider/session-provider.d.ts +426 -0
  115. package/dist/provider/slots.d.ts +120 -0
  116. package/dist/provider/stream-frames.d.ts +25 -0
  117. package/dist/provider/tool-secret.d.ts +57 -0
  118. package/dist/rpc/bridge.d.ts +14 -0
  119. package/dist/rpc/mcp-control.d.ts +26 -0
  120. package/dist/runtime.d.ts +14 -0
  121. package/dist/sandbox/profile.d.ts +249 -0
  122. package/dist/sandbox/spawn.d.ts +139 -0
  123. package/dist/settings/env-filter.d.ts +52 -0
  124. package/dist/settings/loaders/hooks.d.ts +44 -0
  125. package/dist/settings/loaders/mcp-config.d.ts +83 -0
  126. package/dist/settings/loaders/plugin-mcp.d.ts +3 -0
  127. package/dist/settings/loaders/strict-plugin-only.d.ts +13 -0
  128. package/dist/settings/resolve.d.ts +2 -0
  129. package/dist/settings/sources.d.ts +2 -0
  130. package/dist/settings/trust.d.ts +36 -0
  131. package/dist/skills/attachment.d.ts +25 -0
  132. package/dist/skills/frontmatter.d.ts +64 -0
  133. package/dist/skills/index.d.ts +16 -0
  134. package/dist/skills/listing.d.ts +89 -0
  135. package/dist/skills/loader.d.ts +104 -0
  136. package/dist/skills/option.d.ts +68 -0
  137. package/dist/skills/permission-rules.d.ts +21 -0
  138. package/dist/skills/runtime.d.ts +21 -0
  139. package/dist/skills/store.d.ts +163 -0
  140. package/dist/store/continuation-attach.d.ts +44 -0
  141. package/dist/store/dialect.d.ts +526 -0
  142. package/dist/store/provider-state.d.ts +188 -0
  143. package/dist/store/resume.d.ts +92 -0
  144. package/dist/structured/ajv-seam.d.ts +7 -0
  145. package/dist/structured/descriptor.d.ts +9 -0
  146. package/dist/structured/seam.d.ts +51 -0
  147. package/dist/structured/validator.d.ts +22 -0
  148. package/dist/subagents/activity.d.ts +13 -0
  149. package/dist/subagents/availability.d.ts +30 -0
  150. package/dist/subagents/builtin-agents.d.ts +37 -0
  151. package/dist/subagents/child-engine.d.ts +198 -0
  152. package/dist/subagents/child-handle.d.ts +344 -0
  153. package/dist/subagents/definitions.d.ts +189 -0
  154. package/dist/subagents/fork.d.ts +55 -0
  155. package/dist/subagents/git-root.d.ts +1 -0
  156. package/dist/subagents/limits.d.ts +28 -0
  157. package/dist/subagents/notification-queue.d.ts +233 -0
  158. package/dist/subagents/plugin-agents.d.ts +5 -0
  159. package/dist/subagents/policy.d.ts +46 -0
  160. package/dist/subagents/register-default-factory.d.ts +66 -0
  161. package/dist/subagents/resolution.d.ts +56 -0
  162. package/dist/subagents/restore.d.ts +9 -0
  163. package/dist/subagents/roster.d.ts +17 -0
  164. package/dist/subagents/test-fakes.d.ts +12 -0
  165. package/dist/subagents/tool-pools.d.ts +69 -0
  166. package/dist/subagents/watchdog.d.ts +13 -0
  167. package/dist/subagents/workspace.d.ts +27 -0
  168. package/dist/testing.d.ts +5 -0
  169. package/dist/testing.js +194 -0
  170. package/dist/tools/background-tasks.d.ts +10 -0
  171. package/dist/tools/descriptors/_shared.d.ts +34 -0
  172. package/dist/tools/descriptors/advisor.d.ts +1 -0
  173. package/dist/tools/descriptors/agent.d.ts +47 -0
  174. package/dist/tools/descriptors/artifact.d.ts +1 -0
  175. package/dist/tools/descriptors/ask-user-question.d.ts +1 -0
  176. package/dist/tools/descriptors/bash.d.ts +20 -0
  177. package/dist/tools/descriptors/claude-design.d.ts +1 -0
  178. package/dist/tools/descriptors/cron-create.d.ts +1 -0
  179. package/dist/tools/descriptors/cron-delete.d.ts +1 -0
  180. package/dist/tools/descriptors/cron-list.d.ts +1 -0
  181. package/dist/tools/descriptors/edit.d.ts +1 -0
  182. package/dist/tools/descriptors/end-conversation.d.ts +1 -0
  183. package/dist/tools/descriptors/enter-plan-mode.d.ts +1 -0
  184. package/dist/tools/descriptors/enter-worktree.d.ts +1 -0
  185. package/dist/tools/descriptors/exit-plan-mode.d.ts +1 -0
  186. package/dist/tools/descriptors/exit-worktree.d.ts +1 -0
  187. package/dist/tools/descriptors/glob.d.ts +1 -0
  188. package/dist/tools/descriptors/grep.d.ts +1 -0
  189. package/dist/tools/descriptors/index.d.ts +59 -0
  190. package/dist/tools/descriptors/list-agents.d.ts +1 -0
  191. package/dist/tools/descriptors/list-mcp-resources-tool.d.ts +1 -0
  192. package/dist/tools/descriptors/lsp.d.ts +1 -0
  193. package/dist/tools/descriptors/monitor.d.ts +1 -0
  194. package/dist/tools/descriptors/notebook-edit.d.ts +1 -0
  195. package/dist/tools/descriptors/powershell.d.ts +1 -0
  196. package/dist/tools/descriptors/projects.d.ts +1 -0
  197. package/dist/tools/descriptors/propose-goal.d.ts +1 -0
  198. package/dist/tools/descriptors/propose-skills.d.ts +1 -0
  199. package/dist/tools/descriptors/push-notification.d.ts +1 -0
  200. package/dist/tools/descriptors/read-mcp-resource-dir-tool.d.ts +1 -0
  201. package/dist/tools/descriptors/read-mcp-resource-tool.d.ts +1 -0
  202. package/dist/tools/descriptors/read-notifications.d.ts +1 -0
  203. package/dist/tools/descriptors/read.d.ts +1 -0
  204. package/dist/tools/descriptors/refresh-mcp-tools.d.ts +1 -0
  205. package/dist/tools/descriptors/remote-trigger.d.ts +1 -0
  206. package/dist/tools/descriptors/repl.d.ts +1 -0
  207. package/dist/tools/descriptors/report-findings.d.ts +1 -0
  208. package/dist/tools/descriptors/schedule-wakeup.d.ts +1 -0
  209. package/dist/tools/descriptors/send-feedback.d.ts +1 -0
  210. package/dist/tools/descriptors/send-message.d.ts +1 -0
  211. package/dist/tools/descriptors/send-user-file.d.ts +1 -0
  212. package/dist/tools/descriptors/share-onboarding-guide.d.ts +1 -0
  213. package/dist/tools/descriptors/show-onboarding-role-picker.d.ts +1 -0
  214. package/dist/tools/descriptors/skill.d.ts +1 -0
  215. package/dist/tools/descriptors/structured-output.d.ts +1 -0
  216. package/dist/tools/descriptors/task-create.d.ts +1 -0
  217. package/dist/tools/descriptors/task-get.d.ts +1 -0
  218. package/dist/tools/descriptors/task-list.d.ts +1 -0
  219. package/dist/tools/descriptors/task-output.d.ts +1 -0
  220. package/dist/tools/descriptors/task-stop.d.ts +1 -0
  221. package/dist/tools/descriptors/task-update.d.ts +1 -0
  222. package/dist/tools/descriptors/todo-write.d.ts +1 -0
  223. package/dist/tools/descriptors/tool-search.d.ts +1 -0
  224. package/dist/tools/descriptors/wait-for-mcp-servers.d.ts +1 -0
  225. package/dist/tools/descriptors/web-fetch.d.ts +8 -0
  226. package/dist/tools/descriptors/web-search.d.ts +15 -0
  227. package/dist/tools/descriptors/winter-list-agents.d.ts +1 -0
  228. package/dist/tools/descriptors/winter-send-message.d.ts +1 -0
  229. package/dist/tools/descriptors/workflow.d.ts +1 -0
  230. package/dist/tools/descriptors/write.d.ts +1 -0
  231. package/dist/tools/impl/_caller.d.ts +14 -0
  232. package/dist/tools/impl/_domains.d.ts +25 -0
  233. package/dist/tools/impl/_exa-client.d.ts +122 -0
  234. package/dist/tools/impl/_exa-session-client.d.ts +23 -0
  235. package/dist/tools/impl/_inner-model.d.ts +135 -0
  236. package/dist/tools/impl/_search-budget.d.ts +36 -0
  237. package/dist/tools/impl/_web-fetch-cache.d.ts +37 -0
  238. package/dist/tools/impl/_web-fetch-html.d.ts +26 -0
  239. package/dist/tools/impl/_web-fetch-net.d.ts +99 -0
  240. package/dist/tools/impl/_web-search-assembler.d.ts +57 -0
  241. package/dist/tools/impl/advisor.d.ts +37 -0
  242. package/dist/tools/impl/agent.d.ts +10 -0
  243. package/dist/tools/impl/ask-user-question.d.ts +5 -0
  244. package/dist/tools/impl/background-task-runtime.d.ts +272 -0
  245. package/dist/tools/impl/bash.d.ts +78 -0
  246. package/dist/tools/impl/cron.d.ts +11 -0
  247. package/dist/tools/impl/edit.d.ts +1 -0
  248. package/dist/tools/impl/enter-plan-mode.d.ts +4 -0
  249. package/dist/tools/impl/enter-worktree.d.ts +25 -0
  250. package/dist/tools/impl/exit-plan-mode.d.ts +4 -0
  251. package/dist/tools/impl/exit-worktree.d.ts +4 -0
  252. package/dist/tools/impl/glob.d.ts +1 -0
  253. package/dist/tools/impl/grep.d.ts +19 -0
  254. package/dist/tools/impl/index.d.ts +37 -0
  255. package/dist/tools/impl/list-agents.d.ts +7 -0
  256. package/dist/tools/impl/list-mcp-resources-tool.d.ts +9 -0
  257. package/dist/tools/impl/monitor.d.ts +66 -0
  258. package/dist/tools/impl/notebook-edit.d.ts +1 -0
  259. package/dist/tools/impl/push-notification.d.ts +4 -0
  260. package/dist/tools/impl/read-ladder.d.ts +25 -0
  261. package/dist/tools/impl/read-mcp-resource-dir-tool.d.ts +9 -0
  262. package/dist/tools/impl/read-mcp-resource-tool.d.ts +9 -0
  263. package/dist/tools/impl/read-notifications.d.ts +5 -0
  264. package/dist/tools/impl/read.d.ts +44 -0
  265. package/dist/tools/impl/refresh-mcp-tools.d.ts +8 -0
  266. package/dist/tools/impl/report-findings.d.ts +1 -0
  267. package/dist/tools/impl/schedule-wakeup.d.ts +2 -0
  268. package/dist/tools/impl/send-message.d.ts +7 -0
  269. package/dist/tools/impl/skill.d.ts +5 -0
  270. package/dist/tools/impl/task-graph.d.ts +1 -0
  271. package/dist/tools/impl/task-output.d.ts +16 -0
  272. package/dist/tools/impl/task-stop.d.ts +11 -0
  273. package/dist/tools/impl/todo-write.d.ts +8 -0
  274. package/dist/tools/impl/tool-search.d.ts +4 -0
  275. package/dist/tools/impl/wait-for-mcp-servers.d.ts +29 -0
  276. package/dist/tools/impl/web-fetch.d.ts +36 -0
  277. package/dist/tools/impl/web-search.d.ts +30 -0
  278. package/dist/tools/impl/workflow.d.ts +5 -0
  279. package/dist/tools/impl/write.d.ts +8 -0
  280. package/dist/tools/paths-seam.d.ts +6 -0
  281. package/dist/tools/read-state.d.ts +12 -0
  282. package/dist/tools/registry.d.ts +423 -0
  283. package/dist/tools/task-graph-store.d.ts +61 -0
  284. package/dist/toolsearch/aliases.d.ts +26 -0
  285. package/dist/toolsearch/exposure.d.ts +30 -0
  286. package/dist/toolsearch/ranking.d.ts +6 -0
  287. package/dist/toolsearch/search.d.ts +45 -0
  288. package/dist/version.d.ts +1 -0
  289. package/dist/version.js +5 -0
  290. package/dist/web/fetchable-url.d.ts +28 -0
  291. package/dist/web/preapproved-hosts.d.ts +52 -0
  292. package/dist/web/private-address.d.ts +55 -0
  293. package/dist/web/session-runtime.d.ts +86 -0
  294. package/dist/workflows/bridge.d.ts +87 -0
  295. package/dist/workflows/budget.d.ts +24 -0
  296. package/dist/workflows/host-registry.d.ts +142 -0
  297. package/dist/workflows/journal.d.ts +29 -0
  298. package/dist/workflows/meta.d.ts +45 -0
  299. package/dist/workflows/registry.d.ts +24 -0
  300. package/dist/workflows/runtime.d.ts +254 -0
  301. package/dist/workflows/sandbox.d.ts +49 -0
  302. package/dist/workflows/script-api.d.ts +58 -0
  303. package/dist/workflows/seam.d.ts +92 -0
  304. package/dist/workflows/semaphore.d.ts +16 -0
  305. package/dist/workflows/store.d.ts +177 -0
  306. package/dist/workflows/subprocess-entry.d.ts +38 -0
  307. package/dist/workflows/subprocess-entry.js +14 -0
  308. package/dist/workflows/transcript.d.ts +56 -0
  309. package/dist/workflows/types.d.ts +84 -0
  310. package/dist/workflows/worker-harness.d.ts +45 -0
  311. package/package.json +76 -0
@@ -0,0 +1,254 @@
1
+ import { type JournalEntry } from "./journal.js";
2
+ import { type WorkerCommand } from "./sandbox.js";
3
+ import type { SandboxBrand } from "../sandbox/profile.js";
4
+ import type { BrandProfile, SettingSource } from "@yanlinglabs/winter-agent-sdk";
5
+ import { type WorkflowRef } from "./bridge.js";
6
+ import type { WorkflowSessionRuntime } from "./host-registry.js";
7
+ import { type WorkflowMeta } from "./meta.js";
8
+ import type { WorkflowRunView, WorkflowStatus } from "./types.js";
9
+ import type { WorkflowRunHost } from "./seam.js";
10
+ /** WS-11 §1.6's own three numbers, in one place so nothing re-derives them. */
11
+ export declare const TOTAL_AGENTS_PER_RUN = 1000;
12
+ export declare const MAX_ITEMS_PER_CALL = 4096;
13
+ /** A typed launch/resume refusal -- `code` so a tool executor can render each case differently without matching on message text. */
14
+ export declare class WorkflowRuntimeError extends Error {
15
+ readonly code: "unknown-run" | "cross-session" | "not-stopped" | "sandbox-unavailable" | "no-source";
16
+ constructor(code: "unknown-run" | "cross-session" | "not-stopped" | "sandbox-unavailable" | "no-source", message: string);
17
+ }
18
+ export interface WorkerProcess {
19
+ stdin: NodeJS.WritableStream;
20
+ stdout: NodeJS.ReadableStream;
21
+ pid?: number;
22
+ onExit(cb: (code: number | null) => void): void;
23
+ onError(cb: (err: Error) => void): void;
24
+ kill(): void;
25
+ }
26
+ export type WorkerSpawner = (command: WorkerCommand, opts: {
27
+ home?: string;
28
+ winterHome?: string;
29
+ brand?: SandboxBrand;
30
+ cwd?: string;
31
+ }) => WorkerProcess;
32
+ /**
33
+ * The production spawner: `sandbox-exec -p <profile> <worker>`, its own process-group leader.
34
+ *
35
+ * `sandbox: false` spawns the worker DIRECTLY, with no seatbelt. It exists for exactly one caller --
36
+ * `scripts/verify-workflow.ts` on a host that has no `/usr/bin/sandbox-exec` (the linux CI runner),
37
+ * where that gate's subject is the COMPILED ARGV DISPATCH and refusing to run at all would leave that
38
+ * leg unverified. It is NOT a production posture and nothing in the runtime reaches it: `launch`
39
+ * refuses outright when the sandbox is required and unavailable, and the seatbelt's own claims are
40
+ * proved separately in `workflows/worker.darwin.test.ts`.
41
+ */
42
+ export declare function realWorkerSpawner(opts?: {
43
+ sandbox?: boolean;
44
+ }): WorkerSpawner;
45
+ export interface WorkflowRuntimeDeps {
46
+ session: WorkflowSessionRuntime;
47
+ caps?: {
48
+ concurrency?: number;
49
+ totalAgents?: number;
50
+ maxItemsPerCall?: number;
51
+ };
52
+ /** Test seam. Defaults to `realWorkerSpawner()`. */
53
+ spawnWorker?: WorkerSpawner;
54
+ /** Test seam over the worker COMMAND (pre-sandbox). Defaults to the compiled-vs-dev split. */
55
+ workerCommand?: () => WorkerCommand;
56
+ /** Overridable resolver for a nested `workflow(nameOrRef)`. Defaults to store.ts's project resolution. */
57
+ resolveNestedWorkflow?: (ref: WorkflowRef, ctx: {
58
+ cwd: string;
59
+ trustedWorkspace: boolean;
60
+ brand?: BrandProfile;
61
+ pluginWorkflows?: readonly {
62
+ name: string;
63
+ workflowsPath?: string;
64
+ workflowsPaths?: readonly string[];
65
+ }[];
66
+ winterHome?: string;
67
+ settingSources?: readonly SettingSource[];
68
+ }) => Promise<{
69
+ ok: true;
70
+ source: string;
71
+ } | {
72
+ ok: false;
73
+ error: string;
74
+ }>;
75
+ /** Skips the `sandbox-exec` availability refusal. Only a non-default spawner has any business setting this. */
76
+ requireSandbox?: boolean;
77
+ }
78
+ export interface WorkflowLaunchInput {
79
+ sessionId: string;
80
+ cwd: string;
81
+ trustedWorkspace: boolean;
82
+ source: string;
83
+ meta: Pick<WorkflowMeta, "name" | "description"> & Partial<WorkflowMeta>;
84
+ args?: unknown;
85
+ /**
86
+ * The MODEL's own `tool_use` id for the Workflow call (F11). REQUIRED, and deliberately so: WS-10
87
+ * §4 correlates a child's forwarded frames on `SpawnChildRequest.parentToolUseId`, and the previous
88
+ * `?? run.task.taskId` fallback quietly substituted a task id -- a different id space entirely, and
89
+ * exactly the class of fabricated-value-on-a-pinned-field that this lane already removed once from
90
+ * `task_started.workflow_name`. The tool executor refuses the call outright when `ctx.toolUseId` is
91
+ * absent rather than inventing one here.
92
+ */
93
+ parentToolUseId: string;
94
+ /** Only `resume` supplies these; a fresh launch never does. */
95
+ runId?: string;
96
+ resumeJournal?: JournalEntry[];
97
+ }
98
+ export interface WorkflowLaunchResult {
99
+ taskId: string;
100
+ runId: string;
101
+ /**
102
+ * `meta.name` VERBATIM -- item (g) doc-asserts (`4061`) that `WorkflowOutput.workflowName` is
103
+ * `meta.name` and equals `task_started.workflow_name`. It is threaded rather than recovered from
104
+ * the persisted filename, because that filename is SANITIZED (`store.ts`'s `sanitizeFileStem`):
105
+ * a `meta.name` of `My Workflow!` persists as `My-Workflow-<runId>.js`, so a filename-derived name
106
+ * would silently disagree with the pin for every name outside the slug alphabet.
107
+ */
108
+ name: string;
109
+ scriptPath: string;
110
+ transcriptDir: string;
111
+ status: WorkflowStatus;
112
+ summary: string;
113
+ }
114
+ export declare class WorkflowRuntime {
115
+ private readonly deps;
116
+ private readonly registry;
117
+ private readonly live;
118
+ private readonly settlers;
119
+ /** Kept beside `live` because `finish` runs AFTER teardown deleted the LiveRun and still has to settle the task. */
120
+ private readonly tasks;
121
+ /** A-14: same reason as `tasks` -- the terminal record is written after the LiveRun is gone. */
122
+ private readonly transcripts;
123
+ /** Each run's source + launch context, so `resume` can replay it verbatim. Never pruned -- one string per run this session launched. */
124
+ private readonly launches;
125
+ private readonly runsDir;
126
+ private readonly concurrency;
127
+ private readonly totalAgents;
128
+ private readonly maxItemsPerCall;
129
+ private readonly spawnWorker;
130
+ constructor(deps: WorkflowRuntimeDeps);
131
+ launch(input: WorkflowLaunchInput, host: WorkflowRunHost): WorkflowLaunchResult;
132
+ /**
133
+ * WS-11 §1.5: a same-session resume of a STOPPED run, replaying its journal.
134
+ *
135
+ * Both preconditions are the pin's own (`sdk-tools.d.ts:2786`: "same-session only, with the prior
136
+ * run stopped first via TaskStop") and both are typed refusals rather than silent no-ops -- this
137
+ * launches a subprocess, so a typo'd runId failing loudly is worth more than a quiet nothing.
138
+ * `sessionId` is taken from the CALLER, never from the input, so a run cannot be resumed into a
139
+ * session that did not own it.
140
+ *
141
+ * RULING I6 (fix wave) -- `opts.replacement` / `opts.args`: a resume that supplies a NEW source
142
+ * (the model edited the persisted script between the stop and the resume, which is exactly what
143
+ * WS-11 §1.3's loop tells it to do) runs the NEW source against the OLD journal. The positional
144
+ * replay then diverges at the first changed call and everything from there runs live, which is
145
+ * §1.5's own contract. This used to rebuild the launch from `this.launches` unconditionally, so a
146
+ * `{scriptPath: <edited>, resumeFromRunId}` call silently re-ran the PRIOR source and a changed
147
+ * `args` was dropped -- the edit loop's own door was the one input the door ignored. With neither
148
+ * supplied, the original launch input is replayed verbatim (the ruling's other half).
149
+ */
150
+ resume(runId: string, sessionId: string, host: WorkflowRunHost, opts?: {
151
+ parentToolUseId?: string;
152
+ /**
153
+ * The edited script AND its re-parsed meta, together: `meta.name` is what the new run's task,
154
+ * persisted filename and `WorkflowOutput.workflowName` are built from, so carrying the source
155
+ * without re-parsing the meta would label the edited run with the old script's name.
156
+ */
157
+ replacement?: {
158
+ source: string;
159
+ meta: WorkflowLaunchInput["meta"];
160
+ };
161
+ /** Supplied = the new args; OMITTED = the original launch's args, unchanged. */
162
+ args?: unknown;
163
+ }): WorkflowLaunchResult;
164
+ stop(runId: string): boolean;
165
+ get(runId: string): WorkflowRunView | undefined;
166
+ list(sessionId: string): WorkflowRunView[];
167
+ /** Resolves when the run reaches a terminal state. An already-terminal or unknown run resolves immediately. */
168
+ await(runId: string): Promise<WorkflowRunView>;
169
+ /**
170
+ * Whether a run reached `stopped` (as opposed to `failed`). The frozen `WorkflowTaskHandle` has no
171
+ * `stop()`, so this is how a host renders the third terminal state truthfully -- see
172
+ * `tools/impl/workflow.ts`'s `fail` implementation.
173
+ */
174
+ wasStopped(runId: string): boolean;
175
+ /** Test-only: simulates an external kill, for the crash-fallback path. */
176
+ killWorkerForTest(runId: string): void;
177
+ private onWorkerMessage;
178
+ private reply;
179
+ /**
180
+ * The authoritative half of every cap. Checked in this order, deliberately:
181
+ * 1. the TOTAL cap, before the semaphore -- a run pinned at capacity must fail fast rather than
182
+ * queue behind work that can never help it (Norma's original ordering, kept);
183
+ * 2. the BUDGET ceiling, for the same reason;
184
+ * 3. only then a slot.
185
+ */
186
+ private serviceAgent;
187
+ /**
188
+ * Spawns one child and resolves what `agent()` should see.
189
+ *
190
+ * NULL, not a throw, for every terminal child OUTCOME (WS-11 §1.6: "Resolves `null` when the user
191
+ * skips the agent or it dies on a terminal error") -- a failed child, a stopped child, a child
192
+ * whose text does not validate.
193
+ *
194
+ * A `spawnAgent` that THROWS is NOT one of those (whole-branch m5). It means the HOST could not
195
+ * start an agent at all -- `tools/impl/workflow.ts` throws exactly that when the session has no
196
+ * child-spawn capability -- and `script-api.ts`'s own contract lists "no spawn capability at all"
197
+ * beside the agent cap and the budget ceiling as the refusals a script must not be able to
198
+ * swallow. This used to fold it into the same `null`, so a workflow in a session with no spawn
199
+ * capability "completed" with `.filter(Boolean)`-swallowed empties and the real cause appeared
200
+ * nowhere. It now comes back as a refusal, which `serviceAgent` turns into the same
201
+ * teardown-then-`ok:false` the caps use. Nothing escapes as an unhandled rejection either way.
202
+ */
203
+ private spawnAndAwaitChild;
204
+ /**
205
+ * `agent({schema})` rides `SpawnChildRequest.outputFormat` (T3's Lane W item 5) -- the child is put
206
+ * on the identical `StructuredOutput` mechanism the top-level session uses, never a second one.
207
+ *
208
+ * CLOSED by RULING P5-I (Phase 5 fix wave). `ChildResult.structuredOutput` now carries the child's
209
+ * own validated object, so `agent({schema})` returns it directly. This function is the FALLBACK
210
+ * for a child that produced none: it parses the child's text and re-validates it through
211
+ * `host.structured` -- the same validator, so no second opinion is introduced -- and resolves NULL
212
+ * when there is nothing valid, which is the "died on a terminal error" arm of the same rule.
213
+ *
214
+ * The gap it used to be: `child-engine.ts`'s `observe` read `message.result`, which the engine's
215
+ * structured SUCCESS variant does not set (it carries `structured_output` and no `result`), so a
216
+ * child forced onto `StructuredOutput` -- which is every schema'd call -- resolved `null`.
217
+ */
218
+ private validateStructured;
219
+ private buildSpawnRequest;
220
+ /**
221
+ * `agentType` and `effort` BOTH arrive as the child's DEFINITION, because that is the only route
222
+ * either has: `SpawnChildRequest` carries `definition` and no `effort` at all, and engine.ts's own
223
+ * `buildChildInheritance` reads effort exclusively from `req.definition?.effort` (engine.ts:1236,
224
+ * whose comment says so outright: "AgentInput/SpawnChildRequest carry no effort field at all").
225
+ *
226
+ * With `effort` and no `agentType`, a MINIMAL definition is synthesized. That is safe rather than
227
+ * clever: `buildChildInheritance`'s base for a bare child is already `systemPrompt: ""`, an absent
228
+ * `tools` inherits the parent's whole advertised pool, and an absent `permissionMode` changes
229
+ * nothing -- so the synthesized definition differs from a bare child in exactly the one field it
230
+ * exists to carry.
231
+ */
232
+ private resolveChildDefinition;
233
+ /** A nested `workflow(nameOrRef)`: resolved PARENT-side, because the worker can read no files. */
234
+ private serviceNestedWorkflow;
235
+ /**
236
+ * `phase` is the group this progress report belongs to (F2): an agent's own `opts.phase` when it
237
+ * supplied one, otherwise the run's current global phase. Passing it explicitly is the whole point
238
+ * -- WS-11 §1.6 gives `opts.phase` the job of "avoiding races on the global `phase()` state inside
239
+ * `pipeline`/`parallel` stages", and reading the ambient phase here would reintroduce exactly that
240
+ * race for two agents running concurrently under different phases.
241
+ */
242
+ private syncCounts;
243
+ /**
244
+ * `usage` is filled on EVERY progress report, not just where it is convenient. `WorkflowProgress`
245
+ * types it optional, but the pinned `task_progress` message it lands on makes the triple REQUIRED
246
+ * (frames.ts) -- so a host mapping this to the wire would otherwise have to invent the numbers.
247
+ * All three are real readings: tokens from the session accountant, `tool_uses` from this run's own
248
+ * agent count, `duration_ms` from the parent's wall clock (the worker has no clock -- `Date.now` is
249
+ * withheld inside it by design).
250
+ */
251
+ private emitProgress;
252
+ private teardown;
253
+ private finish;
254
+ }
@@ -0,0 +1,49 @@
1
+ import { type SandboxBrand } from "../sandbox/profile.js";
2
+ import { WORKFLOW_WORKER_ARGV_FLAG, WORKFLOW_WORKER_BRIDGE_FLAG } from "./subprocess-entry.js";
3
+ export { WORKFLOW_WORKER_ARGV_FLAG, WORKFLOW_WORKER_BRIDGE_FLAG };
4
+ declare const SANDBOX_EXEC_PATH = "/usr/bin/sandbox-exec";
5
+ export interface WorkerCommand {
6
+ file: string;
7
+ args: string[];
8
+ }
9
+ export interface ResolveWorkerCommandOptions {
10
+ /**
11
+ * Overridable for tests; defaults to a real detection of the single-file `$bunfs` executable.
12
+ * Stating either field bypasses a host command installed by `setHostWorkflowWorkerCommand`.
13
+ */
14
+ compiled?: boolean;
15
+ execPath?: string;
16
+ }
17
+ /** True inside a `bun build --compile` single-file executable. */
18
+ export declare function isCompiledBinary(): boolean;
19
+ /**
20
+ * Install the host's workflow-worker command for this realm; returns a restore function. `undefined`
21
+ * clears it (the default applies again). The command is copied, so a caller mutating its own object
22
+ * afterwards changes nothing here.
23
+ */
24
+ export declare function setHostWorkflowWorkerCommand(command: WorkerCommand | undefined): () => void;
25
+ export declare function resolveWorkerCommand(opts?: ResolveWorkerCommandOptions): WorkerCommand;
26
+ export interface BuildWorkerSpawnOptions {
27
+ command: WorkerCommand;
28
+ /**
29
+ * The session's WINTER HOME. Supplying it is what emits the run-directory read-deny (R5-5);
30
+ * `undefined` opts out EXPLICITLY, which is the only way to opt out now that the profile builder's
31
+ * own argument is required. Every production call site passes a real value, and worker.test.ts pins
32
+ * the difference between the two profiles.
33
+ */
34
+ home?: string;
35
+ /**
36
+ * The RESOLVED Winter home (fix wave I1, the resolved-home class): when it is not
37
+ * `<home>/<homeDirName>`, the profile ALSO denies `<winterHome>/run` -- a `<PREFIX>HOME` pointing
38
+ * at a differently-named root is otherwise unprotected. Both anchors are emitted; overlapping
39
+ * denies cost nothing.
40
+ */
41
+ winterHome?: string;
42
+ /** P7a (D19): the session's brand -- the dot-dir names the worker profile fences. */
43
+ brand?: SandboxBrand;
44
+ }
45
+ /** The actual `(file, args)` to spawn: sandbox-exec wrapping the worker command under the tight profile. */
46
+ export declare function buildWorkerSpawn(opts: BuildWorkerSpawnOptions): WorkerCommand;
47
+ /** WS-12 §3's own availability rule, reused rather than re-derived. */
48
+ export declare function workflowSandboxAvailable(): boolean;
49
+ export { SANDBOX_EXEC_PATH };
@@ -0,0 +1,58 @@
1
+ import { type JournalEntry } from "./journal.js";
2
+ import type { BudgetSnapshot } from "./budget.js";
3
+ import type { AgentOpts } from "./types.js";
4
+ import type { WorkflowRef } from "./bridge.js";
5
+ /**
6
+ * What the bridge answers for one `agent()` call.
7
+ *
8
+ * The `ok: true, value: null` / `ok: false` split IS the WS-11 §1.6 contract, expressed in the type:
9
+ * a skipped or terminally-failed agent RESOLVES null (so `.filter(Boolean)` works, which is what the
10
+ * spec tells authors to write), while a refusal the script must not be able to swallow -- the agent
11
+ * cap, the budget ceiling, no spawn capability at all -- comes back `ok: false` and THROWS.
12
+ */
13
+ export type AgentBridgeResult = {
14
+ ok: true;
15
+ value: unknown;
16
+ budget?: BudgetSnapshot;
17
+ } | {
18
+ ok: false;
19
+ error: string;
20
+ budget?: BudgetSnapshot;
21
+ };
22
+ export type WorkflowResolveResult = {
23
+ ok: true;
24
+ source: string;
25
+ } | {
26
+ ok: false;
27
+ error: string;
28
+ };
29
+ export interface ScriptApiDeps {
30
+ source: string;
31
+ args: unknown;
32
+ concurrency: number;
33
+ totalAgentCap: number;
34
+ maxItemsPerCall: number;
35
+ budget: BudgetSnapshot;
36
+ agent(prompt: string, opts?: AgentOpts): Promise<AgentBridgeResult>;
37
+ /** Resolves a nested `workflow(nameOrRef)` to its SOURCE. Parent-side: the worker cannot read the project workflows dir. */
38
+ resolveWorkflow(ref: WorkflowRef, args: unknown): Promise<WorkflowResolveResult>;
39
+ phase(title: string): void;
40
+ log(message: string): void;
41
+ /** F8: called ONCE, with how many leading `agent()` calls replayed from the resume journal. */
42
+ reportCachedPrefix?(count: number): void;
43
+ /** WS-11 §1.5: the prior run's ordered `agent()` results. Absent/empty for a fresh run. */
44
+ resumeJournal?: JournalEntry[];
45
+ }
46
+ export interface ScriptRunResult {
47
+ meta: unknown;
48
+ result: unknown;
49
+ }
50
+ /**
51
+ * Compiles and runs one workflow body, returning its captured `meta` and its `return` value.
52
+ *
53
+ * Throws only for the conditions WS-11 §1.6/§1.8 say must throw: a syntax error, a determinism-guard
54
+ * violation, a cap breach, a budget ceiling, an unresolvable or over-nested `workflow()`, or whatever
55
+ * the body itself threw. Everything a script is meant to be able to absorb (`parallel`'s failing
56
+ * thunk, a skipped agent) resolves instead.
57
+ */
58
+ export declare function runWorkflowScript(deps: ScriptApiDeps): Promise<ScriptRunResult>;
@@ -0,0 +1,92 @@
1
+ import type { ContextAccountant } from "../engine.js";
2
+ import type { ChildHandle, SpawnChildRequest } from "../subagents/child-handle.js";
3
+ import type { StructuredOutputSeam } from "../structured/seam.js";
4
+ /**
5
+ * A running workflow's progress. WINTER-DEFINED (the pinned surface has no workflow-progress type),
6
+ * but shaped to land on the pinned `task_progress` message without a second mapping: that message's
7
+ * `usage` triple is REQUIRED and is `{total_tokens, tool_uses, duration_ms}`, so a progress report
8
+ * that could not fill all three would produce a frame the pin cannot accept.
9
+ *
10
+ * `running`/`completed`/`total` are WS-11 §1.8's own step counters.
11
+ */
12
+ export interface WorkflowProgress {
13
+ running: number;
14
+ completed: number;
15
+ total: number;
16
+ /** Free-form, model-facing; lands on `task_progress.summary`. */
17
+ summary?: string;
18
+ /** Lands on `task_progress.last_tool_name`. */
19
+ lastToolName?: string;
20
+ /**
21
+ * Phase 5 Task 8 (rider 27): the PHASE GROUP this report belongs to, structurally.
22
+ *
23
+ * Lane W's NEEDS_CONTEXT 7: WS-11 §1.2's "an unmatched `phase()` gets its own group" was honoured
24
+ * in the runtime's own state and reflected in the progress TEXT (`"Title: detail"` for a declared
25
+ * phase versus a bare `"Title"` for an ad-hoc one), but a host rendering a progress tree could not
26
+ * reconstruct the grouping -- it had to parse prose, and a declared phase whose entry carries no
27
+ * `detail` renders identically to an ad-hoc one, so the prose is not even a reliable signal.
28
+ *
29
+ * `declaredPhase` distinguishes the two cases the text cannot.
30
+ *
31
+ * WHAT THIS DOES NOT DO, stated at the field because a reader will look for it: neither value
32
+ * reaches the WIRE. The pinned `task_progress` message (WS-06 §3.5) carries
33
+ * `summary`/`last_tool_name`/`usage` and no phase field, and putting a Winter-invented key on a
34
+ * pinned frame is precisely the divergence class this phase refuses. So the grouping is legible to
35
+ * a host that consumes the SEAM, and on the wire it remains prose. Closing that half needs either
36
+ * a captured pinned field or a deliberate disclosed extension -- neither of which T8 may invent.
37
+ */
38
+ phase?: string;
39
+ /** True when `phase` matched a declared `meta.phases` entry rather than being an ad-hoc `phase()` call. */
40
+ declaredPhase?: boolean;
41
+ usage?: {
42
+ total_tokens: number;
43
+ tool_uses: number;
44
+ duration_ms: number;
45
+ };
46
+ }
47
+ /**
48
+ * The handle one workflow RUN holds. `complete`/`fail` are terminal and idempotent -- a worker that
49
+ * crashes after reporting completion must not be able to re-fail its own task (WS-11 §1.8's
50
+ * `running -> completed | failed | stopped` is a one-way lifecycle).
51
+ */
52
+ export interface WorkflowTaskHandle {
53
+ taskId: string;
54
+ emit(progress: WorkflowProgress): void;
55
+ complete(result: unknown): void;
56
+ fail(error: string): void;
57
+ }
58
+ export interface WorkflowRunHost {
59
+ /**
60
+ * Registers this run as a background task. `kind` is the single literal `"workflow"` -- Winter's
61
+ * INTERNAL `BackgroundTaskKind` spelling. It is NOT what goes on the wire: capture (3) and item (g)
62
+ * both pin `task_started.task_type` / `WorkflowOutput.taskType` as `"local_workflow"`, and
63
+ * `tools/background-tasks.ts`'s own `wireTaskType(kind)` is the one mapping between them. A lane
64
+ * that hand-writes either spelling at an emission site is the drift this split exists to prevent.
65
+ */
66
+ createTask(kind: "workflow", meta: {
67
+ runId: string;
68
+ name: string;
69
+ }): WorkflowTaskHandle;
70
+ /** Spawns a child agent -- the SAME path the Agent tool uses, so `agent({schema})` rides `outputFormat` through `SpawnChildRequest` rather than a parallel mechanism. */
71
+ spawnAgent(req: SpawnChildRequest): Promise<ChildHandle>;
72
+ /** Schema validation, borrowed from Lane K (R5-12's named W->K coupling) -- never a second validator. */
73
+ structured: StructuredOutputSeam;
74
+ /** The session's context accounting -- what a workflow's `budget` ceiling reads. */
75
+ accountant: ContextAccountant;
76
+ }
77
+ /**
78
+ * The spine's test double: an in-memory host recording tasks, progress and terminal calls. It spawns
79
+ * no processes and creates no files, so a lane can exercise its orchestration logic long before its
80
+ * real subprocess runtime works.
81
+ */
82
+ export declare function fakeWorkflowRunHost(deps: {
83
+ structured: StructuredOutputSeam;
84
+ accountant: ContextAccountant;
85
+ spawnAgent?: (req: SpawnChildRequest) => Promise<ChildHandle>;
86
+ log?: Array<{
87
+ kind: string;
88
+ taskId: string;
89
+ event: "created" | "progress" | "complete" | "fail";
90
+ detail?: unknown;
91
+ }>;
92
+ }): WorkflowRunHost;
@@ -0,0 +1,16 @@
1
+ /** The ceiling half of `min(16, CPUs - 2)`. Exported so a test asserts the CONSTANT, not a re-derived literal. */
2
+ export declare const DEFAULT_MAX_CONCURRENCY = 16;
3
+ /**
4
+ * WS-11 §1.6: "concurrent `agent()` calls `min(16, CPUs - 2)` per run (excess queue and run as slots
5
+ * free)".
6
+ *
7
+ * Floored at 1: on a 1- or 2-core machine `CPUs - 2` is 0 or negative, and a semaphore with zero
8
+ * permits deadlocks every run that calls `agent()` even once -- silently, with no error, forever.
9
+ * The floor is the difference between "slow on a small machine" and "broken on a small machine".
10
+ */
11
+ export declare function resolveConcurrencyCap(cpuCount?: number): number;
12
+ export interface Semaphore {
13
+ acquire(): Promise<void>;
14
+ release(): void;
15
+ }
16
+ export declare function makeSemaphore(max: number): Semaphore;
@@ -0,0 +1,177 @@
1
+ import { type BrandProfile, type SettingSource } from "@yanlinglabs/winter-agent-sdk";
2
+ import { type WorkflowMetaPhase } from "./meta.js";
3
+ /** The project workflows directory for a brand -- `<brand.projectDirName>/workflows`. */
4
+ export declare function projectWorkflowsDir(brand?: Pick<BrandProfile, "projectDirName">): string;
5
+ /** Winter's own value, for every caller that has not threaded a brand. */
6
+ export declare const PROJECT_WORKFLOWS_DIR: string;
7
+ export type ResolvedWorkflowSource = {
8
+ ok: true;
9
+ source: string;
10
+ path: string | undefined;
11
+ source_kind: "project" | "user" | "builtin" | "plugin";
12
+ } | {
13
+ ok: false;
14
+ error: string;
15
+ };
16
+ /** A minimal projection of `plugins/bundle.ts`'s `PluginBundle` -- only the fields workflow resolution needs. */
17
+ export interface PluginWorkflowSource {
18
+ name: string;
19
+ workflowsPath?: string;
20
+ /**
21
+ * Fix round 4 (minors, M-3's last bullet): the manifest's own `workflows` override -- see
22
+ * `PluginBundle.workflowsPaths`'s own comment for why this is mutually exclusive with
23
+ * `workflowsPath` above rather than additive to it. `pluginWorkflowSourcePaths` below is where the
24
+ * two are combined into the single list every scan actually walks.
25
+ */
26
+ workflowsPaths?: readonly string[];
27
+ }
28
+ /**
29
+ * Shared by `resolveWorkflowByName` and `listWorkflowsForListing` -- resolution and listing read the
30
+ * SAME tiers under the SAME gates, so they can never disagree about what exists.
31
+ */
32
+ export interface WorkflowDiscoveryOptions {
33
+ cwd: string;
34
+ /**
35
+ * TRUST-GATED, deliberately, and this is a disclosed judgment call (see the lane report).
36
+ *
37
+ * A project `workflows/*.js` file is EXECUTABLE CODE a project supplies and the model runs -- the
38
+ * same category as a project `agents/*.md`, which RULING R4-7 keeps trust-gated, and not the
39
+ * category of skills/commands/instructions, which P5-T1 capture (b) makes merely SOURCE-gated. Norma
40
+ * trust-gated its own project workflow directory for the same reason. The consequence is real and
41
+ * worth stating: in an untrusted workspace `name` resolves nothing, so a freshly-cloned repo's
42
+ * workflows do not run until the workspace is trusted. `script`/`scriptPath` are unaffected.
43
+ *
44
+ * A PLUGIN workflow (below) is DELIBERATELY NOT gated on this bit, for the identical reason every
45
+ * other plugin-contributed resource in this codebase (skills, agents, commands, output styles,
46
+ * MCP servers) is not: a plugin is loaded because the HOST or the USER already decided to, outside
47
+ * the repository, so gating it on workspace trust would make plugin behaviour depend on which
48
+ * directory the session happens to be in. The USER tier (below) is not gated on this bit either,
49
+ * for the same reason skills' user tier is not (skills/store.ts's header).
50
+ */
51
+ trustedWorkspace: boolean;
52
+ /** P7a (D19): the session's brand -- the project dot-dir workflows live under. Omitted = `WINTER_BRAND`. */
53
+ brand?: Pick<BrandProfile, "projectDirName">;
54
+ /**
55
+ * WS-21 §6.3 item 1 (fix round 2): the session's ENABLED plugins that ship a `workflows/`
56
+ * directory. Omitted (every pre-fix-round-2 caller) means a `<plugin>:<name>` name simply falls
57
+ * through to "unknown workflow", exactly as it did before this field existed.
58
+ */
59
+ pluginWorkflows?: readonly PluginWorkflowSource[];
60
+ /**
61
+ * SV-5 fix round 3: the RESOLVED winter root (`SkillIndexOptions.winterHome`'s identical
62
+ * convention and identical naming rationale) -- `<winterHome>/workflows` is the user tier.
63
+ * Omitted means no user tier is read (every pre-fix-round-3 caller), not an error.
64
+ */
65
+ winterHome?: string | undefined;
66
+ /**
67
+ * Fix round 3 (I-4): source gating, mirroring `skills/store.ts`'s `sourcesAllow` exactly.
68
+ * Omitted = all tiers allowed (claude's own `settingSources` default). A caller that wants the
69
+ * project workflows directory (`projectWorkflowsDir`) un-read when the run's `settingSources`
70
+ * excludes `"project"` -- e.g. a `settingSources:["user"]` run that is ALSO
71
+ * `trustedWorkspace:true` -- must pass it; nothing derives it from `trustedWorkspace`, which is a
72
+ * different, narrower gate (R4-7) than this one.
73
+ */
74
+ settingSources?: readonly SettingSource[] | undefined;
75
+ }
76
+ export interface ResolveWorkflowByNameOptions extends WorkflowDiscoveryOptions {
77
+ /** Injectable for the test that proves built-ins are consulted first; production passes nothing. */
78
+ builtins?: Record<string, string>;
79
+ }
80
+ export declare function listBuiltinWorkflows(): string[];
81
+ /** Built-ins first, then a plugin (WS-21 §6.3 item 1), the trusted project directory, or the user directory. Never throws. */
82
+ export declare function resolveWorkflowByName(name: string, opts: ResolveWorkflowByNameOptions): ResolvedWorkflowSource;
83
+ export interface WorkflowListingEntry {
84
+ name: string;
85
+ description: string;
86
+ source: "project" | "user" | "plugin";
87
+ /** The script's real filesystem path -- carried through so a caller building a `SkillMeta`-shaped synthetic entry (production-wiring.ts) never has to invent one. */
88
+ path: string;
89
+ /** Fix round 4 (I-E): carried through for a synthetic skill/command prompt's own structure -- claude's own `m()` includes both alongside name/description. */
90
+ whenToUse?: string;
91
+ phases?: WorkflowMetaPhase[];
92
+ }
93
+ /**
94
+ * SV-5 (batch-2, second round, extended in fix round 3) -- the router same-view test: the pinned
95
+ * binary lists EVERY discovered workflow (user + project + plugin; built-in excluded, the pinned
96
+ * binary's own `d()`/`Ru()` gate that separately and Winter ships none -- see `BUILTIN_WORKFLOWS`)
97
+ * in the init `skills`/`slash_commands` fields and the model-facing Skill listing, named
98
+ * `<plugin>:<meta.name>` for a plugin workflow or bare `<meta.name>` for a user/project one --
99
+ * `getWorkflowCommands` in the pinned binary's own workflow-discovery module maps its FULL discovery
100
+ * result through a `{type:"prompt", name: o.name, description: o.description, ...}` projection,
101
+ * `o.name` already being the qualified/bare identity discovery assigned. `production-wiring.ts` is
102
+ * the one caller, folding this into all three listing surfaces.
103
+ *
104
+ * ORDER matches claude's own final merge in `j()`/`QX()`: plugin entries first (builtins would lead,
105
+ * but Winter has none to list), then user+project merged and name-sorted -- a project entry
106
+ * overriding a user entry of the same name the same way resolution above does, so listing and
107
+ * resolution can never disagree about which tier's copy is "the" workflow of that name.
108
+ */
109
+ export declare function listWorkflowsForListing(opts: WorkflowDiscoveryOptions): WorkflowListingEntry[];
110
+ /**
111
+ * Fix round 4 (I-E, the router same-view test): claude's own `m()` (dump-confirmed) turns every
112
+ * discovered workflow into a `{type:"prompt", kind:"workflow", ...}` command whose PROMPT runs the
113
+ * named workflow and carries the description, `whenToUse` and phases, ending with an instruction to
114
+ * invoke the Workflow tool by name. `SkillMeta` has no dedicated "workflow" shape, so this builds the
115
+ * BODY TEXT `SkillIndex`'s own synthetic-entry seam (`SkillIndexOptions.syntheticSkills`) stores for
116
+ * `Skill("<name>")` to return -- the WS-11 §2.3 contract ("invocation inserts the resolved skill
117
+ * instructions into the main conversation") applied to a workflow instead of a SKILL.md body.
118
+ *
119
+ * THE PROMPT TEXT IS WINTER-AUTHORED, per the user's own ruling that prompts stay Winter's own
120
+ * wording while INTERFACE strings (a field name, a listing label, an error message) may ship
121
+ * verbatim from the pinned binary -- this is prompt content the model reads and acts on, not an
122
+ * interface string, so it is worded fresh here rather than reproduced from the dump. The
123
+ * STRUCTURE claude's own `m()` carries (name, description, `whenToUse`, phases, then the invoke
124
+ * instruction) is preserved; the wording is not claude's.
125
+ *
126
+ * Fix round 5 (promoted minor, the re-review of 57e7fef..20b623e): `/plugin:name some args` must
127
+ * carry `some args` into the invoke line as `Workflow({ name, args })`, matching claude. This
128
+ * body is a SINGLE static string shared by BOTH the `Skill` tool door and the `/name args`
129
+ * slash-command door -- and only the LATTER substitutes `$ARGUMENTS`/`$ARGUMENTS_JSON`
130
+ * (`commands/resolver.ts`'s own "DISCLOSED ASYMMETRY" header: the Skill tool hands a body over
131
+ * verbatim, never substituting). Baking an args token into the ONE unconditional invoke line would
132
+ * leave it literal, unsubstituted, in what the model sees through the Skill-tool door, which is
133
+ * worse than dropping args entirely. So the args-carrying line is a SECOND, explicitly CONDITIONAL
134
+ * sentence: it still contains the literal token (nothing else can make the slash-command door's
135
+ * substitution reach it), but is worded so a model reading it unsubstituted (the Skill-tool door, or
136
+ * a bare `/name` with nothing after it, where the tokens substitute to `""`/`'""'`) recognises it
137
+ * does not apply and falls back to the first, unconditional line instead.
138
+ *
139
+ * Fix round 6 (a promoted minor, the re-review against the pinned 2.1.250 dump): the args value must
140
+ * be ESCAPED the way claude's own `S(e)` does, matching `createWorkflowCommand`'s
141
+ * `getPromptForCommand` (dump-confirmed: `a=e?\`{ name: ${i}, args: ${S(e)} }\`:...\`, i=S(o.name)`
142
+ * -- inferred to be JSON-string-quoting from the call-site shape: applied to a plain, always-defined
143
+ * string, used with no additional quotes around it). Using the RAW `$ARGUMENTS` token inside
144
+ * hand-written quotes (round 5's own shape) would let a literal `"` or `\` in the typed args break
145
+ * out of the quoted literal. `$ARGUMENTS_JSON` (`commands/resolver.ts`'s new second token) substitutes
146
+ * with `JSON.stringify(args)` instead -- already quoted and escaped -- so this line writes NO quotes
147
+ * of its own around it.
148
+ */
149
+ export declare function buildWorkflowSkillPrompt(entry: WorkflowListingEntry): string;
150
+ export interface SessionScriptLocation {
151
+ /** The resolved winter root in production (`resolveWinterHome()`), whose `projects/` child this addresses. */
152
+ winterHome: string;
153
+ projectKey: string;
154
+ /** The session UUID -- the `<session-uuid>` segment of capture (3)'s path. */
155
+ sessionId: string;
156
+ }
157
+ export interface PersistWorkflowScriptInput extends SessionScriptLocation {
158
+ /** `meta.name` (capture (3): `<meta.name>-<runId>.js`). */
159
+ name: string;
160
+ runId: string;
161
+ source: string;
162
+ }
163
+ /** Writes the script and returns its absolute path. Overwrites for the same run, so one run keeps one path. */
164
+ export declare function persistWorkflowScript(input: PersistWorkflowScriptInput): string;
165
+ /** Capture (3)'s sibling: `<session>/subagents/workflows/<runId>` -- what `WorkflowOutput.transcriptDir` reports. */
166
+ export declare function workflowTranscriptDir(input: SessionScriptLocation & {
167
+ runId: string;
168
+ }): string;
169
+ /**
170
+ * The JOURNAL root -- under the SESSION TEMP directory, not the durable projects area.
171
+ *
172
+ * Deliberate, and disclosed. `resumeFromRunId` is SAME-SESSION-ONLY by contract (WS-11 §1.5,
173
+ * `sdk-tools.d.ts:2786`), so a journal has no job to do once the session ends; capture (3) pinned the
174
+ * durable location of the SCRIPT and says nothing about a journal; and WS-01 forbids inventing a new
175
+ * durable directory name. Session temp is the D18 layout's own answer for per-session working state.
176
+ */
177
+ export declare function workflowRunsDir(sessionTempDir: string): string;