@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,115 @@
1
+ import type { ContextAccountant, Provider, ProviderMessage, ProviderRequest } from "../engine.js";
2
+ export interface CompactionInput {
3
+ messages: ProviderMessage[];
4
+ trigger: "auto" | "manual";
5
+ /** `/compact <instructions>` (manual) or a PreCompact hook's forwarded context; `null` when neither. */
6
+ customInstructions: string | null;
7
+ accountant: ContextAccountant;
8
+ /** The SESSION's own provider -- R5-4: the summarizer runs on it, never on a second, separately-configured model. */
9
+ provider: Provider;
10
+ /**
11
+ * WS-23: the session's OWN outbound request for the history as it stands -- the exact system
12
+ * blocks, tools, model and reasoning settings the main loop last sent, and the outbound message list
13
+ * (index-0 context and effort markers included). A controller that appends its instruction to this,
14
+ * rather than building a fresh `{messages, system}` request, reads the whole conversation from the
15
+ * prompt cache the main loop already wrote -- the way a byte-exact fork does -- instead of paying for
16
+ * the largest request of the session uncached. ABSENT before the session's first request (a
17
+ * `/compact` as the very first thing a resumed session does) and on a fixture: the old shape stands.
18
+ *
19
+ * In-dialect by construction: these are the bytes the SAME provider already received, so nothing
20
+ * here reaches a model it had not already reached.
21
+ */
22
+ prefixRequest?: ProviderRequest;
23
+ /**
24
+ * WS-23: WHY this compaction runs, beyond the pinned `trigger`. `"overflow"` is the reactive recovery
25
+ * after the provider refused the history as too long: re-sending that same history (the prefix path)
26
+ * would be refused the same way ("If the input alone already exceeds the model's context window, the
27
+ * API returns a 400"), so such a compaction always takes the redacted request. Absent means an
28
+ * ordinary threshold or `/compact` compaction.
29
+ */
30
+ reason?: "overflow";
31
+ /**
32
+ * WS-23 (reasoning-state, decision 5): the most characters the SUMMARIZER's own request may carry, when
33
+ * the summarizing model is known to be smaller than the history -- a model switch whose target cannot
34
+ * hold the conversation, compacting on the target because the source is out of reach, or an overflow.
35
+ * The oldest part of the summarized window is left out until the rest fits, and the instruction says
36
+ * so; the retained tail is untouched. Absent: unbounded, as before.
37
+ */
38
+ maxInputChars?: number;
39
+ }
40
+ export interface CompactionResult {
41
+ summary: string;
42
+ /**
43
+ * The messages that survive the boundary, in order, ALREADY EXCLUDING anything the summary
44
+ * replaces. The engine swaps its whole history for `[summary-as-user-message, ...retained]`, so a
45
+ * controller that returns the full input here has compacted nothing and the engine will say so
46
+ * rather than silently looping.
47
+ */
48
+ retained: ProviderMessage[];
49
+ /** The reading `contextTokens()` gave BEFORE compaction -- lands on `compact_metadata.pre_tokens`. */
50
+ preTokens: number;
51
+ /**
52
+ * Deferred tools referenced by the retained messages (WS-09 §8.5). Handed to
53
+ * `registry.onCompaction`, which resets the session's loaded set to `evidenced ∩ still-registered`:
54
+ * a tool the model can no longer see evidence of having loaded must not stay silently callable.
55
+ */
56
+ evidencedToolNames: string[];
57
+ }
58
+ export interface CompactionController {
59
+ /**
60
+ * The AUTO trigger. R5-4's own formula is `contextTokens() >= compactionThreshold * limit()`, but
61
+ * the predicate lives with the controller rather than in the engine so the threshold, its default,
62
+ * and any hysteresis are one lane's to own and to capture against.
63
+ *
64
+ * The engine calls this before each provider call of a turn and NEVER for a manual `/compact`.
65
+ */
66
+ shouldCompact(accountant: ContextAccountant): boolean;
67
+ compact(input: CompactionInput): Promise<CompactionResult>;
68
+ }
69
+ /**
70
+ * What the engine hands the store when a compaction commits. The dialect turns it into a
71
+ * `compact_summary` entry plus a `compact_boundary` entry carrying the pinned six-field
72
+ * `compact_metadata` (derived-shapes-p5 item (f)).
73
+ *
74
+ * `retainedCount` rather than the retained messages themselves: the pinned `preserved_messages` names
75
+ * ALREADY-PERSISTED entries by uuid and relinks them, so the store identifies them from its own
76
+ * append log instead of re-persisting copies. Re-persisting would double every surviving message in
77
+ * the transcript a UI renders.
78
+ */
79
+ export interface CompactBoundaryRecord {
80
+ trigger: "auto" | "manual";
81
+ preTokens: number;
82
+ postTokens?: number;
83
+ durationMs?: number;
84
+ summary: string;
85
+ retainedCount: number;
86
+ }
87
+ /**
88
+ * What the store hands BACK (fix round 1, M3). The uuids are minted inside the store layer, so this
89
+ * is the only way the emitted `compact_boundary` frame can carry `preserved_messages` at all -- the
90
+ * first version returned `void`, which made that field permanently unreachable on the wire while the
91
+ * DURABLE entry carried it correctly. A host reading the stream could never relink a preserved
92
+ * segment; only a host re-reading the transcript could.
93
+ *
94
+ * `preservedUuids` is empty when nothing was kept, and the frame then OMITS `preserved_messages`
95
+ * entirely -- absence stays semantic ("compaction summarized everything"), exactly as the pin has it.
96
+ */
97
+ export interface CompactBoundaryWriteResult {
98
+ boundaryUuid: string;
99
+ anchorUuid: string;
100
+ preservedUuids: string[];
101
+ }
102
+ /**
103
+ * The spine's test double. Summarizes by concatenating a marker with the message count and keeps the
104
+ * last `keep` messages -- deterministic, authored-prose-free, and enough for an engine test to prove
105
+ * the whole sequence ran in order.
106
+ */
107
+ export declare function fakeCompactionController(opts?: {
108
+ shouldCompact?: boolean | ((accountant: ContextAccountant) => boolean);
109
+ keep?: number;
110
+ summary?: string;
111
+ evidencedToolNames?: string[];
112
+ calls?: CompactionInput[];
113
+ /** Throws instead of compacting -- the failure arm. */
114
+ fail?: string;
115
+ }): CompactionController;
@@ -0,0 +1,79 @@
1
+ import type { Provider, ProviderMessage, ProviderRequest } from "../engine.js";
2
+ export declare const WINTER_SUMMARY_INSTRUCTION: string;
3
+ /**
4
+ * WS-23: the same instruction for the PREFIX-REUSING summary, where it rides as the last user message
5
+ * after the session's own conversation (so "above", not "below") and the session's tools are still
6
+ * declared -- declared because removing them would change the cached prefix, which is the whole point.
7
+ */
8
+ export declare const WINTER_PREFIX_SUMMARY_INSTRUCTION: string;
9
+ /**
10
+ * WS-23: is this provider request the summariser's, in either shape -- the redacted one (Winter's
11
+ * instruction as `system`) or the prefix-reusing one (the instruction as the final user message)?
12
+ * For a scripted double that must answer the summariser differently from the conversation; nothing in
13
+ * production branches on it.
14
+ */
15
+ export declare function isCompactionSummaryRequest(req: Pick<ProviderRequest, "system" | "messages">): boolean;
16
+ /** WS-23: appended when the conversation already opens with a summary this compaction carries forward VERBATIM. */
17
+ export declare const CARRIED_SUMMARY_NOTE = "The conversation above begins with an earlier summary, which is kept verbatim; summarize only what happened after it.";
18
+ /**
19
+ * WS-23: the prefix-reusing request shows the model the WHOLE conversation, including the exchanges the
20
+ * compaction keeps verbatim after the summary -- the redacted request only ever showed it the part
21
+ * being replaced. This sentence scopes the summary back to that part, so a compaction does not
22
+ * restate what stays in context anyway. It rides the appended instruction, so it costs the cache
23
+ * nothing.
24
+ */
25
+ export declare function retainedExchangesNote(pairs: number): string;
26
+ /** How much of a tool call's own input is rendered into the summarizer's view of the transcript. */
27
+ export declare const DEFAULT_TOOL_INPUT_PREVIEW_CHARS = 500;
28
+ /**
29
+ * Winter's instruction, plus the caller's own on a manual `/compact <instructions>` run (and any
30
+ * context a PreCompact hook forwarded -- the engine has already folded that into the same field).
31
+ * ATTRIBUTED rather than spliced: the caller's words are the caller's, and a model that mis-follows
32
+ * them must be readable as having done so.
33
+ */
34
+ export declare function buildSummaryInstruction(customInstructions: string | null, instruction?: string): string;
35
+ /**
36
+ * The messages as the summarizer is allowed to see them: `{ role, content }` only, roles narrowed to
37
+ * user/assistant (the engine's own `tool` role has no provider meaning outside its history), content
38
+ * flattened to text built from known block types alone. Every other key on the original object --
39
+ * including any a future provider adds -- is left behind by construction.
40
+ */
41
+ export declare function redactForSummary(messages: readonly ProviderMessage[], opts?: {
42
+ toolInputPreviewChars?: number;
43
+ }): ProviderMessage[];
44
+ /**
45
+ * WS-23 (midconv, live gate on claude-opus-5-5): the redacted request's messages, ENDING WITH A USER
46
+ * TURN. The summarised window often ends on an assistant reply, and a request that ends there is an
47
+ * assistant PREFILL, which newer models refuse outright ("This model does not support assistant message
48
+ * prefill. The conversation must end with a user message.", HTTP 400) -- the fallback summary, the one
49
+ * that exists for when the prefix request cannot run, then failed too. So the instruction is the final
50
+ * user turn: the window as it was, then the ask (and nowhere else -- fix round 1). A window that already ends on a user message
51
+ * gets the same trailing turn (the adapters merge adjacent user messages), so the shape is one rule.
52
+ * The prefix-reusing request (`summarizeOverPrefix`) already ends with its instruction as a user turn.
53
+ */
54
+ export declare function summaryRequestMessages(messages: readonly ProviderMessage[], instruction: string): ProviderMessage[];
55
+ /** WS-23 (midconv): the user marker in front of a summarised window that opens on an assistant reply. */
56
+ export declare const SUMMARY_WINDOW_OPENS_MID_CONVERSATION = "[The conversation continues from an earlier point.]";
57
+ export declare class CompactionSummarizerError extends Error {
58
+ }
59
+ /**
60
+ * One generation on the session provider. Its usage is deliberately NOT recorded into the
61
+ * accountant: the accountant reports the LAST TURN's window occupancy, and a summarizer call is not
62
+ * a turn of the conversation -- recording it would leave the trigger reading a number that describes
63
+ * the compaction rather than the context it was meant to shrink.
64
+ */
65
+ export declare function summarize(provider: Provider, messages: readonly ProviderMessage[], instruction: string): Promise<string>;
66
+ /**
67
+ * WS-23: one generation that REUSES the session's own request -- its system blocks, tools, model,
68
+ * reasoning settings and every message the main loop already sent, byte for byte -- with the
69
+ * instruction appended as the final user message, the way a byte-exact fork reuses its parent's
70
+ * prefix. The largest request of a session then reads its prefix from the prompt cache instead of
71
+ * paying for all of it again (the old shape sent `{messages, system}` with no cache blocks at all).
72
+ *
73
+ * Returns `undefined` when the model answered with a tool call despite the instruction: the session's
74
+ * tools are declared (dropping them, or forcing `tool_choice: none`, would change the cached prefix,
75
+ * https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-use-with-prompt-caching), so the
76
+ * caller falls back to the redacted, tool-less summary on the same provider and model rather than
77
+ * running a tool the summariser was never meant to run.
78
+ */
79
+ export declare function summarizeOverPrefix(provider: Provider, prefixRequest: ProviderRequest, instruction: string): Promise<string | undefined>;
@@ -0,0 +1,39 @@
1
+ import type { ProviderMessage } from "../engine.js";
2
+ import { type AgentListingDeltaAttachment } from "./attachments.js";
3
+ /**
4
+ * One agent type this session may list -- already resolved and already FILTERED to what the caller
5
+ * (depth gating, and the deny-rule / required-MCP filters another lane adds) wants advertised. This
6
+ * module makes no filtering decision of its own.
7
+ */
8
+ export interface AgentListingEntry {
9
+ agentType: string;
10
+ whenToUse: string;
11
+ /**
12
+ * claude's `whenToUseLean`, used instead of `whenToUse` when the session's model takes the lean
13
+ * prompt. HOOK ONLY in this lane: the lean-model rule is another lane's, so `leanModel` below is
14
+ * never true yet.
15
+ */
16
+ whenToUseLean?: string;
17
+ tools?: readonly string[];
18
+ disallowedTools?: readonly string[];
19
+ }
20
+ /**
21
+ * claude's `SSn`, exactly: both lists present -> `tools` minus the disallowed ones (`None` when that
22
+ * leaves nothing); only `tools` -> `tools` joined (so `["*"]` renders `*`); only `disallowedTools` ->
23
+ * `All tools except …` in DECLARED order; neither -> `All tools`.
24
+ */
25
+ export declare function renderAgentToolSpec(entry: Pick<AgentListingEntry, "tools" | "disallowedTools">): string;
26
+ /** claude's `hrt`: `- <type>: <whenToUse> (Tools: <spec>)`. */
27
+ export declare function renderAgentListingLine(entry: AgentListingEntry, leanModel?: boolean): string;
28
+ export interface AgentListingDeltaOptions {
29
+ /** claude's `Iu(mz(model))` -- whether the session's model takes the lean `whenToUse`. Another lane decides; `false` until then. */
30
+ leanModel?: boolean;
31
+ /** claude's `plan !== "pro" && mode === "default"`. Winter has neither a plan tier nor a UI mode, so `true`. */
32
+ showConcurrencyNote?: boolean;
33
+ }
34
+ /**
35
+ * claude's `s1t`: the `agent_listing_delta` attachment this history needs now, or `undefined` when
36
+ * the available set equals what `history` already announced. `history` is the engine's own message
37
+ * list, which after a compaction is already claude's post-boundary slice.
38
+ */
39
+ export declare function computeAgentListingDelta(available: readonly AgentListingEntry[], history: readonly ProviderMessage[], opts?: AgentListingDeltaOptions): AgentListingDeltaAttachment | undefined;
@@ -0,0 +1,46 @@
1
+ import type { RuntimeConfig, Settings } from "@yanlinglabs/winter-agent-sdk";
2
+ import type { SystemPromptAssembler } from "./seam.js";
3
+ import { type PluginOutputStyleSource } from "./output-styles.js";
4
+ export interface SystemPromptAssemblerDeps {
5
+ /**
6
+ * The resolved winter home. Omitted resolves from `SystemPromptInput.env` (so `<PREFIX>HOME` is
7
+ * honoured per session, not per process). Tests pass an mkdtemp directory here rather than
8
+ * touching a real home.
9
+ */
10
+ home?: string;
11
+ /**
12
+ * A LIVE GETTER over the resolved effective settings, read afresh on every `assemble()`.
13
+ *
14
+ * A getter and not a value, deliberately: the product rule (WS-11 §5, and Norma's shipped
15
+ * settings-watcher convention) is that no setting may require a restart to take effect. Handing
16
+ * the assembler a settings SNAPSHOT at construction would make `outputStyle`, `autoMemoryEnabled`,
17
+ * `autoMemoryDirectory` and `plansDirectory` frozen for the life of a session, and the failure
18
+ * would be invisible -- the assembler would keep working, just with stale values.
19
+ */
20
+ settings?: () => Settings | undefined;
21
+ /**
22
+ * WS-21 §6.3 item 1 (fix round 2): the session's ENABLED plugins that ship an `output-styles/`
23
+ * directory. A plain VALUE, not a live getter like `settings` above -- a session's loaded-plugin
24
+ * set is resolved once per incarnation (production-wiring.ts's own precedent for skills/agents/
25
+ * MCP: plugins are not something a settings-watcher hot-reloads mid-session), so there is nothing
26
+ * to re-read on a later `assemble()` call. Omitted means no `<plugin>:<style>` name ever resolves,
27
+ * exactly like every pre-fix-round-2 caller.
28
+ */
29
+ pluginOutputStyles?: readonly PluginOutputStyleSource[];
30
+ }
31
+ /**
32
+ * Phase 5 residual round (T8 re-review NEW-1): "would an output style apply at all?", for a caller
33
+ * that needs the answer WITHOUT assembling a prompt.
34
+ *
35
+ * `production-wiring.ts` resolves the style a second time to report RULING P5-G's downgrade as an
36
+ * operator warning, and had no equivalent of the `region.authored` guard below -- so with a
37
+ * caller-supplied `systemPrompt` it told the operator the style "has been applied as an ADDITION"
38
+ * when it was not applied in any form.
39
+ *
40
+ * EXPORTED RATHER THAN HAND-MIRRORED. The condition is one line today ("a string or an array
41
+ * replaces the prompt"), and one line is exactly what gets copied and then drifts -- this codebase
42
+ * has four hand-mirrored copies of one trust predicate already, kept in step only by a tripwire
43
+ * test. One implementation, two callers, no drift possible.
44
+ */
45
+ export declare function isAuthoredPromptRegion(systemPrompt: RuntimeConfig["systemPrompt"]): boolean;
46
+ export declare function createSystemPromptAssembler(deps?: SystemPromptAssemblerDeps): SystemPromptAssembler;
@@ -0,0 +1,104 @@
1
+ import type { ProviderMessage } from "../engine.js";
2
+ /**
3
+ * One attachment payload, exactly as the transcript stores it (`entry.attachment`). Open-ended: the
4
+ * three types below are this lane's; any other `type` is carried verbatim and rendered only when a
5
+ * renderer is registered for it.
6
+ */
7
+ export interface AttachmentPayload {
8
+ type: string;
9
+ [key: string]: unknown;
10
+ }
11
+ /** claude's `agent_listing_delta` (`s1t`): what the Agent tool can spawn, as a delta over what the history already announced. */
12
+ export interface AgentListingDeltaAttachment extends AttachmentPayload {
13
+ type: "agent_listing_delta";
14
+ addedTypes: string[];
15
+ addedLines: string[];
16
+ removedTypes: string[];
17
+ isInitial: boolean;
18
+ showConcurrencyNote: boolean;
19
+ }
20
+ /** claude's `skill_listing` (`Urn`): the skills not yet sent this session. `names` seeds the sent set on resume. */
21
+ export interface SkillListingAttachment extends AttachmentPayload {
22
+ type: "skill_listing";
23
+ content: string;
24
+ skillCount: number;
25
+ isInitial: boolean;
26
+ names: string[];
27
+ }
28
+ /** claude's `date_change` (`alr`): the local date moved past the one the session's context was built with. */
29
+ export interface DateChangeAttachment extends AttachmentPayload {
30
+ type: "date_change";
31
+ newDate: string;
32
+ }
33
+ export declare const AGENT_LISTING_INITIAL_HEADER = "Available agent types for the Agent tool:";
34
+ export declare const AGENT_LISTING_ADDED_HEADER = "New agent types are now available for the Agent tool:";
35
+ export declare const AGENT_LISTING_REMOVED_HEADER = "The following agent types are no longer available:";
36
+ /** claude's `s$`: appended after a "no longer available" section. */
37
+ export declare const AMBIENT_CONTEXT_SENTENCE = "This is ambient context \u2014 do not narrate it to the user unless they ask or it is directly relevant to their request.";
38
+ /** Appended to the INITIAL listing only, when `showConcurrencyNote` is set. */
39
+ export declare const AGENT_CONCURRENCY_SENTENCE = "When you launch multiple agents for independent work, send them in a single message with multiple tool uses so they run concurrently.";
40
+ export declare const SKILL_LISTING_HEADER = "The following skills are available for use with the Skill tool:";
41
+ export declare function dateChangeText(newDate: string): string;
42
+ /** claude's attachment wrapper (`Qa`). Nothing is added around it and nothing after it. */
43
+ export declare function wrapSystemReminder(body: string): string;
44
+ /** A renderer returns the UNWRAPPED body, or `undefined` when the attachment has nothing to say. */
45
+ export type AttachmentRenderer = (attachment: AttachmentPayload) => string | undefined;
46
+ /**
47
+ * SDK 0.0.16 Lane N: `wrap: false` for the ONE attachment family claude does not wrap. Its
48
+ * `queued_command` attachments (a task notification delivered mid-turn) are rendered as a BARE user
49
+ * text block carrying their own `[SYSTEM NOTIFICATION - NOT USER INPUT]` preamble instead of the
50
+ * `<system-reminder>` envelope every other attachment type gets (traced in the pinned binary: the
51
+ * queued-command branch of its request builder calls its origin-aware renderer directly, never the
52
+ * reminder wrapper). Defaults to `true`, so every type registered before this option existed is
53
+ * unchanged.
54
+ */
55
+ export interface AttachmentRendererOptions {
56
+ wrap?: boolean;
57
+ /**
58
+ * WS-23: the attachment may ride as a MID-CONVERSATION `role: "system"` message on a model whose row
59
+ * documents them (`ModelWireFeatures.midConversationSystem`), instead of as user-turn text. OPT-IN,
60
+ * and only for text Winter itself AUTHORS: the vendor is explicit that a system message gives its
61
+ * text operator authority and must not carry "text from outside the conversation"
62
+ * (https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages#limitations).
63
+ * So the agent and skill listings (they fold in project, user and plugin descriptions verbatim) and
64
+ * task notifications (subagent output) stay user text; `date_change` is the built-in that qualifies.
65
+ */
66
+ systemRole?: boolean;
67
+ }
68
+ /**
69
+ * Registers (or replaces) the renderer for one attachment type. Another lane's types (task
70
+ * notifications, plan-mode reminders) plug in here; the engine and the resume path then carry them
71
+ * with no further change.
72
+ */
73
+ export declare function registerAttachmentRenderer(type: string, renderer: AttachmentRenderer, options?: AttachmentRendererOptions): void;
74
+ /** WS-23: whether this attachment's renderer opted into the mid-conversation `system` role. */
75
+ export declare function isSystemRoleAttachment(attachment: AttachmentPayload): boolean;
76
+ /** The wrapped model-facing text for an attachment, or `undefined` when there is none (an unknown type included). */
77
+ export declare function renderAttachment(attachment: AttachmentPayload): string | undefined;
78
+ /** The history message for an attachment, or `undefined` when it renders to nothing (it is then not appended at all). */
79
+ export declare function attachmentMessage(attachment: AttachmentPayload): ProviderMessage | undefined;
80
+ export declare function isAttachmentMessage(message: ProviderMessage): message is ProviderMessage & {
81
+ meta: {
82
+ attachment: AttachmentPayload;
83
+ };
84
+ };
85
+ /** Every attachment payload in `messages`, in order. The engine's history IS claude's post-compaction slice (`Ml`). */
86
+ export declare function attachmentsIn(messages: readonly ProviderMessage[]): AttachmentPayload[];
87
+ /**
88
+ * claude's `s1t` fold: the agent types the history has already announced. A delta's `addedTypes`
89
+ * count only when it carries an `addedLines` array (claude's own guard); `removedTypes` always remove.
90
+ */
91
+ export declare function announcedAgentTypes(messages: readonly ProviderMessage[]): Set<string>;
92
+ /** claude's `alr` fold: whether a `date_change` for `date` is already in the history. */
93
+ export declare function dateChangeAnnounced(messages: readonly ProviderMessage[], date: string): boolean;
94
+ /**
95
+ * claude's `vlr` resume seed for the skill listing: the names every persisted `skill_listing` sent,
96
+ * and whether a legacy entry without `names` asks the next listing to be suppressed (claude's
97
+ * `suppressNext`).
98
+ */
99
+ export declare function skillListingResumeSeed(messages: readonly ProviderMessage[]): {
100
+ names: string[];
101
+ suppressNext: boolean;
102
+ };
103
+ /** claude's `tcn`: the LOCAL calendar date, `YYYY-MM-DD`. */
104
+ export declare function localDateString(now?: Date): string;
@@ -0,0 +1,31 @@
1
+ export declare const ENVIRONMENT_HEADING = "# Environment";
2
+ export declare const ENVIRONMENT_LEAD_IN = "You have been invoked in the following environment: ";
3
+ /** Winter's product line (claude's equivalent lines describe its own CLI). */
4
+ export declare const WINTER_PRODUCT_LINE = "Winter runs this session as an agent runtime on behalf of a host application; the host decides how your output is shown to the user.";
5
+ export interface EnvironmentInput {
6
+ cwd: string;
7
+ isGitRepo: boolean;
8
+ platform: string;
9
+ /** The raw `$SHELL` value; reduced to `zsh` / `bash` the way claude reduces it. */
10
+ shell: string;
11
+ /** `<os type> <os release>`, e.g. `Darwin 25.6.0`. */
12
+ osVersion: string;
13
+ additionalDirectories?: readonly string[];
14
+ /** The model id this session generates with. Absent: no model line. */
15
+ model?: string;
16
+ /** The model's display name, when the catalog knows one. */
17
+ modelDisplayName?: string;
18
+ /** The model's knowledge cutoff, when known. Winter's catalog carries none today, so the line is normally absent. */
19
+ knowledgeCutoff?: string;
20
+ }
21
+ /** claude's `GEe`: the shell as `zsh`, `bash`, the raw value, or `unknown`. */
22
+ export declare function shellName(raw: string): string;
23
+ /** The whole section for the system prompt's dynamic half (claude's `mHn`). */
24
+ export declare function renderEnvironmentSection(input: EnvironmentInput): string;
25
+ /** `excludeDynamicSections`, static half (claude's `fHn`): the model and product lines only. */
26
+ export declare function renderStaticEnvironmentSection(input: Pick<EnvironmentInput, "model" | "modelDisplayName" | "knowledgeCutoff">): string;
27
+ /**
28
+ * `excludeDynamicSections`, userContext half (claude's `gHn` through `jEe`): the machine facts under
29
+ * the lead-in, WITHOUT the heading -- the heading's text becomes the userContext key `Environment`.
30
+ */
31
+ export declare function renderEnvironmentContextValue(input: EnvironmentInput): string;
@@ -0,0 +1,18 @@
1
+ export interface GitFixture {
2
+ /** The main checkout's working-tree root. */
3
+ main: string;
4
+ /** A linked worktree of the same repository (`git worktree add`), at a path OUTSIDE `main`. */
5
+ worktree: string;
6
+ /** The mkdtemp root holding both -- remove this to clean up. */
7
+ root: string;
8
+ }
9
+ /** Runs git with every machine-level influence (hooks, identity, signing, config files) neutralised. */
10
+ export declare function hermeticGit(cwd: string, args: string[], home: string, hooksPath: string): string;
11
+ /**
12
+ * A real repository with one commit plus a real linked worktree, both under one mkdtemp root.
13
+ *
14
+ * The worktree is placed as a SIBLING of the main checkout, not beneath it: a worktree nested
15
+ * inside the main tree would make the common root an ancestor of the worktree by accident, and the
16
+ * WINTER.md boundary test would pass for the wrong reason.
17
+ */
18
+ export declare function makeGitFixture(): GitFixture;
@@ -0,0 +1,16 @@
1
+ /** Winter's snapshot caveat (claude's sentence says the same thing in its own words). */
2
+ export declare const GIT_STATUS_CAVEAT = "This git status was captured when the session began; it is a snapshot and does not change as the conversation goes on.";
3
+ /** claude's `hde`. */
4
+ export declare const GIT_STATUS_MAX_CHARS = 2000;
5
+ /**
6
+ * The `gitStatus` value for `cwd`, or `undefined` when there is none. Never throws. `env` is for
7
+ * tests (a hermetic git config); the engine runs git with the process environment, as the
8
+ * instructions-file and memory-key git reads already do.
9
+ */
10
+ export declare function computeGitStatus(cwd: string, env?: Record<string, string | undefined>): Promise<string | undefined>;
11
+ /**
12
+ * The kill switch (claude's `CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS`, Winter's `<PREFIX>DISABLE_GIT_INSTRUCTIONS`)
13
+ * over the `includeGitInstructions` setting (default true). An explicit env value wins either way,
14
+ * as claude's `VU` does: a truthy value disables, a falsy one ("0"/"false"/"no"/"off") enables.
15
+ */
16
+ export declare function gitInstructionsEnabled(envValue: string | undefined, includeGitInstructions: unknown): boolean;
@@ -0,0 +1,22 @@
1
+ export type ImportTier = "user" | "project" | "local";
2
+ export interface ExpandImportsInput {
3
+ content: string;
4
+ /** The file this content came from -- imports resolve relative to ITS directory. */
5
+ filePath: string;
6
+ tier: ImportTier;
7
+ /** `null` when there is no repository (a bare `cwd`); a project/local import then never resolves. */
8
+ projectRoot: string | null;
9
+ /** Default 5 (F17 / the plan brief). */
10
+ maxDepth?: number;
11
+ }
12
+ export interface ExpandImportsResult {
13
+ content: string;
14
+ /** Absolute paths of every import this expansion DROPPED (out-of-scope for a project/local file). Depth-capped and missing imports are not reported here -- they are ordinary "nothing to substitute" outcomes, not scope refusals. */
15
+ dropped: string[];
16
+ }
17
+ /**
18
+ * Expand every `@import` token in `input.content`, recursively, up to `maxDepth` levels. Returns
19
+ * the expanded content plus the absolute paths of every import DROPPED for being out of a
20
+ * project/local file's scope (never the depth-capped or missing ones -- see the module header).
21
+ */
22
+ export declare function expandImports(input: ExpandImportsInput): ExpandImportsResult;
@@ -0,0 +1,53 @@
1
+ /** Appended to a block that was cut short, so the model knows it is reading a prefix. */
2
+ export declare const TRUNCATION_MARKER = "\n[\u2026truncated]";
3
+ /**
4
+ * Cap to `maxBytes` UTF-8 bytes on a valid boundary. A multibyte character split by the cut
5
+ * degrades to U+FFFD rather than a lone surrogate (`Buffer.toString` guarantees this), which keeps
6
+ * the result a well-formed string every JSON encoder on the path can carry.
7
+ *
8
+ * THE REPLACEMENT CHARACTER CAN PUSH THE RESULT BACK OVER THE CAP, which is why the trailing
9
+ * U+FFFD is dropped when it does. Cutting mid-character consumes 1-3 bytes of the original and
10
+ * emits a 3-byte U+FFFD in their place, so a naive `subarray(0, maxBytes).toString()` can re-encode
11
+ * to `maxBytes + 2` -- Norma's shipped twin has exactly this hole. It is small, but a cap that only
12
+ * approximately holds is not a cap, and this is the primitive every other ceiling in this lane is
13
+ * expressed in terms of. Found by the fixture, not by reading: the assertion was written as
14
+ * "<= maxBytes" and failed at 7 bytes for a 5-byte budget.
15
+ */
16
+ export declare function capBytes(text: string, maxBytes: number): {
17
+ text: string;
18
+ truncated: boolean;
19
+ };
20
+ /**
21
+ * Defuses a literal `<system-reminder>` / `</system-reminder>` inside untrusted file content.
22
+ *
23
+ * Deliberately does NOT collapse newlines (Norma's engine-side twin does, for tool results): these
24
+ * are real multi-line markdown documents, and flattening an index or an instruction file would make
25
+ * it unreadable. Only the tag itself is a containment problem here.
26
+ */
27
+ export declare function neutralizeReminderTags(text: string): string;
28
+ /**
29
+ * Wraps a body as a labelled, harness-injected block. `label` is authored text (a caption naming
30
+ * the file and why it is here); `body` is file content and is neutralised before wrapping.
31
+ */
32
+ export declare function systemReminder(label: string, body: string): string;
33
+ /**
34
+ * Read a UTF-8 file, capped at `maxBytes`. `null` for missing / unreadable / not-a-regular-file /
35
+ * empty -- all four are "there is nothing to inject", which is not an error condition.
36
+ */
37
+ export declare function readCapped(path: string, maxBytes: number): string | null;
38
+ /**
39
+ * Read a UTF-8 file WHOLE, no byte ceiling. WS-21 §6.3 item 10 (F7): claude does not truncate its
40
+ * own instructions file, and winter-md.ts stopped capping the brand's own instructions basename to
41
+ * match. This is a
42
+ * DELIBERATE exception to this module's own rule (1) above -- the instructions file is re-sent every
43
+ * request just like a capped block is, but parity with claude wins here, the same way it already won
44
+ * for the skill description cap. Same "nothing to inject" contract as `readCapped`: missing,
45
+ * unreadable, not-a-regular-file or empty all yield `null`, never a thrown error.
46
+ */
47
+ export declare function readWhole(path: string): string | null;
48
+ /**
49
+ * Read a UTF-8 file capped at `maxLines` AND `maxBytes`, WHICHEVER HITS FIRST (WS-05 §11's
50
+ * memory-index rule; lines are counted before bytes so a 25 KB budget cannot smuggle in a
51
+ * 10 000-line file). `null` on the same four "nothing to inject" cases as `readCapped`.
52
+ */
53
+ export declare function readCappedLinesAndBytes(path: string, maxLines: number, maxBytes: number): string | null;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Norma's `_global`/`_assistant` product buckets (a no-project bucket and the shared dream bucket).
3
+ * WS-11 §3 and WS-05 §11 both pin them as PRODUCT EXTENSIONS that are never silently injected into
4
+ * a Code session. Winter's assembler has no code path that can produce either: the pinned
5
+ * project-key sanitiser maps every non-alphanumeric character to `-`, so a key can never begin with
6
+ * `_`. This constant exists so that fact is assertable rather than merely true.
7
+ */
8
+ export declare const RESERVED_MEMORY_KEYS: readonly string[];
9
+ /**
10
+ * TEST-ONLY. A suite that builds throwaway repositories at reused paths, or that wants to prove the
11
+ * cache is not the thing making an assertion pass, must be able to clear it. Production never calls
12
+ * this.
13
+ */
14
+ export declare function _clearMemoryKeyCacheForTests(): void;
15
+ /**
16
+ * The `<memory-key>` segment for `cwd`: the git-common-root-derived key, then the P1-N env
17
+ * override. `env` is injectable so tests never read the real process environment.
18
+ */
19
+ export declare function memoryProjectKeyFor(cwd: string, env?: Record<string, string | undefined>): string;
20
+ export interface MemoryDirInput {
21
+ cwd: string;
22
+ /** The `~/.winter` root (WINTER_HOME-aware; the caller resolves it). */
23
+ home: string;
24
+ /**
25
+ * WS-21 §3.7: the shared runtime home's durable-paths root (`config.storeHome`), preferred over
26
+ * `home` when present -- code-mode auto-memory is a DURABLE path (spec §3.7's own list), so it
27
+ * lives under `sdk/projects/<key>/memory`, not the per-run folder `home` names once the router
28
+ * links `buildRunHome`. Absent (every incarnation before then, or a non-router host) falls back
29
+ * to `home`, byte-identical to pre-WS-21 behaviour.
30
+ */
31
+ storeHome?: string;
32
+ env?: Record<string, string | undefined>;
33
+ /**
34
+ * `Settings.autoMemoryDirectory` (or a host-supplied `SystemPromptInput.memoryDir`) -- REPLACES
35
+ * the computed path entirely, with no further per-project nesting beneath it, mirroring the
36
+ * pinned relocatable-directory setting. Whitespace-only counts as ABSENT: a settings.json holding
37
+ * `"autoMemoryDirectory": ""` must not resolve memory to the home directory itself.
38
+ *
39
+ * The pinned key is ignored when it comes from PROJECT settings (its own declaration says so, for
40
+ * security) -- that filter is `OVERLAY_NEVER_KEYS` in the settings layer, upstream of here. This
41
+ * module consumes whatever survived it and re-litigates nothing.
42
+ */
43
+ override?: string;
44
+ }
45
+ /** The absolute auto-memory directory for a session. Pure path computation -- creates nothing. */
46
+ export declare function memoryDirFor(input: MemoryDirInput): string;
@@ -0,0 +1,28 @@
1
+ import { type Settings } from "@yanlinglabs/winter-agent-sdk";
2
+ export declare const MEMORY_INDEX_BASENAME = "MEMORY.md";
3
+ /**
4
+ * The compatibility-profile load cap, pinned by WS-05 §11 and WS-11 §3: the first 200 lines OR
5
+ * 25 KB of `MEMORY.md`, whichever hits first. Binary KB (25 * 1024), matching Norma's shipped
6
+ * numbers this is ported from. Version-drift tested; behaviour, not a format guarantee.
7
+ */
8
+ export declare const MEMORY_INDEX_MAX_LINES = 200;
9
+ export declare const MEMORY_INDEX_MAX_BYTES: number;
10
+ /**
11
+ * `Settings.autoMemoryEnabled`. UNSET MEANS ENABLED -- the key is an opt-OUT (WS-11 §3:
12
+ * "hosted/hermetic deployments MAY disable automatic memory"), so the absence of a settings file
13
+ * cannot be read as "no memory". Only a literal `false` disables; a JSON settings file can hold
14
+ * anything, and a truthy-but-not-boolean value must not fall through to disabled by accident.
15
+ */
16
+ export declare function autoMemoryEnabled(settings: Settings | undefined): boolean;
17
+ /** The capped index for a memory directory, or `null` when there is nothing to inject. */
18
+ export declare function loadMemoryIndex(memoryDir: string): string | null;
19
+ /** claude's section heading for the auto-memory guidance. */
20
+ export declare const AUTO_MEMORY_HEADING = "# auto memory";
21
+ /**
22
+ * The system prompt's `# auto memory` section: the heading, a blank line, Winter's own guidance
23
+ * (which names the directory). Injected even with no `MEMORY.md` on disk -- a fresh project has
24
+ * nothing to recall but every reason to know it CAN save something.
25
+ */
26
+ export declare function renderAutoMemorySection(memoryDir: string, instructionsFile?: string): string;
27
+ /** `excludeDynamicSections`: the same guidance as the userContext value under the key `auto memory` (claude's `jEe` strips the heading). */
28
+ export declare function renderAutoMemoryContextValue(memoryDir: string, instructionsFile?: string): string;
@@ -0,0 +1,5 @@
1
+ /** R5-9's ceiling. Asserted, not aspirational -- a "minimal" prompt that grew is no longer minimal. */
2
+ export declare const MINIMAL_PROMPT_MAX_LINES = 20;
3
+ /** Bump on any edit to the text below. Reported as `AssembledPrompt.presetVersion`. */
4
+ export declare const MINIMAL_PROMPT_VERSION = "winter_minimal@1";
5
+ export declare const MINIMAL_PROMPT: string;