clearcote 0.38.1 → 0.40.0

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.
@@ -8,9 +8,14 @@
8
8
  * query alone — rendering is untouched, and the result is byte-identical to what the Windows build
9
9
  * reports.
10
10
  *
11
- * OFF unless asked for. The re-translation is a different code path from the one that rendered, so
12
- * a shader the Vulkan backend accepts but the HLSL translator rejects falls back to the honest
13
- * SPIR-V for that shader. It is for callers who actually hit this check, not a default.
11
+ * ON BY DEFAULT for a Windows claim on a non-Windows host (the Docker entrypoint has done this for
12
+ * CC_PLATFORM=windows since 0.31). Measured 2026-10-06 on a GPU-less Linux host with r30: a Windows
13
+ * persona answered the query with SwiftShader's SPIR-V text next to "Direct3D11"; with the dialect
14
+ * set it answered in HLSL. A shader the HLSL translator rejects falls back to the backend's own
15
+ * output for that shader -- the state every launch was in before, so the default cannot make a page
16
+ * see anything worse. Pass `shaderDialect: false` to turn it off. On a Windows host the D3D11
17
+ * backend already answers in HLSL and nothing is set; a Linux or macOS claim never gets HLSL, nor
18
+ * does a launch that shows the real GPU string or a custom non-Direct3D renderer.
14
19
  *
15
20
  * Delivered as an environment variable because the code lives in the GPU process, which does not
16
21
  * receive the fingerprint switches.
@@ -19,21 +24,66 @@
19
24
  */
20
25
  export const SHADER_DIALECT_ENV = "CLEARCOTE_SHADER_DIALECT";
21
26
  const VALID = ["hlsl"];
27
+ const OFF = ["", "0", "off", "false", "no", "none"];
28
+ /** Switches under which the renderer string is the host's real GPU (SwiftShader, Mesa, ...), not the
29
+ * persona's Direct3D11 one — HLSL beside it would be the contradiction this option removes. */
30
+ const REAL_GPU_STRING_SWITCHES = ["--disable-gpu-fingerprint", "--disable-gpu-string-spoof"];
31
+ /** The dialect a launch gets when the caller did not choose one: `"hlsl"` when the built command
32
+ * line claims Windows (`--fingerprint-platform=windows`, the last one wins) with a Direct3D renderer
33
+ * string and the host is not Windows, else undefined. No default when the page sees the real GPU
34
+ * string (`--disable-gpu-fingerprint` / `--disable-gpu-string-spoof`) or a custom
35
+ * `--fingerprint-gpu-renderer` that does not name Direct3D. */
36
+ export function defaultShaderDialect(args, hostPlatform = process.platform) {
37
+ if (hostPlatform === "win32")
38
+ return undefined;
39
+ let claimed;
40
+ let renderer;
41
+ for (const a of args ?? []) {
42
+ if (typeof a !== "string")
43
+ continue;
44
+ if (a.startsWith("--fingerprint-platform=")) {
45
+ claimed = a.slice("--fingerprint-platform=".length).trim().toLowerCase();
46
+ }
47
+ else if (a.startsWith("--fingerprint-gpu-renderer=")) {
48
+ renderer = a.slice("--fingerprint-gpu-renderer=".length);
49
+ }
50
+ else if (REAL_GPU_STRING_SWITCHES.includes(a.split("=", 1)[0])) {
51
+ return undefined;
52
+ }
53
+ }
54
+ if (claimed !== "windows")
55
+ return undefined;
56
+ if (renderer !== undefined && !renderer.toLowerCase().includes("direct3d"))
57
+ return undefined;
58
+ return "hlsl";
59
+ }
22
60
  /**
23
61
  * Fold `CLEARCOTE_SHADER_DIALECT` into a launch env.
24
62
  *
25
- * Returns `baseEnv` untouched when no dialect is requested — including `undefined`, so the default
26
- * Playwright env is preserved rather than being replaced by a copy of `process.env`.
63
+ * `dialect` undefined -> the default for this claim/host ({@link defaultShaderDialect} over `args`);
64
+ * `false` or an "off" spelling -> nothing. Returns `baseEnv` untouched when nothing applies —
65
+ * including the plain no-claim case, so the default Playwright env is preserved rather than being
66
+ * replaced by a copy of `process.env`. The default never overrides a variable the caller exported.
27
67
  *
28
68
  * Throws on an unknown dialect rather than ignoring it: a typo would otherwise look like it worked
29
69
  * while the engine kept reporting the honest dialect.
30
70
  */
