@alwaysmeticulous/debug-workspace 2.276.0 → 2.276.2
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.
- package/README.md +8 -1
- package/dist/__tests__/extract-screenshot-dom-files.spec.d.ts +1 -0
- package/dist/__tests__/extract-screenshot-dom-files.spec.js +59 -0
- package/dist/__tests__/extract-screenshot-dom-files.spec.js.map +1 -0
- package/dist/__tests__/fetch-dom-diffs.spec.d.ts +1 -0
- package/dist/__tests__/fetch-dom-diffs.spec.js +316 -0
- package/dist/__tests__/fetch-dom-diffs.spec.js.map +1 -0
- package/dist/download-debug-data.js +25 -11
- package/dist/download-debug-data.js.map +1 -1
- package/dist/extract-screenshot-dom-files.d.ts +6 -0
- package/dist/extract-screenshot-dom-files.js +104 -0
- package/dist/extract-screenshot-dom-files.js.map +1 -0
- package/dist/fetch-dom-diffs.d.ts +36 -0
- package/dist/fetch-dom-diffs.js +338 -0
- package/dist/fetch-dom-diffs.js.map +1 -0
- package/dist/generate-debug-derived-files.js +57 -91
- package/dist/generate-debug-derived-files.js.map +1 -1
- package/dist/generate-debug-workspace.d.ts +10 -2
- package/dist/generate-debug-workspace.js +81 -84
- package/dist/generate-debug-workspace.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/pipeline.d.ts +2 -1
- package/dist/pipeline.js +6 -5
- package/dist/pipeline.js.map +1 -1
- package/dist/replay-walk.d.ts +40 -0
- package/dist/replay-walk.js +57 -0
- package/dist/replay-walk.js.map +1 -0
- package/dist/resolve-debug-context.js +12 -15
- package/dist/resolve-debug-context.js.map +1 -1
- package/dist/screenshot-identifier.d.ts +19 -0
- package/dist/screenshot-identifier.js +51 -0
- package/dist/screenshot-identifier.js.map +1 -0
- package/dist/templates/CLAUDE.md +115 -78
- package/package.json +6 -6
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d0fda9da-5200-5954-b500-76a10beac7f3")}catch(e){}}();
|
|
3
|
+
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.extractScreenshotDomFiles = void 0;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const debug_constants_1 = require("./debug-constants");
|
|
13
|
+
const replay_walk_1 = require("./replay-walk");
|
|
14
|
+
const screenshot_identifier_1 = require("./screenshot-identifier");
|
|
15
|
+
/**
|
|
16
|
+
* Extract each `*.metadata.json`'s `before.dom` / `after.dom` into
|
|
17
|
+
* `<name>.html` / `<name>.after.html`, prefixed with a one-line
|
|
18
|
+
* `<!-- screenshot=... url=... vt=... -->` header.
|
|
19
|
+
*/
|
|
20
|
+
const extractScreenshotDomFiles = (workspaceDir) => {
|
|
21
|
+
const debugDataDir = (0, path_1.join)(workspaceDir, debug_constants_1.DEBUG_DATA_DIRECTORY);
|
|
22
|
+
const replaysDir = (0, path_1.join)(debugDataDir, "replays");
|
|
23
|
+
const replayDirs = (0, replay_walk_1.discoverReplayDirs)(replaysDir);
|
|
24
|
+
if (replayDirs.length === 0) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
let extractedCount = 0;
|
|
28
|
+
let skippedMalformedCount = 0;
|
|
29
|
+
for (const replayDir of replayDirs) {
|
|
30
|
+
const screenshotsDir = (0, path_1.join)(replayDir.path, "screenshots");
|
|
31
|
+
if (!(0, fs_1.existsSync)(screenshotsDir)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const virtualTimeByName = readTimelineVirtualTimes((0, path_1.join)(replayDir.path, "timeline.json"));
|
|
35
|
+
for (const filename of (0, fs_1.readdirSync)(screenshotsDir)) {
|
|
36
|
+
if (!filename.endsWith(".metadata.json")) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const baseName = filename.slice(0, -".metadata.json".length);
|
|
40
|
+
const metadata = (0, replay_walk_1.readScreenshotMetadata)((0, path_1.join)(screenshotsDir, filename));
|
|
41
|
+
if (metadata == null) {
|
|
42
|
+
logMalformed(replayDir, filename);
|
|
43
|
+
skippedMalformedCount++;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const url = metadata.before?.routeData?.url ?? null;
|
|
47
|
+
const virtualTime = virtualTimeByName.get(baseName) ?? null;
|
|
48
|
+
const beforeDom = metadata.before?.dom;
|
|
49
|
+
if (typeof beforeDom === "string") {
|
|
50
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(screenshotsDir, `${baseName}.html`), renderWithHeader(beforeDom, baseName, url, virtualTime, "before"));
|
|
51
|
+
extractedCount++;
|
|
52
|
+
}
|
|
53
|
+
const afterDom = metadata.after?.dom;
|
|
54
|
+
if (typeof afterDom === "string") {
|
|
55
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(screenshotsDir, `${baseName}.after.html`), renderWithHeader(afterDom, baseName, url, virtualTime, "after"));
|
|
56
|
+
extractedCount++;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (extractedCount > 0) {
|
|
61
|
+
console.log(chalk_1.default.green(` Extracted ${extractedCount} screenshot DOM snapshot(s) to screenshots/*.html`));
|
|
62
|
+
}
|
|
63
|
+
if (skippedMalformedCount > 0) {
|
|
64
|
+
console.log(chalk_1.default.yellow(` Skipped ${skippedMalformedCount} malformed screenshot metadata file(s)`));
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.extractScreenshotDomFiles = extractScreenshotDomFiles;
|
|
68
|
+
const renderWithHeader = (dom, baseName, url, virtualTime, side) => {
|
|
69
|
+
const headerParts = [
|
|
70
|
+
`screenshot=${baseName}`,
|
|
71
|
+
`side=${side}`,
|
|
72
|
+
];
|
|
73
|
+
if (url != null) {
|
|
74
|
+
headerParts.push(`url=${url}`);
|
|
75
|
+
}
|
|
76
|
+
if (virtualTime != null) {
|
|
77
|
+
headerParts.push(`vt=${virtualTime}`);
|
|
78
|
+
}
|
|
79
|
+
const header = `<!-- ${headerParts.join(" ")} -->\n`;
|
|
80
|
+
return header + dom;
|
|
81
|
+
};
|
|
82
|
+
const readTimelineVirtualTimes = (timelinePath) => {
|
|
83
|
+
const map = new Map();
|
|
84
|
+
const timeline = (0, replay_walk_1.readTimelineJson)(timelinePath);
|
|
85
|
+
if (timeline == null) {
|
|
86
|
+
return map;
|
|
87
|
+
}
|
|
88
|
+
for (const entry of timeline) {
|
|
89
|
+
if (entry.kind !== "screenshot" || !entry.data?.identifier) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const name = (0, screenshot_identifier_1.screenshotIdentifierToBaseName)(entry.data.identifier);
|
|
93
|
+
if (name == null || entry.virtualTimeStart == null) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
map.set(name, entry.virtualTimeStart);
|
|
97
|
+
}
|
|
98
|
+
return map;
|
|
99
|
+
};
|
|
100
|
+
const logMalformed = (replayDir, filename) => {
|
|
101
|
+
console.warn(chalk_1.default.yellow(` Warning: Could not parse ${replayDir.role}/${replayDir.replayId}/screenshots/${filename}`));
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=extract-screenshot-dom-files.js.map
|
|
104
|
+
//# debugId=d0fda9da-5200-5954-b500-76a10beac7f3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-screenshot-dom-files.js","sources":["../src/extract-screenshot-dom-files.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"d0fda9da-5200-5954-b500-76a10beac7f3"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getScreenshotDomDiff, MeticulousClient } from "@alwaysmeticulous/client";
|
|
2
|
+
import type { DebugContext } from "./debug.types";
|
|
3
|
+
export interface DomDiffMapEntry {
|
|
4
|
+
/** 3-lines-of-context diff. `null` when DOMs are identical. */
|
|
5
|
+
diffPath: string | null;
|
|
6
|
+
/**
|
|
7
|
+
* Full-file-context diff (same hunks as `diffPath`, more surrounding lines).
|
|
8
|
+
* `null` when DOMs are identical, OR when the full-context fetch failed
|
|
9
|
+
* while the canonical fetch succeeded (check `diffPath`: if non-null, the
|
|
10
|
+
* canonical diff is still usable and a warning was logged).
|
|
11
|
+
*/
|
|
12
|
+
fullDiffPath: string | null;
|
|
13
|
+
totalHunks: number;
|
|
14
|
+
bytes: number;
|
|
15
|
+
url: string | null;
|
|
16
|
+
}
|
|
17
|
+
export type DomDiffMap = {
|
|
18
|
+
[key: string]: DomDiffMapEntry | undefined;
|
|
19
|
+
};
|
|
20
|
+
export interface FetchDomDiffsOptions {
|
|
21
|
+
client: MeticulousClient;
|
|
22
|
+
debugContext: DebugContext;
|
|
23
|
+
workspaceDir: string;
|
|
24
|
+
maxConcurrency?: number | undefined;
|
|
25
|
+
/** Injectable for tests. */
|
|
26
|
+
fetchScreenshotDiff?: typeof getScreenshotDomDiff | undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Fetch per-screenshot DOM diffs for every replay diff in `debugContext`
|
|
30
|
+
* and write `<label>-<baseName>.diff` (3 lines of context), a sibling
|
|
31
|
+
* `<label>-<baseName>.full.diff` (full-file context), and
|
|
32
|
+
* `<label>.summary.txt` under `debug-data/dom-diffs/`. Per-screenshot
|
|
33
|
+
* errors are logged and recorded as `skipped-error`; the pipeline never
|
|
34
|
+
* fails on a fetch error.
|
|
35
|
+
*/
|
|
36
|
+
export declare const fetchDomDiffs: (options: FetchDomDiffsOptions) => Promise<DomDiffMap>;
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="06b90e7f-cc42-52b9-9629-94d2c20264f4")}catch(e){}}();
|
|
3
|
+
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.fetchDomDiffs = void 0;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const client_1 = require("@alwaysmeticulous/client");
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
const p_limit_1 = __importDefault(require("p-limit"));
|
|
14
|
+
const debug_constants_1 = require("./debug-constants");
|
|
15
|
+
const replay_walk_1 = require("./replay-walk");
|
|
16
|
+
const screenshot_identifier_1 = require("./screenshot-identifier");
|
|
17
|
+
const DEFAULT_MAX_CONCURRENCY = 8;
|
|
18
|
+
/**
|
|
19
|
+
* Fetch per-screenshot DOM diffs for every replay diff in `debugContext`
|
|
20
|
+
* and write `<label>-<baseName>.diff` (3 lines of context), a sibling
|
|
21
|
+
* `<label>-<baseName>.full.diff` (full-file context), and
|
|
22
|
+
* `<label>.summary.txt` under `debug-data/dom-diffs/`. Per-screenshot
|
|
23
|
+
* errors are logged and recorded as `skipped-error`; the pipeline never
|
|
24
|
+
* fails on a fetch error.
|
|
25
|
+
*/
|
|
26
|
+
const fetchDomDiffs = async (options) => {
|
|
27
|
+
const { client, debugContext, workspaceDir, maxConcurrency = DEFAULT_MAX_CONCURRENCY, fetchScreenshotDiff = client_1.getScreenshotDomDiff, } = options;
|
|
28
|
+
const domDiffMap = {};
|
|
29
|
+
const replaysDir = (0, path_1.join)(workspaceDir, debug_constants_1.DEBUG_DATA_DIRECTORY, "replays");
|
|
30
|
+
if (!(0, fs_1.existsSync)(replaysDir)) {
|
|
31
|
+
return domDiffMap;
|
|
32
|
+
}
|
|
33
|
+
const pairs = collectReplayDiffPairs(debugContext);
|
|
34
|
+
if (pairs.length === 0) {
|
|
35
|
+
return domDiffMap;
|
|
36
|
+
}
|
|
37
|
+
const domDiffsDir = (0, path_1.join)(workspaceDir, debug_constants_1.DEBUG_DATA_DIRECTORY, "dom-diffs");
|
|
38
|
+
const limit = (0, p_limit_1.default)(maxConcurrency);
|
|
39
|
+
let totalDiffs = 0;
|
|
40
|
+
let skippedErrorCount = 0;
|
|
41
|
+
let skippedUnsupportedCount = 0;
|
|
42
|
+
for (const pair of pairs) {
|
|
43
|
+
if (!isSafePathSegment(pair.label)) {
|
|
44
|
+
console.warn(chalk_1.default.yellow(` Warning: Skipping replay pair with unsafe label: ${pair.label}`));
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const headScreenshotsDir = (0, path_1.join)(replaysDir, "head", pair.headReplayId, "screenshots");
|
|
48
|
+
const baseScreenshotsDir = (0, path_1.join)(replaysDir, "base", pair.baseReplayId, "screenshots");
|
|
49
|
+
if (!(0, fs_1.existsSync)(headScreenshotsDir) ||
|
|
50
|
+
!(0, fs_1.existsSync)(baseScreenshotsDir)) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const headScreenshots = indexScreenshotsByBaseName(headScreenshotsDir);
|
|
54
|
+
const baseScreenshots = indexScreenshotsByBaseName(baseScreenshotsDir);
|
|
55
|
+
const allNames = new Set([
|
|
56
|
+
...headScreenshots.keys(),
|
|
57
|
+
...baseScreenshots.keys(),
|
|
58
|
+
]);
|
|
59
|
+
if (allNames.size === 0) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// Map on-disk basename → backend-format name via timeline.json
|
|
63
|
+
// (the identifier isn't persisted in screenshot metadata).
|
|
64
|
+
const backendNames = readBackendNameMap([
|
|
65
|
+
(0, path_1.join)(replaysDir, "head", pair.headReplayId, "timeline.json"),
|
|
66
|
+
(0, path_1.join)(replaysDir, "base", pair.baseReplayId, "timeline.json"),
|
|
67
|
+
]);
|
|
68
|
+
(0, fs_1.mkdirSync)(domDiffsDir, { recursive: true });
|
|
69
|
+
const tasks = [...allNames].sort().map((screenshotBaseName) => resolveScreenshot({
|
|
70
|
+
pair,
|
|
71
|
+
screenshotBaseName,
|
|
72
|
+
backendName: backendNames.get(screenshotBaseName) ?? null,
|
|
73
|
+
headMetadataPath: headScreenshots.get(screenshotBaseName),
|
|
74
|
+
baseMetadataPath: baseScreenshots.get(screenshotBaseName),
|
|
75
|
+
domDiffsDir,
|
|
76
|
+
limit,
|
|
77
|
+
fetchScreenshotDiff,
|
|
78
|
+
client,
|
|
79
|
+
}));
|
|
80
|
+
const results = await Promise.all(tasks);
|
|
81
|
+
const summaryRows = [];
|
|
82
|
+
for (const result of results) {
|
|
83
|
+
if (result == null) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
summaryRows.push(result.summaryRow);
|
|
87
|
+
if (result.mapEntry != null) {
|
|
88
|
+
domDiffMap[`${pair.label}/${result.summaryRow.screenshotBaseName}`] =
|
|
89
|
+
result.mapEntry;
|
|
90
|
+
}
|
|
91
|
+
if (result.summaryRow.status === "diff") {
|
|
92
|
+
totalDiffs++;
|
|
93
|
+
}
|
|
94
|
+
if (result.summaryRow.status === "skipped-error") {
|
|
95
|
+
skippedErrorCount++;
|
|
96
|
+
}
|
|
97
|
+
if (result.summaryRow.status === "skipped-unsupported") {
|
|
98
|
+
skippedUnsupportedCount++;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (summaryRows.length > 0) {
|
|
102
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(domDiffsDir, `${pair.label}.summary.txt`), renderPairSummary(pair, summaryRows));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (totalDiffs > 0) {
|
|
106
|
+
console.log(chalk_1.default.green(` Generated ${totalDiffs} DOM diff(s) in dom-diffs/`));
|
|
107
|
+
}
|
|
108
|
+
if (skippedErrorCount > 0) {
|
|
109
|
+
console.log(chalk_1.default.yellow(` Skipped ${skippedErrorCount} screenshot DOM diff(s) due to API errors — fall back to diffing <name>.html files on disk`));
|
|
110
|
+
}
|
|
111
|
+
if (skippedUnsupportedCount > 0) {
|
|
112
|
+
console.log(chalk_1.default.yellow(` Skipped ${skippedUnsupportedCount} screenshot DOM diff(s) with unsupported identifier (e.g. redacted variant, missing timeline entry) — fall back to diffing <name>.html files on disk`));
|
|
113
|
+
}
|
|
114
|
+
return domDiffMap;
|
|
115
|
+
};
|
|
116
|
+
exports.fetchDomDiffs = fetchDomDiffs;
|
|
117
|
+
const resolveScreenshot = async (args) => {
|
|
118
|
+
const { pair, screenshotBaseName, backendName, headMetadataPath, baseMetadataPath, domDiffsDir, limit, fetchScreenshotDiff, client, } = args;
|
|
119
|
+
if (!isSafePathSegment(screenshotBaseName)) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
if (!headMetadataPath || !baseMetadataPath) {
|
|
123
|
+
const availablePath = headMetadataPath ?? baseMetadataPath;
|
|
124
|
+
return {
|
|
125
|
+
summaryRow: {
|
|
126
|
+
screenshotBaseName,
|
|
127
|
+
status: !headMetadataPath ? "only-in-base" : "only-in-head",
|
|
128
|
+
totalHunks: 0,
|
|
129
|
+
bytes: 0,
|
|
130
|
+
url: availablePath ? readUrlFromMetadata(availablePath) : null,
|
|
131
|
+
},
|
|
132
|
+
mapEntry: null,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const url = readUrlFromMetadata(headMetadataPath);
|
|
136
|
+
// Can't derive a backend-compatible name (redacted variant, unknown
|
|
137
|
+
// type, or missing timeline entry) — skip the API call (it would 404).
|
|
138
|
+
if (backendName == null) {
|
|
139
|
+
console.warn(chalk_1.default.yellow(` Warning: Skipping DOM diff for ${pair.label}/${screenshotBaseName}: no backend name available (unsupported variant or missing timeline entry)`));
|
|
140
|
+
return {
|
|
141
|
+
summaryRow: {
|
|
142
|
+
screenshotBaseName,
|
|
143
|
+
status: "skipped-unsupported",
|
|
144
|
+
totalHunks: 0,
|
|
145
|
+
bytes: 0,
|
|
146
|
+
url,
|
|
147
|
+
},
|
|
148
|
+
mapEntry: null,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return limit(async () => {
|
|
152
|
+
let response;
|
|
153
|
+
try {
|
|
154
|
+
response = await fetchScreenshotDiff(client, pair.replayDiffId, backendName);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
158
|
+
console.warn(chalk_1.default.yellow(` Warning: Could not fetch DOM diff for ${pair.label}/${screenshotBaseName}: ${message}`));
|
|
159
|
+
return {
|
|
160
|
+
summaryRow: {
|
|
161
|
+
screenshotBaseName,
|
|
162
|
+
status: "skipped-error",
|
|
163
|
+
totalHunks: 0,
|
|
164
|
+
bytes: 0,
|
|
165
|
+
url,
|
|
166
|
+
},
|
|
167
|
+
mapEntry: null,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (response.totalDiffs === 0 || response.diffs.length === 0) {
|
|
171
|
+
return {
|
|
172
|
+
summaryRow: {
|
|
173
|
+
screenshotBaseName,
|
|
174
|
+
status: "identical",
|
|
175
|
+
totalHunks: 0,
|
|
176
|
+
bytes: 0,
|
|
177
|
+
url,
|
|
178
|
+
},
|
|
179
|
+
mapEntry: {
|
|
180
|
+
diffPath: null,
|
|
181
|
+
fullDiffPath: null,
|
|
182
|
+
totalHunks: 0,
|
|
183
|
+
bytes: 0,
|
|
184
|
+
url,
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
const diffBody = response.diffs.map((d) => d.content).join("\n\n");
|
|
189
|
+
const diffFilename = `${pair.label}-${screenshotBaseName}.diff`;
|
|
190
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(domDiffsDir, diffFilename), diffBody);
|
|
191
|
+
const bytes = Buffer.byteLength(diffBody, "utf-8");
|
|
192
|
+
// Fetch the same hunks with full-file context so the agent never has to
|
|
193
|
+
// shell out. A fetch failure here is non-fatal: we still have the
|
|
194
|
+
// canonical diff, just no `.full.diff` sibling.
|
|
195
|
+
let fullDiffPath = null;
|
|
196
|
+
try {
|
|
197
|
+
const fullResponse = await fetchScreenshotDiff(client, pair.replayDiffId, backendName, undefined, "full");
|
|
198
|
+
const fullBody = fullResponse.diffs.map((d) => d.content).join("\n\n");
|
|
199
|
+
const fullFilename = `${pair.label}-${screenshotBaseName}.full.diff`;
|
|
200
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(domDiffsDir, fullFilename), fullBody);
|
|
201
|
+
fullDiffPath = `dom-diffs/${fullFilename}`;
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
205
|
+
console.warn(chalk_1.default.yellow(` Warning: Could not fetch full-context DOM diff for ${pair.label}/${screenshotBaseName}: ${message}`));
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
summaryRow: {
|
|
209
|
+
screenshotBaseName,
|
|
210
|
+
status: "diff",
|
|
211
|
+
totalHunks: response.totalDiffs,
|
|
212
|
+
bytes,
|
|
213
|
+
url,
|
|
214
|
+
},
|
|
215
|
+
mapEntry: {
|
|
216
|
+
diffPath: `dom-diffs/${diffFilename}`,
|
|
217
|
+
fullDiffPath,
|
|
218
|
+
totalHunks: response.totalDiffs,
|
|
219
|
+
bytes,
|
|
220
|
+
url,
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
const renderPairSummary = (pair, rows) => {
|
|
226
|
+
const diffs = rows.filter((r) => r.status === "diff").length;
|
|
227
|
+
const identical = rows.filter((r) => r.status === "identical").length;
|
|
228
|
+
const onlyHead = rows.filter((r) => r.status === "only-in-head").length;
|
|
229
|
+
const onlyBase = rows.filter((r) => r.status === "only-in-base").length;
|
|
230
|
+
const skipped = rows.filter((r) => r.status === "skipped-error").length;
|
|
231
|
+
const skippedUnsupported = rows.filter((r) => r.status === "skipped-unsupported").length;
|
|
232
|
+
const header = [
|
|
233
|
+
`DOM Diff Summary: ${pair.label}`,
|
|
234
|
+
"=".repeat(20 + pair.label.length),
|
|
235
|
+
"",
|
|
236
|
+
`HEAD replay: ${pair.headReplayId}`,
|
|
237
|
+
`BASE replay: ${pair.baseReplayId}`,
|
|
238
|
+
"",
|
|
239
|
+
`Screenshots analyzed: ${rows.length}`,
|
|
240
|
+
` with DOM diff: ${diffs}`,
|
|
241
|
+
` identical DOM: ${identical}`,
|
|
242
|
+
` only in HEAD: ${onlyHead}`,
|
|
243
|
+
` only in BASE: ${onlyBase}`,
|
|
244
|
+
...(skipped > 0 ? [` skipped (API error): ${skipped}`] : []),
|
|
245
|
+
...(skippedUnsupported > 0
|
|
246
|
+
? [` skipped (unsupported identifier): ${skippedUnsupported}`]
|
|
247
|
+
: []),
|
|
248
|
+
"",
|
|
249
|
+
"For each screenshot below, `<label>-<screenshot>.diff` holds the",
|
|
250
|
+
"unified diff with 3 lines of context per hunk, and the sibling",
|
|
251
|
+
"`<label>-<screenshot>.full.diff` holds the same hunks with",
|
|
252
|
+
"full-file context for when 3 lines aren't enough.",
|
|
253
|
+
"",
|
|
254
|
+
].join("\n");
|
|
255
|
+
const tableRows = rows.map((row) => [
|
|
256
|
+
row.screenshotBaseName,
|
|
257
|
+
row.status,
|
|
258
|
+
String(row.totalHunks),
|
|
259
|
+
formatBytes(row.bytes),
|
|
260
|
+
row.url ?? "",
|
|
261
|
+
].join("\t"));
|
|
262
|
+
const tableHeader = ["screenshot", "status", "hunks", "diff_bytes", "url"].join("\t");
|
|
263
|
+
return `${header}\n${[tableHeader, ...tableRows].join("\n")}\n`;
|
|
264
|
+
};
|
|
265
|
+
const readUrlFromMetadata = (metadataPath) => (0, replay_walk_1.readScreenshotMetadata)(metadataPath)?.before?.routeData?.url ?? null;
|
|
266
|
+
/** Reject segments that could escape `dom-diffs/` when interpolated. */
|
|
267
|
+
const isSafePathSegment = (segment) => segment.length > 0 &&
|
|
268
|
+
!segment.includes("/") &&
|
|
269
|
+
!segment.includes("\\") &&
|
|
270
|
+
!segment.includes("\0") &&
|
|
271
|
+
segment !== "." &&
|
|
272
|
+
segment !== ".." &&
|
|
273
|
+
!segment.split(/[/\\]/).includes("..");
|
|
274
|
+
const formatBytes = (bytes) => {
|
|
275
|
+
if (bytes === 0) {
|
|
276
|
+
return "0";
|
|
277
|
+
}
|
|
278
|
+
if (bytes < 1024) {
|
|
279
|
+
return `${bytes}`;
|
|
280
|
+
}
|
|
281
|
+
if (bytes < 1024 * 1024) {
|
|
282
|
+
return `${(bytes / 1024).toFixed(1)}k`;
|
|
283
|
+
}
|
|
284
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}M`;
|
|
285
|
+
};
|
|
286
|
+
const indexScreenshotsByBaseName = (screenshotsDir) => {
|
|
287
|
+
const index = new Map();
|
|
288
|
+
for (const filename of (0, fs_1.readdirSync)(screenshotsDir)) {
|
|
289
|
+
if (!filename.endsWith(".metadata.json")) {
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
const baseName = filename.slice(0, -".metadata.json".length);
|
|
293
|
+
index.set(baseName, (0, path_1.join)(screenshotsDir, filename));
|
|
294
|
+
}
|
|
295
|
+
return index;
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* Map on-disk basename (e.g. `screenshot-after-event-00164`) to the
|
|
299
|
+
* backend-format name (e.g. `after-event-164`). First timeline wins on
|
|
300
|
+
* disagreement.
|
|
301
|
+
*/
|
|
302
|
+
const readBackendNameMap = (timelinePaths) => {
|
|
303
|
+
const map = new Map();
|
|
304
|
+
for (const timelinePath of timelinePaths) {
|
|
305
|
+
const timeline = (0, replay_walk_1.readTimelineJson)(timelinePath);
|
|
306
|
+
if (timeline == null) {
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
for (const entry of timeline) {
|
|
310
|
+
if (entry.kind !== "screenshot" || !entry.data?.identifier) {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const baseName = (0, screenshot_identifier_1.screenshotIdentifierToBaseName)(entry.data.identifier);
|
|
314
|
+
const backendName = (0, screenshot_identifier_1.screenshotIdentifierToBackendName)(entry.data.identifier);
|
|
315
|
+
if (baseName == null || backendName == null || map.has(baseName)) {
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
map.set(baseName, backendName);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return map;
|
|
322
|
+
};
|
|
323
|
+
const collectReplayDiffPairs = (debugContext) => {
|
|
324
|
+
const pairs = [];
|
|
325
|
+
for (const diff of debugContext.replayDiffs) {
|
|
326
|
+
pairs.push({
|
|
327
|
+
replayDiffId: diff.id,
|
|
328
|
+
headReplayId: diff.headReplayId,
|
|
329
|
+
baseReplayId: diff.baseReplayId,
|
|
330
|
+
label: `${diff.headReplayId}-vs-${diff.baseReplayId}`,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
// `met debug replay --baseReplayId` has no replayDiffId, so no pairs.
|
|
334
|
+
// CLAUDE.md instructs the agent to diff `<name>.html` files directly.
|
|
335
|
+
return pairs;
|
|
336
|
+
};
|
|
337
|
+
//# sourceMappingURL=fetch-dom-diffs.js.map
|
|
338
|
+
//# debugId=06b90e7f-cc42-52b9-9629-94d2c20264f4
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-dom-diffs.js","sources":["../src/fetch-dom-diffs.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"06b90e7f-cc42-52b9-9629-94d2c20264f4"}
|