@demigodmode/pi-web-agent 1.6.1 → 1.6.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/CHANGELOG.md CHANGED
@@ -18,6 +18,19 @@ The format is intentionally simple and release-oriented.
18
18
  ### Breaking
19
19
  - None.
20
20
 
21
+ ## [1.6.2] - 2026-07-10
22
+ ### Added
23
+ - None.
24
+
25
+ ### Changed
26
+ - None.
27
+
28
+ ### Fixed
29
+ - Extension load failure on install (`Cannot find module 'punycode/'` / `Set operation called on non-Set object`) caused by pi's extension loader mishandling a couple of patterns in jsdom's dependency tree (tr46, cssstyle). Added a postinstall step that patches the affected files. Fixes #34
30
+
31
+ ### Breaking
32
+ - None.
33
+
21
34
  ## [1.6.1] - 2026-07-05
22
35
  ### Added
23
36
  - None.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@demigodmode/pi-web-agent",
3
- "version": "1.6.1",
3
+ "version": "1.6.2",
4
4
  "description": "Pi package for reliable web access with explicit search, fetch, and headless boundaries.",
5
5
  "type": "module",
6
6
  "main": "./dist/extension.js",
@@ -13,6 +13,7 @@
13
13
  },
14
14
  "files": [
15
15
  "dist",
16
+ "scripts/patch-jiti-compat.mjs",
16
17
  "README.md",
17
18
  "CHANGELOG.md"
18
19
  ],
@@ -41,6 +42,7 @@
41
42
  "access": "public"
42
43
  },
43
44
  "scripts": {
45
+ "postinstall": "node scripts/patch-jiti-compat.mjs",
44
46
  "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.build.json",
45
47
  "build:dev": "tsc -p tsconfig.json",
46
48
  "test": "vitest run --coverage",
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ // Works around two incompatibilities between pi's extension loader (a patched
3
+ // jiti) and jsdom's dependency tree:
4
+ // 1. jiti can't resolve the trailing-slash bare specifier require("punycode/")
5
+ // used by tr46.
6
+ // 2. jiti wraps `module.exports = new Set(...)` (cssstyle) in a Proxy, which
7
+ // breaks native Set methods on the exported value.
8
+ //
9
+ // Runs as a postinstall step so it self-heals after every install, including
10
+ // when this package is installed as a pi extension via `pi install npm:...`.
11
+ // Safe to run multiple times and safe to no-op if the target files or
12
+ // patterns are missing (e.g. a future dependency bump changes the shape).
13
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
14
+ import { fileURLToPath } from "node:url";
15
+ import { dirname, join } from "node:path";
16
+
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+ const nodeModules = join(__dirname, "..", "node_modules");
19
+
20
+ function patchTr46() {
21
+ const file = join(nodeModules, "tr46", "index.js");
22
+ if (!existsSync(file)) {
23
+ console.debug("patch-jiti-compat: tr46/index.js not found, skipping");
24
+ return;
25
+ }
26
+ const contents = readFileSync(file, "utf8");
27
+ if (!contents.includes('require("punycode/")')) {
28
+ console.debug("patch-jiti-compat: tr46/index.js does not match expected pattern, skipping");
29
+ return;
30
+ }
31
+ writeFileSync(
32
+ file,
33
+ contents.replaceAll('require("punycode/")', 'require("punycode/punycode.js")'),
34
+ );
35
+ console.log("patch-jiti-compat: patched tr46/index.js");
36
+ }
37
+
38
+ const SET_SHIM = `
39
+ // pi/jiti workaround: expose bound native Set methods as own properties so a
40
+ // Proxy wrapper around this export does not break Set brand checks.
41
+ for (const k of ["has", "add", "delete", "forEach", "keys", "values", "entries"]) {
42
+ module.exports[k] = Set.prototype[k].bind(module.exports);
43
+ }
44
+ module.exports[Symbol.iterator] = Set.prototype[Symbol.iterator].bind(module.exports);
45
+ `;
46
+
47
+ function patchCssstyleSetExports() {
48
+ const files = [
49
+ join(nodeModules, "cssstyle", "lib", "allExtraProperties.js"),
50
+ join(nodeModules, "cssstyle", "lib", "generated", "allProperties.js"),
51
+ join(nodeModules, "cssstyle", "lib", "generated", "implementedProperties.js"),
52
+ ];
53
+ for (const file of files) {
54
+ const label = `cssstyle/${file.slice(nodeModules.length + 1)}`;
55
+ if (!existsSync(file)) {
56
+ console.debug(`patch-jiti-compat: ${label} not found, skipping`);
57
+ continue;
58
+ }
59
+ const contents = readFileSync(file, "utf8");
60
+ if (contents.includes("pi/jiti workaround")) continue;
61
+ if (!contents.includes("module.exports = new Set(")) {
62
+ console.debug(`patch-jiti-compat: ${label} does not match expected pattern, skipping`);
63
+ continue;
64
+ }
65
+ writeFileSync(file, contents + SET_SHIM);
66
+ console.log(`patch-jiti-compat: patched ${label}`);
67
+ }
68
+ }
69
+
70
+ try {
71
+ patchTr46();
72
+ patchCssstyleSetExports();
73
+ } catch (err) {
74
+ // Never fail the install over a best-effort compat patch.
75
+ console.warn("patch-jiti-compat: skipped, non-fatal error:", err.message);
76
+ }