codeloop-mcp-server 0.1.48 → 0.1.49
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/dist/auth/critical_floors.d.ts +8 -4
- package/dist/auth/critical_floors.d.ts.map +1 -1
- package/dist/auth/critical_floors.js +13 -17
- package/dist/auth/critical_floors.js.map +1 -1
- package/dist/auth/init_hint_cache.d.ts +35 -0
- package/dist/auth/init_hint_cache.d.ts.map +1 -0
- package/dist/auth/init_hint_cache.js +143 -0
- package/dist/auth/init_hint_cache.js.map +1 -0
- package/dist/evidence/screenshot_diff.d.ts +23 -0
- package/dist/evidence/screenshot_diff.d.ts.map +1 -1
- package/dist/evidence/screenshot_diff.js +46 -13
- package/dist/evidence/screenshot_diff.js.map +1 -1
- package/dist/index.js +168 -11
- package/dist/index.js.map +1 -1
- package/dist/runners/csproj_output_path.d.ts +22 -0
- package/dist/runners/csproj_output_path.d.ts.map +1 -0
- package/dist/runners/csproj_output_path.js +108 -0
- package/dist/runners/csproj_output_path.js.map +1 -0
- package/dist/runners/png_dims.d.ts +20 -0
- package/dist/runners/png_dims.d.ts.map +1 -0
- package/dist/runners/png_dims.js +58 -0
- package/dist/runners/png_dims.js.map +1 -0
- package/dist/runners/window_manager.d.ts +17 -4
- package/dist/runners/window_manager.d.ts.map +1 -1
- package/dist/runners/window_manager.js +135 -22
- package/dist/runners/window_manager.js.map +1 -1
- package/dist/tools/design_compare.d.ts.map +1 -1
- package/dist/tools/design_compare.js +14 -0
- package/dist/tools/design_compare.js.map +1 -1
- package/dist/tools/desktop_app_mode.d.ts +48 -0
- package/dist/tools/desktop_app_mode.d.ts.map +1 -0
- package/dist/tools/desktop_app_mode.js +86 -0
- package/dist/tools/desktop_app_mode.js.map +1 -0
- package/dist/tools/self_test.d.ts +40 -0
- package/dist/tools/self_test.d.ts.map +1 -0
- package/dist/tools/self_test.js +205 -0
- package/dist/tools/self_test.js.map +1 -0
- package/dist/tools/verify.d.ts.map +1 -1
- package/dist/tools/verify.js +4 -5
- package/dist/tools/verify.js.map +1 -1
- package/package.json +1 -1
|
@@ -36,10 +36,14 @@ export interface CriticalFloor {
|
|
|
36
36
|
* The canonical list. Order is not significant — every entry is
|
|
37
37
|
* checked against the running version independently.
|
|
38
38
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
39
|
+
* Roll-up rule (added in 0.1.49): when a release's first ship is
|
|
40
|
+
* older than ~6 months, fold its reason into the next-newest entry
|
|
41
|
+
* and remove the old row so the list stays short. The 0.1.46 row
|
|
42
|
+
* below is the rolled-up entry for 0.1.35 / 0.1.37 / 0.1.44 / 0.1.46
|
|
43
|
+
* — anyone still running pre-0.1.46 in 2026-Q4 has 4 separate
|
|
44
|
+
* known-bad-behaviour reasons and we'd rather show one consolidated
|
|
45
|
+
* "you must upgrade past 0.1.46" message than four nearly-identical
|
|
46
|
+
* "Photometry-DB-flavoured silent fullscreen capture" floors.
|
|
43
47
|
*/
|
|
44
48
|
export declare const CRITICAL_FLOORS: CriticalFloor[];
|
|
45
49
|
//# sourceMappingURL=critical_floors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"critical_floors.d.ts","sourceRoot":"","sources":["../../src/auth/critical_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED
|
|
1
|
+
{"version":3,"file":"critical_floors.d.ts","sourceRoot":"","sources":["../../src/auth/critical_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,EAmB1C,CAAC"}
|
|
@@ -30,27 +30,19 @@
|
|
|
30
30
|
* The canonical list. Order is not significant — every entry is
|
|
31
31
|
* checked against the running version independently.
|
|
32
32
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
33
|
+
* Roll-up rule (added in 0.1.49): when a release's first ship is
|
|
34
|
+
* older than ~6 months, fold its reason into the next-newest entry
|
|
35
|
+
* and remove the old row so the list stays short. The 0.1.46 row
|
|
36
|
+
* below is the rolled-up entry for 0.1.35 / 0.1.37 / 0.1.44 / 0.1.46
|
|
37
|
+
* — anyone still running pre-0.1.46 in 2026-Q4 has 4 separate
|
|
38
|
+
* known-bad-behaviour reasons and we'd rather show one consolidated
|
|
39
|
+
* "you must upgrade past 0.1.46" message than four nearly-identical
|
|
40
|
+
* "Photometry-DB-flavoured silent fullscreen capture" floors.
|
|
37
41
|
*/
|
|
38
42
|
export const CRITICAL_FLOORS = [
|
|
39
|
-
{
|
|
40
|
-
min_version: "0.1.35",
|
|
41
|
-
reason: "Workspace detection fix — pre-0.1.35 builds could silently scaffold CodeLoop into the user's home directory on Windows and misclassify the project as 'node'",
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
min_version: "0.1.37",
|
|
45
|
-
reason: "design_compare PNG-corruption fix + gate_check schema fix — pre-0.1.37 builds reported 15/18 design screens at 0% from one corrupt cached PNG, and rejected codeloop_gate_check calls without spec_path/acceptance_path",
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
min_version: "0.1.44",
|
|
49
|
-
reason: "Windows screenshot honesty fix — pre-0.1.44 builds silently captured the user's primary monitor (Cursor IDE / browser / terminal) and reported it as evidence of the app under test when the requested process wasn't running, causing visual_review to score the IDE as 1.0 and design_compare to misleadingly report 16/18 'below threshold' when most screens had no captured screenshot at all",
|
|
50
|
-
},
|
|
51
43
|
{
|
|
52
44
|
min_version: "0.1.46",
|
|
53
|
-
reason: "Desktop-app
|
|
45
|
+
reason: "Desktop-app honesty floor (rolled-up: 0.1.35 / 0.1.37 / 0.1.44 / 0.1.46) — pre-0.1.46 builds could silently scaffold CodeLoop into the user's home directory on Windows and misclassify the project as 'node', report 15/18 design screens at 0% from a single corrupt cached PNG, reject codeloop_gate_check calls without spec_path/acceptance_path, and silently capture the Cursor IDE as 'evidence of the app under test' on dotnet/WPF/Xcode/Android desktop projects when the requested process wasn't running",
|
|
54
46
|
},
|
|
55
47
|
{
|
|
56
48
|
min_version: "0.1.47",
|
|
@@ -60,5 +52,9 @@ export const CRITICAL_FLOORS = [
|
|
|
60
52
|
min_version: "0.1.48",
|
|
61
53
|
reason: "Desktop interaction reliability — pre-0.1.48 builds rejected target_type: 'windows_desktop' / 'mac_desktop' / 'linux_desktop' with a hard Zod error (agents had to know to type 'desktop' instead), didn't translate window-relative click coordinates to screen-absolute (so coords computed from a captured window-screenshot missed targets by hundreds of pixels), had no codeloop_launch_app tool / auto-launch in start_recording (agents had to hand-roll Get-Process + Start-Process PowerShell every recording), refused agent-natural flat sequence step shapes like { action: 'click', x: 100, y: 200 }, and treated cross-run weak design_compare matches as critical 0% failures of the gate-run screen. All four broke the autonomous loop on Photometry-DB E2E session 8",
|
|
62
54
|
},
|
|
55
|
+
{
|
|
56
|
+
min_version: "0.1.49",
|
|
57
|
+
reason: "Cross-stack desktop-app coverage + coord-DPI fixes — pre-0.1.49 builds skipped desktopAppMode for Electron / Tauri / React Native / Flutter desktop projects (silent IDE capture recurred), didn't scale agent-supplied screenshot coords or apply Windows DPI factors (clicks missed by 2× on high-DPI displays), missed MSIX / Store-installed desktop apps and custom .NET <OutputPath> values (codeloop_launch_app returned 'no .exe found'), only classified one specific pngjs error as a skip (truncated IDAT / bad CRC / malformed IHDR still dragged the gate to 0%), surfaced coordinate_clicks_without_intent as a soft warning AFTER the gate failed instead of a hard step-7 PENDING blocker BEFORE gate_check, and lacked codeloop_self_test for pre-flight validation against any project's stack",
|
|
58
|
+
},
|
|
63
59
|
];
|
|
64
60
|
//# sourceMappingURL=critical_floors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"critical_floors.js","sourceRoot":"","sources":["../../src/auth/critical_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH
|
|
1
|
+
{"version":3,"file":"critical_floors.js","sourceRoot":"","sources":["../../src/auth/critical_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAoB;IAC9C;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,ufAAuf;KAC1f;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,4hBAA4hB;KACriB;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,yvBAAyvB;KAClwB;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,kxBAAkxB;KACrxB;CACF,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
interface CacheFile {
|
|
2
|
+
version: number;
|
|
3
|
+
entries: Record<string, {
|
|
4
|
+
last_seen_at: string;
|
|
5
|
+
}>;
|
|
6
|
+
}
|
|
7
|
+
declare function cachePath(): string;
|
|
8
|
+
declare function readCache(): CacheFile;
|
|
9
|
+
/**
|
|
10
|
+
* Records that `dir` is known to be initialised. Idempotent — called
|
|
11
|
+
* on every tool invocation that resolves to an initialised project.
|
|
12
|
+
*
|
|
13
|
+
* The actual initialisation check (`isProjectInitialized`) is done
|
|
14
|
+
* by the caller; this helper just persists the result.
|
|
15
|
+
*/
|
|
16
|
+
export declare function recordInitialisedDir(dir: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Returns true if `dir` (or one of its ancestors up to 4 levels) was
|
|
19
|
+
* recorded as initialised in a prior MCP session. The ancestor walk
|
|
20
|
+
* is cheap and lets the cache work even when the agent passes a
|
|
21
|
+
* subfolder of the workspace root to a handler.
|
|
22
|
+
*/
|
|
23
|
+
export declare function wasInitialisedAtPath(dir: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Doctor `--clear-init-cache` flag entry point. Resets the cache to
|
|
26
|
+
* empty without removing the file (so subsequent reads see a
|
|
27
|
+
* well-formed JSON document). Returns the number of entries cleared.
|
|
28
|
+
*/
|
|
29
|
+
export declare function clearInitHintCache(): number;
|
|
30
|
+
export declare const _internalsForTests: {
|
|
31
|
+
cachePath: typeof cachePath;
|
|
32
|
+
readCache: typeof readCache;
|
|
33
|
+
};
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=init_hint_cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init_hint_cache.d.ts","sourceRoot":"","sources":["../../src/auth/init_hint_cache.ts"],"names":[],"mappings":"AAiCA,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAMD,iBAAS,SAAS,IAAI,MAAM,CAE3B;AAED,iBAAS,SAAS,IAAI,SAAS,CAe9B;AAYD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAiBtD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAezD;AAUD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAM3C;AAED,eAAO,MAAM,kBAAkB;;;CAG9B,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { join, resolve } from "path";
|
|
4
|
+
/**
|
|
5
|
+
* G9 — persist the "this dir is already CodeLoop-initialised" record
|
|
6
|
+
* to disk so it survives MCP server restarts. Pre-0.1.49 the
|
|
7
|
+
* `lastInitializedDir` lived in module state only; every IDE relaunch
|
|
8
|
+
* spun up a fresh MCP child with an empty cache, so the
|
|
9
|
+
* "[CodeLoop] This project has not been initialized" hint reappeared
|
|
10
|
+
* on the very first tool call until the agent happened to pass
|
|
11
|
+
* `project_dir` to a handler that fed it back into the in-memory
|
|
12
|
+
* cache. That false-positive hint is the #1 reason agents detoured
|
|
13
|
+
* into "let me run codeloop_init_project just to be safe" loops in
|
|
14
|
+
* E2E sessions 5–7.
|
|
15
|
+
*
|
|
16
|
+
* Storage layout — `~/.codeloop/init-hint-cache.json`:
|
|
17
|
+
* {
|
|
18
|
+
* "version": 1,
|
|
19
|
+
* "entries": {
|
|
20
|
+
* "/Users/jiq/Development/Photometry DB": { "last_seen_at": "2026-05-23T10:00:00.000Z" },
|
|
21
|
+
* "D:\\Work\\Photometry DB": { "last_seen_at": "2026-05-23T08:00:00.000Z" }
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* We key by absolute path so the same project on a removable drive
|
|
26
|
+
* remembered correctly even across MCP server restarts. Unbounded
|
|
27
|
+
* growth is capped at 64 entries (LRU on `last_seen_at`).
|
|
28
|
+
*/
|
|
29
|
+
const CACHE_VERSION = 1;
|
|
30
|
+
const MAX_ENTRIES = 64;
|
|
31
|
+
function cacheRoot() {
|
|
32
|
+
return process.env.CODELOOP_HOME_OVERRIDE || join(homedir(), ".codeloop");
|
|
33
|
+
}
|
|
34
|
+
function cachePath() {
|
|
35
|
+
return join(cacheRoot(), "init-hint-cache.json");
|
|
36
|
+
}
|
|
37
|
+
function readCache() {
|
|
38
|
+
const path = cachePath();
|
|
39
|
+
if (!existsSync(path))
|
|
40
|
+
return { version: CACHE_VERSION, entries: {} };
|
|
41
|
+
try {
|
|
42
|
+
const raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
43
|
+
if (!raw || typeof raw !== "object" || raw.version !== CACHE_VERSION) {
|
|
44
|
+
return { version: CACHE_VERSION, entries: {} };
|
|
45
|
+
}
|
|
46
|
+
if (!raw.entries || typeof raw.entries !== "object") {
|
|
47
|
+
return { version: CACHE_VERSION, entries: {} };
|
|
48
|
+
}
|
|
49
|
+
return raw;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return { version: CACHE_VERSION, entries: {} };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function writeCache(cache) {
|
|
56
|
+
const dir = cacheRoot();
|
|
57
|
+
try {
|
|
58
|
+
if (!existsSync(dir))
|
|
59
|
+
mkdirSync(dir, { recursive: true });
|
|
60
|
+
writeFileSync(cachePath(), JSON.stringify(cache, null, 2), "utf-8");
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Best-effort. Cache failure must never break a tool call.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Records that `dir` is known to be initialised. Idempotent — called
|
|
68
|
+
* on every tool invocation that resolves to an initialised project.
|
|
69
|
+
*
|
|
70
|
+
* The actual initialisation check (`isProjectInitialized`) is done
|
|
71
|
+
* by the caller; this helper just persists the result.
|
|
72
|
+
*/
|
|
73
|
+
export function recordInitialisedDir(dir) {
|
|
74
|
+
if (!dir)
|
|
75
|
+
return;
|
|
76
|
+
const abs = resolve(dir);
|
|
77
|
+
const cache = readCache();
|
|
78
|
+
cache.entries[abs] = { last_seen_at: new Date().toISOString() };
|
|
79
|
+
// LRU eviction so a heavy user doesn't bloat the JSON file.
|
|
80
|
+
const keys = Object.keys(cache.entries);
|
|
81
|
+
if (keys.length > MAX_ENTRIES) {
|
|
82
|
+
const sorted = keys.sort((a, b) => {
|
|
83
|
+
const ta = Date.parse(cache.entries[a].last_seen_at) || 0;
|
|
84
|
+
const tb = Date.parse(cache.entries[b].last_seen_at) || 0;
|
|
85
|
+
return ta - tb;
|
|
86
|
+
});
|
|
87
|
+
const drop = sorted.slice(0, keys.length - MAX_ENTRIES);
|
|
88
|
+
for (const k of drop)
|
|
89
|
+
delete cache.entries[k];
|
|
90
|
+
}
|
|
91
|
+
writeCache(cache);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns true if `dir` (or one of its ancestors up to 4 levels) was
|
|
95
|
+
* recorded as initialised in a prior MCP session. The ancestor walk
|
|
96
|
+
* is cheap and lets the cache work even when the agent passes a
|
|
97
|
+
* subfolder of the workspace root to a handler.
|
|
98
|
+
*/
|
|
99
|
+
export function wasInitialisedAtPath(dir) {
|
|
100
|
+
if (!dir)
|
|
101
|
+
return false;
|
|
102
|
+
const cache = readCache();
|
|
103
|
+
const abs = resolve(dir);
|
|
104
|
+
if (cache.entries[abs])
|
|
105
|
+
return true;
|
|
106
|
+
// Walk up. abs.split("/") works on POSIX; on Windows we mix
|
|
107
|
+
// separators, so use a simple two-character lookback.
|
|
108
|
+
let cur = abs;
|
|
109
|
+
for (let i = 0; i < 4; i++) {
|
|
110
|
+
const parent = parentDir(cur);
|
|
111
|
+
if (!parent || parent === cur)
|
|
112
|
+
break;
|
|
113
|
+
if (cache.entries[parent])
|
|
114
|
+
return true;
|
|
115
|
+
cur = parent;
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
function parentDir(p) {
|
|
120
|
+
const win = p.lastIndexOf("\\");
|
|
121
|
+
const posix = p.lastIndexOf("/");
|
|
122
|
+
const cut = Math.max(win, posix);
|
|
123
|
+
if (cut <= 0)
|
|
124
|
+
return p;
|
|
125
|
+
return p.substring(0, cut);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Doctor `--clear-init-cache` flag entry point. Resets the cache to
|
|
129
|
+
* empty without removing the file (so subsequent reads see a
|
|
130
|
+
* well-formed JSON document). Returns the number of entries cleared.
|
|
131
|
+
*/
|
|
132
|
+
export function clearInitHintCache() {
|
|
133
|
+
const cache = readCache();
|
|
134
|
+
const count = Object.keys(cache.entries).length;
|
|
135
|
+
cache.entries = {};
|
|
136
|
+
writeCache(cache);
|
|
137
|
+
return count;
|
|
138
|
+
}
|
|
139
|
+
export const _internalsForTests = {
|
|
140
|
+
cachePath,
|
|
141
|
+
readCache,
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=init_hint_cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init_hint_cache.js","sourceRoot":"","sources":["../../src/auth/init_hint_cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,6 +35,29 @@ export interface ScreenshotDiffSummary {
|
|
|
35
35
|
* unchanged so pngjs can still produce its informative error.
|
|
36
36
|
*/
|
|
37
37
|
declare function trimAfterIend(buf: Buffer): Buffer;
|
|
38
|
+
/**
|
|
39
|
+
* Custom error thrown by readPng() when ANY pngjs decode path fails.
|
|
40
|
+
* Centralised so callers (compareScreenshot → design_compare) can
|
|
41
|
+
* treat every "pngjs couldn't read this file" case uniformly as
|
|
42
|
+
* `{ skipped: true, skip_reason: …}` instead of dragging the gate
|
|
43
|
+
* down with a 0% match score.
|
|
44
|
+
*
|
|
45
|
+
* Photometry-DB E2E 8 surfaced exactly two recurrence paths:
|
|
46
|
+
* 1. Trailing bytes after IEND (PowerShell screenshot path) — the
|
|
47
|
+
* narrow `unrecognised content at end of stream` fix in 0.1.42
|
|
48
|
+
* handled this.
|
|
49
|
+
* 2. Truncated IDAT / bad CRC / malformed IHDR — these still
|
|
50
|
+
* threw a raw pngjs error, propagated through readPng untyped,
|
|
51
|
+
* and isPngDecodeError() would only catch them if the message
|
|
52
|
+
* happened to match a hard-coded substring. The 0.1.49 hardening
|
|
53
|
+
* (this class + the catch-all in readPng) means any pngjs throw
|
|
54
|
+
* is now classified as a skip, regardless of message wording.
|
|
55
|
+
*/
|
|
56
|
+
export declare class PngDecodeError extends Error {
|
|
57
|
+
readonly cause: unknown;
|
|
58
|
+
readonly path: string;
|
|
59
|
+
constructor(path: string, cause: unknown);
|
|
60
|
+
}
|
|
38
61
|
/** Exported for unit testing only. */
|
|
39
62
|
export declare const _trimAfterIendForTests: typeof trimAfterIend;
|
|
40
63
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot_diff.d.ts","sourceRoot":"","sources":["../../src/evidence/screenshot_diff.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC;AAgBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,iBAAS,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAqB1C;
|
|
1
|
+
{"version":3,"file":"screenshot_diff.d.ts","sourceRoot":"","sources":["../../src/evidence/screenshot_diff.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC;AAgBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,iBAAS,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAqB1C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAOzC;AA0BD,sCAAsC;AACtC,eAAO,MAAM,sBAAsB,sBAAgB,CAAC;AAmCpD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,SAAS,GAAE,MAA0B,EACrC,GAAG,CAAC,EAAE,MAAM,GACX,UAAU,CAoEZ;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAA0B,EACrC,GAAG,CAAC,EAAE,MAAM,GACX,qBAAqB,CA+CvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,MAAM,EAAE,CAwBV"}
|
|
@@ -57,25 +57,58 @@ function trimAfterIend(buf) {
|
|
|
57
57
|
}
|
|
58
58
|
return buf;
|
|
59
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Custom error thrown by readPng() when ANY pngjs decode path fails.
|
|
62
|
+
* Centralised so callers (compareScreenshot → design_compare) can
|
|
63
|
+
* treat every "pngjs couldn't read this file" case uniformly as
|
|
64
|
+
* `{ skipped: true, skip_reason: …}` instead of dragging the gate
|
|
65
|
+
* down with a 0% match score.
|
|
66
|
+
*
|
|
67
|
+
* Photometry-DB E2E 8 surfaced exactly two recurrence paths:
|
|
68
|
+
* 1. Trailing bytes after IEND (PowerShell screenshot path) — the
|
|
69
|
+
* narrow `unrecognised content at end of stream` fix in 0.1.42
|
|
70
|
+
* handled this.
|
|
71
|
+
* 2. Truncated IDAT / bad CRC / malformed IHDR — these still
|
|
72
|
+
* threw a raw pngjs error, propagated through readPng untyped,
|
|
73
|
+
* and isPngDecodeError() would only catch them if the message
|
|
74
|
+
* happened to match a hard-coded substring. The 0.1.49 hardening
|
|
75
|
+
* (this class + the catch-all in readPng) means any pngjs throw
|
|
76
|
+
* is now classified as a skip, regardless of message wording.
|
|
77
|
+
*/
|
|
78
|
+
export class PngDecodeError extends Error {
|
|
79
|
+
cause;
|
|
80
|
+
path;
|
|
81
|
+
constructor(path, cause) {
|
|
82
|
+
const inner = cause instanceof Error ? cause.message : String(cause);
|
|
83
|
+
super(`PNG decode failed for ${path}: ${inner}`);
|
|
84
|
+
this.name = "PngDecodeError";
|
|
85
|
+
this.path = path;
|
|
86
|
+
this.cause = cause;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
60
89
|
function readPng(path) {
|
|
61
90
|
const raw = readFileSync(path);
|
|
62
|
-
// First
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
91
|
+
// First attempt against the raw buffer (zero-cost for well-formed
|
|
92
|
+
// PNGs). Then retry against the IEND-trimmed buffer for the
|
|
93
|
+
// PowerShell-screenshot-with-trailing-bytes case, which is the
|
|
94
|
+
// most common recoverable failure mode. ANY other pngjs failure
|
|
95
|
+
// (truncated IDAT, malformed IHDR, bad pixel CRC, EOF-mid-chunk,
|
|
96
|
+
// etc.) is wrapped in PngDecodeError so callers can classify it
|
|
97
|
+
// as a skip uniformly. Pre-0.1.49 these would propagate as bare
|
|
98
|
+
// `Error("invalid IHDR")` etc. and only get classified as skips
|
|
99
|
+
// if the message happened to match a hard-coded substring in
|
|
100
|
+
// `isPngDecodeError`.
|
|
69
101
|
try {
|
|
70
102
|
return PNG.sync.read(raw);
|
|
71
103
|
}
|
|
72
|
-
catch (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
104
|
+
catch (firstErr) {
|
|
105
|
+
try {
|
|
106
|
+
const trimmed = trimAfterIend(raw);
|
|
107
|
+
return PNG.sync.read(trimmed);
|
|
108
|
+
}
|
|
109
|
+
catch (secondErr) {
|
|
110
|
+
throw new PngDecodeError(path, secondErr ?? firstErr);
|
|
76
111
|
}
|
|
77
|
-
const trimmed = trimAfterIend(raw);
|
|
78
|
-
return PNG.sync.read(trimmed);
|
|
79
112
|
}
|
|
80
113
|
}
|
|
81
114
|
/** Exported for unit testing only. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot_diff.js","sourceRoot":"","sources":["../../src/evidence/screenshot_diff.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EACL,UAAU,EACV,SAAS,EACT,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAkBlC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;AAC7C,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAS,aAAa,CAAC,GAAW;IAChC,mEAAmE;IACnE,gEAAgE;IAChE,kDAAkD;IAClD,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IACE,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM;YACzB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM;YAC7B,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM;YAC7B,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM;UAC1B,CAAC;YACD,4DAA4D;YAC5D,mEAAmE;YACnE,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YAClB,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;gBACrB,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,+DAA+D;IAC/D,iEAAiE;IACjE,
|
|
1
|
+
{"version":3,"file":"screenshot_diff.js","sourceRoot":"","sources":["../../src/evidence/screenshot_diff.ts"],"names":[],"mappings":"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"}
|