31
- export function withShaderDialect(dialect, baseEnv) {
32
- if (!dialect)
33
- return baseEnv;
34
- const value = String(dialect).trim().toLowerCase();
35
- if (!VALID.includes(value)) {
36
- throw new Error(`shaderDialect must be one of ${VALID.join(", ")} (got ${JSON.stringify(dialect)})`);
71
+ export function withShaderDialect(dialect, baseEnv, args, hostPlatform = process.platform) {
72
+ let value;
73
+ if (dialect === undefined || dialect === null) { // null (from JS callers) means "not chosen" too
74
+ value = defaultShaderDialect(args, hostPlatform);
75
+ if (!value)
76
+ return baseEnv;
77
+ if ((baseEnv ?? process.env)[SHADER_DIALECT_ENV] !== undefined)
78
+ return baseEnv;
79
+ }
80
+ else {
81
+ if (dialect === false || OFF.includes(String(dialect).trim().toLowerCase()))
82
+ return baseEnv;
83
+ value = String(dialect).trim().toLowerCase();
84
+ if (!VALID.includes(value)) {
85
+ throw new Error(`shaderDialect must be one of ${VALID.join(", ")} (got ${JSON.stringify(dialect)})`);
86
+ }
37
87
  }
38
88
  const src = baseEnv ?? process.env;
39
89
  const out = {};
@@ -1 +1 @@
1
- {"version":3,"file":"shaderdialect.js","sourceRoot":"","sources":["../src/shaderdialect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAK7D,MAAM,KAAK,GAAsB,CAAC,MAAM,CAAC,CAAC;AAE1C;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA2B,EAC3B,OAAuD;IAEvD,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,gCAAgC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CACpF,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;IACnC,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,IAAI,CAAC,KAAK,SAAS;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1E,GAAG,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC;IAChC,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"shaderdialect.js","sourceRoot":"","sources":["../src/shaderdialect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAK7D,MAAM,KAAK,GAAsB,CAAC,MAAM,CAAC,CAAC;AAE1C,MAAM,GAAG,GAAsB,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEvE;+FAC+F;AAC/F,MAAM,wBAAwB,GAAsB,CAAC,2BAA2B,EAAE,4BAA4B,CAAC,CAAC;AAEhH;;;;+DAI+D;AAC/D,MAAM,UAAU,oBAAoB,CAAC,IAAwB,EAAE,eAAuB,OAAO,CAAC,QAAQ;IACpG,IAAI,YAAY,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/C,IAAI,OAA2B,CAAC;IAChC,IAAI,QAA4B,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QAC3B,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,SAAS;QACpC,IAAI,CAAC,CAAC,UAAU,CAAC,yBAAyB,CAAC,EAAE,CAAC;YAC5C,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3E,CAAC;aAAM,IAAI,CAAC,CAAC,UAAU,CAAC,6BAA6B,CAAC,EAAE,CAAC;YACvD,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;QAC3D,CAAC;aAAM,IAAI,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IACD,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC5C,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7F,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA0C,EAC1C,OAAuD,EACvD,IAAwB,EACxB,eAAuB,OAAO,CAAC,QAAQ;IAEvC,IAAI,KAAyB,CAAC;IAC9B,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC,CAAE,gDAAgD;QAChG,KAAK,GAAG,oBAAoB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK;YAAE,OAAO,OAAO,CAAC;QAC3B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,kBAAkB,CAAC,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC;IACjF,CAAC;SAAM,CAAC;QACN,IAAI,OAAO,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAAE,OAAO,OAAO,CAAC;QAC5F,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,gCAAgC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CACpF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;IACnC,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,IAAI,CAAC,KAAK,SAAS;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1E,GAAG,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC;IAChC,OAAO,GAAG,CAAC;AACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clearcote",
3
- "version": "0.38.1",
3
+ "version": "0.40.0",
4
4
  "description": "Playwright drop-in for the Clearcote anti-fingerprint Chromium build. launch() returns a standard Playwright Browser backed by the verified Clearcote binary, which is auto-downloaded and SHA-256 checked.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",