unity-mcp-cli 0.66.0 → 0.67.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +73 -0
  3. package/dist/cli.d.ts +1 -0
  4. package/dist/cli.js +11 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/bootstrap-local.d.ts +17 -0
  7. package/dist/commands/bootstrap-local.js +83 -0
  8. package/dist/commands/bootstrap-local.js.map +1 -0
  9. package/dist/commands/close.d.ts +56 -0
  10. package/dist/commands/close.js +186 -0
  11. package/dist/commands/close.js.map +1 -0
  12. package/dist/commands/configure.js +37 -45
  13. package/dist/commands/configure.js.map +1 -1
  14. package/dist/commands/install-plugin.js +41 -23
  15. package/dist/commands/install-plugin.js.map +1 -1
  16. package/dist/commands/remove-plugin.js +21 -9
  17. package/dist/commands/remove-plugin.js.map +1 -1
  18. package/dist/commands/setup-mcp.js +32 -81
  19. package/dist/commands/setup-mcp.js.map +1 -1
  20. package/dist/index.js +4 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/lib/configure.d.ts +10 -0
  23. package/dist/lib/configure.js +85 -0
  24. package/dist/lib/configure.js.map +1 -0
  25. package/dist/lib/install-plugin.d.ts +8 -0
  26. package/dist/lib/install-plugin.js +68 -0
  27. package/dist/lib/install-plugin.js.map +1 -0
  28. package/dist/lib/logger.d.ts +7 -0
  29. package/dist/lib/logger.js +18 -0
  30. package/dist/lib/logger.js.map +1 -0
  31. package/dist/lib/progress.d.ts +7 -0
  32. package/dist/lib/progress.js +16 -0
  33. package/dist/lib/progress.js.map +1 -0
  34. package/dist/lib/remove-plugin.d.ts +7 -0
  35. package/dist/lib/remove-plugin.js +51 -0
  36. package/dist/lib/remove-plugin.js.map +1 -0
  37. package/dist/lib/setup-mcp.d.ts +12 -0
  38. package/dist/lib/setup-mcp.js +141 -0
  39. package/dist/lib/setup-mcp.js.map +1 -0
  40. package/dist/lib/types.d.ts +132 -0
  41. package/dist/lib/types.js +8 -0
  42. package/dist/lib/types.js.map +1 -0
  43. package/dist/lib/validation.d.ts +37 -0
  44. package/dist/lib/validation.js +50 -0
  45. package/dist/lib/validation.js.map +1 -0
  46. package/dist/lib.d.ts +5 -0
  47. package/dist/lib.js +18 -0
  48. package/dist/lib.js.map +1 -0
  49. package/dist/utils/manifest.d.ts +31 -3
  50. package/dist/utils/manifest.js +27 -11
  51. package/dist/utils/manifest.js.map +1 -1
  52. package/dist/utils/unity-shutdown.d.ts +87 -0
  53. package/dist/utils/unity-shutdown.js +241 -0
  54. package/dist/utils/unity-shutdown.js.map +1 -0
  55. package/package.json +20 -2
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { isNewerVersion, isValidVersion } from './semver.js';
4
- import * as ui from './ui.js';
4
+ import { silentLogger } from '../lib/logger.js';
5
5
  const PACKAGE_ID = 'com.ivanmurzak.unity.mcp';
6
6
  const REGISTRY_NAME = 'package.openupm.com';
7
7
  const REGISTRY_URL = 'https://package.openupm.com';
