unity-mcp-cli 0.69.1 → 0.71.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.
- package/README.md +14 -1
- package/dist/commands/open.d.ts +20 -10
- package/dist/commands/open.js +224 -117
- package/dist/commands/open.js.map +1 -1
- package/dist/lib/open.d.ts +97 -0
- package/dist/lib/open.js +461 -0
- package/dist/lib/open.js.map +1 -0
- package/dist/lib/types.d.ts +191 -0
- package/dist/lib.d.ts +2 -1
- package/dist/lib.js +1 -0
- package/dist/lib.js.map +1 -1
- package/dist/utils/launch-error-dismiss.d.ts +159 -0
- package/dist/utils/launch-error-dismiss.js +440 -0
- package/dist/utils/launch-error-dismiss.js.map +1 -0
- package/dist/utils/unity-editor.d.ts +17 -3
- package/dist/utils/unity-editor.js +47 -11
- package/dist/utils/unity-editor.js.map +1 -1
- package/dist/utils/unity-hub.js +20 -4
- package/dist/utils/unity-hub.js.map +1 -1
- package/package.json +1 -1
package/dist/lib/open.js
ADDED
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { platform as nodePlatform } from 'os';
|
|
4
|
+
import { findEditorPath, getProjectEditorVersion, launchEditor, } from '../utils/unity-editor.js';
|
|
5
|
+
import { findUnityProcess } from '../utils/unity-process.js';
|
|
6
|
+
import { readConfig, isCloudMode, writeConfig } from '../utils/config.js';
|
|
7
|
+
import { tryDismissLaunchErrorsDialog, LINUX_XDOTOOL_MISSING_PREFIX, UNSUPPORTED_PLATFORM_PREFIX, } from '../utils/launch-error-dismiss.js';
|
|
8
|
+
import { emitProgress } from './progress.js';
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the project path from an explicit option or fall back to
|
|
11
|
+
* the supplied cwd. Always returns an absolute, resolved path plus a
|
|
12
|
+
* flag indicating whether the cwd fallback was used (so the CLI
|
|
13
|
+
* surface can emit a friendlier "no path provided" message).
|
|
14
|
+
*
|
|
15
|
+
* Pure / no I/O — exported for tests and for the CLI command's own
|
|
16
|
+
* use so the two paths can share resolution semantics.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveProjectPath(optionPath, cwd) {
|
|
19
|
+
const explicit = optionPath;
|
|
20
|
+
const resolvedPath = explicit ?? cwd;
|
|
21
|
+
return {
|
|
22
|
+
projectPath: path.resolve(resolvedPath),
|
|
23
|
+
usedCwdFallback: explicit === undefined,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Returns true if `projectPath` looks like a Unity project — i.e. it
|
|
28
|
+
* contains an `Assets/` directory and a
|
|
29
|
+
* `ProjectSettings/ProjectVersion.txt` file. Pure / no I/O beyond
|
|
30
|
+
* `fs.existsSync`.
|
|
31
|
+
*/
|
|
32
|
+
export function isUnityProjectDir(projectPath) {
|
|
33
|
+
const hasAssets = fs.existsSync(path.join(projectPath, 'Assets'));
|
|
34
|
+
const hasProjectVersion = fs.existsSync(path.join(projectPath, 'ProjectSettings', 'ProjectVersion.txt'));
|
|
35
|
+
return hasAssets && hasProjectVersion;
|
|
36
|
+
}
|
|
37
|
+
function isValidAuth(v) {
|
|
38
|
+
return v === 'none' || v === 'required';
|
|
39
|
+
}
|
|
40
|
+
function isValidTransport(v) {
|
|
41
|
+
return v === 'streamableHttp' || v === 'stdio';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Extract the leading executable path from a Unity process command
|
|
45
|
+
* line. Quote-aware: a leading double-quoted token (the typical
|
|
46
|
+
* Windows CIM `CommandLine` shape for paths containing spaces) is
|
|
47
|
+
* consumed whole, otherwise the first whitespace-delimited token is
|
|
48
|
+
* used. Pure / no I/O.
|
|
49
|
+
*/
|
|
50
|
+
function extractEditorPathFromCommandLine(commandLine) {
|
|
51
|
+
const trimmed = commandLine.trim();
|
|
52
|
+
if (trimmed.length === 0)
|
|
53
|
+
return '';
|
|
54
|
+
const quoted = trimmed.match(/^"([^"]+)"/);
|
|
55
|
+
if (quoted)
|
|
56
|
+
return quoted[1];
|
|
57
|
+
const unquoted = trimmed.match(/^(\S+)/);
|
|
58
|
+
return unquoted ? unquoted[1] : '';
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Build the env-var map propagated to the editor process when
|
|
62
|
+
* `noConnect !== true`. Pure (returns a fresh object); validates the
|
|
63
|
+
* `auth` and `transport` enums and throws on bad input — the
|
|
64
|
+
* `openProject` boundary catches the throw and returns it as a
|
|
65
|
+
* `{ kind: 'failure' }` result so nothing escapes past the public
|
|
66
|
+
* boundary.
|
|
67
|
+
*
|
|
68
|
+
* Exported for tests so the env-var assembly can be exercised
|
|
69
|
+
* without a real editor launch.
|
|
70
|
+
*/
|
|
71
|
+
export function buildOpenEnv(options) {
|
|
72
|
+
if (options.noConnect === true)
|
|
73
|
+
return undefined;
|
|
74
|
+
const env = {};
|
|
75
|
+
if (options.url !== undefined)
|
|
76
|
+
env['UNITY_MCP_HOST'] = options.url;
|
|
77
|
+
if (options.keepConnected)
|
|
78
|
+
env['UNITY_MCP_KEEP_CONNECTED'] = 'true';
|
|
79
|
+
if (options.tools !== undefined)
|
|
80
|
+
env['UNITY_MCP_TOOLS'] = options.tools;
|
|
81
|
+
if (options.token !== undefined)
|
|
82
|
+
env['UNITY_MCP_TOKEN'] = options.token;
|
|
83
|
+
if (options.auth !== undefined) {
|
|
84
|
+
if (!isValidAuth(options.auth)) {
|
|
85
|
+
throw new Error('auth must be "none" or "required"');
|
|
86
|
+
}
|
|
87
|
+
env['UNITY_MCP_AUTH_OPTION'] = options.auth;
|
|
88
|
+
}
|
|
89
|
+
if (options.transport !== undefined) {
|
|
90
|
+
if (!isValidTransport(options.transport)) {
|
|
91
|
+
throw new Error('transport must be "streamableHttp" or "stdio"');
|
|
92
|
+
}
|
|
93
|
+
env['UNITY_MCP_TRANSPORT'] = options.transport;
|
|
94
|
+
}
|
|
95
|
+
if (options.startServer !== undefined) {
|
|
96
|
+
env['UNITY_MCP_START_SERVER'] = options.startServer ? 'true' : 'false';
|
|
97
|
+
}
|
|
98
|
+
return Object.keys(env).length > 0 ? env : undefined;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Open a Unity project in the Unity Editor — the library-callable
|
|
102
|
+
* equivalent of the `open` CLI command. Library-safe: never calls
|
|
103
|
+
* `process.exit`, never prints to stdout / stderr, never throws past
|
|
104
|
+
* the public boundary.
|
|
105
|
+
*
|
|
106
|
+
* The launch logic (Unity-version detection, editor location,
|
|
107
|
+
* project-path validation, environment-variable wiring, editor
|
|
108
|
+
* spawn) is shared with the CLI command — `commands/open.ts`
|
|
109
|
+
* delegates to this function so the two paths cannot drift.
|
|
110
|
+
*
|
|
111
|
+
* Returns a discriminated union — narrow with
|
|
112
|
+
* `result.kind === 'success'` to access `editorPath` / `editorPid`
|
|
113
|
+
* / `unityVersion` / `projectPath`, or `result.kind === 'failure'`
|
|
114
|
+
* to access `errorMessage` / `error`.
|
|
115
|
+
*/
|
|
116
|
+
export async function openProject(options) {
|
|
117
|
+
const warnings = [];
|
|
118
|
+
let resolvedProjectPath;
|
|
119
|
+
let resolvedEditorPath;
|
|
120
|
+
let resolvedVersion;
|
|
121
|
+
try {
|
|
122
|
+
const { projectPath } = resolveProjectPath(options.projectPath, process.cwd());
|
|
123
|
+
resolvedProjectPath = projectPath;
|
|
124
|
+
if (!fs.existsSync(projectPath)) {
|
|
125
|
+
throw new Error(`Project path does not exist: ${projectPath}`);
|
|
126
|
+
}
|
|
127
|
+
if (!isUnityProjectDir(projectPath)) {
|
|
128
|
+
throw new Error(`Not a Unity project (missing Assets/ or ProjectSettings/ProjectVersion.txt): ${projectPath}`);
|
|
129
|
+
}
|
|
130
|
+
emitProgress(options.onProgress, {
|
|
131
|
+
phase: 'start',
|
|
132
|
+
message: `Opening Unity project at ${projectPath}`,
|
|
133
|
+
});
|
|
134
|
+
// Validate auth/transport BEFORE work begins so callers learn of
|
|
135
|
+
// a typo without first paying for editor-discovery I/O. The
|
|
136
|
+
// returned env is recomputed below if cloud-mode auto-detect
|
|
137
|
+
// flips keepConnected; otherwise we reuse this same map.
|
|
138
|
+
let env = buildOpenEnv(options);
|
|
139
|
+
// Already-running short-circuit. Same semantics as the CLI:
|
|
140
|
+
// success, with the existing PID surfaced.
|
|
141
|
+
const existingProcess = findUnityProcess(projectPath);
|
|
142
|
+
if (existingProcess) {
|
|
143
|
+
warnings.push(`Unity is already running with this project (PID: ${existingProcess.pid}). Skipping launch.`);
|
|
144
|
+
emitProgress(options.onProgress, {
|
|
145
|
+
phase: 'done',
|
|
146
|
+
message: 'Unity is already running for this project — launch skipped.',
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
kind: 'success',
|
|
150
|
+
success: true,
|
|
151
|
+
editorPath: extractEditorPathFromCommandLine(existingProcess.commandLine),
|
|
152
|
+
editorPid: existingProcess.pid,
|
|
153
|
+
unityVersion: getProjectEditorVersion(projectPath) ?? undefined,
|
|
154
|
+
projectPath,
|
|
155
|
+
warnings,
|
|
156
|
+
alreadyRunning: true,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// Resolve editor version: explicit option wins, otherwise read
|
|
160
|
+
// from ProjectVersion.txt.
|
|
161
|
+
emitProgress(options.onProgress, {
|
|
162
|
+
phase: 'detecting-editor-version',
|
|
163
|
+
message: 'Detecting Unity Editor version',
|
|
164
|
+
});
|
|
165
|
+
let version = options.unityVersion;
|
|
166
|
+
if (!version) {
|
|
167
|
+
version = getProjectEditorVersion(projectPath) ?? undefined;
|
|
168
|
+
}
|
|
169
|
+
resolvedVersion = version;
|
|
170
|
+
// Locate editor binary (Unity Hub / common locations).
|
|
171
|
+
const editorPath = await findEditorPath(version);
|
|
172
|
+
// Boolean signal for caller telemetry — we surface only whether
|
|
173
|
+
// editor discovery succeeded, not how many editors are installed.
|
|
174
|
+
emitProgress(options.onProgress, {
|
|
175
|
+
phase: 'editors-located',
|
|
176
|
+
message: editorPath
|
|
177
|
+
? 'Located Unity Editor candidates'
|
|
178
|
+
: 'Failed to locate any Unity Editor',
|
|
179
|
+
found: editorPath !== null,
|
|
180
|
+
});
|
|
181
|
+
if (!editorPath) {
|
|
182
|
+
const detail = version
|
|
183
|
+
? `Unity Editor ${version} is not installed.`
|
|
184
|
+
: 'No Unity Editor found.';
|
|
185
|
+
throw new Error(detail);
|
|
186
|
+
}
|
|
187
|
+
resolvedEditorPath = editorPath;
|
|
188
|
+
emitProgress(options.onProgress, {
|
|
189
|
+
phase: 'editor-resolved',
|
|
190
|
+
message: `Resolved Unity Editor at ${editorPath}`,
|
|
191
|
+
editorPath,
|
|
192
|
+
version,
|
|
193
|
+
});
|
|
194
|
+
// Cloud-mode auto-detect: if the project's config is in Cloud
|
|
195
|
+
// mode AND has a cloudToken, ensure keepConnected so the plugin
|
|
196
|
+
// connects on startup; also enable claude-code skill auto-gen.
|
|
197
|
+
let effectiveOptions = options;
|
|
198
|
+
{
|
|
199
|
+
const config = readConfig(projectPath);
|
|
200
|
+
if (config && isCloudMode(config) && config.cloudToken) {
|
|
201
|
+
if (!effectiveOptions.keepConnected) {
|
|
202
|
+
effectiveOptions = { ...effectiveOptions, keepConnected: true };
|
|
203
|
+
warnings.push('Cloud mode with token detected — auto-enabling keep-connected.');
|
|
204
|
+
// keepConnected flipped — rebuild the env map so the editor
|
|
205
|
+
// receives UNITY_MCP_KEEP_CONNECTED=true.
|
|
206
|
+
env = buildOpenEnv(effectiveOptions);
|
|
207
|
+
}
|
|
208
|
+
const skillAutoGenerate = { ...(config.skillAutoGenerate ?? {}) };
|
|
209
|
+
if (!skillAutoGenerate['claude-code']) {
|
|
210
|
+
skillAutoGenerate['claude-code'] = true;
|
|
211
|
+
writeConfig(projectPath, { ...config, skillAutoGenerate });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
emitProgress(options.onProgress, {
|
|
216
|
+
phase: 'connection-details',
|
|
217
|
+
message: env
|
|
218
|
+
? 'MCP connection environment variables prepared'
|
|
219
|
+
: 'No MCP connection environment variables (--no-connect or no options provided)',
|
|
220
|
+
projectPath,
|
|
221
|
+
editorPath,
|
|
222
|
+
envVars: env ?? {},
|
|
223
|
+
});
|
|
224
|
+
emitProgress(options.onProgress, {
|
|
225
|
+
phase: 'launching-editor',
|
|
226
|
+
message: `Launching Unity Editor`,
|
|
227
|
+
editorPath,
|
|
228
|
+
projectPath,
|
|
229
|
+
});
|
|
230
|
+
// Spawn the editor via the shared util. We capture the spawn /
|
|
231
|
+
// error events with callbacks and bridge them to the
|
|
232
|
+
// onProgress channel.
|
|
233
|
+
const child = launchEditor(editorPath, projectPath, env, {
|
|
234
|
+
onSpawn: (pid) => {
|
|
235
|
+
emitProgress(options.onProgress, {
|
|
236
|
+
phase: 'editor-launched',
|
|
237
|
+
message: `Launched Unity Editor (PID: ${pid ?? 'unknown'})`,
|
|
238
|
+
pid,
|
|
239
|
+
});
|
|
240
|
+
},
|
|
241
|
+
onError: (err) => {
|
|
242
|
+
// Don't throw out of the event listener — the caller can't
|
|
243
|
+
// catch it. Surface the warning for diagnostics.
|
|
244
|
+
warnings.push(`Editor spawn reported error: ${err.message}`);
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
// The `spawn` event fires asynchronously after `spawn(...)` returns.
|
|
248
|
+
// We wait briefly so the PID gets surfaced in the result. The
|
|
249
|
+
// child is already detached + unref'd, so this does NOT block
|
|
250
|
+
// process exit.
|
|
251
|
+
const pid = await waitForSpawn(child);
|
|
252
|
+
// Auto-dismiss the Unity "compile errors at launch" dialog if it
|
|
253
|
+
// appears. The polling loop runs synchronously inside this call
|
|
254
|
+
// (so the CLI's event loop stays alive until it completes) but
|
|
255
|
+
// never throws — a transient platform error is logged via the
|
|
256
|
+
// progress callback as a warning and the loop continues until
|
|
257
|
+
// either the dialog is dismissed and stays dismissed, the abort
|
|
258
|
+
// signal fires, the no-dialog grace window elapses, or the
|
|
259
|
+
// overall timeout elapses.
|
|
260
|
+
//
|
|
261
|
+
// When `autoDismissLaunchErrors === false` the loop is skipped
|
|
262
|
+
// entirely; behaviour is identical to the pre-feature baseline.
|
|
263
|
+
if (options.autoDismissLaunchErrors !== false) {
|
|
264
|
+
await pollAndDismissLaunchErrors({
|
|
265
|
+
timeoutMs: options.launchDismissTimeoutMs ?? 30000,
|
|
266
|
+
intervalMs: options.launchDismissPollIntervalMs ?? 1500,
|
|
267
|
+
onProgress: options.onProgress,
|
|
268
|
+
warnings,
|
|
269
|
+
abortSignal: options.launchDismissAbortSignal,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
emitProgress(options.onProgress, {
|
|
273
|
+
phase: 'done',
|
|
274
|
+
message: 'Editor launched.',
|
|
275
|
+
});
|
|
276
|
+
return {
|
|
277
|
+
kind: 'success',
|
|
278
|
+
success: true,
|
|
279
|
+
editorPath,
|
|
280
|
+
editorPid: pid,
|
|
281
|
+
unityVersion: version,
|
|
282
|
+
projectPath,
|
|
283
|
+
warnings,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
288
|
+
return {
|
|
289
|
+
kind: 'failure',
|
|
290
|
+
success: false,
|
|
291
|
+
projectPath: resolvedProjectPath,
|
|
292
|
+
editorPath: resolvedEditorPath,
|
|
293
|
+
unityVersion: resolvedVersion,
|
|
294
|
+
warnings,
|
|
295
|
+
errorMessage: errorObj.message,
|
|
296
|
+
error: errorObj,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Poll the OS desktop for the Unity "compile errors at launch"
|
|
302
|
+
* dialog and click `Ignore` (or the platform-equivalent) every time
|
|
303
|
+
* the probe reports it as found. Returns once the abort signal has
|
|
304
|
+
* fired, the no-dialog grace window has elapsed, the overall timeout
|
|
305
|
+
* has elapsed, or a permanent platform error has been observed.
|
|
306
|
+
*
|
|
307
|
+
* Re-entrant dismissals are supported: when the dialog re-appears
|
|
308
|
+
* after a successful click (the resolver-fix → dialog-reappears
|
|
309
|
+
* cycle described in the issue), each subsequent dismissal emits its
|
|
310
|
+
* own `launch-errors-dismissed` progress event so the user sees the
|
|
311
|
+
* recurrence in the log.
|
|
312
|
+
*
|
|
313
|
+
* Library-safe: never throws. Transient platform errors (e.g. a
|
|
314
|
+
* missing `xdotool` on Linux, or a momentary syscall failure on
|
|
315
|
+
* Windows) are recorded once as a warning on the supplied
|
|
316
|
+
* `warnings` array; subsequent identical errors are silently
|
|
317
|
+
* suppressed so the warnings array does not balloon over the polling
|
|
318
|
+
* window. Permanent errors (e.g. xdotool truly absent) bail out of
|
|
319
|
+
* the loop after the first occurrence so the helper does not spawn
|
|
320
|
+
* 60 doomed tool invocations on a 30s budget.
|
|
321
|
+
*/
|
|
322
|
+
export async function _pollAndDismissLaunchErrorsForTests(opts) {
|
|
323
|
+
return pollAndDismissLaunchErrors(opts);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Substring markers that identify a `kind: 'error'` outcome as
|
|
327
|
+
* permanent for this run. When seen, the polling loop bails out
|
|
328
|
+
* after recording the warning once; ticking again would just respawn
|
|
329
|
+
* the same doomed tool. Keep this list narrow — only conditions that
|
|
330
|
+
* cannot self-heal mid-launch belong here.
|
|
331
|
+
*
|
|
332
|
+
* The entries reference the producer-side constants in
|
|
333
|
+
* `launch-error-dismiss.ts` so a re-word at the producer site stays
|
|
334
|
+
* in sync with the bailout matcher (and the test in
|
|
335
|
+
* `launch-error-dismiss.test.ts` locks the constants down).
|
|
336
|
+
*/
|
|
337
|
+
const PERMANENT_DISMISS_ERROR_MARKERS = [
|
|
338
|
+
LINUX_XDOTOOL_MISSING_PREFIX,
|
|
339
|
+
UNSUPPORTED_PLATFORM_PREFIX,
|
|
340
|
+
];
|
|
341
|
+
function isPermanentDismissError(message) {
|
|
342
|
+
return PERMANENT_DISMISS_ERROR_MARKERS.some((m) => message.includes(m));
|
|
343
|
+
}
|
|
344
|
+
async function pollAndDismissLaunchErrors(opts) {
|
|
345
|
+
const platform = (opts.platform ?? nodePlatform());
|
|
346
|
+
const probe = opts.probe ?? tryDismissLaunchErrorsDialog;
|
|
347
|
+
const start = Date.now();
|
|
348
|
+
const deadline = start + Math.max(0, opts.timeoutMs);
|
|
349
|
+
const interval = Math.max(50, opts.intervalMs);
|
|
350
|
+
const graceMs = Math.max(0, opts.noDialogGraceMs ?? 15000);
|
|
351
|
+
const seenErrorMessages = new Set();
|
|
352
|
+
let dismissedAtLeastOnce = false;
|
|
353
|
+
let aborted = opts.abortSignal?.aborted ?? false;
|
|
354
|
+
const onAbort = () => { aborted = true; };
|
|
355
|
+
opts.abortSignal?.addEventListener('abort', onAbort, { once: true });
|
|
356
|
+
try {
|
|
357
|
+
while (Date.now() < deadline && !aborted) {
|
|
358
|
+
const outcome = await probe(platform);
|
|
359
|
+
// Re-check the exit conditions BEFORE applying the outcome:
|
|
360
|
+
// if abort fired (or the deadline lapsed) while `probe` was
|
|
361
|
+
// in flight, the in-flight result is stale and applying it
|
|
362
|
+
// would emit a misleading progress event or warning.
|
|
363
|
+
if (aborted || Date.now() >= deadline)
|
|
364
|
+
break;
|
|
365
|
+
if (outcome.kind === 'dismissed') {
|
|
366
|
+
dismissedAtLeastOnce = true;
|
|
367
|
+
emitProgress(opts.onProgress, {
|
|
368
|
+
phase: 'launch-errors-dismissed',
|
|
369
|
+
message: `[open] dismissed Unity launch-errors dialog (button=${outcome.button}, platform=${platform})`,
|
|
370
|
+
button: outcome.button,
|
|
371
|
+
platform,
|
|
372
|
+
});
|
|
373
|
+
// Keep polling — the dialog may re-appear after the resolver
|
|
374
|
+
// fixes one error and surfaces the next.
|
|
375
|
+
}
|
|
376
|
+
else if (outcome.kind === 'error') {
|
|
377
|
+
if (!seenErrorMessages.has(outcome.message)) {
|
|
378
|
+
seenErrorMessages.add(outcome.message);
|
|
379
|
+
opts.warnings.push(`launch-errors auto-dismiss: ${outcome.message}`);
|
|
380
|
+
}
|
|
381
|
+
if (isPermanentDismissError(outcome.message)) {
|
|
382
|
+
// No point ticking another 59 times — bail out.
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
else if (
|
|
387
|
+
// outcome.kind === 'not-found'
|
|
388
|
+
!dismissedAtLeastOnce &&
|
|
389
|
+
opts.abortSignal === undefined &&
|
|
390
|
+
Date.now() - start >= graceMs) {
|
|
391
|
+
// No dialog within the grace window AND no caller-supplied
|
|
392
|
+
// abort signal to wait on. Exit early — the README's "no
|
|
393
|
+
// extra delay" claim depends on this.
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const remaining = deadline - Date.now();
|
|
397
|
+
if (remaining <= 0 || aborted)
|
|
398
|
+
break;
|
|
399
|
+
await sleep(Math.min(interval, remaining), opts.abortSignal);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
finally {
|
|
403
|
+
opts.abortSignal?.removeEventListener('abort', onAbort);
|
|
404
|
+
}
|
|
405
|
+
// Surface a timeout warning ONLY when the deadline was actually
|
|
406
|
+
// reached (not the abort path) AND a platform error was observed.
|
|
407
|
+
// The grace-window exit returns silently above; the abort path is
|
|
408
|
+
// a caller-driven cancellation, not a timeout.
|
|
409
|
+
if (Date.now() >= deadline &&
|
|
410
|
+
!aborted &&
|
|
411
|
+
seenErrorMessages.size > 0 &&
|
|
412
|
+
!dismissedAtLeastOnce) {
|
|
413
|
+
opts.warnings.push(`launch-errors auto-dismiss timed out after ${opts.timeoutMs}ms — continuing with wait-for-ready`);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
function sleep(ms, signal) {
|
|
417
|
+
return new Promise((resolve) => {
|
|
418
|
+
if (signal?.aborted) {
|
|
419
|
+
resolve();
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const t = setTimeout(() => {
|
|
423
|
+
signal?.removeEventListener('abort', onAbort);
|
|
424
|
+
resolve();
|
|
425
|
+
}, ms);
|
|
426
|
+
const onAbort = () => {
|
|
427
|
+
clearTimeout(t);
|
|
428
|
+
resolve();
|
|
429
|
+
};
|
|
430
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
431
|
+
// Do NOT unref() — the polling timer is the reason `openProject`
|
|
432
|
+
// is awaiting in the first place, and unref'ing would let Node
|
|
433
|
+
// exit before the loop completes.
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Resolve to the spawned PID once the child process emits its
|
|
438
|
+
* `spawn` event, or to `undefined` if a short timeout elapses or
|
|
439
|
+
* the process emits `error` first. Library-safe: never throws,
|
|
440
|
+
* never blocks process exit (the caller has already detached).
|
|
441
|
+
*/
|
|
442
|
+
function waitForSpawn(child, timeoutMs = 2000) {
|
|
443
|
+
return new Promise((resolve) => {
|
|
444
|
+
if (child.pid !== undefined && child.pid !== null) {
|
|
445
|
+
// Some Node versions populate `pid` synchronously on spawn().
|
|
446
|
+
resolve(child.pid);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
let settled = false;
|
|
450
|
+
const finish = (pid) => {
|
|
451
|
+
if (settled)
|
|
452
|
+
return;
|
|
453
|
+
settled = true;
|
|
454
|
+
resolve(pid);
|
|
455
|
+
};
|
|
456
|
+
child.once('spawn', () => finish(child.pid ?? undefined));
|
|
457
|
+
child.once('error', () => finish(undefined));
|
|
458
|
+
setTimeout(() => finish(child.pid ?? undefined), timeoutMs).unref();
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
//# sourceMappingURL=open.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/lib/open.ts"],"names":[],"mappings":"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"}
|