@yanlinglabs/winter-conformance 0.0.9 → 0.0.11

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.
@@ -110,9 +110,10 @@ async function fetchAndVerifyUpstream2(opts = {}) {
110
110
  }
111
111
  // src/official/capture.ts
112
112
  import { mkdtempSync as mkdtempSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, rmSync, readdirSync, statSync } from "node:fs";
113
- import { createHash as createHash2 } from "node:crypto";
113
+ import { createHash as createHash2, randomUUID } from "node:crypto";
114
114
  import { tmpdir as tmpdir2 } from "node:os";
115
115
  import { dirname, join as join2 } from "node:path";
116
+ import { fileURLToPath } from "node:url";
116
117
  var CANNED_TEXT_RESPONSE = {
117
118
  id: "msg_capture_canned_01",
118
119
  type: "message",
@@ -1530,6 +1531,117 @@ async function runCostCapture(officialSdk) {
1530
1531
  cleanup();
1531
1532
  }
1532
1533
  }
1534
+ var COMPACTION_GOLDEN_VOLATILE_TOP_LEVEL = new Set([
1535
+ "uuid",
1536
+ "logicalParentUuid",
1537
+ "timestamp",
1538
+ "cwd",
1539
+ "sessionId",
1540
+ "version",
1541
+ "gitBranch",
1542
+ "slug",
1543
+ "userType",
1544
+ "entrypoint",
1545
+ "isMeta",
1546
+ "promptId"
1547
+ ]);
1548
+ var COMPACTION_GOLDEN_VOLATILE_METADATA = new Set(["preTokens", "postTokens", "durationMs", "preservedSegment", "preservedMessages", "cumulativeDroppedTokens"]);
1549
+ function normalizeCompactionEntry(raw) {
1550
+ const out = {};
1551
+ for (const [k, v] of Object.entries(raw)) {
1552
+ if (COMPACTION_GOLDEN_VOLATILE_TOP_LEVEL.has(k))
1553
+ continue;
1554
+ if (k === "parentUuid" && v !== null)
1555
+ continue;
1556
+ out[k] = v;
1557
+ }
1558
+ if (out.compactMetadata !== undefined && typeof out.compactMetadata === "object" && out.compactMetadata !== null) {
1559
+ out.compactMetadata = Object.fromEntries(Object.entries(out.compactMetadata).filter(([k]) => !COMPACTION_GOLDEN_VOLATILE_METADATA.has(k)));
1560
+ }
1561
+ return out;
1562
+ }
1563
+ function redactTranscriptPath(content, transcriptPath) {
1564
+ return content.split(transcriptPath).join("<TRANSCRIPT_PATH>");
1565
+ }
1566
+ async function runCompactionCapture(officialSdk, opts = {}) {
1567
+ const cleanups = [];
1568
+ let server;
1569
+ try {
1570
+ const dirs = makeScenarioDirs("l", cleanups);
1571
+ let requestCount = 0;
1572
+ server = Bun.serve({
1573
+ port: 0,
1574
+ hostname: "127.0.0.1",
1575
+ async fetch(req) {
1576
+ requestCount++;
1577
+ let body = {};
1578
+ try {
1579
+ body = await req.json();
1580
+ } catch {}
1581
+ const url = new URL(req.url);
1582
+ console.error(`[loopback L] #${requestCount} ${req.method} ${url.pathname} model=${JSON.stringify(body.model)}`);
1583
+ return jsonResponse({
1584
+ id: `msg_capture_l_${requestCount}`,
1585
+ type: "message",
1586
+ role: "assistant",
1587
+ model: body.model ?? "claude-haiku-4-5",
1588
+ content: [{ type: "text", text: `capture: reply ${requestCount}` }],
1589
+ stop_reason: "end_turn",
1590
+ stop_sequence: null,
1591
+ usage: { input_tokens: 20, output_tokens: 5 }
1592
+ });
1593
+ }
1594
+ });
1595
+ console.error(`
1596
+ === Scenario L: the compaction golden (W18-12) ===`);
1597
+ console.error(`[capture L] loopback ${server.url.href}; CLAUDE_CONFIG_DIR=${dirs.claudeConfigDir} HOME=${dirs.homeDir} (fresh mkdtemp)`);
1598
+ const sessionId = randomUUID();
1599
+ const commonOptions = { model: "claude-haiku-4-5", cwd: dirs.fixtureCwd, settingSources: [] };
1600
+ const ac1 = new AbortController;
1601
+ await drainWithDeadline(officialSdk.query({ prompt: "hi from turn one", options: { ...commonOptions, sessionId, abortController: ac1, env: hermeticEnv(dirs, server.url.href) } }), [], "capture L/turn1", 60000, ac1);
1602
+ const ac2 = new AbortController;
1603
+ await drainWithDeadline(officialSdk.query({ prompt: "hi from turn two", options: { ...commonOptions, resume: sessionId, abortController: ac2, env: hermeticEnv(dirs, server.url.href) } }), [], "capture L/turn2", 60000, ac2);
1604
+ const ac3 = new AbortController;
1605
+ const entries3 = [];
1606
+ const r3 = await drainWithDeadline(officialSdk.query({ prompt: "/compact", options: { ...commonOptions, resume: sessionId, abortController: ac3, env: hermeticEnv(dirs, server.url.href) } }), entries3, "capture L/compact", 60000, ac3);
1607
+ if (r3.thrown)
1608
+ console.error(`[capture L] /compact threw: ${r3.thrown instanceof Error ? r3.thrown.stack ?? r3.thrown.message : String(r3.thrown)}`);
1609
+ const transcripts = findFileRecursive(dirs.claudeConfigDir, (name) => name === `${sessionId}.jsonl`);
1610
+ if (transcripts.length === 0) {
1611
+ console.log(`
1612
+ --- Scenario L: NOT CAPTURABLE — no ${sessionId}.jsonl transcript was written ---`);
1613
+ return;
1614
+ }
1615
+ const transcriptPath = transcripts[0];
1616
+ const lines = readFileSync2(transcriptPath, "utf8").trim().split(`
1617
+ `).filter((l) => l.length > 0).map((l) => JSON.parse(l));
1618
+ const rawBoundary = lines.find((e) => e.type === "system" && e.subtype === "compact_boundary");
1619
+ const rawSummary = lines.find((e) => e.isCompactSummary === true);
1620
+ if (rawBoundary === undefined || rawSummary === undefined) {
1621
+ console.log(`
1622
+ --- Scenario L: NOT CAPTURABLE — /compact ran but wrote no boundary+summary pair (types: ${lines.map((e) => e.type).join(",")}) ---`);
1623
+ return;
1624
+ }
1625
+ const boundary = normalizeCompactionEntry(rawBoundary);
1626
+ const summaryMessage = rawSummary.message.content;
1627
+ const summary = normalizeCompactionEntry({ ...rawSummary, message: { ...rawSummary.message, content: redactTranscriptPath(summaryMessage, transcriptPath) } });
1628
+ console.log(`
1629
+ --- Scenario L: normalized boundary+summary ---`);
1630
+ console.log(JSON.stringify({ boundary, summary }, null, 2));
1631
+ if (opts.writeGolden === true) {
1632
+ const goldenPath = fileURLToPath(new URL("../../goldens/claude-2.1.250/compaction.jsonl", import.meta.url));
1633
+ writeFileSync2(goldenPath, `${JSON.stringify(boundary)}
1634
+ ${JSON.stringify(summary)}
1635
+ `);
1636
+ console.error(`[capture L] wrote ${goldenPath}`);
1637
+ }
1638
+ return { boundary, summary };
1639
+ } finally {
1640
+ server?.stop(true);
1641
+ for (const cleanup of cleanups)
1642
+ cleanup();
1643
+ }
1644
+ }
1533
1645
  async function runCapture2() {
1534
1646
  requireBunRuntime2("runCapture", "Bun.spawn and Bun.serve", "It installs the pinned official SDK into a throwaway npm prefix and drives it against loopback fakes. Run the capture under Bun (`bun run scripts/capture-official-golden.ts`); the GOLDENS it produces are plain JSON and are readable from Node.");
1535
1647
  const only = (process.env.RUN_OFFICIAL_CAPTURE_ONLY ?? "").split(",").map((s) => s.trim().toUpperCase()).filter((s) => s.length > 0);
@@ -1568,6 +1680,8 @@ async function runCapture2() {
1568
1680
  await runModelControlCapture(officialSdk);
1569
1681
  if (want("K"))
1570
1682
  await runCostCapture(officialSdk);
1683
+ if (want("L"))
1684
+ await runCompactionCapture(officialSdk, { writeGolden: process.env.RUN_OFFICIAL_CAPTURE_WRITE_GOLDEN === "1" });
1571
1685
  } finally {
1572
1686
  for (const cleanup of cleanups)
1573
1687
  cleanup();
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  resolveCacheDir2,
15
15
  fetchAndVerifyUpstream2,
16
16
  runCapture2
17
- } from "./index-v0zvhx0z.js";
17
+ } from "./index-5sjwc9ne.js";
18
18
  // src/goldens.ts