@@ -16,8 +16,12 @@ const REQUIRED_SCOPES = [
16
16
  /**
17
17
  * Resolve the latest plugin version from the OpenUPM registry.
18
18
  * Throws an error with actionable suggestions if the network request fails.
19
+ *
20
+ * @param logger Optional logger. Defaults to `silentLogger` so library
21
+ * callers stay side-effect-free; CLI call sites must pass a chalk-
22
+ * styled logger adapter explicitly to preserve the historical output.
19
23
  */
20
- export async function resolveLatestVersion() {
24
+ export async function resolveLatestVersion(logger = silentLogger) {
21
25
  const controller = new AbortController();
22
26
  const timeout = setTimeout(() => controller.abort(), 5000);
23
27
  try {
@@ -29,7 +33,7 @@ export async function resolveLatestVersion() {
29
33
  const data = (await res.json());
30
34
  const latest = data?.['dist-tags']?.latest;
31
35
  if (latest) {
32
- ui.info(`Resolved latest version from OpenUPM: ${latest}`);
36
+ logger.info(`Resolved latest version from OpenUPM: ${latest}`);
33
37
  return latest;
34
38
  }
35
39
  }
@@ -74,8 +78,12 @@ export function shouldUpdateVersion(currentVersion, newVersion) {
74
78
  * - Adds/updates the plugin dependency
75
79
  * - When force is false (auto-resolved version): never downgrades
76
80
  * - When force is true (user-specified --plugin-version): allows downgrade
81
+ *
82
+ * @param logger Optional logger. Defaults to `silentLogger` so library
83
+ * callers stay side-effect-free; CLI call sites must pass a chalk-
84
+ * styled logger adapter explicitly to preserve the historical output.
77
85
  */
78
- export function addPluginToManifest(projectPath, version, force = false) {
86
+ export function addPluginToManifest(projectPath, version, force = false, logger = silentLogger) {
79
87
  const manifestPath = path.join(projectPath, 'Packages', 'manifest.json');
80
88
  if (!fs.existsSync(manifestPath)) {
81
89
  throw new Error(`manifest.json not found at: ${manifestPath}`);
@@ -116,28 +124,35 @@ export function addPluginToManifest(projectPath, version, force = false) {
116
124
  modified = true;
117
125
  }
118
126
  const currentVersion = manifest.dependencies[PACKAGE_ID];
127
+ let resolvedVersion = version;
119
128
  if (!currentVersion || force || shouldUpdateVersion(currentVersion, version)) {
120
129
  manifest.dependencies[PACKAGE_ID] = version;
121
130
  modified = true;
122
131
  }
123
132
  else {
124
- ui.info(`Plugin already at version ${currentVersion} (>= ${version}). Skipping version update. Use --plugin-version to force a specific version.`);
133
+ resolvedVersion = currentVersion;
134
+ logger.info(`Plugin already at version ${currentVersion} (>= ${version}). Skipping version update. Use --plugin-version to force a specific version.`);
125
135
  }
126
136
  // --- Write back
127
137
  if (modified) {
128
138
  fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
129
- ui.success(`Updated ${manifestPath}`);
139
+ logger.success(`Updated ${manifestPath}`);
130
140
  }
131
141
  else {
132
- ui.info('manifest.json is already up to date.');
142
+ logger.info('manifest.json is already up to date.');
133
143
  }
144
+ return { modified, resolvedVersion, manifestPath };
134
145
  }
135
146
  /**
136
147
  * Remove Unity-MCP plugin from a Unity project's Packages/manifest.json.
137
148
  * Only removes the plugin dependency — scoped registries and scopes are
138
149
  * left untouched because other packages may depend on them.
150
+ *
151
+ * @param logger Optional logger. Defaults to `silentLogger` so library
152
+ * callers stay side-effect-free; CLI call sites must pass a chalk-
153
+ * styled logger adapter explicitly to preserve the historical output.
139
154
  */
140
- export function removePluginFromManifest(projectPath) {
155
+ export function removePluginFromManifest(projectPath, logger = silentLogger) {
141
156
  const manifestPath = path.join(projectPath, 'Packages', 'manifest.json');
142
157
  if (!fs.existsSync(manifestPath)) {
143
158
  throw new Error(`manifest.json not found at: ${manifestPath}`);
@@ -145,11 +160,12 @@ export function removePluginFromManifest(projectPath) {
145
160
  const rawJson = fs.readFileSync(manifestPath, 'utf-8');
146
161
  const manifest = JSON.parse(rawJson);
147
162
  if (!manifest.dependencies || !(PACKAGE_ID in manifest.dependencies)) {
148
- ui.info('Unity-MCP plugin is not installed. Nothing to remove.');
149
- return;
163
+ logger.info('Unity-MCP plugin is not installed. Nothing to remove.');
164
+ return { removed: false, manifestPath };
150
165
  }
151
166
  delete manifest.dependencies[PACKAGE_ID];
152
167
  fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
153
- ui.success(`Removed ${PACKAGE_ID} from ${manifestPath}`);
168
+ logger.success(`Removed ${PACKAGE_ID} from ${manifestPath}`);
169
+ return { removed: true, manifestPath };
154
170
  }
155
171
  //# sourceMappingURL=manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/utils/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,MAAM,UAAU,GAAG,0BAA0B,CAAC;AAC9C,MAAM,aAAa,GAAG,qBAAqB,CAAC;AAC5C,MAAM,YAAY,GAAG,6BAA6B,CAAC;AACnD,MAAM,eAAe,GAAG;IACtB,gBAAgB;IAChB,kBAAkB;IAClB,0BAA0B;IAC1B,qBAAqB;IACrB,kBAAkB;IAClB,cAAc;CACf,CAAC;AAcF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;IAE3D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,+BAA+B,UAAU,EAAE,EAAE;YACnE,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SACxC,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0C,CAAC;YACzE,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;YAC3C,IAAI,MAAM,EAAE,CAAC;gBACX,EAAE,CAAC,IAAI,CAAC,yCAAyC,MAAM,EAAE,CAAC,CAAC;gBAC3D,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAED,MAAM,IAAI,KAAK,CACb,2BAA2B,GAAG,CAAC,MAAM,IAAI;YACzC,wGAAwG,CACzG,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACrE,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,IAAI,KAAK,CACb,wDAAwD;YACxD,wGAAwG,CACzG,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,cAAsB,EAAE,UAAkB;IAC5E,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAE9B,uEAAuE;IACvE,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC/D,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,cAAc,CAAC,cAAc,CAAC,IAAI,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC;QACjE,OAAO,cAAc,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,UAAU,CAAC,WAAW,EAAE,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;AACjE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAmB,EAAE,OAAe,EAAE,KAAK,GAAG,KAAK;IACrF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IAEzE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,+BAA+B,YAAY,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAa,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,2CAA2C;IAC3C,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAC/B,QAAQ,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC/B,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,0CAA0C;IAC1C,IAAI,eAAe,GAAG,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAClD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAChC,CAAC;IAEF,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,eAAe,GAAG;YAChB,IAAI,EAAE,aAAa;YACnB,GAAG,EAAE,YAAY;YACjB,MAAM,EAAE,EAAE;SACX,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAChD,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,yBAAyB;IACzB,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;QAC5B,eAAe,CAAC,MAAM,GAAG,EAAE,CAAC;QAC5B,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;QACpC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC3B,QAAQ,CAAC,YAAY,GAAG,EAAE,CAAC;QAC3B,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,MAAM,cAAc,GAAG,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IACzD,IAAI,CAAC,cAAc,IAAI,KAAK,IAAI,mBAAmB,CAAC,cAAc,EAAE,OAAO,CAAC,EAAE,CAAC;QAC7E,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC;QAC5C,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,IAAI,CACL,6BAA6B,cAAc,QAAQ,OAAO,+EAA+E,CAC1I,CAAC;IACJ,CAAC;IAED,iBAAiB;IACjB,IAAI,QAAQ,EAAE,CAAC;QACb,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACzE,EAAE,CAAC,OAAO,CAAC,WAAW,YAAY,EAAE,CAAC,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAmB;IAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IAEzE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,+BAA+B,YAAY,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAa,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE/C,IAAI,CAAC,QAAQ,CAAC,YAAY,IAAI,CAAC,CAAC,UAAU,IAAI,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACrE,EAAE,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,OAAO,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IACzC,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACzE,EAAE,CAAC,OAAO,CAAC,WAAW,UAAU,SAAS,YAAY,EAAE,CAAC,CAAC;AAC3D,CAAC"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/utils/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Supported Node.js `process.platform` values for the close subcommand.
3
+ * Narrowed alias of NodeJS.Platform — keeps signal-selection logic exhaustive
4
+ * in tests without forcing callers to import a Node-internal type.
5
+ */
6
+ export type SupportedPlatform = 'win32' | 'darwin' | 'linux';
7
+ /**
8
+ * The polite-quit "graceful shutdown" signal for the current platform.
9
+ *
10
+ * - Linux / macOS: `SIGTERM` — Unity catches this and runs its normal exit
11
+ * path (autosave, asset-import finalisation, plugin disconnect).
12
+ * - Windows: `WM_CLOSE` via `taskkill` (no `/F`) — same idea, sent through
13
+ * `taskkill /PID <pid>` in the runtime helper. We return the string
14
+ * sentinel `WM_CLOSE` here so the call site can branch on it.
15
+ *
16
+ * Exposed as a pure function so the unit test suite can assert the platform
17
+ * matrix without booting an editor.
18
+ */
19
+ export declare function gracefulShutdownSignal(platform: SupportedPlatform): NodeJS.Signals | 'WM_CLOSE';
20
+ /**
21
+ * The hard-kill signal for the current platform.
22
+ *
23
+ * - Linux / macOS: `SIGKILL`.
24
+ * - Windows: `taskkill /F` — represented here by the sentinel `TASKKILL_FORCE`.
25
+ */
26
+ export declare function forceKillSignal(platform: SupportedPlatform): NodeJS.Signals | 'TASKKILL_FORCE';
27
+ /**
28
+ * Read the editor PID stored in `<project>/Temp/UnityLockfile`.
29
+ *
30
+ * Unity writes the running editor's PID into the first 4 bytes of this file
31
+ * as a little-endian uint32 the moment it acquires the project lock. Returns
32
+ * `null` when the lockfile is missing, too small, or holds a zero/negative PID.
33
+ *
34
+ * The caller is responsible for cross-checking the PID against a live process
35
+ * list — stale lockfiles can survive an unclean editor exit.
36
+ */
37
+ export declare function readLockfilePid(projectPath: string): number | null;
38
+ /**
39
+ * Returns true when a process with the given PID is alive.
40
+ *
41
+ * Both platforms first try `process.kill(pid, 0)` — Node maps it through
42
+ * `OpenProcess` on Windows, so the check is in-process and effectively free
43
+ * compared to spawning `tasklist`. At a 250ms `waitForExit` cadence with a
44
+ * 30s default timeout that's ~120 fewer subprocesses per close on Windows.
45
+ *
46
+ * The Windows fallback to `tasklist` is kept as defence-in-depth: if a
47
+ * future Node release ever changes behaviour or `OpenProcess` denies access
48
+ * for a process owned by another session, we still get the right answer
49
+ * (just more slowly).
50
+ *
51
+ * On any failure the function errs on the side of "not running" and returns
52
+ * false, which keeps the wait loop progressing rather than spinning forever
53
+ * on a transient error.
54
+ */
55
+ export declare function isProcessAlive(pid: number, platform?: SupportedPlatform): boolean;
56
+ /**
57
+ * Send the platform's polite-quit signal to the given PID.
58
+ *
59
+ * Returns true on apparent success (the OS accepted the signal); false if the
60
+ * underlying call threw. The caller still has to poll `isProcessAlive` — the
61
+ * editor may take seconds to wind down.
62
+ *
63
+ * Windows caveat: `taskkill /PID <pid>` (no `/F`) delivers `WM_CLOSE`, which
64
+ * only reaches processes that own a top-level window on the same desktop /
65
+ * session as the caller. In headless contexts (Unity launched in session 0
66
+ * by a Windows service, or another non-interactive desktop) `taskkill` will
67
+ * exit 0 and this function will report `true`, but the editor will never
68
+ * receive the message. The `--timeout` will then elapse, and `--force` is
69
+ * the only path that brings the process down. This is documented in the
70
+ * close subcommand README and is consistent with the design decision to
71
+ * stick to OS-level polite-quit (rather than a Unity-side MCP `editor-quit`
72
+ * tool which would route through SignalR and bypass session walls).
73
+ */
74
+ export declare function sendGracefulShutdown(pid: number, platform?: SupportedPlatform): boolean;
75
+ /**
76
+ * Hard-kill the given PID. Used only when `--force` is set and the polite
77
+ * shutdown timed out.
78
+ */
79
+ export declare function sendForceKill(pid: number, platform?: SupportedPlatform): boolean;
80
+ /**
81
+ * Poll until the given PID disappears or the timeout elapses.
82
+ *
83
+ * Returns true if the process exited within `timeoutMs`; false otherwise.
84
+ * Uses a 250ms poll interval — short enough to give crisp UX on a fast exit
85
+ * without busy-looping.
86
+ */
87
+ export declare function waitForExit(pid: number, timeoutMs: number, platform?: SupportedPlatform): Promise<boolean>;
@@ -0,0 +1,241 @@
1
+ import { execFileSync } from 'child_process';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { platform as nodePlatform } from 'os';
5
+ import { verbose } from './ui.js';
6
+ /**
7
+ * The polite-quit "graceful shutdown" signal for the current platform.
8
+ *
9
+ * - Linux / macOS: `SIGTERM` — Unity catches this and runs its normal exit
10
+ * path (autosave, asset-import finalisation, plugin disconnect).
11
+ * - Windows: `WM_CLOSE` via `taskkill` (no `/F`) — same idea, sent through
12
+ * `taskkill /PID <pid>` in the runtime helper. We return the string
13
+ * sentinel `WM_CLOSE` here so the call site can branch on it.
14
+ *
15
+ * Exposed as a pure function so the unit test suite can assert the platform
16
+ * matrix without booting an editor.
17
+ */
18
+ export function gracefulShutdownSignal(platform) {
19
+ if (platform === 'win32')
20
+ return 'WM_CLOSE';
21
+ return 'SIGTERM';
22
+ }
23
+ /**
24
+ * The hard-kill signal for the current platform.
25
+ *
26
+ * - Linux / macOS: `SIGKILL`.
27
+ * - Windows: `taskkill /F` — represented here by the sentinel `TASKKILL_FORCE`.
28
+ */
29
+ export function forceKillSignal(platform) {
30
+ if (platform === 'win32')
31
+ return 'TASKKILL_FORCE';
32
+ return 'SIGKILL';
33
+ }
34
+ /**
35
+ * Read the editor PID stored in `<project>/Temp/UnityLockfile`.
36
+ *
37
+ * Unity writes the running editor's PID into the first 4 bytes of this file
38
+ * as a little-endian uint32 the moment it acquires the project lock. Returns
39
+ * `null` when the lockfile is missing, too small, or holds a zero/negative PID.
40
+ *
41
+ * The caller is responsible for cross-checking the PID against a live process
42
+ * list — stale lockfiles can survive an unclean editor exit.
43
+ */
44
+ export function readLockfilePid(projectPath) {
45
+ const lockfilePath = path.join(projectPath, 'Temp', 'UnityLockfile');
46
+ if (!fs.existsSync(lockfilePath)) {
47
+ verbose(`No Unity lockfile at ${lockfilePath}`);
48
+ return null;
49
+ }
50
+ let buf;
51
+ try {
52
+ buf = fs.readFileSync(lockfilePath);
53
+ }
54
+ catch (err) {
55
+ verbose(`Failed to read Unity lockfile: ${err instanceof Error ? err.message : String(err)}`);
56
+ return null;
57
+ }
58
+ if (buf.length < 4) {
59
+ verbose(`Unity lockfile too small (${buf.length} bytes)`);
60
+ return null;
61
+ }
62
+ // `readUInt32LE` always returns a finite integer in [0, 2^32-1], so a
63
+ // non-positive check is the only meaningful filter here.
64
+ const pid = buf.readUInt32LE(0);
65
+ if (pid <= 0) {
66
+ verbose(`Unity lockfile holds non-positive PID: ${pid}`);
67
+ return null;
68
+ }
69
+ return pid;
70
+ }
71
+ /**
72
+ * Returns true when a process with the given PID is alive.
73
+ *
74
+ * Both platforms first try `process.kill(pid, 0)` — Node maps it through
75
+ * `OpenProcess` on Windows, so the check is in-process and effectively free
76
+ * compared to spawning `tasklist`. At a 250ms `waitForExit` cadence with a
77
+ * 30s default timeout that's ~120 fewer subprocesses per close on Windows.
78
+ *
79
+ * The Windows fallback to `tasklist` is kept as defence-in-depth: if a
80
+ * future Node release ever changes behaviour or `OpenProcess` denies access
81
+ * for a process owned by another session, we still get the right answer
82
+ * (just more slowly).
83
+ *
84
+ * On any failure the function errs on the side of "not running" and returns
85
+ * false, which keeps the wait loop progressing rather than spinning forever
86
+ * on a transient error.
87
+ */
88
+ export function isProcessAlive(pid, platform = nodePlatform()) {
89
+ if (!Number.isFinite(pid) || pid <= 0)
90
+ return false;
91
+ try {
92
+ process.kill(pid, 0);
93
+ return true;
94
+ }
95
+ catch (err) {
96
+ const code = err.code;
97
+ // EPERM means the process exists but we can't signal it — treat as alive.
98
+ if (code === 'EPERM')
99
+ return true;
100
+ if (code !== 'ESRCH') {
101
+ // Anything other than ESRCH is unexpected; fall through to the
102
+ // Windows-only verification path so we don't return a wrong answer
103
+ // on a transient OS hiccup. POSIX paths just return false.
104
+ if (platform !== 'win32')
105
+ return false;
106
+ }
107
+ }
108
+ if (platform !== 'win32')
109
+ return false;
110
+ // Windows fallback: `tasklist /FI "PID eq <pid>" /NH /FO CSV`.
111
+ // The first CSV column is the image name, the second is the PID. Parse
112
+ // field-wise so a digit run that happens to appear in another column
113
+ // (image name, session, memory, status) cannot produce a false positive.
114
+ try {
115
+ const out = execFileSync('tasklist', ['/FI', `PID eq ${pid}`, '/NH', '/FO', 'CSV'], {
116
+ encoding: 'utf-8',
117
+ timeout: 3000,
118
+ stdio: ['pipe', 'pipe', 'pipe'],
119
+ });
120
+ // tasklist prints "INFO: No tasks are running ..." when nothing matches.
121
+ const target = `"${pid}"`;
122
+ for (const line of out.split(/\r?\n/)) {
123
+ const trimmed = line.trim();
124
+ if (trimmed.length === 0)
125
+ continue;
126
+ // Second CSV field — split on `,` and check column index 1. CSV from
127
+ // tasklist quotes every field, so a simple split is safe. Image names
128
+ // with embedded commas would shift the PID into a later column and
129
+ // produce a false negative; that's an accepted trade-off — Unity
130
+ // executable names don't contain commas in practice, and any false
131
+ // negative simply ends the wait loop one tick early.
132
+ const cols = trimmed.split(',');
133
+ if (cols.length >= 2 && cols[1] === target)
134
+ return true;
135
+ }
136
+ return false;
137
+ }
138
+ catch {
139
+ return false;
140
+ }
141
+ }
142
+ /**
143
+ * Send the platform's polite-quit signal to the given PID.
144
+ *
145
+ * Returns true on apparent success (the OS accepted the signal); false if the
146
+ * underlying call threw. The caller still has to poll `isProcessAlive` — the
147
+ * editor may take seconds to wind down.
148
+ *
149
+ * Windows caveat: `taskkill /PID <pid>` (no `/F`) delivers `WM_CLOSE`, which
150
+ * only reaches processes that own a top-level window on the same desktop /
151
+ * session as the caller. In headless contexts (Unity launched in session 0
152
+ * by a Windows service, or another non-interactive desktop) `taskkill` will
153
+ * exit 0 and this function will report `true`, but the editor will never
154
+ * receive the message. The `--timeout` will then elapse, and `--force` is
155
+ * the only path that brings the process down. This is documented in the
156
+ * close subcommand README and is consistent with the design decision to
157
+ * stick to OS-level polite-quit (rather than a Unity-side MCP `editor-quit`
158
+ * tool which would route through SignalR and bypass session walls).
159
+ */
160
+ export function sendGracefulShutdown(pid, platform = nodePlatform()) {
161
+ if (!Number.isFinite(pid) || pid <= 0)
162
+ return false;
163
+ const sig = gracefulShutdownSignal(platform);
164
+ verbose(`Sending graceful shutdown to PID ${pid} via ${sig}`);
165
+ try {
166
+ if (sig === 'WM_CLOSE') {
167
+ execFileSync('taskkill', ['/PID', String(pid)], {
168
+ timeout: 3000,
169
+ stdio: ['pipe', 'pipe', 'pipe'],
170
+ });
171
+ return true;
172
+ }
173
+ process.kill(pid, sig);
174
+ return true;
175
+ }
176
+ catch (err) {
177
+ // Race: the editor can exit between PID resolution and signal delivery.
178
+ // POSIX surfaces this as ESRCH; Windows `taskkill` exits non-zero with
179
+ // "process … not found". The desired end state (process gone) is already
180
+ // reached, so we re-check liveness and report success when the PID is
181
+ // truly absent. This preserves close's idempotency contract.
182
+ if (!isProcessAlive(pid, platform)) {
183
+ verbose(`Graceful shutdown: PID ${pid} already gone — treating as success`);
184
+ return true;
185
+ }
186
+ verbose(`Graceful shutdown failed: ${err instanceof Error ? err.message : String(err)}`);
187
+ return false;
188
+ }
189
+ }
190
+ /**
191
+ * Hard-kill the given PID. Used only when `--force` is set and the polite
192
+ * shutdown timed out.
193
+ */
194
+ export function sendForceKill(pid, platform = nodePlatform()) {
195
+ if (!Number.isFinite(pid) || pid <= 0)
196
+ return false;
197
+ const sig = forceKillSignal(platform);
198
+ verbose(`Force-killing PID ${pid} via ${sig}`);
199
+ try {
200
+ if (sig === 'TASKKILL_FORCE') {
201
+ execFileSync('taskkill', ['/F', '/PID', String(pid)], {
202
+ timeout: 3000,
203
+ stdio: ['pipe', 'pipe', 'pipe'],
204
+ });
205
+ return true;
206
+ }
207
+ process.kill(pid, sig);
208
+ return true;
209
+ }
210
+ catch (err) {
211
+ // Same race as sendGracefulShutdown — the polite-quit path may have
212
+ // already won between waitForExit's last poll and our SIGKILL call.
213
+ if (!isProcessAlive(pid, platform)) {
214
+ verbose(`Force kill: PID ${pid} already gone — treating as success`);
215
+ return true;
216
+ }
217
+ verbose(`Force kill failed: ${err instanceof Error ? err.message : String(err)}`);
218
+ return false;
219
+ }
220
+ }
221
+ /**
222
+ * Poll until the given PID disappears or the timeout elapses.
223
+ *
224
+ * Returns true if the process exited within `timeoutMs`; false otherwise.
225
+ * Uses a 250ms poll interval — short enough to give crisp UX on a fast exit
226
+ * without busy-looping.
227
+ */
228
+ export async function waitForExit(pid, timeoutMs, platform = nodePlatform()) {
229
+ const pollIntervalMs = 250;
230
+ const deadline = Date.now() + timeoutMs;
231
+ while (Date.now() < deadline) {
232
+ if (!isProcessAlive(pid, platform)) {
233
+ return true;
234
+ }
235
+ await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
236
+ }
237
+ // One last check after the deadline elapses — the process may have exited
238
+ // in the trailing poll-interval slice we slept through.
239
+ return !isProcessAlive(pid, platform);
240
+ }
241
+ //# sourceMappingURL=unity-shutdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unity-shutdown.js","sourceRoot":"","sources":["../../src/utils/unity-shutdown.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,30 @@
1
1
  {
2
2
  "name": "unity-mcp-cli",
3
- "version": "0.66.0",
3
+ "version": "0.67.0",
4
4
  "description": "Cross-platform CLI tool for AI Game Developer (Skills & MCP). Full AI develop and test loop. Efficient token usage, advanced tools. Creates Unity project, installs plugins, configures tools, and manages HTTP connection with Unity Editor and a game made with Unity. Works with Claude Code, Gemini, Copilot, Cursor and any other absolutely for free.",
5
5
  "type": "module",
6
- "main": "dist/index.js",
6
+ "main": "dist/lib.js",
7
+ "types": "dist/lib.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/lib.d.ts",
11
+ "import": "./dist/lib.js"
12
+ },
13
+ "./cli": {
14
+ "types": "./dist/cli.d.ts",
15
+ "import": "./dist/cli.js"
16
+ }
17
+ },
7
18
  "bin": {
8
19
  "unity-mcp-cli": "bin/unity-mcp-cli.js"
9
20
  },
21
+ "files": [
22
+ "dist",
23
+ "bin",
24
+ "README.md",
25
+ "CHANGELOG.md",
26
+ "docs"
27
+ ],
10
28
  "scripts": {
11
29
  "build": "tsc",
12
30
  "pretest": "npm run build",