specrails-desktop 2.11.4 → 2.11.5
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/package.json
CHANGED
|
@@ -120,6 +120,25 @@ function fastPathDirectories() {
|
|
|
120
120
|
}
|
|
121
121
|
return [];
|
|
122
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Well-known Windows directories that hold globally-installed CLI shims
|
|
125
|
+
* (`claude.cmd` / `codex.cmd` / `gemini.cmd`) which a GUI-launched (Explorer/
|
|
126
|
+
* Tauri) process may not have on its inherited PATH. The per-user npm prefix
|
|
127
|
+
* places `.cmd` shims DIRECTLY in the prefix root (`%APPDATA%\npm`), not a `bin`
|
|
128
|
+
* subdir. `npm prefix -g` is the authoritative location for a custom prefix.
|
|
129
|
+
*/
|
|
130
|
+
function windowsGlobalBinDirs() {
|
|
131
|
+
if (process.platform !== 'win32')
|
|
132
|
+
return [];
|
|
133
|
+
const dirs = [];
|
|
134
|
+
// Default per-user npm prefix: shims (`claude.cmd` …) live in the prefix ROOT.
|
|
135
|
+
if (process.env.APPDATA)
|
|
136
|
+
dirs.push(path_1.default.join(process.env.APPDATA, 'npm'));
|
|
137
|
+
// Machine-wide Node install (also where a machine-scope npm prefix points).
|
|
138
|
+
if (process.env.ProgramFiles)
|
|
139
|
+
dirs.push(path_1.default.join(process.env.ProgramFiles, 'nodejs'));
|
|
140
|
+
return dirs;
|
|
141
|
+
}
|
|
123
142
|
/**
|
|
124
143
|
* Returns the absolute path to the bundled runtimes directory.
|
|
125
144
|
* Only valid when SPECRAILS_IS_DESKTOP=1 and SPECRAILS_BUNDLED_RUNTIMES_PATH is set.
|
|
@@ -200,9 +219,26 @@ function resolveStartupPath() {
|
|
|
200
219
|
const inherited = splitPath(process.env.PATH);
|
|
201
220
|
const inheritedSet = new Set(inherited);
|
|
202
221
|
if (process.platform === 'win32') {
|
|
222
|
+
// Prepend well-known global-CLI dirs (npm prefix, Program Files\nodejs) that
|
|
223
|
+
// a GUI-launched process may lack, so provider shims (claude/codex/gemini
|
|
224
|
+
// .cmd) — and any RECURSIVE bare-name invocation by a spawned CLI — resolve.
|
|
225
|
+
// Existence-gated + deduped; no-op when already present (the common case).
|
|
226
|
+
const winPrepend = [];
|
|
227
|
+
for (const dir of windowsGlobalBinDirs()) {
|
|
228
|
+
if (dir && fileExists(dir) && !inheritedSet.has(dir)) {
|
|
229
|
+
winPrepend.push(dir);
|
|
230
|
+
inheritedSet.add(dir);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const winMerged = [...winPrepend, ...inherited];
|
|
234
|
+
if (winPrepend.length > 0)
|
|
235
|
+
process.env.PATH = joinPath(winMerged);
|
|
203
236
|
diagnostic = {
|
|
204
|
-
pathSegments:
|
|
205
|
-
pathSources:
|
|
237
|
+
pathSegments: winMerged,
|
|
238
|
+
pathSources: [
|
|
239
|
+
...winPrepend.map(() => 'fast-path'),
|
|
240
|
+
...inherited.map(() => 'inherited'),
|
|
241
|
+
],
|
|
206
242
|
loginShellStatus: 'skipped',
|
|
207
243
|
};
|
|
208
244
|
return;
|
|
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports._GEMINI_MIN_VERSION = exports.geminiAdapter = void 0;
|
|
30
30
|
exports._compareSemver = compareSemver;
|
|
31
31
|
const child_process_1 = require("child_process");
|
|
32
|
+
const win_spawn_1 = require("../util/win-spawn");
|
|
32
33
|
const gemini_agent_ack_1 = require("./gemini-agent-ack");
|
|
33
34
|
const WHICH_CMD = process.platform === 'win32' ? 'where' : 'which';
|
|
34
35
|
// Floor where `--output-format stream-json` + headless `--resume` are available.
|
|
@@ -180,16 +181,20 @@ function compareSemver(a, b) {
|
|
|
180
181
|
}
|
|
181
182
|
async function detectGeminiInstalled() {
|
|
182
183
|
try {
|
|
183
|
-
(0, child_process_1.execSync)(`${WHICH_CMD} gemini`, { stdio: 'ignore' });
|
|
184
|
+
(0, child_process_1.execSync)(`${WHICH_CMD} gemini`, { stdio: 'ignore', env: (0, win_spawn_1.windowsSpawnEnv)() });
|
|
184
185
|
}
|
|
185
186
|
catch {
|
|
186
187
|
return { installed: false, executable: false };
|
|
187
188
|
}
|
|
188
189
|
try {
|
|
190
|
+
// gemini is a Node CLI; its cold `--version` (cmd.exe → node → load bundle,
|
|
191
|
+
// Defender scanning) can exceed a few seconds on Windows. Give it a generous
|
|
192
|
+
// budget + SystemRoot env so it isn't wrongly reported not-executable.
|
|
189
193
|
const raw = (0, child_process_1.execSync)('gemini --version', {
|
|
190
194
|
encoding: 'utf-8',
|
|
191
195
|
stdio: ['pipe', 'pipe', 'ignore'],
|
|
192
|
-
timeout:
|
|
196
|
+
timeout: process.platform === 'win32' ? 20_000 : 8_000,
|
|
197
|
+
env: (0, win_spawn_1.windowsSpawnEnv)(),
|
|
193
198
|
}).trim();
|
|
194
199
|
const match = raw.match(/\d+\.\d+\.\d+/);
|
|
195
200
|
const version = match ? match[0] : raw;
|
|
@@ -28,13 +28,19 @@ const WHICH_CMD = process.platform === 'win32' ? 'where' : 'which';
|
|
|
28
28
|
* inherited a stripped env) — without it every bundled probe failed with a bogus
|
|
29
29
|
* "bundle corrupted — reinstall the app".
|
|
30
30
|
*/
|
|
31
|
-
function runVersionSpawn(cmd, args) {
|
|
32
|
-
const opts = { env: (0, win_spawn_1.windowsSpawnEnv)(), encoding: 'utf-8', timeout:
|
|
31
|
+
function runVersionSpawn(cmd, args, timeoutMs = 5_000) {
|
|
32
|
+
const opts = { env: (0, win_spawn_1.windowsSpawnEnv)(), encoding: 'utf-8', timeout: timeoutMs };
|
|
33
33
|
if (process.platform === 'win32') {
|
|
34
34
|
return cross_spawn_1.default.sync(cmd, args, opts);
|
|
35
35
|
}
|
|
36
36
|
return (0, child_process_1.spawnSync)(cmd, args, opts);
|
|
37
37
|
}
|
|
38
|
+
// A bundled/system CLI's `--version` cold start can be slow on Windows: a npm
|
|
39
|
+
// `.cmd` shim goes cmd.exe → node.exe → load the CLI bundle, while Defender
|
|
40
|
+
// scans it. The Node-based gemini CLI in particular exceeded the old 5s cap and
|
|
41
|
+
// was wrongly reported not-executable. Give version probes a generous Windows
|
|
42
|
+
// budget; the `where`/`which` LOCATE probe stays fast (5s) since it's a builtin.
|
|
43
|
+
const VERSION_PROBE_TIMEOUT_MS = process.platform === 'win32' ? 20_000 : 8_000;
|
|
38
44
|
exports.MIN_VERSIONS = {
|
|
39
45
|
node: '18.0.0',
|
|
40
46
|
npm: '9.0.0',
|
|
@@ -53,7 +59,7 @@ function locateCommand(command) {
|
|
|
53
59
|
}
|
|
54
60
|
/** Run `<bin> <args>` and interpret the result as a `--version` probe. */
|
|
55
61
|
function runProbe(bin, args) {
|
|
56
|
-
const result = runVersionSpawn(bin, args);
|
|
62
|
+
const result = runVersionSpawn(bin, args, VERSION_PROBE_TIMEOUT_MS);
|
|
57
63
|
if (result.error) {
|
|
58
64
|
const err = result.error;
|
|
59
65
|
return { executed: false, error: `${err.code ?? 'ERR'}: ${err.message}` };
|