@alwaysmeticulous/debug-workspace 2.269.1 → 2.270.1
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 +74 -11
- package/dist/download-debug-data.d.ts +1 -1
- package/dist/download-debug-data.js +24 -33
- package/dist/download-debug-data.js.map +1 -1
- package/dist/generate-debug-derived-files.d.ts +1 -0
- package/dist/generate-debug-derived-files.js +378 -0
- package/dist/generate-debug-derived-files.js.map +1 -0
- package/dist/generate-debug-workspace.js +4 -2
- package/dist/generate-debug-workspace.js.map +1 -1
- package/dist/pipeline.d.ts +1 -1
- package/dist/pipeline.js +3 -3
- package/dist/pipeline.js.map +1 -1
- package/dist/templates/CLAUDE.md +86 -24
- package/dist/templates/agents/log-diff-analyzer.md +66 -0
- package/dist/templates/agents/planner.md +1 -1
- package/dist/templates/agents/pr-analyzer.md +57 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,27 +1,90 @@
|
|
|
1
1
|
# @alwaysmeticulous/debug-workspace
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Shared package that provides the debug workspace pipeline used by the
|
|
4
|
+
[Meticulous](https://meticulous.ai) CLI (`meticulous debug`) to investigate visual diffs
|
|
5
|
+
and replay issues.
|
|
4
6
|
|
|
5
7
|
## What it does
|
|
6
8
|
|
|
7
9
|
Given a replay diff ID or replay ID(s), this package:
|
|
8
10
|
|
|
9
|
-
1. **Resolves context**
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
1. **Resolves context** -- Fetches metadata about the test run and its replay diffs from the
|
|
12
|
+
Meticulous API, producing a `DebugContext` with all related IDs.
|
|
13
|
+
|
|
14
|
+
2. **Downloads debug data** -- Downloads replay data (logs, timeline, params, assets), session
|
|
15
|
+
recordings, replay diffs, and test run metadata into a local workspace directory. Downloads
|
|
16
|
+
run in parallel with configurable concurrency.
|
|
17
|
+
|
|
18
|
+
3. **Generates a workspace** -- Scaffolds a structured directory with:
|
|
19
|
+
- **Templates** -- `CLAUDE.md`, agents, rules, skills, hooks, and settings copied into
|
|
20
|
+
`.claude/` for use with Claude Code.
|
|
21
|
+
- **Derived analysis files** -- Pre-computed artifacts that make large replay data greppable
|
|
22
|
+
and manageable:
|
|
23
|
+
- Filtered logs (noise-stripped deterministic logs)
|
|
24
|
+
- Log diffs (raw, filtered, and summary)
|
|
25
|
+
- Diff summaries (compact screenshot diff results)
|
|
26
|
+
- Events index (one-line-per-event timeline summary)
|
|
27
|
+
- Network log (compact request log)
|
|
28
|
+
- VT progression (virtual time values for diffing)
|
|
29
|
+
- Logs index (one-line-per-entry log summary)
|
|
30
|
+
- Screenshot timeline context (events surrounding each screenshot)
|
|
31
|
+
- Timeline summaries, session summaries, params diffs, assets diffs
|
|
32
|
+
- Formatted assets (pretty-printed JS/CSS)
|
|
33
|
+
- PR diff (source code changes between base and head commits)
|
|
34
|
+
- **Context JSON** -- Machine-readable metadata with all IDs, paths, file sizes, screenshot
|
|
35
|
+
map, and replay comparison stats.
|
|
36
|
+
|
|
37
|
+
## Overlay templates
|
|
38
|
+
|
|
39
|
+
`generateDebugWorkspace` accepts an optional `additionalTemplatesDir` parameter. Files in this
|
|
40
|
+
overlay directory take precedence over the base templates bundled with this package. For
|
|
41
|
+
subdirectories (agents, rules, hooks, skills), base files are copied first, then overlay files
|
|
42
|
+
are copied on top -- so overlays can add new files or replace specific ones by name.
|
|
43
|
+
|
|
44
|
+
This is used by `met_debug` (in the internal Meticulous repo) to provide admin-specific
|
|
45
|
+
templates, skills, and a custom `CLAUDE.md` without forking the base package.
|
|
12
46
|
|
|
13
47
|
## Usage
|
|
14
48
|
|
|
15
|
-
This package is
|
|
49
|
+
This package is consumed by `@alwaysmeticulous/cli` via the `meticulous debug` command.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { runDebugPipeline } from "@alwaysmeticulous/debug-workspace";
|
|
53
|
+
|
|
54
|
+
await runDebugPipeline({
|
|
55
|
+
client,
|
|
56
|
+
replayDiffId: "some-replay-diff-id",
|
|
57
|
+
screenshot: "screenshot-after-event-00042.png",
|
|
58
|
+
createWorktree: (ctx, workspaceDir) => createProjectWorktree({ debugContext: ctx, workspaceDir }),
|
|
59
|
+
onWorkspaceReady: (workspaceDir, projectRepoDir) => presentWorkspace({ workspaceDir, projectRepoDir }),
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Or use individual steps for more control:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import {
|
|
67
|
+
resolveDebugContext,
|
|
68
|
+
downloadDebugData,
|
|
69
|
+
generateDebugWorkspace,
|
|
70
|
+
} from "@alwaysmeticulous/debug-workspace";
|
|
71
|
+
|
|
72
|
+
const debugContext = await resolveDebugContext({ client, replayDiffId });
|
|
73
|
+
await downloadDebugData({ client, debugContext, workspaceDir });
|
|
74
|
+
generateDebugWorkspace({ debugContext, workspaceDir, projectRepoDir });
|
|
75
|
+
```
|
|
16
76
|
|
|
17
77
|
## Key exports
|
|
18
78
|
|
|
19
|
-
- `runDebugPipeline`
|
|
20
|
-
- `resolveDebugContext`
|
|
21
|
-
- `downloadDebugData`
|
|
22
|
-
- `generateDebugWorkspace`
|
|
23
|
-
|
|
79
|
+
- `runDebugPipeline` -- Runs the full pipeline (resolve, download, generate workspace).
|
|
80
|
+
- `resolveDebugContext` -- Resolves a `DebugContext` from a replay diff ID or replay ID(s).
|
|
81
|
+
- `downloadDebugData` -- Downloads replay data and artifacts into a workspace directory.
|
|
82
|
+
- `generateDebugWorkspace` -- Scaffolds the workspace directory from templates and generates
|
|
83
|
+
all derived analysis files.
|
|
84
|
+
- `DebugContext`, `ReplayDiffInfo` -- Types describing the resolved debug context.
|
|
85
|
+
- `DEBUG_DATA_DIRECTORY`, `getDebugSessionsDir` -- Path constants.
|
|
24
86
|
|
|
25
87
|
## Part of the Meticulous SDK
|
|
26
88
|
|
|
27
|
-
This package is part of the [meticulous-sdk](https://github.com/alwaysmeticulous/meticulous-sdk)
|
|
89
|
+
This package is part of the [meticulous-sdk](https://github.com/alwaysmeticulous/meticulous-sdk)
|
|
90
|
+
monorepo.
|
|
@@ -4,7 +4,7 @@ export interface DownloadDebugDataOptions {
|
|
|
4
4
|
client: MeticulousClient;
|
|
5
5
|
debugContext: DebugContext;
|
|
6
6
|
workspaceDir: string;
|
|
7
|
-
|
|
7
|
+
maxConcurrentDownloads?: number | undefined;
|
|
8
8
|
additionalDownloads?: ((debugContext: DebugContext, debugDataDir: string) => void | Promise<void>) | undefined;
|
|
9
9
|
}
|
|
10
10
|
export declare const downloadDebugData: (options: DownloadDebugDataOptions) => Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
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]="
|
|
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]="0ec7dcd9-8c78-5830-8e60-8c31c2e4a5f5")}catch(e){}}();
|
|
3
3
|
|
|
4
4
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
5
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -11,34 +11,36 @@ const path_1 = require("path");
|
|
|
11
11
|
const client_1 = require("@alwaysmeticulous/client");
|
|
12
12
|
const downloading_helpers_1 = require("@alwaysmeticulous/downloading-helpers");
|
|
13
13
|
const chalk_1 = __importDefault(require("chalk"));
|
|
14
|
+
const p_limit_1 = __importDefault(require("p-limit"));
|
|
14
15
|
const debug_constants_1 = require("./debug-constants");
|
|
15
16
|
const REPLAY_SKIP_DIRS = new Set(["screenshots"]);
|
|
16
17
|
const DEFAULT_MAX_REPLAY_DOWNLOADS = 8;
|
|
17
18
|
const downloadDebugData = async (options) => {
|
|
18
|
-
var _a;
|
|
19
|
+
var _a, _b;
|
|
19
20
|
const { client, debugContext, workspaceDir } = options;
|
|
20
|
-
const maxConcurrency = (_a = options.
|
|
21
|
+
const maxConcurrency = (_a = options.maxConcurrentDownloads) !== null && _a !== void 0 ? _a : DEFAULT_MAX_REPLAY_DOWNLOADS;
|
|
21
22
|
const debugDataDir = (0, path_1.join)(workspaceDir, debug_constants_1.DEBUG_DATA_DIRECTORY);
|
|
22
23
|
(0, fs_1.mkdirSync)(debugDataDir, { recursive: true });
|
|
23
|
-
await
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
await Promise.all([
|
|
25
|
+
downloadReplays(client, debugContext, debugDataDir, maxConcurrency),
|
|
26
|
+
downloadSessionData(client, debugContext, debugDataDir, maxConcurrency),
|
|
27
|
+
downloadReplayDiffs(client, debugContext, debugDataDir, maxConcurrency),
|
|
28
|
+
downloadTestRunMetadata(client, debugContext, debugDataDir),
|
|
29
|
+
downloadPrDiffFromApi(client, debugContext, debugDataDir),
|
|
30
|
+
(_b = options.additionalDownloads) === null || _b === void 0 ? void 0 : _b.call(options, debugContext, debugDataDir),
|
|
31
|
+
]);
|
|
31
32
|
};
|
|
32
33
|
exports.downloadDebugData = downloadDebugData;
|
|
33
34
|
const downloadReplays = async (client, debugContext, debugDataDir, maxConcurrency) => {
|
|
34
35
|
const headReplayIds = new Set(debugContext.replayDiffs.map((d) => d.headReplayId));
|
|
35
36
|
const baseReplayIds = new Set(debugContext.replayDiffs.map((d) => d.baseReplayId));
|
|
36
37
|
console.log(chalk_1.default.cyan(` Downloading ${debugContext.replayIds.length} replays...`));
|
|
37
|
-
const
|
|
38
|
+
const limit = (0, p_limit_1.default)(maxConcurrency);
|
|
39
|
+
const results = await Promise.all(debugContext.replayIds.map((replayId) => limit(async () => {
|
|
38
40
|
const { fileName: cachedPath } = await (0, downloading_helpers_1.getOrFetchReplayArchive)(client, replayId, "everything", true);
|
|
39
41
|
console.log(chalk_1.default.cyan(` Downloaded replay ${replayId}`));
|
|
40
42
|
return { replayId, cachedPath };
|
|
41
|
-
})
|
|
43
|
+
})));
|
|
42
44
|
for (const { replayId, cachedPath } of results) {
|
|
43
45
|
const isHead = headReplayIds.has(replayId);
|
|
44
46
|
const isBase = baseReplayIds.has(replayId);
|
|
@@ -64,29 +66,31 @@ const copyReplayDir = (src, dest) => {
|
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
};
|
|
67
|
-
const downloadSessionData = async (client, debugContext, debugDataDir) => {
|
|
69
|
+
const downloadSessionData = async (client, debugContext, debugDataDir, maxConcurrency) => {
|
|
68
70
|
if (debugContext.sessionIds.length === 0) {
|
|
69
71
|
return;
|
|
70
72
|
}
|
|
71
|
-
|
|
73
|
+
const limit = (0, p_limit_1.default)(maxConcurrency);
|
|
74
|
+
await Promise.all(debugContext.sessionIds.map((sessionId) => limit(async () => {
|
|
72
75
|
console.log(chalk_1.default.cyan(` Downloading session ${sessionId}...`));
|
|
73
76
|
const { data: sessionData } = await (0, downloading_helpers_1.getOrFetchRecordedSessionData)(client, sessionId);
|
|
74
77
|
const sessionDir = (0, path_1.join)(debugDataDir, "sessions", sessionId);
|
|
75
78
|
(0, fs_1.mkdirSync)(sessionDir, { recursive: true });
|
|
76
79
|
(0, fs_1.writeFileSync)((0, path_1.join)(sessionDir, "data.json"), JSON.stringify(sessionData, null, 2));
|
|
77
|
-
}
|
|
80
|
+
})));
|
|
78
81
|
};
|
|
79
|
-
const downloadReplayDiffs = async (client, debugContext, debugDataDir) => {
|
|
82
|
+
const downloadReplayDiffs = async (client, debugContext, debugDataDir, maxConcurrency) => {
|
|
80
83
|
if (debugContext.replayDiffs.length === 0) {
|
|
81
84
|
return;
|
|
82
85
|
}
|
|
83
86
|
const diffsDir = (0, path_1.join)(debugDataDir, "diffs");
|
|
84
87
|
(0, fs_1.mkdirSync)(diffsDir, { recursive: true });
|
|
85
|
-
|
|
88
|
+
const limit = (0, p_limit_1.default)(maxConcurrency);
|
|
89
|
+
await Promise.all(debugContext.replayDiffs.map((diff) => limit(async () => {
|
|
86
90
|
console.log(chalk_1.default.cyan(` Downloading replay diff ${diff.id}...`));
|
|
87
91
|
const diffData = await (0, client_1.getReplayDiff)(client, diff.id);
|
|
88
92
|
(0, fs_1.writeFileSync)((0, path_1.join)(diffsDir, `${diff.id}.json`), JSON.stringify(diffData, null, 2));
|
|
89
|
-
}
|
|
93
|
+
})));
|
|
90
94
|
};
|
|
91
95
|
const downloadTestRunMetadata = async (client, debugContext, debugDataDir) => {
|
|
92
96
|
if (!debugContext.testRunId) {
|
|
@@ -127,18 +131,5 @@ const downloadPrDiffFromApi = async (client, debugContext, debugDataDir) => {
|
|
|
127
131
|
console.warn(chalk_1.default.yellow(` Warning: Could not download PR diff (${detail}).`));
|
|
128
132
|
}
|
|
129
133
|
};
|
|
130
|
-
const inParallel = async (tasks, concurrency) => {
|
|
131
|
-
const results = [];
|
|
132
|
-
let index = 0;
|
|
133
|
-
const runNext = async () => {
|
|
134
|
-
while (index < tasks.length) {
|
|
135
|
-
const currentIndex = index++;
|
|
136
|
-
results[currentIndex] = await tasks[currentIndex]();
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
const workers = Array.from({ length: Math.min(concurrency, tasks.length) }, () => runNext());
|
|
140
|
-
await Promise.all(workers);
|
|
141
|
-
return results;
|
|
142
|
-
};
|
|
143
134
|
//# sourceMappingURL=download-debug-data.js.map
|
|
144
|
-
//# debugId=
|
|
135
|
+
//# debugId=0ec7dcd9-8c78-5830-8e60-8c31c2e4a5f5
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download-debug-data.js","sources":["../src/download-debug-data.ts"],"sourceRoot":"","names":[],"mappings":";;;;;;;;AAAA,2BAA+E;AAC/E,+BAA4B;AAC5B,qDAKkC;AAClC,+EAG+C;AAC/C,kDAA0B;AAC1B,uDAAyD;AAGzD,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;AAClD,MAAM,4BAA4B,GAAG,CAAC,CAAC;AAehC,MAAM,iBAAiB,GAAG,KAAK,EACpC,OAAiC,EAClB,EAAE;;IACjB,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IACvD,MAAM,cAAc,GAClB,MAAA,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"download-debug-data.js","sources":["../src/download-debug-data.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"0ec7dcd9-8c78-5830-8e60-8c31c2e4a5f5"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const generateDebugDerivedFiles: (workspaceDir: string) => void;
|
|
@@ -0,0 +1,378 @@
|
|
|
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]="6f37046f-ff48-55b9-91e9-e1672d9e6957")}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.generateDebugDerivedFiles = 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 NETWORK_KINDS = new Set([
|
|
14
|
+
"pollyReplay",
|
|
15
|
+
"passedThroughNetworkRequest",
|
|
16
|
+
"assetLoadNetworkRequest",
|
|
17
|
+
"customResponseOverrideNetworkRequest",
|
|
18
|
+
]);
|
|
19
|
+
const MAX_LOG_MSG_LENGTH = 200;
|
|
20
|
+
const EVENTS_BEFORE_SCREENSHOT = 30;
|
|
21
|
+
const EVENTS_AFTER_SCREENSHOT = 10;
|
|
22
|
+
const generateDebugDerivedFiles = (workspaceDir) => {
|
|
23
|
+
const debugDataDir = (0, path_1.join)(workspaceDir, debug_constants_1.DEBUG_DATA_DIRECTORY);
|
|
24
|
+
const replaysDir = (0, path_1.join)(debugDataDir, "replays");
|
|
25
|
+
if (!(0, fs_1.existsSync)(replaysDir)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const replayDirs = discoverReplayDirs(replaysDir);
|
|
29
|
+
if (replayDirs.length === 0) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
console.log(chalk_1.default.cyan(" Generating debug derived files..."));
|
|
33
|
+
for (const replayDir of replayDirs) {
|
|
34
|
+
const timelineEntries = parseTimelineJson((0, path_1.join)(replayDir.path, "timeline.json"));
|
|
35
|
+
if (timelineEntries) {
|
|
36
|
+
generateTimelineNdjson(replayDir, timelineEntries);
|
|
37
|
+
generateEventsIndex(debugDataDir, replayDir, timelineEntries);
|
|
38
|
+
generateNetworkLog(debugDataDir, replayDir, timelineEntries);
|
|
39
|
+
generateScreenshotTimelineContext(debugDataDir, replayDir, timelineEntries);
|
|
40
|
+
}
|
|
41
|
+
generateVtProgression(debugDataDir, replayDir);
|
|
42
|
+
generateLogsIndex(debugDataDir, replayDir);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
exports.generateDebugDerivedFiles = generateDebugDerivedFiles;
|
|
46
|
+
const discoverReplayDirs = (replaysDir) => {
|
|
47
|
+
const dirs = [];
|
|
48
|
+
const roles = ["head", "base", "other"];
|
|
49
|
+
for (const role of roles) {
|
|
50
|
+
const roleDir = (0, path_1.join)(replaysDir, role);
|
|
51
|
+
if (!(0, fs_1.existsSync)(roleDir)) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
for (const replayId of (0, fs_1.readdirSync)(roleDir)) {
|
|
55
|
+
const replayPath = (0, path_1.join)(roleDir, replayId);
|
|
56
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(replayPath, "timeline.json"))) {
|
|
57
|
+
dirs.push({ role, replayId, path: replayPath });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return dirs;
|
|
62
|
+
};
|
|
63
|
+
const generateTimelineNdjson = (replayDir, entries) => {
|
|
64
|
+
const ndjsonPath = (0, path_1.join)(replayDir.path, "timeline.ndjson");
|
|
65
|
+
if ((0, fs_1.existsSync)(ndjsonPath)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const lines = entries.map((entry) => JSON.stringify(entry)).join("\n") + "\n";
|
|
69
|
+
(0, fs_1.writeFileSync)(ndjsonPath, lines, "utf-8");
|
|
70
|
+
};
|
|
71
|
+
const generateEventsIndex = (debugDataDir, replayDir, entries) => {
|
|
72
|
+
const lines = entries.map((entry, index) => formatTimelineEntry(entry, index));
|
|
73
|
+
const outDir = (0, path_1.join)(debugDataDir, "events-index");
|
|
74
|
+
(0, fs_1.mkdirSync)(outDir, { recursive: true });
|
|
75
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(outDir, `${replayDir.role}-${replayDir.replayId}.txt`), lines.join("\n") + "\n", "utf-8");
|
|
76
|
+
};
|
|
77
|
+
const generateNetworkLog = (debugDataDir, replayDir, entries) => {
|
|
78
|
+
const lines = [];
|
|
79
|
+
for (let i = 0; i < entries.length; i++) {
|
|
80
|
+
const entry = entries[i];
|
|
81
|
+
if (NETWORK_KINDS.has(entry.kind)) {
|
|
82
|
+
lines.push(formatNetworkEntry(entry, i));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (lines.length === 0) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const outDir = (0, path_1.join)(debugDataDir, "network-log");
|
|
89
|
+
(0, fs_1.mkdirSync)(outDir, { recursive: true });
|
|
90
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(outDir, `${replayDir.role}-${replayDir.replayId}.txt`), lines.join("\n") + "\n", "utf-8");
|
|
91
|
+
};
|
|
92
|
+
const generateVtProgression = (debugDataDir, replayDir) => {
|
|
93
|
+
const logsPath = (0, path_1.join)(replayDir.path, "logs.ndjson");
|
|
94
|
+
if (!(0, fs_1.existsSync)(logsPath)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const content = (0, fs_1.readFileSync)(logsPath, "utf-8");
|
|
98
|
+
const vtValues = [];
|
|
99
|
+
for (const line of content.split("\n")) {
|
|
100
|
+
if (!line.trim()) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const entry = JSON.parse(line);
|
|
105
|
+
if (entry.type === "virtual-time-change" && entry.virtualTime != null) {
|
|
106
|
+
vtValues.push(entry.virtualTime);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// skip malformed lines
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (vtValues.length === 0) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const outDir = (0, path_1.join)(debugDataDir, "vt-progression");
|
|
117
|
+
(0, fs_1.mkdirSync)(outDir, { recursive: true });
|
|
118
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(outDir, `${replayDir.role}-${replayDir.replayId}.txt`), vtValues.join("\n") + "\n", "utf-8");
|
|
119
|
+
};
|
|
120
|
+
const generateLogsIndex = (debugDataDir, replayDir) => {
|
|
121
|
+
var _a, _b, _c;
|
|
122
|
+
const logsPath = (0, path_1.join)(replayDir.path, "logs.ndjson");
|
|
123
|
+
if (!(0, fs_1.existsSync)(logsPath)) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const content = (0, fs_1.readFileSync)(logsPath, "utf-8");
|
|
127
|
+
const lines = [];
|
|
128
|
+
let lastVt = 0;
|
|
129
|
+
let lineIndex = 0;
|
|
130
|
+
for (const rawLine of content.split("\n")) {
|
|
131
|
+
if (!rawLine.trim()) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
let entry;
|
|
135
|
+
try {
|
|
136
|
+
entry = JSON.parse(rawLine);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
lineIndex++;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (entry.type === "virtual-time-change" && entry.virtualTime != null) {
|
|
143
|
+
const newVt = Number(entry.virtualTime);
|
|
144
|
+
lines.push(`[${lineIndex}] vt=${lastVt} [virtual-time-change -> ${newVt}]`);
|
|
145
|
+
lastVt = newVt;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const source = (_a = entry.source) !== null && _a !== void 0 ? _a : "?";
|
|
149
|
+
const type = (_b = entry.type) !== null && _b !== void 0 ? _b : "?";
|
|
150
|
+
const msg = truncate(String((_c = entry.message) !== null && _c !== void 0 ? _c : ""), MAX_LOG_MSG_LENGTH);
|
|
151
|
+
lines.push(`[${lineIndex}] vt=${lastVt} source=${source} type=${type} msg=${msg}`);
|
|
152
|
+
}
|
|
153
|
+
lineIndex++;
|
|
154
|
+
}
|
|
155
|
+
if (lines.length === 0) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const outDir = (0, path_1.join)(debugDataDir, "logs-index");
|
|
159
|
+
(0, fs_1.mkdirSync)(outDir, { recursive: true });
|
|
160
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(outDir, `${replayDir.role}-${replayDir.replayId}.txt`), lines.join("\n") + "\n", "utf-8");
|
|
161
|
+
};
|
|
162
|
+
const generateScreenshotTimelineContext = (debugDataDir, replayDir, entries) => {
|
|
163
|
+
const screenshotIndexes = [];
|
|
164
|
+
for (let i = 0; i < entries.length; i++) {
|
|
165
|
+
if (entries[i].kind === "screenshot") {
|
|
166
|
+
screenshotIndexes.push(i);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (screenshotIndexes.length === 0) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const outDir = (0, path_1.join)(debugDataDir, "screenshot-timeline-context");
|
|
173
|
+
(0, fs_1.mkdirSync)(outDir, { recursive: true });
|
|
174
|
+
for (const screenshotIdx of screenshotIndexes) {
|
|
175
|
+
const screenshotEntry = entries[screenshotIdx];
|
|
176
|
+
const identifier = getScreenshotIdentifierString(screenshotEntry);
|
|
177
|
+
const startIdx = Math.max(0, screenshotIdx - EVENTS_BEFORE_SCREENSHOT);
|
|
178
|
+
const endIdx = Math.min(entries.length - 1, screenshotIdx + EVENTS_AFTER_SCREENSHOT);
|
|
179
|
+
const lines = [];
|
|
180
|
+
lines.push(`Screenshot: ${identifier} (index ${screenshotIdx}, vt=${formatVt(screenshotEntry)})`);
|
|
181
|
+
lines.push(`Showing events [${startIdx}..${endIdx}] (${EVENTS_BEFORE_SCREENSHOT} before, ${EVENTS_AFTER_SCREENSHOT} after)`);
|
|
182
|
+
lines.push("");
|
|
183
|
+
for (let i = startIdx; i <= endIdx; i++) {
|
|
184
|
+
const prefix = i === screenshotIdx ? ">>>" : " ";
|
|
185
|
+
lines.push(`${prefix} ${formatTimelineEntry(entries[i], i)}`);
|
|
186
|
+
}
|
|
187
|
+
const filename = identifier
|
|
188
|
+
? `${replayDir.role}-${replayDir.replayId}-${identifier}.txt`
|
|
189
|
+
: `${replayDir.role}-${replayDir.replayId}-idx${screenshotIdx}.txt`;
|
|
190
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(outDir, filename), lines.join("\n") + "\n", "utf-8");
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
const parseTimelineJson = (path) => {
|
|
194
|
+
if (!(0, fs_1.existsSync)(path)) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const raw = (0, fs_1.readFileSync)(path, "utf-8");
|
|
199
|
+
const parsed = JSON.parse(raw);
|
|
200
|
+
if (Array.isArray(parsed)) {
|
|
201
|
+
return parsed;
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
const formatVt = (entry) => {
|
|
210
|
+
const vts = entry.virtualTimeStart;
|
|
211
|
+
const vte = entry.virtualTimeEnd;
|
|
212
|
+
if (vts == null && vte == null) {
|
|
213
|
+
return "?";
|
|
214
|
+
}
|
|
215
|
+
if (vts === vte || vte == null) {
|
|
216
|
+
return `${vts}`;
|
|
217
|
+
}
|
|
218
|
+
if (vts == null) {
|
|
219
|
+
return `?-${vte}`;
|
|
220
|
+
}
|
|
221
|
+
return `${vts}-${vte}`;
|
|
222
|
+
};
|
|
223
|
+
const truncate = (s, maxLen) => s.length > maxLen ? s.slice(0, maxLen) + "..." : s;
|
|
224
|
+
const formatTimelineEntry = (entry, index) => {
|
|
225
|
+
const vt = formatVt(entry);
|
|
226
|
+
const base = `[${index}] vt=${vt} kind=${entry.kind}`;
|
|
227
|
+
const detail = getKindSpecificDetail(entry);
|
|
228
|
+
return detail ? `${base} ${detail}` : base;
|
|
229
|
+
};
|
|
230
|
+
const getKindSpecificDetail = (entry) => {
|
|
231
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20;
|
|
232
|
+
const data = (_a = entry.data) !== null && _a !== void 0 ? _a : {};
|
|
233
|
+
switch (entry.kind) {
|
|
234
|
+
case "screenshot":
|
|
235
|
+
return `id=${formatScreenshotIdentifier(data.identifier)}`;
|
|
236
|
+
case "pollyReplay": {
|
|
237
|
+
const req = (_b = data.pollyRequest) !== null && _b !== void 0 ? _b : {};
|
|
238
|
+
const reqReq = (_c = req.request) !== null && _c !== void 0 ? _c : {};
|
|
239
|
+
const method = (_d = reqReq.method) !== null && _d !== void 0 ? _d : "?";
|
|
240
|
+
const url = truncate(String((_e = reqReq.url) !== null && _e !== void 0 ? _e : "?"), 120);
|
|
241
|
+
const result = (_f = data.result) !== null && _f !== void 0 ? _f : "?";
|
|
242
|
+
const matched = (_g = data.matchedRequest) !== null && _g !== void 0 ? _g : {};
|
|
243
|
+
const matchedResp = (_h = matched.response) !== null && _h !== void 0 ? _h : {};
|
|
244
|
+
const status = (_j = matchedResp.status) !== null && _j !== void 0 ? _j : "";
|
|
245
|
+
const repair = data.repairSource ? ` repair=${data.repairSource}` : "";
|
|
246
|
+
return `${method} ${url} -> ${status} (${result})${repair}`;
|
|
247
|
+
}
|
|
248
|
+
case "passedThroughNetworkRequest": {
|
|
249
|
+
const req = (_k = data.request) !== null && _k !== void 0 ? _k : {};
|
|
250
|
+
const method = (_l = req.method) !== null && _l !== void 0 ? _l : "?";
|
|
251
|
+
const url = truncate(String((_m = req.url) !== null && _m !== void 0 ? _m : "?"), 120);
|
|
252
|
+
return `${method} ${url} (passed-through)`;
|
|
253
|
+
}
|
|
254
|
+
case "assetLoadNetworkRequest": {
|
|
255
|
+
const req = (_o = data.request) !== null && _o !== void 0 ? _o : {};
|
|
256
|
+
const resp = (_p = data.response) !== null && _p !== void 0 ? _p : {};
|
|
257
|
+
const method = (_q = req.method) !== null && _q !== void 0 ? _q : "?";
|
|
258
|
+
const url = truncate(String((_r = req.url) !== null && _r !== void 0 ? _r : "?"), 120);
|
|
259
|
+
const status = (_s = resp.statusCode) !== null && _s !== void 0 ? _s : "?";
|
|
260
|
+
return `${method} ${url} -> ${status} (asset)`;
|
|
261
|
+
}
|
|
262
|
+
case "customResponseOverrideNetworkRequest": {
|
|
263
|
+
const req = (_t = data.request) !== null && _t !== void 0 ? _t : {};
|
|
264
|
+
const method = (_u = req.method) !== null && _u !== void 0 ? _u : "?";
|
|
265
|
+
const url = truncate(String((_v = req.url) !== null && _v !== void 0 ? _v : "?"), 120);
|
|
266
|
+
return `${method} ${url} (custom-override)`;
|
|
267
|
+
}
|
|
268
|
+
case "consoleMessage": {
|
|
269
|
+
const type = (_w = data.type) !== null && _w !== void 0 ? _w : "?";
|
|
270
|
+
const msg = truncate(String((_x = data.message) !== null && _x !== void 0 ? _x : ""), 150);
|
|
271
|
+
return `type=${type} msg=${msg}`;
|
|
272
|
+
}
|
|
273
|
+
case "urlChange":
|
|
274
|
+
case "fullPageNavigation":
|
|
275
|
+
return `url=${truncate(String((_y = data.url) !== null && _y !== void 0 ? _y : "?"), 120)}`;
|
|
276
|
+
case "initialNavigation": {
|
|
277
|
+
const url = truncate(String((_z = data.url) !== null && _z !== void 0 ? _z : "?"), 120);
|
|
278
|
+
const status = (_0 = data.status) !== null && _0 !== void 0 ? _0 : "?";
|
|
279
|
+
return `url=${url} -> ${status}`;
|
|
280
|
+
}
|
|
281
|
+
case "jsReplay": {
|
|
282
|
+
const event = (_1 = data.event) !== null && _1 !== void 0 ? _1 : "?";
|
|
283
|
+
if (event === "simulate") {
|
|
284
|
+
const userEvent = (_2 = data.userEvent) !== null && _2 !== void 0 ? _2 : {};
|
|
285
|
+
const eventType = (_3 = userEvent.type) !== null && _3 !== void 0 ? _3 : "?";
|
|
286
|
+
const result = (_4 = data.result) !== null && _4 !== void 0 ? _4 : "?";
|
|
287
|
+
return `${eventType} result=${result}`;
|
|
288
|
+
}
|
|
289
|
+
return `event=${event}`;
|
|
290
|
+
}
|
|
291
|
+
case "fatalError":
|
|
292
|
+
case "assertionError":
|
|
293
|
+
case "error": {
|
|
294
|
+
const msg = truncate(String((_6 = (_5 = data.message) !== null && _5 !== void 0 ? _5 : data.type) !== null && _6 !== void 0 ? _6 : ""), 150);
|
|
295
|
+
return msg;
|
|
296
|
+
}
|
|
297
|
+
case "timeoutError": {
|
|
298
|
+
const waitedFor = (_7 = data.waitedFor) !== null && _7 !== void 0 ? _7 : "?";
|
|
299
|
+
const timeout = (_8 = data.timeoutInMs) !== null && _8 !== void 0 ? _8 : "?";
|
|
300
|
+
return `waitedFor=${waitedFor} timeout=${timeout}ms`;
|
|
301
|
+
}
|
|
302
|
+
case "webSocket": {
|
|
303
|
+
const event = (_9 = data.event) !== null && _9 !== void 0 ? _9 : "?";
|
|
304
|
+
const url = data.url ? truncate(String(data.url), 80) : "";
|
|
305
|
+
return `${event}${url ? ` url=${url}` : ""}`;
|
|
306
|
+
}
|
|
307
|
+
case "eventSource": {
|
|
308
|
+
const event = (_10 = data.event) !== null && _10 !== void 0 ? _10 : "?";
|
|
309
|
+
const url = data.url ? truncate(String(data.url), 80) : "";
|
|
310
|
+
return `${event}${url ? ` url=${url}` : ""}`;
|
|
311
|
+
}
|
|
312
|
+
case "streamingFetch": {
|
|
313
|
+
const event = (_11 = data.event) !== null && _11 !== void 0 ? _11 : "?";
|
|
314
|
+
const url = data.url ? truncate(String(data.url), 80) : "";
|
|
315
|
+
const method = (_12 = data.method) !== null && _12 !== void 0 ? _12 : "";
|
|
316
|
+
return `${event} ${method} ${url}`.trim();
|
|
317
|
+
}
|
|
318
|
+
case "applicationStorageAccess": {
|
|
319
|
+
const storageType = (_13 = data.storageType) !== null && _13 !== void 0 ? _13 : "?";
|
|
320
|
+
const key = truncate(String((_14 = data.key) !== null && _14 !== void 0 ? _14 : "?"), 60);
|
|
321
|
+
return `${storageType} key=${key} found=${data.didFindValue}`;
|
|
322
|
+
}
|
|
323
|
+
case "applicationStorageWrite": {
|
|
324
|
+
const storageType = (_15 = data.storageType) !== null && _15 !== void 0 ? _15 : "?";
|
|
325
|
+
const key = truncate(String((_16 = data.key) !== null && _16 !== void 0 ? _16 : "?"), 60);
|
|
326
|
+
return `${storageType} key=${key}`;
|
|
327
|
+
}
|
|
328
|
+
case "correctnessWarning":
|
|
329
|
+
case "potentialFlakinessWarning": {
|
|
330
|
+
const type = (_17 = data.type) !== null && _17 !== void 0 ? _17 : "?";
|
|
331
|
+
return `type=${type}`;
|
|
332
|
+
}
|
|
333
|
+
case "debugEvent": {
|
|
334
|
+
const type = (_18 = data.type) !== null && _18 !== void 0 ? _18 : "?";
|
|
335
|
+
return `type=${type}`;
|
|
336
|
+
}
|
|
337
|
+
case "timelineEntryLimitReached": {
|
|
338
|
+
const entryKind = (_19 = data.entryKind) !== null && _19 !== void 0 ? _19 : "?";
|
|
339
|
+
const limit = (_20 = data.limit) !== null && _20 !== void 0 ? _20 : "?";
|
|
340
|
+
return `entryKind=${entryKind} limit=${limit}`;
|
|
341
|
+
}
|
|
342
|
+
default:
|
|
343
|
+
return "";
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
const formatNetworkEntry = (entry, index) => {
|
|
347
|
+
const vt = formatVt(entry);
|
|
348
|
+
const base = `[${index}] vt=${vt}`;
|
|
349
|
+
const detail = getKindSpecificDetail(entry);
|
|
350
|
+
return `${base} ${detail}`;
|
|
351
|
+
};
|
|
352
|
+
const formatScreenshotIdentifier = (identifier) => {
|
|
353
|
+
var _a, _b;
|
|
354
|
+
if (identifier == null) {
|
|
355
|
+
return "?";
|
|
356
|
+
}
|
|
357
|
+
if (typeof identifier === "string") {
|
|
358
|
+
return identifier;
|
|
359
|
+
}
|
|
360
|
+
if (typeof identifier === "object") {
|
|
361
|
+
const id = identifier;
|
|
362
|
+
if (id.variant && id.variant !== "normal") {
|
|
363
|
+
return `${id.variant}-screenshot-after-event-${String((_a = id.eventNumber) !== null && _a !== void 0 ? _a : "?").padStart(5, "0")}`;
|
|
364
|
+
}
|
|
365
|
+
return `screenshot-after-event-${String((_b = id.eventNumber) !== null && _b !== void 0 ? _b : "?").padStart(5, "0")}`;
|
|
366
|
+
}
|
|
367
|
+
return String(identifier);
|
|
368
|
+
};
|
|
369
|
+
const getScreenshotIdentifierString = (entry) => {
|
|
370
|
+
var _a;
|
|
371
|
+
const id = (_a = entry.data) === null || _a === void 0 ? void 0 : _a.identifier;
|
|
372
|
+
if (id == null) {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
return formatScreenshotIdentifier(id);
|
|
376
|
+
};
|
|
377
|
+
//# sourceMappingURL=generate-debug-derived-files.js.map
|
|
378
|
+
//# debugId=6f37046f-ff48-55b9-91e9-e1672d9e6957
|