@lincoln504/pi-research 1.7.8 → 1.7.10
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 +5 -1
- package/agent-skill/pi-research/README.md +3 -3
- package/agent-skill/pi-research/SKILL.md +1 -1
- package/dist/cli-bin.mjs +3 -0
- package/dist/cli.mjs +673 -383
- package/dist/pdf-extract-worker.mjs +1 -1
- package/dist/thread-worker.mjs +6 -6
- package/docs/AGENT-SKILL.md +6 -4
- package/docs/ARCHITECTURE.md +64 -50
- package/docs/CHANGELOG.md +41 -0
- package/docs/CONFIGURATION.md +2 -2
- package/docs/PI-EXTENSION.md +4 -0
- package/docs/SDK.md +10 -7
- package/docs/THIRD-PARTY-NOTICES.md +11 -7
- package/package.json +10 -8
- package/scripts/camoufox-layout.cjs +455 -0
- package/scripts/cleanup.cjs +72 -29
- package/scripts/setup.cjs +73 -111
- package/src/cli-bin.mjs +3 -0
- package/src/cli.ts +12 -13
- package/src/core/pi-version.ts +9 -1
- package/src/healthcheck/index.ts +1 -1
- package/src/infrastructure/browser/browser-cleanup.ts +1 -1
- package/src/infrastructure/browser/browser-error-utils.ts +5 -4
- package/src/infrastructure/browser/camoufox-layout.ts +450 -0
- package/src/infrastructure/browser/config.ts +46 -103
- package/src/infrastructure/browser/ensure-browser.ts +90 -52
- package/src/infrastructure/browser/thread-worker-browser.ts +38 -42
- package/src/infrastructure/browser/thread-worker.mjs +6 -6
- package/src/infrastructure/knowledge-store-service.ts +6 -6
- package/src/orchestration/researcher-executor.ts +47 -1
- package/src/tui/research-health.ts +1 -1
- package/src/utils/log-utils.ts +1 -1
- package/src/web-research/browser-search.ts +8 -10
- package/src/web-research/pdf-extract-worker.mjs +1 -1
- package/src/web-research/scraper-utils.ts +11 -2
- package/src/web-research/web-scraper.ts +1 -1
package/scripts/setup.cjs
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
* of hiding behind the graceful path.
|
|
13
13
|
*
|
|
14
14
|
* Environment:
|
|
15
|
-
* PLAYWRIGHT_BROWSERS_PATH
|
|
15
|
+
* CAMOUFOX_INSTALL_DIR / PLAYWRIGHT_BROWSERS_PATH - relocate the browser cache (Linux: XDG_CACHE_HOME,
|
|
16
|
+
* Windows: LOCALAPPDATA; ignored on macOS)
|
|
16
17
|
* PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 - skip download entirely
|
|
17
18
|
* PLAYWRIGHT_INSTALL_DEPS=true - also install Linux system deps (or pass --system-deps)
|
|
18
19
|
*/
|
|
@@ -26,7 +27,6 @@ const path = require('path');
|
|
|
26
27
|
const projectRoot = path.join(__dirname, '..');
|
|
27
28
|
|
|
28
29
|
const isLinux = process.platform === 'linux';
|
|
29
|
-
const isDarwin = process.platform === 'darwin';
|
|
30
30
|
const isWindows = process.platform === 'win32';
|
|
31
31
|
|
|
32
32
|
const [nodeMajor, nodeMinor, nodePatch] = process.version.replace('v', '').split('.').map((n) => parseInt(n, 10));
|
|
@@ -37,73 +37,55 @@ if (belowMinimum) {
|
|
|
37
37
|
console.warn(`WARNING: Node.js ${process.version} is below the minimum (>=22.22.2). Upgrade to 22.22.2+.`);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
const layout = require('./camoufox-layout.cjs');
|
|
41
|
+
|
|
40
42
|
/**
|
|
41
|
-
* Resolve the camoufox
|
|
43
|
+
* Resolve the `camoufox` CLI entry of @camoufox/camoufox.
|
|
42
44
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
45
|
+
* Dependencies are hoisted, so the package's own node_modules may be empty:
|
|
46
|
+
* require.resolve finds the real location. We run the CLI's JS entry with
|
|
47
|
+
* process.execPath instead of the .bin shim: no .cmd quoting on Windows, no
|
|
48
|
+
* shell, and an argv array that cannot be reinterpreted.
|
|
46
49
|
*/
|
|
47
|
-
function
|
|
50
|
+
function resolveCamoufoxCli() {
|
|
48
51
|
try {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
const pkgJson = require.resolve('@camoufox/camoufox/package.json', { paths: [projectRoot] });
|
|
53
|
+
const pkg = require(pkgJson);
|
|
54
|
+
const rel = typeof pkg.bin === 'string' ? pkg.bin : pkg.bin && pkg.bin.camoufox;
|
|
55
|
+
if (rel) {
|
|
56
|
+
const entry = path.join(path.dirname(pkgJson), rel);
|
|
57
|
+
if (existsSync(entry)) return entry;
|
|
58
|
+
}
|
|
55
59
|
} catch (_) { /* fall through */ }
|
|
56
60
|
return null;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
/**
|
|
60
|
-
* The custom camoufox location, if the user set one. Mirrors
|
|
61
|
-
* getCustomCamoufoxDir() in src/infrastructure/browser/config.ts — the two must
|
|
62
|
-
* agree or install and lookup land in different directories.
|
|
63
|
-
*
|
|
64
|
-
* CAMOUFOX_INSTALL_DIR first: it is camoufox-js's own variable and the only one
|
|
65
|
-
* that can relocate the install (camoufox-js <0.12.0 hardcoded
|
|
66
|
-
* userCacheDir("camoufox") and honoured nothing — inert there; effective on the
|
|
67
|
-
* 0.12.0+ refresh). PLAYWRIGHT_BROWSERS_PATH is kept as the documented alias
|
|
68
|
-
* and is exported BELOW as CAMOUFOX_INSTALL_DIR. See
|
|
69
|
-
* src/infrastructure/browser/config.ts and thread-worker-browser.ts.
|
|
70
|
-
*/
|
|
71
|
-
function customCamoufoxDir() {
|
|
72
|
-
return process.env.CAMOUFOX_INSTALL_DIR || process.env.PLAYWRIGHT_BROWSERS_PATH || null;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function camoufoxCachePath() {
|
|
76
|
-
const customPath = customCamoufoxDir();
|
|
77
|
-
if (customPath) return customPath;
|
|
78
|
-
|
|
79
|
-
if (isWindows) {
|
|
80
|
-
// Mirror camoufox-js userCacheDir("camoufox") exactly: homedir-based with a
|
|
81
|
-
// DOUBLED "camoufox" segment. Must match src getWindowsCamoufoxDir().
|
|
82
|
-
return path.join(homedir(), 'AppData', 'Local', 'camoufox', 'camoufox', 'Cache');
|
|
83
|
-
}
|
|
84
|
-
if (isDarwin) return path.join(homedir(), 'Library', 'Caches', 'camoufox');
|
|
85
|
-
|
|
86
|
-
const cacheHome = process.env.XDG_CACHE_HOME || path.join(homedir(), '.cache');
|
|
87
|
-
return path.join(cacheHome, 'camoufox');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
63
|
let browsersInstalled = false;
|
|
91
64
|
// Set when a fetch cannot possibly succeed (an unusable configured install dir),
|
|
92
65
|
// so the download is skipped rather than run to completion and then fail. Kept
|
|
93
66
|
// separate from browsersInstalled so the summary below still tells the truth.
|
|
94
67
|
let fetchSkipped = false;
|
|
95
68
|
|
|
69
|
+
// @camoufox/camoufox derives its install dir ONLY from the platform cache location
|
|
70
|
+
// and ignores CAMOUFOX_INSTALL_DIR / PLAYWRIGHT_BROWSERS_PATH. The layout module turns
|
|
71
|
+
// a user's custom dir into the variable it does read (XDG_CACHE_HOME / LOCALAPPDATA).
|
|
72
|
+
// The same function runs at runtime (src/infrastructure/browser/config.ts), so the
|
|
73
|
+
// install and the lookup cannot disagree.
|
|
74
|
+
const install = layout.resolveInstall(process.env, process.platform, homedir());
|
|
75
|
+
const cachePath = install.dir;
|
|
76
|
+
if (install.ignoredCustom) {
|
|
77
|
+
console.warn(
|
|
78
|
+
`pi-research: CAMOUFOX_INSTALL_DIR / PLAYWRIGHT_BROWSERS_PATH (${install.custom}) is ignored on macOS: ` +
|
|
79
|
+
`the Camoufox launcher always uses ${cachePath} and cannot be relocated without moving HOME.`,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
96
83
|
if (process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD === '1') {
|
|
97
84
|
console.log('pi-research: skipping browser download (PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1)');
|
|
98
85
|
} else {
|
|
99
|
-
const env = { ...process.env };
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
// custom one: the "already installed" probe never matched, every install
|
|
103
|
-
// re-fetched, and at runtime the browser was reported missing despite having
|
|
104
|
-
// downloaded successfully.
|
|
105
|
-
const customDir = customCamoufoxDir();
|
|
106
|
-
if (customDir) env.CAMOUFOX_INSTALL_DIR = customDir;
|
|
86
|
+
const env = { ...process.env, ...install.overrides };
|
|
87
|
+
delete env.CAMOUFOX_INSTALL_DIR;
|
|
88
|
+
delete env.PLAYWRIGHT_BROWSERS_PATH;
|
|
107
89
|
|
|
108
90
|
const installDeps = process.argv.includes('--system-deps') || process.env.PLAYWRIGHT_INSTALL_DEPS === 'true';
|
|
109
91
|
if (installDeps && isLinux) {
|
|
@@ -122,62 +104,44 @@ if (process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD === '1') {
|
|
|
122
104
|
}
|
|
123
105
|
}
|
|
124
106
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
107
|
+
// A configured install dir whose parent exists but cannot be used as a directory (a
|
|
108
|
+
// plain file, a broken mount) makes the fetch impossible: it would download the whole
|
|
109
|
+
// ~1.3GB archive and then fail to place it. Report and skip instead.
|
|
110
|
+
if (install.custom && existsSync(install.custom)) {
|
|
128
111
|
try {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
alreadyInstalled = true;
|
|
132
|
-
console.log(`pi-research: Camoufox already installed at ${cachePath}. Skipping fetch.`);
|
|
133
|
-
}
|
|
112
|
+
if (!statSync(install.custom).isDirectory()) throw new Error('not a directory');
|
|
113
|
+
readdirSync(install.custom);
|
|
134
114
|
} catch (e) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
// fails to place it. Report and skip instead, which is what the user's
|
|
139
|
-
// install needs either way (the catch further down exits 0, and the
|
|
140
|
-
// browser is re-fetchable once the path is usable).
|
|
141
|
-
console.warn(`pi-research: cannot use the browser install directory ${cachePath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
142
|
-
if (customCamoufoxDir()) {
|
|
143
|
-
console.warn('pi-research: skipping the browser fetch because CAMOUFOX_INSTALL_DIR / PLAYWRIGHT_BROWSERS_PATH points at a path that is not a usable directory. Fix or unset it, then run: npx camoufox-js fetch');
|
|
144
|
-
fetchSkipped = true;
|
|
145
|
-
}
|
|
115
|
+
console.warn(`pi-research: cannot use the browser install directory ${install.custom}: ${e instanceof Error ? e.message : String(e)}`);
|
|
116
|
+
console.warn('pi-research: skipping the browser fetch because CAMOUFOX_INSTALL_DIR / PLAYWRIGHT_BROWSERS_PATH points at a path that is not a usable directory. Fix or unset it, then run: npx camoufox fetch');
|
|
117
|
+
fetchSkipped = true;
|
|
146
118
|
}
|
|
147
119
|
}
|
|
148
120
|
|
|
149
|
-
if (fetchSkipped) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
// Bound the ~500MB camoufox-js 0.12 browser download (was ~100MB on the
|
|
162
|
-
// 0.10 pin — the old 15-minute bound could kill a download that would
|
|
163
|
-
// have succeeded on a slow link) so a stalled/interrupted network fails
|
|
164
|
-
// eventually instead of hanging `npm install` forever (the catch below
|
|
165
|
-
// exits 0, and the browser is re-fetchable manually). 45 min covers a
|
|
166
|
-
// working link down to ~180 KB/s; a dead link aborts on its own sooner.
|
|
167
|
-
const spawnOpts = { stdio: 'inherit', env, timeout: 45 * 60 * 1000 };
|
|
168
|
-
const res = bin
|
|
169
|
-
? (isWindows
|
|
170
|
-
? spawnSync(`"${bin}"`, ['fetch'], { ...spawnOpts, shell: true })
|
|
171
|
-
: spawnSync(bin, ['fetch'], spawnOpts))
|
|
172
|
-
: spawnSync('npx', ['camoufox-js', 'fetch'], { ...spawnOpts, shell: isWindows });
|
|
121
|
+
if (!fetchSkipped) {
|
|
122
|
+
const cli = resolveCamoufoxCli();
|
|
123
|
+
// The fetch runs through process.execPath with an ARGV ARRAY, never a shell string:
|
|
124
|
+
// `cli` is a filesystem path derived from the install directory, and a shell string
|
|
125
|
+
// would let a directory name containing `$(…)` execute at install time. The runtime
|
|
126
|
+
// twin in ensure-browser.ts uses the same shape.
|
|
127
|
+
// Bound the ~1.3GB browser download so a stalled network fails eventually instead of
|
|
128
|
+
// hanging `npm install` forever (the failure path below exits 0 and the browser is
|
|
129
|
+
// re-fetchable). 45 min covers a working link down to ~500 KB/s.
|
|
130
|
+
const runFetch = () => {
|
|
131
|
+
if (!cli) throw new Error('@camoufox/camoufox is not installed (cannot find its CLI)');
|
|
132
|
+
const res = spawnSync(process.execPath, [cli, 'fetch'], { stdio: 'inherit', env, timeout: 45 * 60 * 1000 });
|
|
173
133
|
if (res.error) throw res.error;
|
|
174
134
|
if (res.status !== 0) throw new Error(`camoufox fetch exited with code ${res.status}`);
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
135
|
+
return true;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
console.log('pi-research: downloading the ~1.3 GB Camoufox browser — this can take several minutes on a slow link…');
|
|
139
|
+
const pkgRoot = layout.findPackageRoot(projectRoot);
|
|
140
|
+
const result = layout.provisionBrowser(cachePath, runFetch, (m) => console.log(m), pkgRoot ? layout.loadPin(pkgRoot) : null);
|
|
141
|
+
if (result.status === 'failed') {
|
|
178
142
|
console.error('ERROR: Camoufox browser install failed — pi-research will not work.');
|
|
179
|
-
console.error('Run manually to fix: npx camoufox
|
|
180
|
-
console.error(`Reason: ${
|
|
143
|
+
console.error('Run manually to fix: npx camoufox fetch');
|
|
144
|
+
console.error(`Reason: ${result.reason}`);
|
|
181
145
|
// Exit 0 by default: the browser is fetched lazily on first use, so a restrictive
|
|
182
146
|
// network must not fail a user's install. But that also meant nothing here could
|
|
183
147
|
// ever turn CI red — a broken Windows launcher yielded a green `npm ci`. CI sets
|
|
@@ -187,23 +151,21 @@ if (process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD === '1') {
|
|
|
187
151
|
process.env.PI_RESEARCH_STRICT_SETUP === 'true';
|
|
188
152
|
process.exit(strict ? 1 : 0);
|
|
189
153
|
}
|
|
190
|
-
} else {
|
|
191
154
|
browsersInstalled = true;
|
|
155
|
+
if (result.status === 'present') {
|
|
156
|
+
console.log(`pi-research: Camoufox already installed at ${cachePath}. Skipping fetch.`);
|
|
157
|
+
}
|
|
192
158
|
}
|
|
193
159
|
}
|
|
194
160
|
|
|
195
161
|
// Verify
|
|
196
|
-
const cachePath = camoufoxCachePath();
|
|
197
162
|
if (existsSync(cachePath)) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
// broken CAMOUFOX_INSTALL_DIR turned into a mysterious "browser missing at
|
|
205
|
-
// runtime" much later. The fetch path above already printed the remedy.
|
|
206
|
-
console.warn(`pi-research: camoufox install path ${cachePath} could not be verified: ${e instanceof Error ? e.message : String(e)}`);
|
|
163
|
+
const builds = layout.listInstalls(cachePath).map((b) => b.name);
|
|
164
|
+
const pkgRootForVerify = layout.findPackageRoot(projectRoot);
|
|
165
|
+
if (builds.length > 0 && layout.isUsable(cachePath, pkgRootForVerify ? layout.loadPin(pkgRootForVerify) : null)) {
|
|
166
|
+
console.log(`pi-research: camoufox ready (${builds.join(', ')})`);
|
|
167
|
+
} else if (browsersInstalled) {
|
|
168
|
+
console.warn(`pi-research: camoufox install at ${cachePath} could not be verified (no usable browser build found)`);
|
|
207
169
|
}
|
|
208
170
|
} else if (browsersInstalled) {
|
|
209
171
|
console.warn(`pi-research: camoufox binary not found at expected path ${cachePath}`);
|
package/src/cli-bin.mjs
CHANGED
|
@@ -43,6 +43,9 @@ const REQUIRED_PEERS = [
|
|
|
43
43
|
// dist/cli.mjs imports it directly (TUI width helpers), so an install that skips
|
|
44
44
|
// peers can lack it even though pi-coding-agent normally brings it in.
|
|
45
45
|
'@earendil-works/pi-tui',
|
|
46
|
+
// Host-provided too (peerDependency since 1.7.9): dist/cli.mjs imports it for
|
|
47
|
+
// every tool schema, and pi supplies its own copy when it loads the extension.
|
|
48
|
+
'typebox',
|
|
46
49
|
];
|
|
47
50
|
|
|
48
51
|
/**
|
package/src/cli.ts
CHANGED
|
@@ -818,10 +818,11 @@ async function cmdStatus(json?: boolean): Promise<number> {
|
|
|
818
818
|
// anything.
|
|
819
819
|
//
|
|
820
820
|
// The browser's NATIVE DEPENDENCIES are a separate and harsher question, and were
|
|
821
|
-
// previously assumed away here with "nothing else fails".
|
|
822
|
-
//
|
|
823
|
-
//
|
|
824
|
-
//
|
|
821
|
+
// previously assumed away here with "nothing else fails". The launcher's native
|
|
822
|
+
// module (`impit`) resolves a prebuilt platform package; if npm drops it (npm/cli#4828)
|
|
823
|
+
// the module fails at first use. (Historically this was better-sqlite3, a dependency
|
|
824
|
+
// of the camoufox-js launcher this package replaced with @camoufox/camoufox.)
|
|
825
|
+
// When it is missing every browser worker dies and SEARCH IS DEAD — not degraded — while the knowledge store keeps
|
|
825
826
|
// working because onnxruntime and lancedb both ship their binaries. That is not a
|
|
826
827
|
// capability note, so it gates `ready`: a build that cannot search cannot research.
|
|
827
828
|
const browserInstalled = isBrowserAvailable();
|
|
@@ -843,17 +844,14 @@ async function cmdStatus(json?: boolean): Promise<number> {
|
|
|
843
844
|
installed: browserInstalled,
|
|
844
845
|
nativeDepsOk: nativeDeps.ok,
|
|
845
846
|
nativeDepsError: nativeDeps.ok ? null : nativeDeps.error,
|
|
846
|
-
//
|
|
847
|
-
//
|
|
848
|
-
//
|
|
849
|
-
// binding.gyp-without-install-script triggers is skipped, so a missing
|
|
850
|
-
// binding here means an old/broken install, not an approval problem:
|
|
851
|
-
// point at the upgrade that fixes it.
|
|
847
|
+
// impit ships its binding as a per-platform optional package, no install script
|
|
848
|
+
// involved: a missing binding means npm dropped that package, and a reinstall
|
|
849
|
+
// restores it.
|
|
852
850
|
nativeDepsFix: nativeDeps.ok
|
|
853
851
|
? null
|
|
854
|
-
: '
|
|
852
|
+
: 'Reinstall @lincoln504/pi-research (npm install). The browser launcher\'s native module (impit) ships as a separate platform package that npm sometimes drops (npm/cli#4828); a fresh install restores it.',
|
|
855
853
|
// Same remedy the health check prints, so both surfaces name one command.
|
|
856
|
-
fix: browserInstalled ? null : 'npx camoufox
|
|
854
|
+
fix: browserInstalled ? null : 'npx camoufox fetch',
|
|
857
855
|
note: browserInstalled
|
|
858
856
|
? null
|
|
859
857
|
: 'Stealth browser not installed — scraping falls back to plain fetch, which some sites block. npm 12 blocks install scripts by default, which skips this package\'s postinstall; the engine is fetched on first use instead.',
|
|
@@ -1384,7 +1382,8 @@ COMMANDS
|
|
|
1384
1382
|
state tree (<config dir>/research/state) and the cache, including
|
|
1385
1383
|
downloaded embedding models. Keeps config.env and the knowledge
|
|
1386
1384
|
store database. --purge-browsers also deletes the shared
|
|
1387
|
-
stealth-browser cache (~/.cache/camoufox
|
|
1385
|
+
stealth-browser cache (~/.cache/camoufox, every installed
|
|
1386
|
+
browser build) other tools use.
|
|
1388
1387
|
|
|
1389
1388
|
help, --help, -h Show this help.
|
|
1390
1389
|
--version, -v Print the pi-research version.
|
package/src/core/pi-version.ts
CHANGED
|
@@ -122,8 +122,16 @@ export const PI_MIN_VERSION: SemverParts = { major: 0, minor: 99, patch: 0 };
|
|
|
122
122
|
* modes), the `builtin:<name>` naming for built-in extensions and tools, and
|
|
123
123
|
* `--no-extensions` now also disabling the built-in extensions. None of them
|
|
124
124
|
* change what this package does.
|
|
125
|
+
*
|
|
126
|
+
* 1.1.0 (2026-10-07) is additive for this package. Diffed against 1.0.4 on 2026-10-08:
|
|
127
|
+
* `@earendil-works/pi-coding-agent` adds `durationMs` on the tool render context and
|
|
128
|
+
* `tool_execution_end`, `aborted` on `agent_settled` events, and the `+name`/`-name`
|
|
129
|
+
* tool modifiers; `@earendil-works/pi-ai` adds the Decisions-API classifier surface
|
|
130
|
+
* and an optional `AuthProvider.agentName`; `@earendil-works/pi-tui` adds the OSC 7501
|
|
131
|
+
* program-status helpers and `Text.setPaddingX`. `docs/extensions.md` is unchanged,
|
|
132
|
+
* and nothing was removed or re-signed, so the 0.99.0 floor is unchanged too.
|
|
125
133
|
*/
|
|
126
|
-
export const PI_TESTED_MAX_VERSION: SemverParts = { major: 1, minor:
|
|
134
|
+
export const PI_TESTED_MAX_VERSION: SemverParts = { major: 1, minor: 1, patch: 0 };
|
|
127
135
|
|
|
128
136
|
export type PiCompatibilityLevel = 'ok' | 'unparseable' | 'too-old' | 'untested';
|
|
129
137
|
|
package/src/healthcheck/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ export async function checkBrowserCapability(): Promise<{ healthy: boolean; erro
|
|
|
41
41
|
}
|
|
42
42
|
return { healthy: true, diagnostic: { status: mockMode ? 'mocked' : 'available' } };
|
|
43
43
|
} else {
|
|
44
|
-
return { healthy: false, error: 'Camoufox (browser) not found. Run "npx camoufox
|
|
44
|
+
return { healthy: false, error: 'Camoufox (browser) not found. Run "npx camoufox fetch" to install the browser.' };
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -42,7 +42,7 @@ export async function cleanupOrphanedCamoufoxProcesses(): Promise<void> {
|
|
|
42
42
|
* Marker that identifies a browser process as one WE launched (Camoufox via
|
|
43
43
|
* Playwright), never the user's own system Firefox. We match on the launched
|
|
44
44
|
* EXECUTABLE — `camoufox-bin` (Linux), `camoufox.exe` (Windows) or
|
|
45
|
-
* `…/MacOS/camoufox` (macOS), per camoufox
|
|
45
|
+
* `…/MacOS/camoufox` (macOS), per @camoufox/camoufox's LAUNCH_FILE — plus our
|
|
46
46
|
* `…/pi-research/profiles/…` profile path (the fallback when PI_RESEARCH_TMP_DIR
|
|
47
47
|
* relocates profiles). Anchoring on the executable name (rather than a bare
|
|
48
48
|
* `camoufox` substring) keeps an incidental `tail camoufox.log`, `grep camoufox`,
|
|
@@ -129,10 +129,11 @@ export function isPoolShutdownError(error: unknown): boolean {
|
|
|
129
129
|
* anything about the page, the network or the load on the machine.
|
|
130
130
|
*
|
|
131
131
|
* The case that produced this: npm 12 turns `allowScripts` OFF by default, so a
|
|
132
|
-
* plain `npm install` no longer runs dependency lifecycle scripts
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
132
|
+
* plain `npm install` no longer runs dependency lifecycle scripts, and npm can drop a
|
|
133
|
+
* native dependency's platform package (npm/cli#4828). Historically this was
|
|
134
|
+
* `better-sqlite3` (a dependency of the old `camoufox-js` launcher; the launcher is now
|
|
135
|
+
* `@camoufox/camoufox`, whose native module is `impit`). Every browser worker then dies
|
|
136
|
+
* with "Could not locate the bindings file", every query fails, and the run reported that DuckDuckGo might be
|
|
136
137
|
* unreachable or the machine under extreme load. Neither was true, and the advice
|
|
137
138
|
* that follows from each is useless. An install fault has to say so.
|
|
138
139
|
*/
|