@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,52 @@
1
+ /**
2
+ * The 92 literals exactly as they appear in `c7t`'s source order (duplicate `learn.microsoft.com`
3
+ * included) -- kept verbatim so a future re-extraction diffs cleanly against this array.
4
+ */
5
+ export declare const PREAPPROVED_HOST_ENTRIES: readonly string[];
6
+ /**
7
+ * `wX(hostname, pathname)`, verbatim: an EXACT hostname match (no subdomains) against the
8
+ * hostname-only half, OR a hostname with a registered path prefix whose pathname is that prefix or a
9
+ * `/`-bounded child of it -- rejected outright when the raw pathname contains an encoded slash,
10
+ * backslash or dot (`%2f`, `%5c`, `%2e`, doubly-encoded or not), which is exactly the traversal class
11
+ * that would otherwise let `/docs%2f..%2fadmin` read as a legitimate child of `/docs`.
12
+ */
13
+ export declare function isPreapprovedHost(hostname: string, pathname: string): boolean;
14
+ /** `isPreapprovedHost`, taking the URL directly. A URL that fails to parse is never preapproved. */
15
+ export declare function isPreapprovedUrl(url: URL): boolean;
16
+ /**
17
+ * The registered entry that matched `url`, if any -- distinguishes a bare hostname match from a
18
+ * path-scoped one, and names the scope's prefix, so the redirect walk can ask "does the hop's own
19
+ * path still fall under the SAME scope" rather than only "is this host preapproved at all."
20
+ */
21
+ export interface PreapprovedMatch {
22
+ host: string;
23
+ /** `undefined` for a hostname-only entry; the exact `/`-prefixed scope for a path-scoped one. */
24
+ pathPrefix?: string;
25
+ }
26
+ /**
27
+ * Security review round 2, minor: this was EXACT-hostname-only, while `staysWithinScope` (below)
28
+ * already applied the three-way `[host, stripped, "www."+stripped]` match -- half of one fix. The
29
+ * gap is not cosmetic: a redirect chain `claude.com/docs/a` -> `www.claude.com/docs/a` (eligible,
30
+ * `staysWithinScope` says so) -> `www.claude.com/other` recomputes THIS function fresh at the top of
31
+ * the SECOND hop, on hostname `www.claude.com` -- which `PATH_PREFIXES` only ever keys by
32
+ * `claude.com`, so the old exact match returned `undefined` for it. An `undefined` scope makes
33
+ * `isEligibleAutoFollow`'s own `scope !== undefined && ...` check SHORT-CIRCUIT to "no restriction
34
+ * at all," so the THIRD hop (genuinely outside `/docs`) was auto-followed, not refused -- and because
35
+ * `claude.com/docs/a` (the ORIGINAL input URL) is still preapproved, that off-scope content got
36
+ * permissive guidelines and was eligible for the verbatim markdown passthrough. Matching hosts the
37
+ * same three-way way `staysWithinScope` does closes it: hop 2 now still resolves a scope (matched via
38
+ * the `claude.com` entry), and `staysWithinScope` correctly refuses hop 3's `/other` path.
39
+ */
40
+ export declare function preapprovedScopeOf(url: URL): PreapprovedMatch | undefined;
41
+ /**
42
+ * Whether `url` still falls under the SAME preapproved scope `from` matched -- used by the redirect
43
+ * walk's "not leaving a preapproved path scope" gate.
44
+ *
45
+ * HOST comparison is the same three-way test claude's own code runs (security review corrections
46
+ * §4.8, measured): `[host, stripped, "www."+stripped]`, i.e. the scope's own host, that host with a
47
+ * leading `www.` stripped, and that stripped form with `www.` re-added -- so a scope matched on
48
+ * `claude.com/docs` still covers a redirect to `www.claude.com/docs/x`, and one matched on
49
+ * `www.example.com/docs` still covers a redirect to `example.com/docs/x`. An EXACT match only (this
50
+ * lane's earlier version) refused a same-site www-variant redirect claude itself follows.
51
+ */
52
+ export declare function staysWithinScope(from: PreapprovedMatch, url: URL): boolean;
@@ -0,0 +1,55 @@
1
+ export type AddressVerdict = "public" | "private";
2
+ /** One classified fact about a hop's target -- WHERE it came from is what a caller's message names. */
3
+ export interface PrivateAddressFinding {
4
+ class: AddressVerdict;
5
+ /** The shared classifier's own class name, or a reserved-name label -- safe to show the model. */
6
+ reason?: string;
7
+ }
8
+ /** Strips a `[...]` IPv6 literal's brackets; a non-bracketed host is returned unchanged. */
9
+ export declare function stripIpv6Brackets(hostname: string): string;
10
+ /**
11
+ * Classifies a literal IP address -- family auto-detected via `net.isIP` (0 = not a literal IP at
12
+ * all, in which case this returns `undefined` rather than guessing). Delegates the actual range
13
+ * logic to the shared classifier, which already handles IPv4-mapped IPv6 in both its dotted-quad
14
+ * (`::ffff:127.0.0.1`) and hex-group (`::ffff:7f00:1`) forms.
15
+ */
16
+ export declare function classifyIpLiteral(address: string): PrivateAddressFinding | undefined;
17
+ /** Reserved names RFC 6761 (`localhost`) and mDNS (`.local`) carve out -- private by NAME, whatever they resolve to. A single trailing dot (the DNS root, `localhost.`/`a.localhost.`/`foo.local.`) is stripped first so it cannot defeat the check. */
18
+ export declare function classifyReservedName(hostname: string): PrivateAddressFinding | undefined;
19
+ /**
20
+ * The LEXICAL verdict for `hostname` as written in the URL: an IP literal classified by range, or a
21
+ * reserved name. `undefined` means "not lexically decidable" -- an ordinary DNS name, which is only
22
+ * classifiable by its RESOLVED address (see `classifyHostname` below).
23
+ */
24
+ export declare function classifyHostnameLexically(hostname: string): PrivateAddressFinding | undefined;
25
+ /** The verdict for one resolved connection address (whatever DNS returned for an ordinary name). */
26
+ export declare function classifyResolvedAddress(address: string): PrivateAddressFinding;
27
+ /**
28
+ * The full verdict for `hostname`: lexical first (an IP literal or reserved name never needs a
29
+ * lookup), else every address `resolve` returns for it -- ANY private address among them makes the
30
+ * whole hostname private, because a caller reaches whichever address the OS connects to, not
31
+ * necessarily the first one.
32
+ *
33
+ * NOT the function that guards the actual connection any more (security review finding M6):
34
+ * `_web-fetch-net.ts`'s own `resolveTarget` now does its own single resolution and PINS the fetch
35
+ * to the exact address it classified (`Host` + `tls.serverName` carrying the logical name), closing
36
+ * the rebinding TOCTOU this function's own resolve-then-classify shape cannot by itself (a second,
37
+ * independent `fetch()`-internal resolution could still answer differently). This function remains
38
+ * the upfront, pre-cache gate in `web-fetch.ts` -- a decision, not a connection -- where that gap
39
+ * does not apply the same way (nothing here opens a socket).
40
+ *
41
+ * FAILS CLOSED on a resolution failure (security review finding M6): an EARLIER version of this
42
+ * function answered `PUBLIC` when `resolve` threw or answered nothing, on the reasoning that "the
43
+ * fetch step reports the real failure" -- but a caller that only asks THIS function before deciding
44
+ * whether to proceed (as `web-fetch.ts`'s own upfront gate does, ahead of a cache-hit) would treat an
45
+ * unresolvable name as safe to serve. There is no address to pin a decision to, so the honest answer
46
+ * is `private` (refuse), never `public` (silently proceed).
47
+ */
48
+ /**
49
+ * Item 2: the ONE spelling of "resolution failed" -- shared so a caller that needs to tell "actually
50
+ * private" apart from "unknown, because DNS didn't answer" (`web-fetch.ts`'s own cache-hit refusal,
51
+ * which used to say "it is a private/loopback address" for BOTH) compares against this constant,
52
+ * never a re-typed literal that could drift from the one below.
53
+ */
54
+ export declare const UNRESOLVABLE_HOST_REASON = "could not resolve any address for this host";
55
+ export declare function classifyHostname(hostname: string, resolve: (hostname: string) => Promise<readonly string[]>): Promise<PrivateAddressFinding>;
@@ -0,0 +1,86 @@
1
+ import type { CredentialRef, ResolvedWebToolsConfig } from "@yanlinglabs/winter-agent-sdk";
2
+ import type { MessageOrigin } from "@yanlinglabs/winter-provider-runtime";
3
+ import type { Provider, ProviderUsage } from "../engine.js";
4
+ import type { AuxiliaryModelResolution } from "../provider/session-provider.js";
5
+ import type { ToolSecretResolver } from "../provider/tool-secret.js";
6
+ /** The model a run is generating with RIGHT NOW -- live across `set_model` and a fallback. */
7
+ export interface SessionModelHandle {
8
+ provider: Provider;
9
+ /**
10
+ * The session's live model string -- BOTH what an inner request carries as `model` (exactly what
11
+ * the main loop sends, so the adapter translates it identically) AND the key its usage is
12
+ * accounted under (so an inner generation lands on the SAME `modelUsage` row as the main loop's).
13
+ * `undefined` only for a scripted double started with no model string.
14
+ */
15
+ model: string | undefined;
16
+ /** Stamped onto the inner transcript's assistant messages so a real adapter replays them in-domain. */
17
+ origin?: MessageOrigin;
18
+ }
19
+ export interface WebSessionRuntime {
20
+ /** `RuntimeConfig.web` with every default applied (`resolveWebToolsConfig`). */
21
+ readonly web: ResolvedWebToolsConfig;
22
+ /**
23
+ * THE SESSION'S OWN MODEL, live. The default for every inner pass: always resolvable (the session
24
+ * is already generating on it) and needing no second credential. Read at CALL time, never cached
25
+ * by a consumer -- a `set_model` between two tool calls must move the inner pass with it.
26
+ */
27
+ sessionModel(): SessionModelHandle;
28
+ /**
29
+ * A STATED inner model (`web.fetch.digestModel`), by tag, under the cross-provider credential
30
+ * rule. ABSENT when the session has no catalog identity to resolve against (a scripted double, a
31
+ * session whose own model was refused): a stated tag is then unresolvable, and the consumer says
32
+ * so rather than falling back.
33
+ */
34
+ resolveAuxiliaryModel?: (tag: string, opts?: {
35
+ authRef?: CredentialRef;
36
+ }) => AuxiliaryModelResolution;
37
+ /**
38
+ * Folds ONE inner generation's usage into this run's accounting, exactly as far as a main-loop
39
+ * generation's goes and no further: it is SPEND (cumulative tokens, the cost ledger, and therefore
40
+ * `maxBudgetUsd`), and it is NOT context -- the inner prompt is never part of the session's next
41
+ * request, so it must not move the context reading compaction triggers on.
42
+ */
43
+ accountUsage(modelKey: string | undefined, usage: ProviderUsage): void;
44
+ /**
45
+ * Has this run crossed `maxBudgetUsd`? The main loop asks this only before ITS OWN requests, so an
46
+ * inner pass asks it before each of its generations -- otherwise a bounded inner loop is the one
47
+ * place a session could keep spending past its ceiling. OPTIONAL and additive: absent (a hand-built
48
+ * runtime, a run with no budget) reads as "no".
49
+ */
50
+ budgetExceeded?(): boolean;
51
+ /** Resolves a tool's secret from a ref. ABSENT for an engine run with no provider wiring (a bare `runEngine` over a double). */
52
+ resolveToolSecret?: ToolSecretResolver;
53
+ }
54
+ /**
55
+ * Registers `runtime` under `key` (`config.agentId ?? config.sessionId` -- a child shares its
56
+ * parent's session id, so the agent id is what tells them apart). Returns an IDENTITY-CHECKED
57
+ * disposer: a late teardown of a previous generation never removes the live one's registration.
58
+ */
59
+ export declare function registerWebSessionRuntime(key: string, runtime: WebSessionRuntime): () => void;
60
+ export declare function getWebSessionRuntime(key: string): WebSessionRuntime | undefined;
61
+ /**
62
+ * The runtime for the engine run EXECUTING this tool call: the child's own when the call is a
63
+ * child's, else the session's. Falls back to the owning session's for a child whose own
64
+ * registration is missing, so a wiring gap degrades to "the parent's model" rather than to a tool
65
+ * that cannot run.
66
+ */
67
+ export declare function webSessionRuntimeFor(ctx: {
68
+ sessionId: string;
69
+ agentId?: string;
70
+ }): WebSessionRuntime | undefined;
71
+ /** The three SESSION-level facts a child run inherits from the root's registration (see the header). */
72
+ export declare function inheritedWebSessionFacts(sessionId: string): Pick<WebSessionRuntime, "web" | "resolveAuxiliaryModel" | "resolveToolSecret"> | undefined;
73
+ /** Test hygiene only: the registry is a process-wide singleton and `bun test` shares one module graph. */
74
+ export declare function resetWebSessionRuntimesForTest(): void;
75
+ /** `winter.search-backend`'s session fact: the host has not switched the backend off. */
76
+ export declare function searchBackendUsable(runtime: Pick<WebSessionRuntime, "web">): boolean;
77
+ /**
78
+ * `winter.fetch-extractor`'s session fact: a digest model resolves.
79
+ *
80
+ * With no `digestModel` stated the digest runs on the session's own model, which resolves by
81
+ * construction. A STATED one must actually resolve -- it is never quietly replaced -- so an
82
+ * unresolvable tag withdraws the tool rather than advertising one that can only refuse. (Whether a
83
+ * CREDENTIAL exists for a cross-provider digest model is not knowable synchronously; that arrives as
84
+ * a typed refusal in the tool's result at the first generation.)
85
+ */
86
+ export declare function digestModelResolves(runtime: Pick<WebSessionRuntime, "web" | "resolveAuxiliaryModel">): boolean;
@@ -0,0 +1,87 @@
1
+ import type { AgentOpts } from "./types.js";
2
+ import type { BudgetSnapshot } from "./budget.js";
3
+ /** Worker -> parent. */
4
+ export type BridgeRequest = {
5
+ op: "agent";
6
+ callId: number;
7
+ prompt: string;
8
+ opts?: AgentOpts;
9
+ } | {
10
+ op: "workflow";
11
+ callId: number;
12
+ ref: WorkflowRef;
13
+ args?: unknown;
14
+ } | {
15
+ op: "log";
16
+ message: string;
17
+ } | {
18
+ op: "resumed";
19
+ cachedPrefix: number;
20
+ } | {
21
+ op: "phase";
22
+ title: string;
23
+ } | {
24
+ op: "done";
25
+ result: unknown;
26
+ } | {
27
+ op: "error";
28
+ message: string;
29
+ };
30
+ /** WS-11 §1.6's `workflow(nameOrRef, args?)`: "a saved name or `{scriptPath}`". */
31
+ export type WorkflowRef = {
32
+ name: string;
33
+ } | {
34
+ scriptPath: string;
35
+ };
36
+ /**
37
+ * Parent -> worker: the reply to an `agent`/`workflow` request.
38
+ *
39
+ * `ok: true, value: null` is a MEANINGFUL, non-error outcome for `agent` -- WS-11 §1.6: "Resolves
40
+ * `null` when the user skips the agent or it dies on a terminal error -- callers filter with
41
+ * `.filter(Boolean)`." `ok: false` is reserved for the conditions that must THROW inside the script
42
+ * (the total-agent cap, the budget ceiling, an unresolvable nested workflow), because those are
43
+ * conditions a `.filter(Boolean)` must not be able to swallow.
44
+ */
45
+ export type BridgeResponse = {
46
+ callId: number;
47
+ ok: true;
48
+ value: unknown;
49
+ budget?: BudgetSnapshot;
50
+ } | {
51
+ callId: number;
52
+ ok: false;
53
+ error: string;
54
+ budget?: BudgetSnapshot;
55
+ };
56
+ /** The single init line the parent writes on spawn, before anything else. */
57
+ export interface WorkerInit {
58
+ runId: string;
59
+ source: string;
60
+ args: unknown;
61
+ /** `min(16, CPUs - 2)`, resolved parent-side (semaphore.ts). */
62
+ concurrency: number;
63
+ /** WS-11 §1.6: 1000 total agents per run. Mirrored so the worker can fail fast; enforced parent-side regardless. */
64
+ totalAgentCap: number;
65
+ /** WS-11 §1.6: 4096 items max per `parallel`/`pipeline` call -- an EXPLICIT error, entirely in-worker (the parent never sees the array). */
66
+ maxItemsPerCall: number;
67
+ budget: BudgetSnapshot;
68
+ /** WS-11 §1.5: the prior run's ordered agent() results. Absent/empty for a fresh run. */
69
+ resumeJournal?: Array<{
70
+ promptKey: string;
71
+ value: unknown;
72
+ }>;
73
+ }
74
+ /**
75
+ * The framing both ends share. Deliberately a FUNCTION over a string buffer rather than a class:
76
+ * the worker and the runtime both need it, the worker's copy is bundled into the compiled binary,
77
+ * and a shared pure function has no lifecycle to get wrong on either side.
78
+ *
79
+ * Returns the complete lines found and the unconsumed remainder, which the caller carries forward --
80
+ * a `data` chunk may split a line in half or coalesce ten of them.
81
+ */
82
+ export declare function splitNdjson(buffer: string): {
83
+ lines: string[];
84
+ rest: string;
85
+ };
86
+ /** One NDJSON frame, terminator included. One place, so the two ends cannot disagree about the newline. */
87
+ export declare function encodeNdjson(value: unknown): string;
@@ -0,0 +1,24 @@
1
+ /** What crosses the bridge so the worker's own `budget` object can answer without a round trip. */
2
+ export interface BudgetSnapshot {
3
+ total: number | null;
4
+ spent: number;
5
+ }
6
+ export interface WorkflowBudget {
7
+ /** `null` = no ceiling. THE DEFAULT (WS-11 §1.6 as amended by the task brief). */
8
+ readonly total: number | null;
9
+ spent(): number;
10
+ remaining(): number;
11
+ /** True once `spent() >= total`. Always false when `total` is null. */
12
+ exceeded(): boolean;
13
+ snapshot(): BudgetSnapshot;
14
+ }
15
+ export interface BudgetDeps {
16
+ /**
17
+ * The session's CUMULATIVE token spend (RULING P5-J). Absent = 0, never `contextTokens()` -- see
18
+ * this module's header for why substituting that quantity is worse than reporting nothing.
19
+ */
20
+ spentTokens?: () => number;
21
+ /** Omitted (or null) = no ceiling. */
22
+ total?: number | null;
23
+ }
24
+ export declare function createBudget(deps: BudgetDeps): WorkflowBudget;
@@ -0,0 +1,142 @@
1
+ import type { BrandProfile, SettingSource } from "@yanlinglabs/winter-agent-sdk";
2
+ import type { RuntimeAgentDefinition } from "@yanlinglabs/winter-agent-sdk";
3
+ import type { ContextAccountant } from "../engine.js";
4
+ import type { StructuredOutputSeam } from "../structured/seam.js";
5
+ export interface WorkflowSessionRuntime {
6
+ /**
7
+ * THE REGISTRATION KEY (fix wave, whole-branch I5). The engine's own `config.sessionId`.
8
+ *
9
+ * OPTIONAL ONLY FOR COMPILE COMPATIBILITY, and the omission is not the intended shape: an
10
+ * unkeyed registration lands in the single legacy slot below, which is exactly the
11
+ * one-live-session-per-process assumption I5 is about. `engine.ts` (the sole production
12
+ * registrant) is another lane's file in this wave and still omits it -- see this module's own
13
+ * "PRODUCTION WIRING" note.
14
+ *
15
+ * A CHILD engine reaches the registration site with its PARENT's `config.sessionId`, which is why
16
+ * registration is FIRST-WINS: see `registerWorkflowSession`.
17
+ */
18
+ sessionId?: string;
19
+ /** The winter root this session persists under -- `resolveWinterHome()`'s value, whose `projects/` child holds the session area. */
20
+ winterHome: string;
21
+ /**
22
+ * SV-5 fix round 3: the DISCOVERY root a nested `workflow(name)` call's project/user tier
23
+ * resolution reads (`resolveWorkflowByName`'s `winterHome` -- the user tier's
24
+ * `<winterHome>/workflows`) -- DELIBERATELY DISTINCT from `winterHome` above, which is the
25
+ * DURABLE persist root (`storeHome ?? winterHome`) capture (3)'s script path is built from.
26
+ * Conflating the two would read the user tier from the wrong root whenever a router-linked run
27
+ * has a `storeHome` that differs from its per-run `winterHome` -- exactly the SV-1/SV-2 bug class
28
+ * this field exists to not repeat. Absent means the nested resolver's user tier stays inert,
29
+ * matching every pre-fix-round-3 caller.
30
+ */
31
+ discoveryWinterHome?: string;
32
+ /** P7a (D19): the session's brand -- the project dot-dir a `workflow(name)` resolves under, and the worker seatbelt's fences. */
33
+ brand?: BrandProfile;
34
+ /** SV-5 fix round 3 (I-4): threaded to `resolveWorkflowByName` so a nested call's project/user tier resolution is source-gated exactly like the top-level Workflow tool. */
35
+ settingSources?: readonly SettingSource[];
36
+ /**
37
+ * WS-21 §6.3 item 1 (batch-2 fix round): the session's ENABLED plugins that ship a `workflows/`
38
+ * directory -- threaded to `defaultNestedResolver` (workflows/runtime.ts) so a nested
39
+ * `workflow("plugin:name")` call resolves a plugin workflow exactly like the top-level Workflow
40
+ * tool does (tools/impl/workflow.ts). Absent means a qualified name never resolves here either,
41
+ * matching every pre-fix caller.
42
+ *
43
+ * Fix round 4 (minors, M-3's last bullet): also carries `workflowsPaths` -- see
44
+ * `engine.ts`'s `EngineOptions.pluginWorkflows` for why every hop widened rather than gaining a
45
+ * new field.
46
+ */
47
+ pluginWorkflows?: readonly {
48
+ name: string;
49
+ workflowsPath?: string;
50
+ workflowsPaths?: readonly string[];
51
+ }[];
52
+ /** `compatibilityKeys(cwd).transcriptProjectKey`, after `resolveProjectDirName` -- the SAME key the transcript store uses, never a second derivation. */
53
+ projectKey: string;
54
+ /** The session's own temp directory (paths/temp.ts) -- where per-run journals live (store.ts's `workflowRunsDir`). */
55
+ sessionTempDir: string;
56
+ /** Borrowed from Lane K through the seam (R5-12's named W->K coupling) -- never a second validator. */
57
+ structured: StructuredOutputSeam;
58
+ /** The session's live context accounting. Passed straight to `WorkflowRunHost.accountant`. */
59
+ accountant: ContextAccountant;
60
+ /**
61
+ * The session's CUMULATIVE token spend, for `budget.spent()` -- RULING P5-J (spine, fix wave).
62
+ *
63
+ * Deliberately NOT `accountant.contextTokens()`, which is the last provider call's context SIZE:
64
+ * an overwrite rather than an accumulation, non-monotonic, and blind to a workflow's own agents
65
+ * (each child builds its own accountant). Absent = `spent()` reports 0 and a ceiling never trips,
66
+ * which is honest; substituting the wrong quantity would look plausible and bound nothing.
67
+ *
68
+ * P5-J is expected to add the counter to `ContextAccountant` and route child usage into the
69
+ * parent's; when it lands, T8 wires that accessor here.
70
+ */
71
+ spentTokens?: () => number;
72
+ /**
73
+ * The workflow budget ceiling, if the host set one. `null`/absent is the DEFAULT and means no
74
+ * ceiling (WS-11 §1.6 as amended by the task brief). No `WorkflowInput` field carries this -- it is
75
+ * a host/session-level setting, which is why it arrives here rather than through the tool call.
76
+ */
77
+ budgetTotal?: number | null;
78
+ /**
79
+ * Resolves `agent({ agentType })` against the SAME registry the Agent tool uses (WS-11 §1.6:
80
+ * "a custom subagent type resolved from the same registry as the Agent tool"). Injected rather
81
+ * than called directly so this module keeps no dependency on `subagents/definitions.ts`, and so a
82
+ * host that has already loaded its definitions does not make the runtime re-read the filesystem
83
+ * once per `agent()` call.
84
+ *
85
+ * Absent = no custom types resolve; `agent({agentType})` then spawns a child whose definition
86
+ * records the unresolved name (runtime.ts's `resolveChildDefinition`), never a silent generic one.
87
+ */
88
+ resolveAgentType?(agentType: string, ctx: {
89
+ cwd: string;
90
+ trustedWorkspace: boolean;
91
+ }): RuntimeAgentDefinition | undefined;
92
+ }
93
+ /**
94
+ * Register this session's runtime and return an IDENTITY-CHECKED disposer (the shape
95
+ * `registerSessionMcpLifecycle` already uses): the disposer withdraws the registration only while it
96
+ * is still the one this call made, so a stopped-and-immediately-restarted run's late teardown cannot
97
+ * remove the live generation's runtime.
98
+ *
99
+ * FIRST-WINS PER SESSION ID, deliberately. A CHILD engine reaches the production registration site
100
+ * (`engine.ts`) with `config.sessionId` -- which for a child IS the parent's id -- because the child
101
+ * is given the parent's structured-output seam, the condition that site gates on. Last-wins would
102
+ * therefore let a child replace its parent's registration mid-run (different `sessionTempDir`,
103
+ * different `projectKey`) and withdraw it at the child's teardown: the daemon defect, reachable
104
+ * inside one session. First-wins makes the child's register/dispose pair a no-op, which is also the
105
+ * "children resolve against the parent's registration" reading the seam already documents.
106
+ *
107
+ * PRODUCTION WIRING IS **NEEDS_CONTEXT** (this wave's lane split): `engine.ts` is another lane's
108
+ * file, so its two call sites still pass no `sessionId` and still call `clearWorkflowSession()` with
109
+ * no argument -- which is why the legacy slot below exists and why production behaviour is BYTE
110
+ * IDENTICAL to the pre-fix build until those two lines change to
111
+ * `registerWorkflowSession({ sessionId: config.sessionId, ... })` and `disposeWorkflowSession?.()`.
112
+ */
113
+ export declare function registerWorkflowSession(runtime: WorkflowSessionRuntime): () => void;
114
+ /**
115
+ * The runtime registered for `sessionId`, or the legacy unkeyed one when no keyed registration
116
+ * exists for it (the pre-I5 production path, unchanged). `undefined` when nothing is registered at
117
+ * all -- the Workflow tool answers a typed tool error rather than crashing.
118
+ */
119
+ export declare function getWorkflowSession(sessionId?: string): WorkflowSessionRuntime | undefined;
120
+ /**
121
+ * Withdraw one session's registration. PRODUCTION teardown calls this (engine.ts, at the end of
122
+ * every run) for the reason the registration shape makes concrete: a run that left its registration
123
+ * standing would let a LATER session's Workflow call persist its script under the finished session's
124
+ * `projects/<key>/<uuid>/` directory.
125
+ *
126
+ * With no argument it clears the LEGACY slot only -- never the whole map. Clearing every session
127
+ * would reinstate I5 in the other direction: one run's teardown disabling every other live session's
128
+ * workflows.
129
+ *
130
+ * AT ENGINE TEARDOWN, USE THE DISPOSER `registerWorkflowSession` RETURNS -- never
131
+ * `clearWorkflowSession(config.sessionId)`. First-wins protects REGISTRATION from a child engine
132
+ * (which arrives with its parent's `config.sessionId`); only the identity-checked disposer protects
133
+ * WITHDRAWAL from the same child, whose teardown would otherwise delete its still-running parent's
134
+ * entry by key. This by-key form is for a host that is genuinely ending that session.
135
+ */
136
+ export declare function clearWorkflowSession(sessionId?: string): void;
137
+ /**
138
+ * Test-only: clears EVERY registration, keyed and legacy. Same rationale as every sibling singleton
139
+ * in this codebase: bun's test runner shares ONE module instance across every file in a run, so one
140
+ * file's registration would otherwise leak into another's assertions.
141
+ */
142
+ export declare function resetWorkflowSessionForTest(): void;
@@ -0,0 +1,29 @@
1
+ import type { AgentOpts } from "./types.js";
2
+ export interface JournalEntry {
3
+ promptKey: string;
4
+ value: unknown;
5
+ }
6
+ /**
7
+ * The positional cache key: `(prompt, opts)` serialized. WS-11 §1.5's "a per-run journal keyed by
8
+ * call order + prompt/opts key" -- the ORDER is the array index, this is the identity check at that
9
+ * index. `undefined` opts normalize to `null` so `agent("go")` and `agent("go", undefined)` are the
10
+ * same call, which they are.
11
+ */
12
+ export declare function promptKey(prompt: string, opts?: AgentOpts): string;
13
+ export declare class RunJournal {
14
+ private readonly path;
15
+ constructor(dir: string, runId: string);
16
+ append(promptKeyValue: string, value: unknown): void;
17
+ /** Escape hatch for the corrupt-line test -- a real caller always uses `append`. */
18
+ appendRaw(line: string): void;
19
+ /**
20
+ * The journal's readable prefix. A missing file is an empty array (a fresh run has no journal),
21
+ * and a CORRUPT line is skipped rather than fatal: a run killed mid-append leaves a partial last
22
+ * line, and refusing to resume at all because of it would be strictly worse than resuming the
23
+ * complete entries that precede it. The positional replay in script-api.ts diverges at the first
24
+ * key mismatch anyway, so a skipped line can only ever shorten the cached prefix, never
25
+ * misalign it -- a dropped middle entry shifts the entries after it, and the very next key
26
+ * comparison fails and latches `diverged`, sending everything from there on live.
27
+ */
28
+ load(): JournalEntry[];
29
+ }
@@ -0,0 +1,45 @@
1
+ /** A declared phase (WS-11 §1.2). `title` is matched against `phase()` calls EXACTLY. */
2
+ export interface WorkflowMetaPhase {
3
+ title: string;
4
+ detail?: string;
5
+ model?: string;
6
+ }
7
+ export interface WorkflowMeta {
8
+ name: string;
9
+ description: string;
10
+ whenToUse?: string;
11
+ phases?: WorkflowMetaPhase[];
12
+ /** Any further literal keys the author wrote. Preserved, never interpreted -- this parser validates the SHAPE it is specified to validate and does not silently drop what it does not know. */
13
+ [key: string]: unknown;
14
+ }
15
+ export type ParsedWorkflowMeta = {
16
+ ok: true;
17
+ meta: WorkflowMeta;
18
+ } | {
19
+ ok: false;
20
+ error: string;
21
+ };
22
+ /**
23
+ * Parses and validates a script's `meta` block.
24
+ *
25
+ * Never throws and never evaluates: every failure -- absent block, non-literal value, missing
26
+ * required key, malformed `phases` -- comes back as `{ ok: false, error }`. The Workflow tool turns
27
+ * that into a `WorkflowOutput` carrying `error` (derived-shapes-p5 item (g): a script that fails the
28
+ * syntax check still RETURNS a WorkflowOutput, it does not throw).
29
+ */
30
+ export declare function parseWorkflowMeta(source: string): ParsedWorkflowMeta;
31
+ /** The resolution of one `phase(title)` call against the declared phases. */
32
+ export interface PhaseGroup extends WorkflowMetaPhase {
33
+ /** true when `title` matched a declared `meta.phases` entry EXACTLY. */
34
+ declared: boolean;
35
+ }
36
+ /**
37
+ * WS-11 §1.2's own rule, at the one point it actually applies -- when a `phase()` call arrives over
38
+ * the bridge, not at parse time: "phase titles match `phase()` calls exactly; an unmatched `phase()`
39
+ * call gets its own progress group."
40
+ *
41
+ * A near-miss is deliberately NOT fuzzy-matched to a declared phase: a script that mistypes a phase
42
+ * title gets a visible extra group, which is a diagnosable outcome, rather than silently landing in
43
+ * the wrong one.
44
+ */
45
+ export declare function matchPhaseGroup(declared: readonly WorkflowMetaPhase[] | undefined, title: string): PhaseGroup;
@@ -0,0 +1,24 @@
1
+ import type { WorkflowCounts, WorkflowRunView } from "./types.js";
2
+ export declare class WorkflowRegistry {
3
+ private readonly runs;
4
+ register(entry: {
5
+ runId: string;
6
+ sessionId: string;
7
+ taskId: string;
8
+ name: string;
9
+ abort: AbortController;
10
+ startedAt?: number;
11
+ }): void;
12
+ setPhase(runId: string, phase: string): void;
13
+ setCounts(runId: string, counts: WorkflowCounts): void;
14
+ /** `running -> completed | failed`. No-op if unknown or already terminal. */
15
+ complete(runId: string, outcome: {
16
+ ok: boolean;
17
+ result: string;
18
+ }): void;
19
+ fail(runId: string, error: string): void;
20
+ /** `running -> stopped`, firing the run's abort. Returns false if unknown or already terminal. */
21
+ stop(runId: string): boolean;
22
+ get(runId: string): WorkflowRunView | undefined;
23
+ list(sessionId: string): WorkflowRunView[];
24
+ }