unity-mcp-cli 0.88.0 → 0.90.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 CHANGED
@@ -93,6 +93,7 @@ npx unity-mcp-cli install-plugin /path/to/unity/project
93
93
  - [Commands](#commands)
94
94
  - [`configure`](#configure)
95
95
  - [`create-project`](#create-project)
96
+ - [`install-extension`](#install-extension)
96
97
  - [`install-plugin`](#install-plugin)
97
98
  - [`install-unity`](#install-unity)
98
99
  - [`login`](#login)
@@ -181,6 +182,55 @@ unity-mcp-cli create-project ./MyGame --unity 2022.3.62f1
181
182
 
182
183
  ![AI Game Developer — Unity SKILLS and MCP](https://github.com/IvanMurzak/Unity-MCP/blob/main/docs/img/promo/hazzard-divider.svg?raw=true)
183
184
 
185
+ ## `install-extension`
186
+
187
+ Install one of the Unity-MCP extensions — the optional tool packs that add MCP tools for Animation, Cinemachine, Input System, Navigation, Particle System, ProBuilder, Splines, Terrain, Tilemap, and Timeline — into a Unity project's `Packages/manifest.json`. This is the command-line equivalent of the **Extensions** section in the *AI Game Developer* editor window, and it installs from the same shared catalogue.
188
+
189
+ ```bash
190
+ # See what is installable (no project and no network required)
191
+ unity-mcp-cli install-extension --list
192
+
193
+ # Run from inside the Unity project folder — the path is optional
194
+ cd ./MyGame && unity-mcp-cli install-extension Tilemap
195
+ ```
196
+
197
+ | Argument / Option | Required | Description |
198
+ |---|---|---|
199
+ | `[id]` | Yes (unless `--list`) | Extension to install — the OpenUPM package id (`com.ivanmurzak.unity.mcp.tilemap`) or the catalogue name (`Tilemap`). Matched case-insensitively. An unknown id lists every installable extension so you can self-correct. |
200
+ | `[path]` | No | Path to the Unity project (positional or `--path`). Defaults to the current directory, verified the same way as `install-plugin`. |
201
+ | `--extension-version <version>` | No | Extension version to install (defaults to latest from OpenUPM). **Not `--version`** — that is the CLI's own global version flag. |
202
+ | `--list` | No | List the installable extensions and exit. |
203
+
204
+ This command:
205
+ 1. Adds the **OpenUPM scoped registry** with all required scopes (the `com.ivanmurzak` scope is what makes the extension resolvable at all)
206
+ 2. Adds the extension's package id to `dependencies`, resolving OpenUPM's `latest` at install time
207
+ 3. **Never downgrades** on an auto-resolved version — if a higher version is already installed, it is preserved and a warning is printed. Pass `--extension-version` to force a specific value, including a downgrade.
208
+ 4. Is **idempotent** — a re-run that finds the extension already up to date reports so and writes nothing
209
+
210
+ **Example — install a specific extension version:**
211
+
212
+ ```bash
213
+ unity-mcp-cli install-extension Cinemachine ./MyGame --extension-version 1.0.17
214
+ ```
215
+
216
+ **Example — in-process, from the library:**
217
+
218
+ ```ts
219
+ import { installExtension, EXTENSIONS_CATALOG } from 'unity-mcp-cli';
220
+
221
+ const result = await installExtension({
222
+ unityProjectPath: './MyGame',
223
+ extensionId: 'Tilemap',
224
+ });
225
+ if (result.kind === 'success') {
226
+ console.log(result.outcome, result.fromVersion, '->', result.toVersion);
227
+ }
228
+ ```
229
+
230
+ > After running this command, open (or focus) the Unity Editor so the Package Manager resolves the new dependency.
231
+
232
+ ![AI Game Developer — Unity SKILLS and MCP](https://github.com/IvanMurzak/Unity-MCP/blob/main/docs/img/promo/hazzard-divider.svg?raw=true)
233
+
184
234
  ## `install-plugin`
185
235
 
186
236
  Install the Unity-MCP plugin into a Unity project's `Packages/manifest.json`. Optionally download the RID-matched MCP server binary and redeem a team enrollment code in the same run.
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const installExtensionCommand: Command;
@@ -0,0 +1,99 @@
1
+ import { Command } from 'commander';
2
+ import * as ui from '../utils/ui.js';
3
+ import { verbose } from '../utils/ui.js';
4
+ import { installExtension } from '../lib/install-extension.js';
5
+ import { EXTENSIONS_CATALOG } from '../utils/extensions-catalog.js';
6
+ import { resolveInstallTarget, unityAdapter } from '@baizor/gamedev-cli-core';
7
+ export const installExtensionCommand = new Command('install-extension')
8
+ .description('Install a Unity-MCP extension into a Unity project: resolve the extension <id> from the shared catalogue, add (or update) its dependency plus the OpenUPM scoped registry in Packages/manifest.json, then let Unity resolve it. Idempotent. The project path defaults to the current directory (like install-plugin).')
9
+ .argument('[id]', 'Extension to install (the OpenUPM package id, or the catalogue name e.g. "Tilemap")')
10
+ .argument('[path]', 'Path to the Unity project (defaults to the current directory)')
11
+ .option('--path <path>', 'Path to the Unity project')
12
+ // NOT `--version`: the root program registers `-V, --version` via `.version()`, which
13
+ // intercepts it before this subcommand sees it — `install-extension X --version 1.2.3`
14
+ // would print the CLI's own version and exit 0 without installing anything. This is the
15
+ // same reason `install-plugin` spells its flag `--plugin-version`.
16
+ .option('--extension-version <version>', 'Extension version to install (default: latest from OpenUPM)')
17
+ .option('--list', 'List the installable extensions and exit')
18
+ .action(async (id, positionalPath, options) => {
19
+ // `--list` is a pure read: no project needed, no network, exit 0.
20
+ if (options.list) {
21
+ ui.heading('Installable Unity-MCP extensions');
22
+ for (const ext of EXTENSIONS_CATALOG) {
23
+ ui.label(ext.name, ext.packageId);
24
+ }
25
+ ui.info(`${EXTENSIONS_CATALOG.length} extensions. Install one with: unity-mcp-cli install-extension <id> [path]`);
26
+ return;
27
+ }
28
+ if (!id || id.trim() === '') {
29
+ ui.error('Missing extension id. Pass one (e.g. `unity-mcp-cli install-extension Tilemap`), or run with --list to see what is installable.');
30
+ process.exit(1);
31
+ }
32
+ // Same path resolution as install-plugin: `path? → --path? → cwd`, then verify the
33
+ // directory really is a Unity project so the error names what was checked.
34
+ const target = resolveInstallTarget({
35
+ adapter: unityAdapter,
36
+ positional: positionalPath,
37
+ path: options.path,
38
+ });
39
+ if (target.kind === 'failure') {
40
+ ui.error(target.error.message);
41
+ process.exit(1);
42
+ }
43
+ const projectPath = target.projectRoot;
44
+ ui.heading('Installing Unity-MCP extension');
45
+ verbose(`Extension id: ${id}`);
46
+ verbose(`Project path: ${projectPath}`);
47
+ if (options.extensionVersion)
48
+ verbose(`--extension-version: ${options.extensionVersion}`);
49
+ let spinner;
50
+ if (!options.extensionVersion) {
51
+ spinner = ui.startSpinner('Resolving latest extension version...');
52
+ }
53
+ const result = await installExtension({
54
+ unityProjectPath: projectPath,
55
+ extensionId: id,
56
+ version: options.extensionVersion,
57
+ onProgress: (event) => {
58
+ if (event.phase === 'dependencies-resolved' && spinner) {
59
+ spinner.success(`Resolved extension version: ${event.version}`);
60
+ spinner = undefined;
61
+ return;
62
+ }
63
+ if (event.phase === 'manifest-patched') {
64
+ verbose(event.message);
65
+ }
66
+ },
67
+ });
68
+ if (result.kind === 'failure') {
69
+ if (spinner) {
70
+ spinner.error('Failed to resolve extension version');
71
+ spinner = undefined;
72
+ }
73
+ ui.error(result.error.message);
74
+ for (const warning of result.warnings) {
75
+ ui.warn(warning);
76
+ }
77
+ process.exit(1);
78
+ }
79
+ switch (result.outcome) {
80
+ case 'added':
81
+ ui.success(`Installed ${result.packageId} ${result.toVersion}`);
82
+ break;
83
+ case 'updated':
84
+ ui.success(`Updated ${result.packageId} ${result.fromVersion} → ${result.toVersion}`);
85
+ break;
86
+ case 'already-up-to-date':
87
+ ui.info(`${result.packageId} is already up to date (${result.toVersion})`);
88
+ break;
89
+ }
90
+ ui.label('Status', result.message);
91
+ ui.label('Manifest', result.manifestPath);
92
+ for (const warning of result.warnings) {
93
+ ui.warn(warning);
94
+ }
95
+ for (const step of result.nextSteps) {
96
+ ui.label('Next step', step);
97
+ }
98
+ });
99
+ //# sourceMappingURL=install-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-extension.js","sourceRoot":"","sources":["../../src/commands/install-extension.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import { closeCommand } from './commands/close.js';
5
5
  import { createProjectCommand } from './commands/create-project.js';
6
6
  import { installUnityCommand } from './commands/install-unity.js';
7
7
  import { openCommand } from './commands/open.js';
8
+ import { installExtensionCommand } from './commands/install-extension.js';
8
9
  import { installPluginCommand } from './commands/install-plugin.js';
9
10
  import { loginCommand } from './commands/login.js';
10
11
  import { configureCommand } from './commands/configure.js';
@@ -32,6 +33,7 @@ const subcommands = [
32
33
  closeCommand,
33
34
  configureCommand,
34
35
  createProjectCommand,
36
+ installExtensionCommand,
35
37
  installPluginCommand,
36
38
  installUnityCommand,
37
39
  loginCommand,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { InstallExtensionOptions, InstallExtensionResult } from './types.js';
2
+ /**
3
+ * Install (or update) a Unity-MCP extension into a consumer Unity project, as a
4
+ * REAL installer that is behaviourally identical to the in-editor window's
5
+ * `ExtensionPanel`:
6
+ *
7
+ * 1. Resolve `extensionId` to a descriptor in the SHARED catalogue
8
+ * (`Unity-MCP-Plugin/Packages/com.ivanmurzak.unity.mcp/extensions.catalog.json`,
9
+ * mirrored here by `EXTENSIONS_CATALOG`).
10
+ * 2. Validate that the target path hosts a Unity project (`Packages/manifest.json`).
11
+ * 3. Resolve the version to install: the explicit `version` override, else the
12
+ * catalogue pin, else OpenUPM's `dist-tags.latest` fetched live. Every shipped
13
+ * catalogue entry is unpinned, so the live fetch is the normal path.
14
+ * 4. Read-modify-write `Packages/manifest.json`: ensure the OpenUPM scoped registry
15
+ * and its required scopes, then add or version-bump the package dependency.
16
+ * 5. Tell the caller Unity must resolve packages (the CLI cannot call
17
+ * `UnityEditor.PackageManager.Client.Resolve()` — only the editor can).
18
+ *
19
+ * Library-safe: no stdout noise, no `process.exit`, no throws past the public
20
+ * boundary; returns a `{ kind: 'success' | 'failure' }` union. Idempotent: a re-run
21
+ * that finds the dependency at an equal-or-newer version reports
22
+ * `already-up-to-date` and makes no write. Mirrors `installPlugin`'s shape exactly
23
+ * so the app can adopt it the same way.
24
+ */
25
+ export declare function installExtension(opts: InstallExtensionOptions): Promise<InstallExtensionResult>;
@@ -0,0 +1,182 @@
1
+ import * as fs from 'fs';
2
+ import { EXTENSIONS_CATALOG, findExtension, hasVersion, } from '../utils/extensions-catalog.js';
3
+ import { addPackageToManifest, resolveLatestPackageVersion } from '../utils/manifest.js';
4
+ import { silentLogger } from './logger.js';
5
+ import { emitProgress } from './progress.js';
6
+ import { requireUnityProject } from './validation.js';
7
+ /**
8
+ * Install (or update) a Unity-MCP extension into a consumer Unity project, as a
9
+ * REAL installer that is behaviourally identical to the in-editor window's
10
+ * `ExtensionPanel`:
11
+ *
12
+ * 1. Resolve `extensionId` to a descriptor in the SHARED catalogue
13
+ * (`Unity-MCP-Plugin/Packages/com.ivanmurzak.unity.mcp/extensions.catalog.json`,
14
+ * mirrored here by `EXTENSIONS_CATALOG`).
15
+ * 2. Validate that the target path hosts a Unity project (`Packages/manifest.json`).
16
+ * 3. Resolve the version to install: the explicit `version` override, else the
17
+ * catalogue pin, else OpenUPM's `dist-tags.latest` fetched live. Every shipped
18
+ * catalogue entry is unpinned, so the live fetch is the normal path.
19
+ * 4. Read-modify-write `Packages/manifest.json`: ensure the OpenUPM scoped registry
20
+ * and its required scopes, then add or version-bump the package dependency.
21
+ * 5. Tell the caller Unity must resolve packages (the CLI cannot call
22
+ * `UnityEditor.PackageManager.Client.Resolve()` — only the editor can).
23
+ *
24
+ * Library-safe: no stdout noise, no `process.exit`, no throws past the public
25
+ * boundary; returns a `{ kind: 'success' | 'failure' }` union. Idempotent: a re-run
26
+ * that finds the dependency at an equal-or-newer version reports
27
+ * `already-up-to-date` and makes no write. Mirrors `installPlugin`'s shape exactly
28
+ * so the app can adopt it the same way.
29
+ */
30
+ export async function installExtension(opts) {
31
+ const warnings = [];
32
+ const nextSteps = [];
33
+ const extensionId = opts?.extensionId ?? '';
34
+ try {
35
+ const catalog = opts.catalog ?? EXTENSIONS_CATALOG;
36
+ const resolved = findExtension(extensionId, catalog);
37
+ if (resolved === null) {
38
+ return {
39
+ kind: 'failure',
40
+ success: false,
41
+ extensionId,
42
+ warnings,
43
+ nextSteps,
44
+ error: new Error(unknownExtensionMessage(extensionId, catalog)),
45
+ };
46
+ }
47
+ const validated = requireUnityProject(opts?.unityProjectPath);
48
+ if (!validated.ok) {
49
+ return {
50
+ kind: 'failure',
51
+ success: false,
52
+ extensionId,
53
+ packageId: resolved.packageId,
54
+ manifestPath: validated.manifestPath,
55
+ warnings,
56
+ nextSteps,
57
+ error: validated.error,
58
+ };
59
+ }
60
+ const { projectPath } = validated;
61
+ emitProgress(opts.onProgress, {
62
+ phase: 'start',
63
+ message: `Installing extension ${resolved.packageId} into ${projectPath}`,
64
+ });
65
+ // Apply the optional `version` override (drives both the pin written and, via
66
+ // `force`, whether a downgrade is permitted).
67
+ const descriptor = applyVersionOverride(resolved, opts.version, warnings);
68
+ const isExplicitVersion = (opts.version ?? '').trim() !== '';
69
+ let version;
70
+ if (hasVersion(descriptor)) {
71
+ // Non-null only for an explicit override or a (currently unused) catalogue pin.
72
+ version = descriptor.version;
73
+ }
74
+ else {
75
+ version = await resolveLatestPackageVersion(descriptor.packageId, silentLogger, '--extension-version');
76
+ emitProgress(opts.onProgress, {
77
+ phase: 'dependencies-resolved',
78
+ message: `Resolved latest ${descriptor.packageId} version: ${version}`,
79
+ version,
80
+ });
81
+ }
82
+ const before = readInstalledVersion(validated.manifestPath, descriptor.packageId);
83
+ const result = addPackageToManifest(projectPath, descriptor.packageId, version, isExplicitVersion, silentLogger);
84
+ // `addPackageToManifest` refuses to downgrade unless `force`; surface that as a
85
+ // warning rather than silently reporting the requested version.
86
+ if (result.resolvedVersion !== version && !isExplicitVersion) {
87
+ warnings.push(`${descriptor.packageId} is already at version ${result.resolvedVersion} (>= ${version}). ` +
88
+ 'Skipping version update. Pass an explicit `version` to force a specific value.');
89
+ }
90
+ emitProgress(opts.onProgress, {
91
+ phase: 'manifest-patched',
92
+ message: result.modified
93
+ ? `Updated ${result.manifestPath}`
94
+ : 'manifest.json is already up to date.',
95
+ manifestPath: result.manifestPath,
96
+ });
97
+ // Derive the outcome from what was actually on disk before the write, NOT from
98
+ // `modified` alone: `modified` is also true when only the scoped registry had to
99
+ // be added, which is not an "added extension".
100
+ const outcome = before === null
101
+ ? 'added'
102
+ : result.resolvedVersion === before
103
+ ? 'already-up-to-date'
104
+ : 'updated';
105
+ const message = outcome === 'added'
106
+ ? `Added ${descriptor.packageId} ${result.resolvedVersion}. Unity will resolve the package on next focus.`
107
+ : outcome === 'updated'
108
+ ? `Updated ${descriptor.packageId} from ${before} to ${result.resolvedVersion}.`
109
+ : `${descriptor.name} is already installed and up to date (${result.resolvedVersion}).`;
110
+ if (outcome !== 'already-up-to-date') {
111
+ nextSteps.push('Open (or focus) the Unity Editor so the Package Manager resolves the new dependency.');
112
+ }
113
+ emitProgress(opts.onProgress, { phase: 'done', message: 'Extension install complete.' });
114
+ return {
115
+ kind: 'success',
116
+ success: true,
117
+ outcome,
118
+ changed: outcome !== 'already-up-to-date',
119
+ extensionId,
120
+ packageId: descriptor.packageId,
121
+ fromVersion: before,
122
+ toVersion: result.resolvedVersion,
123
+ manifestPath: result.manifestPath,
124
+ message,
125
+ warnings,
126
+ nextSteps,
127
+ };
128
+ }
129
+ catch (err) {
130
+ return {
131
+ kind: 'failure',
132
+ success: false,
133
+ extensionId,
134
+ warnings,
135
+ nextSteps,
136
+ error: err instanceof Error ? err : new Error(String(err)),
137
+ };
138
+ }
139
+ }
140
+ /**
141
+ * Read the version currently pinned for `packageId` in the project manifest, or
142
+ * `null` when the dependency is absent. Used to classify the outcome as
143
+ * added / updated / already-up-to-date, which `addPackageToManifest`'s
144
+ * `{ modified }` flag cannot express on its own.
145
+ *
146
+ * Deliberately forgiving: any read/parse problem yields `null` (treated as
147
+ * "not installed"). The subsequent `addPackageToManifest` call performs the
148
+ * authoritative read and throws a precise error if the manifest is unusable, so
149
+ * swallowing here cannot mask a real failure — it only avoids duplicating the
150
+ * error path.
151
+ */
152
+ function readInstalledVersion(manifestPath, packageId) {
153
+ try {
154
+ const raw = fs.readFileSync(manifestPath, 'utf-8');
155
+ const parsed = JSON.parse(raw);
156
+ const current = parsed?.dependencies?.[packageId];
157
+ return typeof current === 'string' && current.trim() !== '' ? current : null;
158
+ }
159
+ catch {
160
+ return null;
161
+ }
162
+ }
163
+ /** Return a descriptor with the `version` override applied (empty/whitespace override is ignored). */
164
+ function applyVersionOverride(descriptor, version, warnings) {
165
+ const v = (version ?? '').trim();
166
+ if (v === '')
167
+ return descriptor;
168
+ if (descriptor.version !== null && descriptor.version !== v) {
169
+ warnings.push(`version ${v} overrides the catalogue pin ${descriptor.packageId}@${descriptor.version} for this install.`);
170
+ }
171
+ return { ...descriptor, version: v };
172
+ }
173
+ /** A clear "unknown extension" error that lists what IS installable (or says the catalogue is empty). */
174
+ function unknownExtensionMessage(id, catalog) {
175
+ if (catalog.length === 0) {
176
+ return (`Unknown extension "${id}". The Unity-MCP extension catalogue is currently empty, ` +
177
+ 'so there is nothing to install.');
178
+ }
179
+ const available = catalog.map((d) => d.packageId).join(', ');
180
+ return `Unknown extension "${id}". Available extensions: ${available}.`;
181
+ }
182
+ //# sourceMappingURL=install-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-extension.js","sourceRoot":"","sources":["../../src/lib/install-extension.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { ExtensionDescriptor } from '../utils/extensions-catalog.js';
1
2
  /**
2
3
  * Discriminated union describing every progress event the library can
3
4
  * emit to the optional `onProgress` callback.
@@ -120,6 +121,84 @@ export interface InstallFailure {
120
121
  error: Error;
121
122
  }
122
123
  export type InstallResult = InstallSuccess | InstallFailure;
124
+ /**
125
+ * What `installExtension` actually did. Distinguished from `changed` because a
126
+ * caller usually wants to say "installed" vs "updated" vs "nothing to do" in its
127
+ * UI, and `changed` alone cannot tell the first two apart.
128
+ */
129
+ export type InstallExtensionOutcome = 'added' | 'updated' | 'already-up-to-date';
130
+ export interface InstallExtensionOptions {
131
+ /** Absolute or relative path to the Unity project's root. */
132
+ unityProjectPath: string;
133
+ /**
134
+ * Extension to install — either the OpenUPM package id
135
+ * (`com.ivanmurzak.unity.mcp.tilemap`) or the catalogue display name
136
+ * (`Tilemap`). Matched case-insensitively, package id first.
137
+ */
138
+ extensionId: string;
139
+ /**
140
+ * Version to install. When omitted, OpenUPM's `dist-tags.latest` is resolved
141
+ * live at install time — which is the normal path, because every catalogue
142
+ * entry is unpinned (`version: null`). Supplying a value also permits a
143
+ * downgrade, mirroring `installPlugin`'s explicit-version semantics.
144
+ */
145
+ version?: string;
146
+ /**
147
+ * Catalogue override, for tests and for callers that carry their own list.
148
+ * Defaults to the built-in `EXTENSIONS_CATALOG`.
149
+ */
150
+ catalog?: readonly ExtensionDescriptor[];
151
+ /**
152
+ * Optional progress callback — fires for `start`, `dependencies-resolved`
153
+ * (when the version was auto-resolved), `manifest-patched`, and `done`.
154
+ */
155
+ onProgress?: ProgressCallback;
156
+ }
157
+ /** Successful `installExtension` outcome. Narrow with `kind === 'success'`. */
158
+ export interface InstallExtensionSuccess {
159
+ kind: 'success';
160
+ /** Always `true` for the success variant. */
161
+ success: true;
162
+ /** What happened — see {@link InstallExtensionOutcome}. */
163
+ outcome: InstallExtensionOutcome;
164
+ /** `true` when `manifest.json` was written. `false` for `already-up-to-date`. */
165
+ changed: boolean;
166
+ /** The `extensionId` as supplied by the caller. */
167
+ extensionId: string;
168
+ /** The resolved OpenUPM package id that was written to the manifest. */
169
+ packageId: string;
170
+ /** Version present before the call, or `null` when the extension was absent. */
171
+ fromVersion: string | null;
172
+ /** Version present after the call. */
173
+ toVersion: string;
174
+ /** Absolute path to the `Packages/manifest.json` that was inspected / written. */
175
+ manifestPath: string;
176
+ /** Human-readable summary the caller may surface directly. */
177
+ message: string;
178
+ /** Non-fatal warnings collected during the run. */
179
+ warnings: string[];
180
+ /** Suggested next steps for the caller to surface to a human user. */
181
+ nextSteps: string[];
182
+ }
183
+ /** Failed `installExtension` outcome. Narrow with `kind === 'failure'`. */
184
+ export interface InstallExtensionFailure {
185
+ kind: 'failure';
186
+ /** Always `false` for the failure variant. */
187
+ success: false;
188
+ /** The `extensionId` as supplied by the caller. */
189
+ extensionId: string;
190
+ /** Resolved package id, when catalogue lookup succeeded before the failure. */
191
+ packageId?: string;
192
+ /** Manifest path may be known even on failure (e.g. a validation failure that reached it). */
193
+ manifestPath?: string;
194
+ /** Non-fatal warnings collected before the failure. */
195
+ warnings: string[];
196
+ /** Suggested next steps the caller may surface to a human user. */
197
+ nextSteps: string[];
198
+ /** The captured error. Never thrown past this boundary. */
199
+ error: Error;
200
+ }
201
+ export type InstallExtensionResult = InstallExtensionSuccess | InstallExtensionFailure;
123
202
  export interface RemovePluginOptions {
124
203
  unityProjectPath: string;
125
204
  onProgress?: ProgressCallback;
package/dist/lib.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  export { installPlugin } from './lib/install-plugin.js';
2
+ export { installExtension } from './lib/install-extension.js';
2
3
  export { removePlugin } from './lib/remove-plugin.js';
3
4
  export { configure } from './lib/configure.js';
4
5
  export { setupMcp, listAgentIds } from './lib/setup-mcp.js';
5
6
  export { openProject } from './lib/open.js';
6
7
  export { createProject } from './lib/create-project.js';
7
8
  export { runTool, runSystemTool } from './lib/run-tool.js';
8
- export type { ProgressEvent, ProgressCallback, ResultKind, InstallPluginOptions, InstallResult, InstallSuccess, InstallFailure, RemovePluginOptions, RemoveResult, RemoveSuccess, RemoveFailure, ConfigureOptions, ConfigureResult, ConfigureSuccess, ConfigureFailure, ConfigureSnapshot, FeatureAction, McpFeatureSnapshot, SetupMcpOptions, SetupMcpResult, SetupMcpSuccess, SetupMcpFailure, McpTransport, OpenProjectOptions, OpenProjectResult, OpenProjectSuccess, OpenProjectFailure, OpenProjectAuthOption, OpenProjectTransport, CreateProjectOptions, CreateProjectResult, CreateProjectSuccess, CreateProjectFailure, CreateProjectEditorInfo, RunToolOptions, RunToolResult, RunToolSuccess, RunToolFailure, RunToolFailureReason, RunSystemToolOptions, RunSystemToolResult, RunSystemToolSuccess, RunSystemToolFailure, } from './lib/types.js';
9
+ export { EXTENSIONS_CATALOG, findExtension, hasVersion, } from './utils/extensions-catalog.js';
10
+ export type { ExtensionDescriptor, ExtensionTool, } from './utils/extensions-catalog.js';
11
+ export type { ProgressEvent, ProgressCallback, ResultKind, InstallPluginOptions, InstallResult, InstallSuccess, InstallFailure, InstallExtensionOptions, InstallExtensionResult, InstallExtensionSuccess, InstallExtensionFailure, InstallExtensionOutcome, RemovePluginOptions, RemoveResult, RemoveSuccess, RemoveFailure, ConfigureOptions, ConfigureResult, ConfigureSuccess, ConfigureFailure, ConfigureSnapshot, FeatureAction, McpFeatureSnapshot, SetupMcpOptions, SetupMcpResult, SetupMcpSuccess, SetupMcpFailure, McpTransport, OpenProjectOptions, OpenProjectResult, OpenProjectSuccess, OpenProjectFailure, OpenProjectAuthOption, OpenProjectTransport, CreateProjectOptions, CreateProjectResult, CreateProjectSuccess, CreateProjectFailure, CreateProjectEditorInfo, RunToolOptions, RunToolResult, RunToolSuccess, RunToolFailure, RunToolFailureReason, RunSystemToolOptions, RunSystemToolResult, RunSystemToolSuccess, RunSystemToolFailure, } from './lib/types.js';
package/dist/lib.js CHANGED
@@ -16,10 +16,15 @@
16
16
  // Consumers: `import { installPlugin } from 'unity-mcp-cli'` (maps to
17
17
  // this file via the `exports` field in package.json).
18
18
  export { installPlugin } from './lib/install-plugin.js';
19
+ export { installExtension } from './lib/install-extension.js';
19
20
  export { removePlugin } from './lib/remove-plugin.js';
20
21
  export { configure } from './lib/configure.js';
21
22
  export { setupMcp, listAgentIds } from './lib/setup-mcp.js';
22
23
  export { openProject } from './lib/open.js';
23
24
  export { createProject } from './lib/create-project.js';
24
25
  export { runTool, runSystemTool } from './lib/run-tool.js';
26
+ // The extension catalogue is part of the public library surface: a consumer that
27
+ // renders an "install an extension" list (the desktop app) needs the same ten
28
+ // entries the CLI installs from, and must not re-declare them.
29
+ export { EXTENSIONS_CATALOG, findExtension, hasVersion, } from './utils/extensions-catalog.js';
25
30
  //# sourceMappingURL=lib.js.map
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,qDAAqD;AACrD,iEAAiE;AACjE,sEAAsE;AACtE,oDAAoD;AACpD,yEAAyE;AACzE,0EAA0E;AAC1E,0EAA0E;AAC1E,uEAAuE;AACvE,uEAAuE;AACvE,iEAAiE;AACjE,oEAAoE;AACpE,2BAA2B;AAC3B,EAAE;AACF,sEAAsE;AACtE,sDAAsD;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,qDAAqD;AACrD,iEAAiE;AACjE,sEAAsE;AACtE,oDAAoD;AACpD,yEAAyE;AACzE,0EAA0E;AAC1E,0EAA0E;AAC1E,uEAAuE;AACvE,uEAAuE;AACvE,iEAAiE;AACjE,oEAAoE;AACpE,2BAA2B;AAC3B,EAAE;AACF,sEAAsE;AACtE,sDAAsD;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAE3D,iFAAiF;AACjF,8EAA8E;AAC9E,+DAA+D;AAC/D,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,UAAU,GACX,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,40 @@
1
+ /** One tool a catalogue extension contributes — mirrors the JSON `tools[]` entry. */
2
+ export interface ExtensionTool {
3
+ readonly name: string;
4
+ readonly description: string;
5
+ }
6
+ /**
7
+ * One installable extension — the CLI analog of the C# `ExtensionPanel.ExtensionData`.
8
+ * `packageId` is the INSTALL IDENTITY (the `Packages/manifest.json` dependency key,
9
+ * resolved from the OpenUPM scoped registry).
10
+ * `version` is `null` for a floating (unpinned) reference — every catalogue entry is
11
+ * unpinned, so OpenUPM's `dist-tags.latest` is resolved live at install time.
12
+ *
13
+ * `tools` is the same CURATED highlight list the editor renders in an extension's
14
+ * tooltip (`ExtensionPanel.BuildTooltip`) — it is deliberately NOT an exhaustive
15
+ * inventory of the extension's MCP tools, and must not be consumed as one.
16
+ */
17
+ export interface ExtensionDescriptor {
18
+ readonly name: string;
19
+ readonly description: string;
20
+ readonly packageId: string;
21
+ readonly version: string | null;
22
+ readonly gitUrl: string | null;
23
+ readonly tools: readonly ExtensionTool[];
24
+ }
25
+ /**
26
+ * The extension catalogue, single-sourced from
27
+ * `Unity-MCP-Plugin/Packages/com.ivanmurzak.unity.mcp/extensions.catalog.json`.
28
+ * Ten shipped extensions; `Unity-AI-Tools-Template` is a template and is excluded.
29
+ */
30
+ export declare const EXTENSIONS_CATALOG: readonly ExtensionDescriptor[];
31
+ /** True when a descriptor carries a concrete version pin (drives the up-to-date / update decision). */
32
+ export declare function hasVersion(descriptor: ExtensionDescriptor): boolean;
33
+ /**
34
+ * Resolve a user-supplied `<id>` to a catalogue descriptor. Matches by `packageId`
35
+ * first (case-insensitively — UPM package names are lowercase by convention, and
36
+ * this is the install identity), then falls back to an exact case-insensitive `name`
37
+ * match for convenience (`unity-mcp-cli install-extension Tilemap`). Returns `null`
38
+ * when absent or `id` is empty.
39
+ */
40
+ export declare function findExtension(id: string | undefined | null, catalog?: readonly ExtensionDescriptor[]): ExtensionDescriptor | null;
@@ -0,0 +1,197 @@
1
+ // The CLI's typed mirror of the SHARED extension catalogue — the single source of
2
+ // truth `Unity-MCP-Plugin/Packages/com.ivanmurzak.unity.mcp/extensions.catalog.json`
3
+ // (see that file's sibling `extensions.catalog.md`).
4
+ //
5
+ // There are THREE artifacts holding this same list, and all three are kept in
6
+ // lockstep by build-failing parity tests:
7
+ //
8
+ // 1. `extensions.catalog.json` — the JSON source of truth, shipped in the UPM package.
9
+ // 2. `MainWindowEditor._extensions` — the C# array that drives the editor's Extensions
10
+ // section and `ExtensionPanel.AddToManifest`.
11
+ // 3. `EXTENSIONS_CATALOG` (this file) — drives `installExtension` in this CLI.
12
+ //
13
+ // SINGLE SOURCE OF TRUTH: this constant MUST stay equivalent to the JSON. The parity
14
+ // test `cli/tests/extensions-catalog-parity.test.ts` reads the JSON and FAILS the build
15
+ // if this mirror drifts; `cli/tests/extensions-catalog-csharp-parity.test.ts` does the
16
+ // same for the C# array. Adding an extension = appending an entry to the JSON, the C#
17
+ // array, AND this array (both tests enforce it). This mirror exists so the published npm
18
+ // package stays self-contained — no runtime `../Unity-MCP-Plugin` dependency.
19
+ //
20
+ // No top-level side effects; pure data + pure lookups only.
21
+ /**
22
+ * The extension catalogue, single-sourced from
23
+ * `Unity-MCP-Plugin/Packages/com.ivanmurzak.unity.mcp/extensions.catalog.json`.
24
+ * Ten shipped extensions; `Unity-AI-Tools-Template` is a template and is excluded.
25
+ */
26
+ export const EXTENSIONS_CATALOG = [
27
+ {
28
+ name: 'Animation',
29
+ description: 'AI-driven animation control and playback tools.',
30
+ packageId: 'com.ivanmurzak.unity.mcp.animation',
31
+ version: null,
32
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-Animation.git',
33
+ tools: [
34
+ { name: 'animation-create', description: 'Create AnimationClip assets with keyframes' },
35
+ { name: 'animation-get-data', description: 'Inspect clip curves, events, and properties' },
36
+ { name: 'animation-modify', description: 'Edit curves, events, and settings on a clip' },
37
+ { name: 'animator-create', description: 'Create AnimatorController assets' },
38
+ { name: 'animator-get-data', description: 'Inspect controller layers, states, and parameters' },
39
+ { name: 'animator-modify', description: 'Edit parameters, states, and transitions' },
40
+ ],
41
+ },
42
+ {
43
+ name: 'Cinemachine',
44
+ description: 'AI-assisted Cinemachine camera setup and configuration tools.',
45
+ packageId: 'com.ivanmurzak.unity.mcp.cinemachine',
46
+ version: null,
47
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-Cinemachine.git',
48
+ tools: [
49
+ { name: 'cinemachine-camera-create', description: 'Create a CinemachineCamera in the scene' },
50
+ { name: 'cinemachine-set-targets', description: 'Set the Follow and LookAt targets' },
51
+ { name: 'cinemachine-set-lens', description: 'Configure FOV, clip planes, and dutch' },
52
+ { name: 'cinemachine-set-body', description: 'Set the position-control component (Follow/Orbital/...)' },
53
+ { name: 'cinemachine-set-noise', description: 'Add camera shake via Perlin noise' },
54
+ ],
55
+ },
56
+ {
57
+ name: 'InputSystem',
58
+ description: 'AI-assisted Unity Input System authoring: InputActionAssets, maps, actions, bindings, and control schemes.',
59
+ packageId: 'com.ivanmurzak.unity.mcp.inputsystem',
60
+ version: null,
61
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-InputSystem.git',
62
+ tools: [
63
+ { name: 'inputsystem-asset-create', description: 'Create a new .inputactions InputActionAsset' },
64
+ { name: 'inputsystem-actionmap-add', description: 'Add an ActionMap to the asset' },
65
+ { name: 'inputsystem-action-add', description: 'Add an Action (type + expectedControlType)' },
66
+ { name: 'inputsystem-binding-add', description: 'Add a binding path to an Action' },
67
+ { name: 'inputsystem-binding-composite-add', description: 'Add a composite binding (2DVector/1DAxis)' },
68
+ { name: 'inputsystem-controlscheme-add', description: 'Add a control scheme with device requirements' },
69
+ { name: 'inputsystem-get', description: "Read the asset's maps, actions, and bindings" },
70
+ ],
71
+ },
72
+ {
73
+ name: 'Navigation',
74
+ description: 'AI-driven NavMesh navigation: surfaces, baking, agents, and links.',
75
+ packageId: 'com.ivanmurzak.unity.mcp.navigation',
76
+ version: null,
77
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-Navigation.git',
78
+ tools: [
79
+ { name: 'navigation-surface-add', description: 'Add and configure a NavMeshSurface' },
80
+ { name: 'navigation-set-bake-settings', description: 'Set agent radius/height/slope/step and voxel size' },
81
+ { name: 'navigation-surface-bake', description: 'Bake or clear a NavMeshSurface' },
82
+ { name: 'navigation-modifier-add', description: 'Add a NavMeshModifier (override area / ignore)' },
83
+ { name: 'navigation-modifier-volume-add', description: 'Add a NavMeshModifierVolume' },
84
+ { name: 'navigation-link-add', description: 'Add a NavMeshLink between two points' },
85
+ { name: 'navigation-agent-add', description: 'Add and configure a NavMeshAgent' },
86
+ { name: 'navigation-agent-set-destination', description: "Set a NavMeshAgent's destination" },
87
+ { name: 'navigation-list', description: 'List NavMeshSurfaces and NavMeshAgents' },
88
+ { name: 'navigation-get', description: 'Serialize any NavMesh component' },
89
+ { name: 'navigation-modify', description: 'Modify any NavMesh component via ReflectorNet' },
90
+ ],
91
+ },
92
+ {
93
+ name: 'ParticleSystem',
94
+ description: 'AI-powered particle system creation and control tools.',
95
+ packageId: 'com.ivanmurzak.unity.mcp.particlesystem',
96
+ version: null,
97
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-ParticleSystem.git',
98
+ tools: [
99
+ { name: 'particle-system-get', description: 'Inspect ParticleSystem modules and settings' },
100
+ { name: 'particle-system-modify', description: 'Modify emission, shape, color, noise, and more' },
101
+ ],
102
+ },
103
+ {
104
+ name: 'ProBuilder',
105
+ description: 'AI-assisted ProBuilder geometry modeling tools.',
106
+ packageId: 'com.ivanmurzak.unity.mcp.probuilder',
107
+ version: null,
108
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-ProBuilder.git',
109
+ tools: [
110
+ { name: 'probuilder-create-shape', description: 'Create editable 3D primitives in the scene' },
111
+ { name: 'probuilder-get-mesh-info', description: 'Retrieve faces, vertices, and edges data' },
112
+ { name: 'probuilder-extrude', description: 'Extrude faces along their normals' },
113
+ { name: 'probuilder-delete-faces', description: 'Remove faces to create holes or trim geometry' },
114
+ { name: 'probuilder-set-face-material', description: 'Assign materials to individual faces' },
115
+ ],
116
+ },
117
+ {
118
+ name: 'Splines',
119
+ description: 'AI-assisted Spline authoring: containers, knots, tangents, and evaluation.',
120
+ packageId: 'com.ivanmurzak.unity.mcp.splines',
121
+ version: null,
122
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-Splines.git',
123
+ tools: [
124
+ { name: 'splines-container-create', description: 'Create a SplineContainer in the scene' },
125
+ { name: 'splines-add-knot', description: 'Append a knot to a spline' },
126
+ { name: 'splines-set-knot', description: "Set a knot's position, tangents, and rotation" },
127
+ { name: 'splines-set-tangent-mode', description: "Set a knot's tangent mode" },
128
+ { name: 'splines-evaluate', description: 'Evaluate position/tangent/up along a spline' },
129
+ { name: 'splines-modify', description: 'Modify any Splines component via ReflectorNet' },
130
+ ],
131
+ },
132
+ {
133
+ name: 'Terrain',
134
+ description: 'AI-powered Unity Terrain authoring tools.',
135
+ packageId: 'com.ivanmurzak.unity.mcp.terrain',
136
+ version: null,
137
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-Terrain.git',
138
+ tools: [
139
+ { name: 'terrain-create', description: 'Create a Terrain GameObject backed by new TerrainData' },
140
+ { name: 'terrain-set-heights', description: 'Sculpt heightmap values over a region or the whole terrain' },
141
+ { name: 'terrain-paint-layer', description: 'Paint a TerrainLayer onto the alphamap (splatmap)' },
142
+ { name: 'terrain-place-trees', description: 'Scatter or place trees from a tree prototype' },
143
+ { name: 'terrain-set-neighbors', description: 'Stitch neighbor Terrains so Unity blends seams' },
144
+ ],
145
+ },
146
+ {
147
+ name: 'Tilemap',
148
+ description: 'AI-assisted 2D Tilemap creation, painting, and tile/RuleTile asset tools.',
149
+ packageId: 'com.ivanmurzak.unity.mcp.tilemap',
150
+ version: null,
151
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-Tilemap.git',
152
+ tools: [
153
+ { name: 'tilemap-create', description: 'Create a Grid + Tilemap + TilemapRenderer' },
154
+ { name: 'tilemap-set-tile', description: 'Paint a tile into a cell' },
155
+ { name: 'tilemap-box-fill', description: 'Fill a rectangular region with a tile' },
156
+ { name: 'tilemap-create-tile-asset', description: 'Create a Tile asset from a Sprite' },
157
+ { name: 'tilemap-create-rule-tile', description: 'Create a RuleTile asset (2D Tilemap Extras)' },
158
+ ],
159
+ },
160
+ {
161
+ name: 'Timeline',
162
+ description: 'AI-assisted Timeline cutscene and sequence authoring tools.',
163
+ packageId: 'com.ivanmurzak.unity.mcp.timeline',
164
+ version: null,
165
+ gitUrl: 'https://github.com/IvanMurzak/Unity-AI-Timeline.git',
166
+ tools: [
167
+ { name: 'timeline-create', description: 'Create a TimelineAsset (.playable)' },
168
+ { name: 'timeline-track-add', description: 'Add Animation/Activation/Audio/Signal/Control tracks' },
169
+ { name: 'timeline-clip-add', description: 'Add clips to a track with start and duration' },
170
+ { name: 'timeline-director-bind', description: 'Bind a TimelineAsset to a scene PlayableDirector' },
171
+ { name: 'timeline-modify', description: 'Modify any Timeline object via ReflectorNet' },
172
+ ],
173
+ },
174
+ ];
175
+ /** True when a descriptor carries a concrete version pin (drives the up-to-date / update decision). */
176
+ export function hasVersion(descriptor) {
177
+ return descriptor.version !== null && descriptor.version.trim() !== '';
178
+ }
179
+ /**
180
+ * Resolve a user-supplied `<id>` to a catalogue descriptor. Matches by `packageId`
181
+ * first (case-insensitively — UPM package names are lowercase by convention, and
182
+ * this is the install identity), then falls back to an exact case-insensitive `name`
183
+ * match for convenience (`unity-mcp-cli install-extension Tilemap`). Returns `null`
184
+ * when absent or `id` is empty.
185
+ */
186
+ export function findExtension(id, catalog = EXTENSIONS_CATALOG) {
187
+ if (id === undefined || id === null)
188
+ return null;
189
+ const needle = id.trim();
190
+ if (needle === '')
191
+ return null;
192
+ const byPackageId = catalog.find((d) => d.packageId.toLowerCase() === needle.toLowerCase());
193
+ if (byPackageId)
194
+ return byPackageId;
195
+ return catalog.find((d) => d.name.toLowerCase() === needle.toLowerCase()) ?? null;
196
+ }
197
+ //# sourceMappingURL=extensions-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions-catalog.js","sourceRoot":"","sources":["../../src/utils/extensions-catalog.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,23 @@ import { type LibLogger } from '../lib/logger.js';
8
8
  * styled logger adapter explicitly to preserve the historical output.
9
9
  */
10
10
  export declare function resolveLatestVersion(logger?: LibLogger): Promise<string>;
11
+ /**
12
+ * Resolve the latest version of ANY OpenUPM-hosted package (the plugin itself, or
13
+ * one of the catalogue extensions) from the OpenUPM registry. Throws an error with
14
+ * actionable suggestions if the network request fails.
15
+ *
16
+ * This is the generalisation of {@link resolveLatestVersion}: same 5000 ms
17
+ * `AbortController` abort, same "no cached fallback" behaviour, same actionable
18
+ * error — the only difference is that the package id is a parameter and the
19
+ * suggested escape-hatch flag is caller-supplied, because `install-plugin` offers
20
+ * `--plugin-version` where `install-extension` offers `--version`.
21
+ *
22
+ * @param packageId OpenUPM package id to resolve (e.g. `com.ivanmurzak.unity.mcp.tilemap`).
23
+ * @param logger Optional logger. Defaults to `silentLogger` so library callers stay
24
+ * side-effect-free.
25
+ * @param versionFlag Name of the CLI flag suggested in the failure message.
26
+ */
27
+ export declare function resolveLatestPackageVersion(packageId: string, logger?: LibLogger, versionFlag?: string): Promise<string>;
11
28
  /**
12
29
  * Determines if the version should be updated.
13
30
  * Only update if the new version is higher than the current version.
@@ -36,6 +53,27 @@ export interface AddPluginResult {
36
53
  * styled logger adapter explicitly to preserve the historical output.
37
54
  */
38
55
  export declare function addPluginToManifest(projectPath: string, version: string, force?: boolean, logger?: LibLogger): AddPluginResult;
56
+ /**
57
+ * Add ANY OpenUPM-hosted package to a Unity project's `Packages/manifest.json` —
58
+ * the plugin itself, or one of the catalogue extensions.
59
+ *
60
+ * This is the generalisation of {@link addPluginToManifest}, which now delegates
61
+ * here with `PACKAGE_ID`. Keeping ONE implementation matters because the
62
+ * scoped-registry rules (registry name, URL, and the `REQUIRED_SCOPES` pair
63
+ * `com.ivanmurzak` / `extensions.unity`) must be identical for the plugin and for
64
+ * every extension — the extensions live under the `com.ivanmurzak` scope, so an
65
+ * extension installed without that scope resolves against Unity's default registry
66
+ * and fails. It also mirrors the C# editor installer
67
+ * (`ExtensionPanel.AddToManifest` / `EnsureScopedRegistry`), which single-sources
68
+ * the same three constants on the Unity side.
69
+ *
70
+ * Behaviour (unchanged from the plugin-only version):
71
+ * - Adds the OpenUPM scoped registry with the required scopes when missing.
72
+ * - Adds/updates the package dependency.
73
+ * - When `force` is false (auto-resolved version): never downgrades.
74
+ * - When `force` is true (user-specified version): allows downgrade.
75
+ */
76
+ export declare function addPackageToManifest(projectPath: string, packageId: string, version: string, force?: boolean, logger?: LibLogger): AddPluginResult;
39
77
  export interface RemovePluginResult {
40
78
  /** Whether the plugin was present and has been removed. */
41
79
  removed: boolean;
@@ -18,10 +18,29 @@ const REQUIRED_SCOPES = [
18
18
  * styled logger adapter explicitly to preserve the historical output.
19
19
  */
20
20
  export async function resolveLatestVersion(logger = silentLogger) {
21
+ return resolveLatestPackageVersion(PACKAGE_ID, logger);
22
+ }
23
+ /**
24
+ * Resolve the latest version of ANY OpenUPM-hosted package (the plugin itself, or
25
+ * one of the catalogue extensions) from the OpenUPM registry. Throws an error with
26
+ * actionable suggestions if the network request fails.
27
+ *
28
+ * This is the generalisation of {@link resolveLatestVersion}: same 5000 ms
29
+ * `AbortController` abort, same "no cached fallback" behaviour, same actionable
30
+ * error — the only difference is that the package id is a parameter and the
31
+ * suggested escape-hatch flag is caller-supplied, because `install-plugin` offers
32
+ * `--plugin-version` where `install-extension` offers `--version`.
33
+ *
34
+ * @param packageId OpenUPM package id to resolve (e.g. `com.ivanmurzak.unity.mcp.tilemap`).
35
+ * @param logger Optional logger. Defaults to `silentLogger` so library callers stay
36
+ * side-effect-free.
37
+ * @param versionFlag Name of the CLI flag suggested in the failure message.
38
+ */
39
+ export async function resolveLatestPackageVersion(packageId, logger = silentLogger, versionFlag = '--plugin-version') {
21
40
  const controller = new AbortController();
22
41
  const timeout = setTimeout(() => controller.abort(), 5000);
23
42
  try {
24
- const res = await fetch(`https://package.openupm.com/${PACKAGE_ID}`, {
43
+ const res = await fetch(`https://package.openupm.com/${packageId}`, {
25
44
  signal: controller.signal,
26
45
  headers: { Accept: 'application/json' },
27
46
  });
@@ -34,14 +53,14 @@ export async function resolveLatestVersion(logger = silentLogger) {
34
53
  }
35
54
  }
36
55
  throw new Error(`OpenUPM returned status ${res.status}. ` +
37
- 'Check your network connection and retry, or specify a version manually with --plugin-version <version>');
56
+ `Check your network connection and retry, or specify a version manually with ${versionFlag} <version>`);
38
57
  }
39
58
  catch (err) {
40
- if (err instanceof Error && err.message.includes('--plugin-version')) {
59
+ if (err instanceof Error && err.message.includes(versionFlag)) {
41
60
  throw err;
42
61
  }
43
- throw new Error('Failed to resolve latest plugin version from OpenUPM. ' +
44
- 'Check your network connection and retry, or specify a version manually with --plugin-version <version>');
62
+ throw new Error(`Failed to resolve the latest version of ${packageId} from OpenUPM. ` +
63
+ `Check your network connection and retry, or specify a version manually with ${versionFlag} <version>`);
45
64
  }
46
65
  finally {
47
66
  clearTimeout(timeout);
@@ -80,6 +99,29 @@ export function shouldUpdateVersion(currentVersion, newVersion) {
80
99
  * styled logger adapter explicitly to preserve the historical output.
81
100
  */
82
101
  export function addPluginToManifest(projectPath, version, force = false, logger = silentLogger) {
102
+ return addPackageToManifest(projectPath, PACKAGE_ID, version, force, logger);
103
+ }
104
+ /**
105
+ * Add ANY OpenUPM-hosted package to a Unity project's `Packages/manifest.json` —
106
+ * the plugin itself, or one of the catalogue extensions.
107
+ *
108
+ * This is the generalisation of {@link addPluginToManifest}, which now delegates
109
+ * here with `PACKAGE_ID`. Keeping ONE implementation matters because the
110
+ * scoped-registry rules (registry name, URL, and the `REQUIRED_SCOPES` pair
111
+ * `com.ivanmurzak` / `extensions.unity`) must be identical for the plugin and for
112
+ * every extension — the extensions live under the `com.ivanmurzak` scope, so an
113
+ * extension installed without that scope resolves against Unity's default registry
114
+ * and fails. It also mirrors the C# editor installer
115
+ * (`ExtensionPanel.AddToManifest` / `EnsureScopedRegistry`), which single-sources
116
+ * the same three constants on the Unity side.
117
+ *
118
+ * Behaviour (unchanged from the plugin-only version):
119
+ * - Adds the OpenUPM scoped registry with the required scopes when missing.
120
+ * - Adds/updates the package dependency.
121
+ * - When `force` is false (auto-resolved version): never downgrades.
122
+ * - When `force` is true (user-specified version): allows downgrade.
123
+ */
124
+ export function addPackageToManifest(projectPath, packageId, version, force = false, logger = silentLogger) {
83
125
  const manifestPath = path.join(projectPath, 'Packages', 'manifest.json');
84
126
  if (!fs.existsSync(manifestPath)) {
85
127
  throw new Error(`manifest.json not found at: ${manifestPath}`);
@@ -119,15 +161,15 @@ export function addPluginToManifest(projectPath, version, force = false, logger
119
161
  manifest.dependencies = {};
120
162
  modified = true;
121
163
  }
122
- const currentVersion = manifest.dependencies[PACKAGE_ID];
164
+ const currentVersion = manifest.dependencies[packageId];
123
165
  let resolvedVersion = version;
124
166
  if (!currentVersion || force || shouldUpdateVersion(currentVersion, version)) {
125
- manifest.dependencies[PACKAGE_ID] = version;
167
+ manifest.dependencies[packageId] = version;
126
168
  modified = true;
127
169
  }
128
170
  else {
129
171
  resolvedVersion = currentVersion;
130
- logger.info(`Plugin already at version ${currentVersion} (>= ${version}). Skipping version update. Use --plugin-version to force a specific version.`);
172
+ logger.info(`${packageId} already at version ${currentVersion} (>= ${version}). Skipping version update. Pass an explicit version to force a specific version.`);
131
173
  }
132
174
  // --- Write back
133
175
  if (modified) {
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/utils/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/utils/manifest.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unity-mcp-cli",
3
- "version": "0.88.0",
3
+ "version": "0.90.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
6
  "main": "dist/lib.js",