edsger 0.37.0 → 0.37.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/dist/utils/validation.d.ts +2 -1
- package/dist/utils/validation.js +85 -20
- package/package.json +1 -1
|
@@ -22,7 +22,8 @@ export declare const validateMCPEnvironment: () => {
|
|
|
22
22
|
export declare const validateCommandEnvironment: (options: CliOptions) => ValidationResult;
|
|
23
23
|
/**
|
|
24
24
|
* Ensure Playwright is installed, auto-installing if necessary.
|
|
25
|
-
* Installs the npm package
|
|
25
|
+
* Installs the npm package where edsger's module resolution can find it,
|
|
26
|
+
* plus the Chromium browser binary.
|
|
26
27
|
*/
|
|
27
28
|
export declare const ensurePlaywright: (checkFunction: () => Promise<boolean>) => Promise<void>;
|
|
28
29
|
/**
|
package/dist/utils/validation.js
CHANGED
|
@@ -1,7 +1,44 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
1
|
+
import { execSync, spawnSync } from 'child_process';
|
|
2
|
+
import { dirname, resolve, sep } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
2
4
|
import { getMcpServerUrl, getMcpToken } from '../auth/auth-store.js';
|
|
3
5
|
import { loadConfig, validateConfig } from '../config.js';
|
|
4
6
|
import { logInfo, logWarning } from './logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Determine the correct npm install target for optional dependencies.
|
|
9
|
+
*
|
|
10
|
+
* `Function('return import("pkg")')()` resolves from the edsger module's
|
|
11
|
+
* own location, walking up the node_modules chain. We need to install
|
|
12
|
+
* packages into a directory that sits on that resolution path.
|
|
13
|
+
*
|
|
14
|
+
* - Global install → `npm install -g`
|
|
15
|
+
* - Project dependency → `npm install` in the project root
|
|
16
|
+
* - Monorepo / development → `npm install` in the edsger package dir
|
|
17
|
+
*/
|
|
18
|
+
function getNpmInstallTarget() {
|
|
19
|
+
const edsgerDir = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
|
|
20
|
+
const nodeModulesSegment = `${sep}node_modules${sep}`;
|
|
21
|
+
if (!edsgerDir.includes(nodeModulesSegment)) {
|
|
22
|
+
// Source checkout / monorepo — install in edsger's own package dir
|
|
23
|
+
return { global: false, cwd: edsgerDir };
|
|
24
|
+
}
|
|
25
|
+
// edsger is inside some node_modules tree
|
|
26
|
+
try {
|
|
27
|
+
const globalPrefix = execSync('npm config get prefix', {
|
|
28
|
+
encoding: 'utf-8',
|
|
29
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
30
|
+
}).trim();
|
|
31
|
+
if (edsgerDir.startsWith(globalPrefix)) {
|
|
32
|
+
return { global: true };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// ignore — fall through to project-local
|
|
37
|
+
}
|
|
38
|
+
// Project dependency — install at the project root (parent of node_modules)
|
|
39
|
+
const projectRoot = edsgerDir.split(nodeModulesSegment)[0];
|
|
40
|
+
return { global: false, cwd: projectRoot };
|
|
41
|
+
}
|
|
5
42
|
/**
|
|
6
43
|
* Common configuration validation for all CLI commands
|
|
7
44
|
*/
|
|
@@ -49,18 +86,50 @@ export const validateCommandEnvironment = (options) => {
|
|
|
49
86
|
mcpToken,
|
|
50
87
|
};
|
|
51
88
|
};
|
|
89
|
+
/**
|
|
90
|
+
* Re-exec the current CLI command in a fresh process.
|
|
91
|
+
* Node.js caches failed module resolutions for the lifetime of a process,
|
|
92
|
+
* so after installing a new package we must restart to pick it up.
|
|
93
|
+
* An env flag prevents infinite restart loops.
|
|
94
|
+
*/
|
|
95
|
+
const restartProcess = (envFlag) => {
|
|
96
|
+
const result = spawnSync(process.argv[0], process.argv.slice(1), {
|
|
97
|
+
stdio: 'inherit',
|
|
98
|
+
env: { ...process.env, [envFlag]: '1' },
|
|
99
|
+
});
|
|
100
|
+
return process.exit(result.status ?? 1);
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Run `npm install <pkg>` targeting the correct location for edsger's
|
|
104
|
+
* module resolution chain.
|
|
105
|
+
*/
|
|
106
|
+
function npmInstall(packageName) {
|
|
107
|
+
const target = getNpmInstallTarget();
|
|
108
|
+
const globalFlag = target.global ? ' -g' : '';
|
|
109
|
+
const cmd = `npm install${globalFlag} ${packageName}`;
|
|
110
|
+
logInfo(` $ ${cmd}${target.cwd ? ` (in ${target.cwd})` : ''}`);
|
|
111
|
+
execSync(cmd, { cwd: target.cwd, stdio: 'inherit' });
|
|
112
|
+
}
|
|
52
113
|
/**
|
|
53
114
|
* Ensure Playwright is installed, auto-installing if necessary.
|
|
54
|
-
* Installs the npm package
|
|
115
|
+
* Installs the npm package where edsger's module resolution can find it,
|
|
116
|
+
* plus the Chromium browser binary.
|
|
55
117
|
*/
|
|
56
118
|
export const ensurePlaywright = async (checkFunction) => {
|
|
57
119
|
if (await checkFunction()) {
|
|
58
120
|
return;
|
|
59
121
|
}
|
|
122
|
+
// Already attempted install in a previous run — don't loop
|
|
123
|
+
if (process.env.__EDSGER_PW_INSTALLED) {
|
|
124
|
+
throw new Error('Playwright auto-install succeeded but it is still not loadable.\n\n' +
|
|
125
|
+
' Please install it manually:\n\n' +
|
|
126
|
+
' npm install playwright\n' +
|
|
127
|
+
' npx playwright install chromium\n\n' +
|
|
128
|
+
' Then re-run this command. Use --listings-only to skip screenshots.');
|
|
129
|
+
}
|
|
60
130
|
logWarning('Playwright is not installed. Installing automatically (this may take a minute)...');
|
|
61
131
|
try {
|
|
62
|
-
|
|
63
|
-
execSync('npm install playwright', { stdio: 'inherit' });
|
|
132
|
+
npmInstall('playwright');
|
|
64
133
|
logInfo(' Installing Chromium browser...');
|
|
65
134
|
execSync('npx playwright install chromium', { stdio: 'inherit' });
|
|
66
135
|
}
|
|
@@ -71,15 +140,8 @@ export const ensurePlaywright = async (checkFunction) => {
|
|
|
71
140
|
' npx playwright install chromium\n\n' +
|
|
72
141
|
' Then re-run this command. Use --listings-only to skip screenshots.');
|
|
73
142
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
throw new Error('Playwright was installed but is still not available.\n\n' +
|
|
77
|
-
' Try installing manually:\n\n' +
|
|
78
|
-
' npm install playwright\n' +
|
|
79
|
-
' npx playwright install chromium\n\n' +
|
|
80
|
-
' Then re-run this command. Use --listings-only to skip screenshots.');
|
|
81
|
-
}
|
|
82
|
-
logInfo(' Playwright installed successfully!');
|
|
143
|
+
logInfo(' Playwright installed successfully! Restarting command...\n');
|
|
144
|
+
restartProcess('__EDSGER_PW_INSTALLED');
|
|
83
145
|
};
|
|
84
146
|
/**
|
|
85
147
|
* Ensure an npm package is installed, auto-installing if necessary.
|
|
@@ -88,21 +150,24 @@ export const ensureNpmPackage = async (checkFunction, packageName) => {
|
|
|
88
150
|
if (await checkFunction()) {
|
|
89
151
|
return;
|
|
90
152
|
}
|
|
153
|
+
const envFlag = `__EDSGER_PKG_${packageName.replace(/[^a-zA-Z0-9]/g, '_').toUpperCase()}`;
|
|
154
|
+
// Already attempted install in a previous run — don't loop
|
|
155
|
+
if (process.env[envFlag]) {
|
|
156
|
+
throw new Error(`${packageName} auto-install succeeded but it is still not loadable.\n\n` +
|
|
157
|
+
` Please install it manually:\n\n` +
|
|
158
|
+
` npm install ${packageName}`);
|
|
159
|
+
}
|
|
91
160
|
logWarning(`${packageName} is not installed. Installing automatically...`);
|
|
92
161
|
try {
|
|
93
|
-
|
|
162
|
+
npmInstall(packageName);
|
|
94
163
|
}
|
|
95
164
|
catch {
|
|
96
165
|
throw new Error(`Failed to auto-install ${packageName}.\n\n` +
|
|
97
166
|
` Please install it manually:\n\n` +
|
|
98
167
|
` npm install ${packageName}`);
|
|
99
168
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
` Try installing manually:\n\n` +
|
|
103
|
-
` npm install ${packageName}`);
|
|
104
|
-
}
|
|
105
|
-
logInfo(` ${packageName} installed successfully!`);
|
|
169
|
+
logInfo(` ${packageName} installed successfully! Restarting command...\n`);
|
|
170
|
+
restartProcess(envFlag);
|
|
106
171
|
};
|
|
107
172
|
/**
|
|
108
173
|
* Ensure ffmpeg is installed, auto-installing via Homebrew on macOS if possible.
|