19
19
  import { readFileSync, readdirSync } from "node:fs";
20
20
  import { join } from "node:path";
@@ -1 +1,28 @@
1
+ type OfficialQueryFn = (args: {
2
+ prompt: unknown;
3
+ options: Record<string, unknown>;
4
+ }) => AsyncIterable<{
5
+ type: string;
6
+ subtype?: string;
7
+ }>;
8
+ type OfficialSdk = {
9
+ query: OfficialQueryFn;
10
+ };
11
+ /**
12
+ * Strips the fields that differ on every real capture (uuids, timestamps, host/session identity,
13
+ * the numeric token/timing counters, and any preserved-message relink data — `preservedMessages`/
14
+ * `preservedSegment` name capture-specific uuids, so they vary run to run even though, since fix
15
+ * round 1, Winter's own writer DOES reproduce `compactMetadata.preservedMessages` byte-shape-exact
16
+ * to this golden — see `claudeCompactBoundaryEntry`'s own header in `dialect.ts`) while keeping
17
+ * `parentUuid` when it is the fixed `null` the boundary always carries (that value IS the shape,
18
+ * not noise).
19
+ */
20
+ export declare function normalizeCompactionEntry(raw: Record<string, unknown>): Record<string, unknown>;
21
+ export declare function runCompactionCapture(officialSdk: OfficialSdk, opts?: {
22
+ writeGolden?: boolean;
23
+ }): Promise<{
24
+ boundary: Record<string, unknown>;
25
+ summary: Record<string, unknown>;
26
+ } | undefined>;
1
27
  export declare function runCapture(): Promise<void>;
