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.
@@ -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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"}