@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,62 @@
1
+ import type { ActionEnvelope } from "../../permissions/auto/envelope.js";
2
+ import type { ClassifierContext } from "../../permissions/auto/engine.js";
3
+ /**
4
+ * P2 carry, WS-07 §10.4 ("a bounded portion of..."): the ceiling on the app-owned
5
+ * `accumulatedClassifierContext` a single review may carry.
6
+ *
7
+ * 8000 characters is roughly a couple of thousand tokens — enough for a real PostToolUse
8
+ * accumulation, far short of anything that would push a review request into a context-length failure
9
+ * (which §10.5 treats as its own no-verdict class, i.e. as a DENIAL). The bound exists so an
10
+ * accumulator that grows across a long session degrades by dropping its oldest entries rather than
11
+ * by silently failing every permission decision in the session.
12
+ */
13
+ export declare const DEFAULT_MAX_CONTEXT_CHARS = 8000;
14
+ /**
15
+ * The system prompt.
16
+ *
17
+ * A CONSTANT, not a template: nothing about the pending action, the session, the rules or the
18
+ * context appears here. That separation is the point — this half is trusted text Winter wrote, and
19
+ * everything the reviewer could be attacked through arrives in the other half, fenced and labelled.
20
+ *
21
+ * What it states, and why each line is here rather than implied:
22
+ * - the role and the single output channel (§10.6-3: "the classifier receives strict data blocks
23
+ * and no tools" — one tool, and it is the answer channel, not an action);
24
+ * - that data is data (§10.4);
25
+ * - the three-value vocabulary and, crucially, that `no_verdict` is a real answer rather than a
26
+ * failure to answer (§10.6-5: insufficient information must not be guessed into an allow — the
27
+ * engine fails closed on it, so honest abstention costs the user a prompt, not a compromise);
28
+ * - that the rules block is authoritative over the reviewer's own opinion (§10.2's tier semantics
29
+ * are enforced deterministically OUTSIDE the model too — `resolveAutoTier`'s backstop can only
30
+ * make an outcome stricter — but a reviewer that argues with the configured policy produces
31
+ * verdicts a user cannot reason about).
32
+ */
33
+ export declare const CLASSIFIER_SYSTEM_PROMPT: string;
34
+ export interface ClassifierPromptOptions {
35
+ /** P2 carry: the ceiling on the app-owned accumulated context. Oldest entries are dropped first. */
36
+ maxContextChars?: number;
37
+ /** Test seam ONLY: forces the fence token, so a fixture can drive a payload that contains it. Production never passes this. */
38
+ nonce?: string;
39
+ /**
40
+ * P7a fix wave (item 5, M-1): the running brand's instructions file, named in the prompt sent to
41
+ * the CLASSIFIER MODEL. A rebranded session labelled its own `ACME.md` block "The project's loaded
42
+ * WINTER.md guidance", which is a false statement about the operator's own file in a prompt whose
43
+ * job is to judge a permission decision. Defaults to Winter's, so every fixture is byte-identical.
44
+ */
45
+ instructionsFile?: string;
46
+ }
47
+ export interface ClassifierPromptResult {
48
+ text: string;
49
+ /** The one-time fence token this call used. Returned so a fixture can assert what is inside the fences without re-deriving it. */
50
+ fence: string;
51
+ /** Bounding evidence (P2 carry): how much app-owned context survived, and how much was dropped. */
52
+ contextIncluded: number;
53
+ contextDropped: number;
54
+ }
55
+ /**
56
+ * Assembles the review request.
57
+ *
58
+ * The block ORDER is deliberate: rules first, then the action, then the softer context. A reviewer
59
+ * that reads the policy before the action is being asked "does this action fit these rules"; one
60
+ * that reads the action first is being invited to form an opinion and then look for support.
61
+ */
62
+ export declare function buildClassifierPrompt(envelope: ActionEnvelope, context: ClassifierContext, opts?: ClassifierPromptOptions): ClassifierPromptResult;
@@ -0,0 +1,83 @@
1
+ import type { ClassifierRawResult } from "../../permissions/auto/engine.js";
2
+ import type { ProviderToolSpec } from "../../engine.js";
3
+ /** The one tool the classifier is allowed to call, and the one it is FORCED to call. */
4
+ export declare const CLASSIFIER_TOOL_NAME = "classifier_verdict";
5
+ /**
6
+ * Length caps, stated once and used by both the schema and the report.
7
+ *
8
+ * `category`/`severity`/`reasonCode` are vocabulary slots — a value longer than this is prose in a
9
+ * slot that is not for prose. `auditReason` is prose, so its cap is the real one: it bounds how much
10
+ * of a hostile envelope a compromised reviewer can launder into the audit stream in a single call.
11
+ */
12
+ export declare const CLASSIFIER_FIELD_CAPS: {
13
+ readonly category: 64;
14
+ readonly severity: 32;
15
+ readonly reasonCode: 64;
16
+ readonly auditReason: 1024;
17
+ };
18
+ /**
19
+ * The verdict schema — draft-07, closed.
20
+ *
21
+ * `additionalProperties: false` is load-bearing, and it is the "extra output" half of §10.6-5:
22
+ * a reviewer that returns a field nobody asked for has not answered the question it was asked, and
23
+ * the safe reading of an unrecognised field is that the answer is not one this engine understands.
24
+ */
25
+ export declare const CLASSIFIER_VERDICT_SCHEMA: Record<string, unknown>;
26
+ /**
27
+ * Every way this classifier can fail to obtain a verdict, as a CLOSED vocabulary.
28
+ *
29
+ * A closed union rather than free strings because these codes reach `AutoAuditRecord.reasonCode` and
30
+ * are the only evidence a reader has for WHY auto mode failed closed on a given action. "It returned
31
+ * no_verdict" is not a diagnosis; "the model answered with prose instead of calling the tool" and
32
+ * "the request timed out" call for opposite responses.
33
+ */
34
+ export declare const CLASSIFIER_NO_VERDICT_REASONS: readonly ["no_tool_call", "multiple_calls", "wrong_tool", "refusal", "provider_error", "timeout", "schema_invalid"];
35
+ export type ClassifierNoVerdictReason = (typeof CLASSIFIER_NO_VERDICT_REASONS)[number];
36
+ /**
37
+ * The namespace every MODEL-AUTHORED `reasonCode` is stamped with on its way out of the parse.
38
+ *
39
+ * Review round 1, I2. The vocabulary above is closed, and the whole point of it being closed is that
40
+ * a reader of the audit journal can tell WHY a review failed — the engine writes `reasonCode`
41
+ * straight onto `AutoAuditRecord` (`permissions/auto/engine.ts`), which is a frozen file this lane
42
+ * cannot change. But `reasonCode` is also a field the MODEL fills in, constrained only by
43
+ * `{ type: "string", maxLength: 64 }`. A model answering `{ verdict: "no_verdict", reasonCode:
44
+ * "timeout" }` would therefore be byte-identical, in the audit, to a genuine transport timeout —
45
+ * a reviewer able to forge the transcript of its own supervision.
46
+ *
47
+ * Namespacing on the way out closes that at the one seam both paths cross: Winter's own codes stay
48
+ * bare (they are what `noVerdict()` produces), and anything the model said is unambiguously the
49
+ * model's. A fixture asserts the closed vocabulary contains no `model:` entry, so the two spaces
50
+ * cannot collide by accident later either.
51
+ */
52
+ export declare const MODEL_REASON_CODE_PREFIX = "model:";
53
+ /** The fail-closed answer, built in ONE place so every arm of the collapse produces the identical shape. */
54
+ export declare function noVerdict(reasonCode: ClassifierNoVerdictReason): ClassifierRawResult;
55
+ /**
56
+ * The tool spec the request advertises.
57
+ *
58
+ * A FUNCTION returning a fresh object rather than a shared const: `ProviderRequest.tools` reaches an
59
+ * adapter that may serialise, decorate or (in a test double) mutate it, and one shared mutable
60
+ * schema object living for the life of the process is the kind of shared state that produces a bug
61
+ * nobody can reproduce.
62
+ */
63
+ export declare function classifierVerdictToolSpec(): ProviderToolSpec;
64
+ /**
65
+ * The forced tool call's input -> a `ClassifierRawResult`, or the reason it is not one.
66
+ *
67
+ * Keys are copied INDIVIDUALLY rather than spread. A spread would carry through whatever the model
68
+ * sent (the schema's `additionalProperties: false` makes that unreachable today, but a future schema
69
+ * relaxation would silently widen what reaches the audit record), and `exactOptionalPropertyTypes`
70
+ * means an absent field must be an absent KEY rather than an `undefined` value.
71
+ *
72
+ * `reasonCode` is NAMESPACED here, and this is the one seam where it can be: see
73
+ * `MODEL_REASON_CODE_PREFIX`. Everything else the model wrote (`category`, `severity`,
74
+ * `auditReason`) is already unambiguously the model's — only `reasonCode` shares a field with
75
+ * Winter's own closed vocabulary.
76
+ */
77
+ export declare function parseClassifierVerdict(input: unknown): {
78
+ ok: true;
79
+ result: ClassifierRawResult;
80
+ } | {
81
+ ok: false;
82
+ reasonCode: ClassifierNoVerdictReason;
83
+ };
@@ -0,0 +1,160 @@
1
+ import type { CredentialMaterial, CredentialStatus, CredentialStore, ProviderContext, ProviderRegistry } from "@yanlinglabs/winter-provider-runtime";
2
+ import type { CredentialRef } from "@yanlinglabs/winter-agent-sdk";
3
+ /** The one keychain-ref shape these doors deal in. `set`/`delete` are Keychain-only by TYPE on `CredentialStore`, so this is not a narrowing choice — it is the only representable one. */
4
+ export type ProviderCredentialRef = Extract<CredentialRef, {
5
+ kind: "keychain";
6
+ }>;
7
+ export interface ProviderCredentialLocator {
8
+ providerId: string;
9
+ /** WHICH account on that provider. R6-10: one record per provider/account, never a shared global slot — two accounts on one provider, or two providers at once, need two records. */
10
+ accountId: string;
11
+ /** Overrides the store's configured service. Omitted means the store's own default (the session's `brand.keychainService`, else `DEFAULT_KEYCHAIN_SERVICE`). */
12
+ service?: string;
13
+ }
14
+ export interface StoreProviderCredentialInput extends ProviderCredentialLocator {
15
+ material: CredentialMaterial;
16
+ }
17
+ /**
18
+ * The ref one provider/account occupies.
19
+ *
20
+ * EXPORTED because a host that stored a credential needs to name it again in
21
+ * `config.provider.authRef`, and deriving that string a second time by hand is the drift this
22
+ * function exists to prevent.
23
+ */
24
+ export declare function providerCredentialRef(locator: ProviderCredentialLocator): ProviderCredentialRef;
25
+ /**
26
+ * Writes one provider credential, and answers with the ref that now addresses it.
27
+ *
28
+ * Returning the ref rather than `void` is the point of the door: the host's very next act is to put
29
+ * that ref in a session config, and handing it back is what stops it being retyped.
30
+ */
31
+ export declare function storeProviderCredential(store: CredentialStore, input: StoreProviderCredentialInput): Promise<ProviderCredentialRef>;
32
+ /**
33
+ * Removes one provider credential.
34
+ *
35
+ * IDEMPOTENT by delegation: the store's own `delete` decides what removing an absent record means,
36
+ * and neither of the shipped stores treats it as an error. This door does not probe first — a `get`
37
+ * before a `delete` would read the secret into memory for no reason other than to answer a question
38
+ * the caller did not ask.
39
+ */
40
+ export declare function deleteProviderCredential(store: CredentialStore, locator: ProviderCredentialLocator): Promise<ProviderCredentialRef>;
41
+ /**
42
+ * Asks the provider's own adapter whether a credential reference works.
43
+ *
44
+ * ROUTED THROUGH THE REGISTRY because the answer is the ADAPTER's: only it knows which endpoint
45
+ * proves a key, what an expiry looks like for its auth kind, and which ref kinds it can check at all.
46
+ * The registry is how a provider id becomes that adapter, and it has no adapter-by-provider door of
47
+ * its own — so this reaches one through a model resolution, in two steps.
48
+ *
49
+ * THE SECOND STEP IS NOT A NICETY. A provider's catalog ROWS are the natural route, but ten of the
50
+ * twenty-one seed providers have none: every local one (lm-studio, vllm, llama-cpp, llamafile, the
51
+ * mlx pair, oobabooga, triton, xinference, docker-model-runner, lemonade) ships as a provider whose
52
+ * models exist only on the user's own machine. Stopping at "no rows" would make this door useless
53
+ * for exactly the providers a host is most likely to be helping someone configure. So a provider with
54
+ * no usable row falls through to `allowUnlisted` — registry.ts's own step 2, which answers with the
55
+ * adapter and `descriptor: undefined` for any provider whose live catalog is not authoritative, and
56
+ * with a typed refusal for one where it is (there, an absent id is a FACT and there is nothing
57
+ * honest to probe with). `validateCredential` never sees a model id, so the probe string below is
58
+ * inert — it is a key into the registry, not something that reaches a wire.
59
+ *
60
+ * NEVER THROWS. A host door that reports status by return value for four outcomes and by exception
61
+ * for the fifth is a door every caller wraps in a try. Every failure is a `{ ok: false }` row.
62
+ */
63
+ export declare function validateProviderCredential(registry: ProviderRegistry, ref: CredentialRef, ctx: ProviderContext): Promise<CredentialStatus>;
64
+ /**
65
+ * The providers whose credential is obtained by a LOGIN rather than by pasting a key.
66
+ *
67
+ * DECLARED IN FULL NOW, ahead of two of its four flows. A host offering sign-in should compile
68
+ * against one door rather than discover a second one when the next flow lands, and a case that
69
+ * throws a typed refusal is a much better thing to ship than a member missing from the union — which
70
+ * fails at a caller's call site as an unassignable literal and tells them nothing about why.
71
+ * `xai-oauth` and `qoder` are wired by their own lane; this file's switch is where they land.
72
+ */
73
+ export type ProviderLoginId = "anthropic" | "codex-oauth" | "xai-oauth" | "qoder";
74
+ export interface StartProviderLoginOptions {
75
+ /**
76
+ * Opens the browser. HOST-supplied: the SDK never shells out to one, and a login is a host action.
77
+ *
78
+ * **A DEVICE-CODE FLOW NEVER CALLS THIS.** That is the whole point of RFC 8628 — the device has no
79
+ * browser to open, so there is no URL to hand one. Its verification URL and its user code reach the
80
+ * host through `onAuthStatus.output` instead, and a host that renders a device login by waiting for
81
+ * `openUrl` will wait forever while the two strings the user actually needs go past on the other
82
+ * channel. Required rather than optional only because the two flows that exist today are both
83
+ * loopback ones; a device flow may be handed a function that is never invoked.
84
+ */
85
+ openUrl: (url: string) => Promise<void>;
86
+ /** Overridden by a fixture; production uses each flow's own derived constants. */
87
+ authorizeUrl?: string;
88
+ tokenUrl?: string;
89
+ /**
90
+ * Device-code flows only (RFC 8628): where the device authorization request is posted.
91
+ *
92
+ * Present ahead of its flows for the same reason `ProviderLoginId` carries all four members — and
93
+ * for one more that is not cosmetic. Without a fixture endpoint here, a test driving a device login
94
+ * THROUGH THIS DOOR has nowhere to point it and would reach the vendor live, which the phase's
95
+ * hermeticity rule forbids outright. An option that only appears alongside its implementation is an
96
+ * option whose first test cannot be written.
97
+ */
98
+ deviceCodeUrl?: string;
99
+ /** Device-code flows only: the poll interval FLOOR in ms. The vendor's own `interval` wins when larger. */
100
+ pollIntervalMs?: number;
101
+ callbackPort?: number;
102
+ timeoutMs?: number;
103
+ /** The Keychain service the record lands in — `config.keychainService` from the host. */
104
+ service?: string;
105
+ /** A login-flow PROGRESS channel (R6-F). Never carries credential material. */
106
+ onAuthStatus?: (status: {
107
+ isAuthenticating: boolean;
108
+ output?: string[];
109
+ error?: string;
110
+ }) => void;
111
+ /**
112
+ * `anthropic` (host-brokered Console OAuth, P10a-1 amendment) ONLY: the resolved `ant` executable
113
+ * and the config dir `console-broker.ts` spawns with. Present ahead of their one consumer for the
114
+ * same reason `deviceCodeUrl` is: an option that only appears alongside its implementation is an
115
+ * option whose first test cannot be written. Ignored by every other flow.
116
+ */
117
+ antExecutable?: string;
118
+ anthropicConfigDir?: string;
119
+ /**
120
+ * UNUSED (Lane S round 2, measured 2026-09-13): a live measurement found `claude auth login
121
+ * --console` writes no Anthropic profile for this org, so `console-broker.ts` never spawns
122
+ * `claude` for the Console login -- `ant` is the one broker binary. These two fields are accepted
123
+ * ONLY for source compatibility with existing callers that still pass them; this door never reads
124
+ * either, and never gates on them.
125
+ */
126
+ claudeExecutable?: string;
127
+ claudeConfigDir?: string;
128
+ /** `anthropic` only: `ANTHROPIC_PROFILE`. Defaults to `console-broker.ts`'s own default (`"winter"`). */
129
+ profile?: string;
130
+ /**
131
+ * `anthropic` only: supplies the one-time code the operator pastes after visiting the URL this
132
+ * door's `onAuthStatus` progress lines print. `startProviderLogin` is a single flat `Promise`, and
133
+ * the Console login is genuinely TWO-PHASE (a URL appears, then — sometime later, off this
134
+ * process's clock — a human types a code) — so this callback is what lets that shape fit here at
135
+ * all, the same way `openUrl` lets every OTHER flow's browser leg fit: the host implements it
136
+ * however it renders the prompt (a CLI `readline`, a UI text field), and this door awaits it once
137
+ * the login is already running.
138
+ */
139
+ readConsoleCode?: () => Promise<string>;
140
+ }
141
+ export interface ProviderLoginResult {
142
+ /** The record the credential now occupies — the very thing a host puts in `config.provider.authRef`. */
143
+ ref: ProviderCredentialRef;
144
+ accountId: string;
145
+ /** Epoch milliseconds. */
146
+ expiresAt: number;
147
+ }
148
+ /**
149
+ * Runs one provider's login and PERSISTS the result, answering with the ref that now addresses it.
150
+ *
151
+ * ONE DOOR, for the same reason `storeProviderCredential` is one: every flow writes a record whose
152
+ * name is `"<providerId>:<accountId>"` (R6-10), and a host that reaches each flow's own function
153
+ * directly is a host that will eventually spell that name differently from whatever reads it back.
154
+ * Routing through here means the login and the lookup agree by construction.
155
+ *
156
+ * WHAT THIS DOES NOT DO: choose a provider, open a browser itself, or decide that a failed login
157
+ * should be retried. Each is a host's decision, and the SDK taking any of them would be a library
158
+ * driving a user interface.
159
+ */
160
+ export declare function startProviderLogin(providerId: ProviderLoginId, store: CredentialStore, options: StartProviderLoginOptions): Promise<ProviderLoginResult>;
@@ -0,0 +1,27 @@
1
+ import type { WinterCatalog } from "@yanlinglabs/winter-provider-catalog";
2
+ import type { ActiveSlotSet, ModelFamilyListing, ModelRowServable } from "@yanlinglabs/winter-agent-sdk";
3
+ export interface FamilyListingInput {
4
+ catalog: WinterCatalog;
5
+ active: ActiveSlotSet | undefined;
6
+ /**
7
+ * WS-13c §7 as amended by P7a: a TRI-STATE, not a boolean.
8
+ *
9
+ * `"present"` a credential is configured and the provider is not disabled (§4 step 2).
10
+ * `"absent"` a probe answered, and there is none — or the provider is disabled.
11
+ * `"unknown"` nobody has probed this provider yet.
12
+ *
13
+ * The third state is the honest first paint. `hasCredential` has been tri-state at the wiring
14
+ * since R-6c-27, and this seam was the last place it was flattened: a boolean has to collapse
15
+ * `unknown` onto one of the other two, and BOTH collapses are false statements to a model
16
+ * switcher — `false` greys out a row the user can perfectly well use, and `true` (the shape the
17
+ * cold paint originally shipped) claims every row in a 604-model catalog is available against an
18
+ * empty credential store.
19
+ */
20
+ servable: (providerId: string) => ModelRowServable;
21
+ /** Fills `SlotView.resolvesTo` — absent when nothing this session has can serve the slot. */
22
+ resolveSlot?: (canonicalModelId: string, provider?: string) => {
23
+ providerId: string;
24
+ key: string;
25
+ } | undefined;
26
+ }
27
+ export declare function buildModelFamilyListing(input: FamilyListingInput): ModelFamilyListing;
@@ -0,0 +1,4 @@
1
+ /** The catalog provider ids that ARE Anthropic's own API. `cc` (claude.ai subscription auth) is deliberately absent: it does not ship. */
2
+ export declare const FIRST_PARTY_ANTHROPIC_PROVIDER_IDS: ReadonlySet<string>;
3
+ /** Is this session on Anthropic's own API? `undefined` (no catalog identity at all -- the reserved test namespace, a refused session) is never first-party. */
4
+ export declare function isFirstPartyAnthropic(providerId: string | undefined): boolean;
@@ -0,0 +1,59 @@
1
+ import type { CredentialStore } from "@yanlinglabs/winter-provider-runtime";
2
+ import { DEFAULT_KEYCHAIN_SERVICE, type CredentialRef } from "@yanlinglabs/winter-agent-sdk";
3
+ export { DEFAULT_KEYCHAIN_SERVICE };
4
+ /**
5
+ * The shape this store needs from a secrets backend.
6
+ *
7
+ * A NAMED INTERFACE rather than a direct dependency on the global, and the reason is testability
8
+ * without exception: the real backend is injected by DEFAULT and overridable by a caller, so the
9
+ * unit tests below drive a double and the real path has exactly one construction site. Mirrors
10
+ * `Bun.secrets`' own three methods and nothing more.
11
+ */
12
+ export interface SecretsBackend {
13
+ get(options: {
14
+ service: string;
15
+ name: string;
16
+ }): Promise<string | null>;
17
+ set(options: {
18
+ service: string;
19
+ name: string;
20
+ value: string;
21
+ }): Promise<void>;
22
+ delete(options: {
23
+ service: string;
24
+ name: string;
25
+ }): Promise<boolean | void>;
26
+ }
27
+ export interface KeychainCredentialStoreOptions {
28
+ /** Injected in tests. The real `Bun.secrets` path is NEVER exercised under test -- see this file's header. */
29
+ secrets?: SecretsBackend;
30
+ }
31
+ /**
32
+ * A `CredentialStore` backed by the macOS Keychain.
33
+ *
34
+ * `get` answers `null` for a ref this store does not own, rather than throwing: a composite store
35
+ * (provider-runtime's `createCompositeCredentialStore`) tries each member in turn, and a member that
36
+ * threw on someone else's ref kind would break the composition.
37
+ */
38
+ export declare function createKeychainCredentialStore(service?: string, opts?: KeychainCredentialStoreOptions): CredentialStore;
39
+ /** Reads ONE keychain item's stored string, uninterpreted. `null` when there is no such item. */
40
+ export type KeychainSecretReader = (ref: Extract<CredentialRef, {
41
+ kind: "keychain";
42
+ }>) => Promise<string | null>;
43
+ /**
44
+ * The RAW half of this store, for a TOOL's secret rather than a provider's credential.
45
+ *
46
+ * WHY IT EXISTS, AND WHY HERE. `get` above insists the item is JSON `CredentialMaterial` and throws
47
+ * `malformed` for anything else -- correct for a provider credential, which this SDK writes itself.
48
+ * A tool's key is different: a host may store it as the BARE KEY STRING because another client of
49
+ * the same keychain slot reads it that way, and that format is not this SDK's to change. So a reader
50
+ * that returns the item uninterpreted has to exist, and it has to live in THIS file -- the only one
51
+ * allowed to name the secrets backend (see the header, and the tripwire in the test beside it).
52
+ *
53
+ * It interprets NOTHING: `provider/tool-secret.ts` decides what the string means. It never logs and
54
+ * never quotes the value; a backend failure is the same typed, ref-redacted `io` error `get` raises.
55
+ * The ref's own `service` wins over the session's, exactly as in `get`.
56
+ */
57
+ export declare function createKeychainSecretReader(service?: string, opts?: KeychainCredentialStoreOptions): KeychainSecretReader;
58
+ /** `account = "<providerId>:<accountId>"` (R6-10). One helper, so a caller never assembles the key by hand and drifts. */
59
+ export declare function keychainAccountName(providerId: string, accountId: string): string;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * `modelKey` is a provider-qualified key (`anthropic/claude-opus-5`) or a bare id. claude compares a
3
+ * NORMALIZED id, so the Opus match tolerates the two spellings a catalog row really uses for the same
4
+ * build: a trailing `-YYYYMMDD` snapshot date, and a dotted minor (`claude-opus-4.1`). The original
5
+ * Opus 4 has no minor in its dated id (`claude-opus-4-20250514`); it is `claude-opus-4-0`.
6
+ */
7
+ export declare function claudeModelTakesFullPrompt(modelKey: string): boolean;
@@ -0,0 +1,55 @@
1
+ import type { Provider, ProviderMessage, ProviderTurn, ToolExecutor } from "../engine.js";
2
+ /** Every `system` value handed to a mock provider this process, in call order. Test-only. */
3
+ export declare function recordedProviderSystems(): readonly (string | undefined)[];
4
+ /** Clears the recording. A test that asserts on the log MUST call this first -- the log is process-wide, like the tool registry. */
5
+ export declare function resetRecordedProviderSystems(): void;
6
+ /**
7
+ * SDK 0.0.16: a user message's TEXT. The live request now merges the index-0 context, the persisted
8
+ * attachments and the prompt into one message of text blocks (claude's wire shape), so a double that
9
+ * reads "the user's text" joins the text blocks; the prompt is always the LAST block, so the last line
10
+ * is still the prompt's last line.
11
+ */
12
+ export declare function userMessageText(message: ProviderMessage | undefined): string;
13
+ export declare const echoProvider: Provider;
14
+ export declare function scriptedProvider(turns: ProviderTurn[]): Provider;
15
+ export declare const stubExecutor: ToolExecutor;
16
+ /**
17
+ * Phase 5 Task 8: the fixture skill the `p5skill` provider invokes. Exported so the scenario that
18
+ * WRITES the `SKILL.md` and the provider that CALLS it cannot disagree about the name.
19
+ */
20
+ export declare const P5_FIXTURE_SKILL_NAME = "p5probe";
21
+ /**
22
+ * Phase 5 Task 8: the workflow script the `p5workflow` provider launches.
23
+ *
24
+ * Deliberately a script a merely-STARTED worker cannot satisfy by accident (Lane W's own recipe):
25
+ * it makes one real `agent()` call, one `phase()` and one `log()`, and returns a value DERIVED from
26
+ * the agent's answer. With the child answering "42" the run must reach `completed` with
27
+ * `{"answer":"42","doubled":"4242"}` on every leg.
28
+ */
29
+ export declare const P5_WORKFLOW_SCRIPT: string;
30
+ export type TestProviderName = "boom" | "tooluse" | "hang" | "reflect" | "modeswitch" | "bgtask" | "lanea" | "laneb" | "lanec" | "laned" | "lanee" | "mcpsdk" | "subagent" | "childmsg" | "subagentperm" | "toolsearch" | "p5compact" | "p5structured" | "p5structuredfail" | "p5skill" | "p5checkpoint" | "p5workflow";
31
+ export declare function isTestProviderName(v: string): v is TestProviderName;
32
+ /**
33
+ * The name the reserved `winter-test/<name>` namespace uses for the plain echo double.
34
+ *
35
+ * A REAL NAME rather than "the default", because after Task 10 there IS no default: production
36
+ * selection is catalog-first and a session that names no resolvable model refuses to start (R6-9).
37
+ * A harness that wants the echo provider asks for it by name, exactly like every other scripted
38
+ * double, and the reserved namespace is the only door either of them comes through (R6-13).
39
+ */
40
+ export declare const ECHO_TEST_PROVIDER_NAME = "echo";
41
+ /**
42
+ * The `winter-test/<name>` namespace's resolver — the ONE production door to an in-process double.
43
+ *
44
+ * `selection.ts` calls this through `SelectionDeps.testProviders` after checking the namespace, so
45
+ * this function never has to know about the namespace prefix or about `WINTER_TEST_PROVIDER`; it
46
+ * answers one question ("is there a scripted double called this?") and answers `undefined` when
47
+ * there is not, which selection turns into a typed refusal rather than a silent miss.
48
+ */
49
+ export declare function testProviderForNamespace(name: string): Provider | undefined;
50
+ export declare function testProviderByName(name: TestProviderName): Provider;
51
+ export declare const SUBAGENT_CHILD_PROBE_TEXT = "child probe text";
52
+ export declare const MCP_SDK_TEST_SERVER_NAME = "t8mcpsdk";
53
+ export declare const MCP_SDK_TEST_TOOL_NAME = "mcp__t8mcpsdk__echo";
54
+ export declare const BGTASK_TEST_TOOL_NAME = "test_bgtask_probe";
55
+ export declare function registerBgTaskTestTool(): void;
@@ -0,0 +1,96 @@
1
+ /** One recorded request. `headers` are lower-cased; a credential header keeps its SCHEME and loses its material. */
2
+ export interface ScenarioRequest {
3
+ method: string;
4
+ path: string;
5
+ search: string;
6
+ headers: Record<string, string>;
7
+ body: string;
8
+ }
9
+ export interface ScenarioFake {
10
+ /** `http://127.0.0.1:<port>` — what a `ConnectionProfile.baseUrl` points at. */
11
+ url: string;
12
+ /** Every request received, in order. THE GROUND TRUTH for what a provider was actually asked. */
13
+ requests: ScenarioRequest[];
14
+ close(): Promise<void>;
15
+ }
16
+ /** The four families this fake serves, and the model key each scenario pins. Real catalog rows, so selection resolves them for real. */
17
+ export declare const SCENARIO_MODELS: {
18
+ readonly anthropic: "anthropic/claude-sonnet-5";
19
+ readonly openaiResponses: "openai/gpt-4.1";
20
+ readonly openaiChat: "deepseek/deepseek-v4-pro";
21
+ readonly gemini: "google/gemini-2.5-flash";
22
+ };
23
+ /**
24
+ * A REAL row whose `toolCalling` evidence is `native`, in each family.
25
+ *
26
+ * Not an incidental choice: WS-13 §8.1 makes Winter FAIL capability negotiation rather than silently
27
+ * drop tools, so a session pinned to a row the catalog says has no native tool calling cannot run a
28
+ * tool round at all — which is correct behaviour and the wrong subject for an equivalence scenario.
29
+ * `SCENARIO_TOOL_CALLING_NONE` is the row that proves the refusal instead.
30
+ */
31
+ export declare const SCENARIO_TOOL_CALLING_NONE = "anthropic/claude-sonnet-4.5";
32
+ /** The CHILD's model for the R6-17 scenario: the same provider, a different row, also `native`. */
33
+ export declare const SCENARIO_CHILD_MODEL = "anthropic/claude-haiku-4-5-20251001";
34
+ /**
35
+ * The marker a prompt carries to ask the scripted turn for an `Agent` call instead of a `Glob` one.
36
+ *
37
+ * KEYED ON THE PROMPT rather than on a request counter, for the same reason `carriesToolResult` is:
38
+ * three legs share this fake, and a counter would hand "the delegation turn" to whichever leg asked
39
+ * first.
40
+ */
41
+ export declare const SCENARIO_DELEGATE_MARKER = "winter-t10-delegate";
42
+ /** The subagent type the delegation turn asks for. The scenario defines an `agents` entry under this name. */
43
+ export declare const SCENARIO_CHILD_AGENT = "prober";
44
+ /** The tool the scripted turn calls, and the text the scripted final turn answers with. Shared so an assertion never re-spells them. */
45
+ export declare const SCENARIO_TOOL_NAME = "Glob";
46
+ export declare const SCENARIO_TOOL_INPUT: {
47
+ pattern: string;
48
+ };
49
+ export declare const SCENARIO_FIRST_TEXT = "checking the tree";
50
+ export declare const SCENARIO_FINAL_TEXT = "the provider scenario is done";
51
+ /** The child model's PROVIDER-LOCAL id — what actually goes on the wire when a child runs its own provider. */
52
+ export declare const SCENARIO_CHILD_WIRE_ID = "claude-haiku-4-5-20251001";
53
+ /**
54
+ * Starts the shared scenario fake.
55
+ *
56
+ * ALWAYS close it in a `finally`. A leaked fake keeps a port and an event loop alive for the rest of
57
+ * the process, which is how one careless scenario makes an unrelated one flaky.
58
+ */
59
+ export interface ScenarioFakeOptions {
60
+ /**
61
+ * Answer each leg's FIRST ATTEMPT at a turn with this status (and `retry-after: 0`), then behave
62
+ * normally — so the retry succeeds.
63
+ *
64
+ * "EACH LEG'S", not "the first request", and the difference is the whole reason this option is a
65
+ * state machine rather than a counter: three legs share one fake, so a plain `requests.length === 1`
66
+ * check fails leg A's first attempt and leaves every other leg's untouched — which is a cross-leg
67
+ * divergence the harness itself invented. The rule below is leg-count-independent: fail a request
68
+ * that opens a turn, never the retry that immediately follows it.
69
+ *
70
+ * `retry-after: 0` deliberately: R6-6 honours the header verbatim up to 60 s, and a scenario that
71
+ * waited a real backoff would spend seconds per leg proving something the delay is not part of.
72
+ */
73
+ firstAttemptStatus?: number;
74
+ /** Answer EVERY request with this status. Drives R6-F's terminal provider failure. */
75
+ alwaysFailStatus?: number;
76
+ /**
77
+ * P6 fix wave (Ruling E-3): answer every request for ONE wire model with this status -- in the body
78
+ * (`"model":"<id>"`) or, for the Gemini family, in the PATH (`/models/<id>:`, the colon so that
79
+ * `gemini-2.5-flash` does not also match `gemini-2.5-flash-lite`) -- and serve every other model
80
+ * normally. `retryAfter` is sent verbatim: R6-6 honours a positive `Retry-After` in place of its
81
+ * jittered backoff, which is what keeps a retries-exhausted scenario at a bounded wall-clock
82
+ * (10 retries x the header, rather than 10 jittered steps capped at 30 s each).
83
+ */
84
+ failModel?: {
85
+ wireModel: string;
86
+ status: number;
87
+ retryAfter?: string;
88
+ };
89
+ /**
90
+ * P6 fix wave round 2 (R-E2): on the Anthropic route, send `message_start` and then DROP the
91
+ * connection -- a failure AFTER the first byte, which the adapter normalizes as a network error
92
+ * (retryable) that the fold has already committed to. The class R6-6 forbids replaying.
93
+ */
94
+ dropAfterFirstEvent?: boolean;
95
+ }
96
+ export declare function startScenarioFake(options?: ScenarioFakeOptions): Promise<ScenarioFake>;