28
+ export {};
@@ -10,7 +10,7 @@ import {
10
10
  resolveCacheDir2,
11
11
  fetchAndVerifyUpstream2,
12
12
  runCapture2
13
- } from "../index-v0zvhx0z.js";
13
+ } from "../index-5sjwc9ne.js";
14
14
  import"../index-z5gwvsfh.js";
15
15
  export {
16
16
  BunRequiredError2 as BunRequiredError,
@@ -0,0 +1,2 @@
1
+ {"parentUuid": null, "isSidechain": false, "type": "system", "subtype": "compact_boundary", "content": "Conversation compacted", "level": "info", "compactMetadata": {"trigger": "manual"}}
2
+ {"isSidechain": false, "type": "user", "message": {"role": "user", "content": "This session is being continued from a previous conversation that ran out of context. The summary below covers the earlier portion of the conversation.\n\nturn-3-reply\n\nIf you need specific details from before compaction (like exact code snippets, error messages, or content you generated), read the full transcript at: <TRANSCRIPT_PATH>\nContinue the conversation from where it left off without asking the user any further questions. Resume directly \u2014 do not acknowledge the summary, do not recap what was happening, do not preface with \"I'll continue\" or similar. Pick up the last task as if the break never happened."}, "isVisibleInTranscriptOnly": true, "isCompactSummary": true}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yanlinglabs/winter-conformance",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "engines": {