unity-mcp-cli 0.87.0 → 0.89.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 (46) hide show
  1. package/README.md +60 -2
  2. package/dist/commands/install-extension.d.ts +2 -0
  3. package/dist/commands/install-extension.js +99 -0
  4. package/dist/commands/install-extension.js.map +1 -0
  5. package/dist/commands/install-plugin.js +20 -0
  6. package/dist/commands/install-plugin.js.map +1 -1
  7. package/dist/commands/login.js +47 -2
  8. package/dist/commands/login.js.map +1 -1
  9. package/dist/commands/run-tool-builder.js +19 -3
  10. package/dist/commands/run-tool-builder.js.map +1 -1
  11. package/dist/commands/setup-skills.js +1 -1
  12. package/dist/commands/setup-skills.js.map +1 -1
  13. package/dist/commands/status.js +1 -1
  14. package/dist/commands/status.js.map +1 -1
  15. package/dist/commands/wait-for-ready.js +4 -4
  16. package/dist/commands/wait-for-ready.js.map +1 -1
  17. package/dist/index.js +2 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/lib/install-extension.d.ts +25 -0
  20. package/dist/lib/install-extension.js +182 -0
  21. package/dist/lib/install-extension.js.map +1 -0
  22. package/dist/lib/run-tool.js +79 -41
  23. package/dist/lib/run-tool.js.map +1 -1
  24. package/dist/lib/types.d.ts +92 -4
  25. package/dist/lib.d.ts +4 -1
  26. package/dist/lib.js +5 -0
  27. package/dist/lib.js.map +1 -1
  28. package/dist/utils/cloud-credentials.d.ts +43 -0
  29. package/dist/utils/cloud-credentials.js +84 -0
  30. package/dist/utils/cloud-credentials.js.map +1 -0
  31. package/dist/utils/cloud-login.d.ts +29 -13
  32. package/dist/utils/cloud-login.js +198 -17
  33. package/dist/utils/cloud-login.js.map +1 -1
  34. package/dist/utils/config.d.ts +15 -21
  35. package/dist/utils/config.js +8 -26
  36. package/dist/utils/config.js.map +1 -1
  37. package/dist/utils/connection.d.ts +8 -5
  38. package/dist/utils/connection.js +7 -3
  39. package/dist/utils/connection.js.map +1 -1
  40. package/dist/utils/extensions-catalog.d.ts +40 -0
  41. package/dist/utils/extensions-catalog.js +197 -0
  42. package/dist/utils/extensions-catalog.js.map +1 -0
  43. package/dist/utils/manifest.d.ts +38 -0
  44. package/dist/utils/manifest.js +50 -8
  45. package/dist/utils/manifest.js.map +1 -1
  46. package/package.json +2 -2
@@ -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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"}
@@ -5,6 +5,7 @@
5
5
  // - Errors are returned in `{ kind: 'failure', success: false, ... }`,
6
6
  // never thrown past the public boundary.
7
7
  import { readConfig, resolveConnectionFromConfig, isCloudMode } from '../utils/config.js';
8
+ import { readCloudAccessToken, refreshCloudAccessToken } from '../utils/cloud-credentials.js';
8
9
  import { generatePortFromDirectory } from '../utils/port.js';
9
10
  import { requireProjectPath } from './validation.js';
10
11
  const DEFAULT_TIMEOUT_MS = 60000;
@@ -30,22 +31,10 @@ async function invokeTool(routePrefix, opts) {
30
31
  const validationFailure = validateOptions(opts);
31
32
  if (validationFailure)
32
33
  return validationFailure;
33
- const resolved = resolveConnection(opts);
34
- if (resolved.kind === 'failure')
35
- return resolved;
36
- const { url, token } = resolved;
37
- const body = serializeInput(opts.input);
38
- if ('error' in body) {
39
- return makeFailure({
40
- endpoint: '',
41
- reason: 'invalid-input',
42
- message: body.error.message,
43
- error: body.error,
44
- });
45
- }
46
- const endpoint = `${url}${routePrefix}/${encodeURIComponent(opts.toolName)}`;
47
34
  const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
48
35
  const timeoutMs = typeof opts.timeoutMs === 'number' && opts.timeoutMs > 0 ? opts.timeoutMs : DEFAULT_TIMEOUT_MS;
36
+ // Wire the abort/timeout plumbing BEFORE the first await so an external abort issued right
37
+ // after the call is never lost (connection resolution below may itself await a token refresh).
49
38
  const controller = new AbortController();
50
39
  const timer = setTimeout(() => controller.abort(), timeoutMs);
51
40
  const externalAbort = () => controller.abort();
@@ -55,35 +44,76 @@ async function invokeTool(routePrefix, opts) {
55
44
  else
56
45
  opts.signal.addEventListener('abort', externalAbort, { once: true });
57
46
  }
58
- const headers = { 'Content-Type': 'application/json' };
59
- if (token)
60
- headers['Authorization'] = `Bearer ${token}`;
47
+ let endpoint = '';
61
48
  try {
62
- const response = await fetchImpl(endpoint, {
63
- method: 'POST',
64
- headers,
65
- body: body.json,
66
- signal: controller.signal,
67
- });
68
- const text = await safeReadText(response);
69
- const data = parseJsonOrText(text);
70
- if (!response.ok) {
49
+ const resolved = await resolveConnection(opts);
50
+ if (resolved.kind === 'failure')
51
+ return resolved;
52
+ const { url, token } = resolved;
53
+ const body = serializeInput(opts.input);
54
+ if ('error' in body) {
71
55
  return makeFailure({
56
+ endpoint: '',
57
+ reason: 'invalid-input',
58
+ message: body.error.message,
59
+ error: body.error,
60
+ });
61
+ }
62
+ endpoint = `${url}${routePrefix}/${encodeURIComponent(opts.toolName)}`;
63
+ // Reactive-refresh loop (unified-machine-auth 04 §3 rule 1): when the Bearer came from the
64
+ // shared machine credential store and the server answers 401 — revocation or clock skew the
65
+ // proactive expiry check could not see — refresh the plugin family once under the
66
+ // cross-process lock and retry the call with the rotated token. At most ONE reactive attempt
67
+ // per invocation; an explicit --token / --url override is never refreshed. Both attempts
68
+ // share one timeout.
69
+ let bearer = token;
70
+ let attemptedReactiveRefresh = false;
71
+ for (;;) {
72
+ // Mirror fetch's contract for an ALREADY-aborted signal (an external abort may land while
73
+ // connection resolution above is awaiting): reject up front instead of relying on the
74
+ // 'abort' event, which has already fired.
75
+ if (controller.signal.aborted) {
76
+ throw new DOMException('The operation was aborted', 'AbortError');
77
+ }
78
+ const headers = { 'Content-Type': 'application/json' };
79
+ if (bearer)
80
+ headers['Authorization'] = `Bearer ${bearer}`;
81
+ const response = await fetchImpl(endpoint, {
82
+ method: 'POST',
83
+ headers,
84
+ body: body.json,
85
+ signal: controller.signal,
86
+ });
87
+ const text = await safeReadText(response);
88
+ const data = parseJsonOrText(text);
89
+ if (!response.ok) {
90
+ if (response.status === 401 &&
91
+ resolved.tokenFromCloudStore &&
92
+ !attemptedReactiveRefresh) {
93
+ attemptedReactiveRefresh = true;
94
+ const fresh = await (opts.refreshCloudToken ?? refreshCloudAccessToken)();
95
+ if (fresh) {
96
+ bearer = fresh;
97
+ continue;
98
+ }
99
+ }
100
+ return makeFailure({
101
+ endpoint,
102
+ reason: 'http-error',
103
+ httpStatus: response.status,
104
+ data,
105
+ message: response.statusText || `HTTP ${response.status}`,
106
+ });
107
+ }
108
+ const success = {
109
+ kind: 'success',
110
+ success: true,
72
111
  endpoint,
73
- reason: 'http-error',
74
112
  httpStatus: response.status,
75
113
  data,
76
- message: response.statusText || `HTTP ${response.status}`,
77
- });
114
+ };
115
+ return success;
78
116
  }
79
- const success = {
80
- kind: 'success',
81
- success: true,
82
- endpoint,
83
- httpStatus: response.status,
84
- data,
85
- };
86
- return success;
87
117
  }
88
118
  catch (err) {
89
119
  return classifyFetchError(err, endpoint, timeoutMs);
@@ -119,9 +149,14 @@ function validateOptions(opts) {
119
149
  }
120
150
  return null;
121
151
  }
122
- function resolveConnection(opts) {
152
+ async function resolveConnection(opts) {
123
153
  if (opts.url) {
124
- return { kind: 'success', url: opts.url.replace(/\/$/, ''), token: opts.token };
154
+ return {
155
+ kind: 'success',
156
+ url: opts.url.replace(/\/$/, ''),
157
+ token: opts.token,
158
+ tokenFromCloudStore: false,
159
+ };
125
160
  }
126
161
  // `unityProjectPath` is library-only — does NOT require an `Assets/`
127
162
  // folder, unlike the CLI's `resolveAndValidateProjectPath`. The
@@ -138,7 +173,9 @@ function resolveConnection(opts) {
138
173
  const projectPath = validated.projectPath;
139
174
  const config = readConfig(projectPath);
140
175
  const fromConfig = config
141
- ? resolveConnectionFromConfig(config, { readCloudToken: opts.readCloudToken })
176
+ ? await resolveConnectionFromConfig(config, {
177
+ readCloudToken: opts.readCloudToken ?? readCloudAccessToken,
178
+ })
142
179
  : { url: undefined, token: undefined };
143
180
  const url = fromConfig.url
144
181
  ? fromConfig.url.replace(/\/$/, '')
@@ -154,7 +191,8 @@ function resolveConnection(opts) {
154
191
  message: 'Not logged in to ai-game.dev. Run `unity-mcp-cli login` to sign in, or pass an explicit --token / --url.',
155
192
  });
156
193
  }
157
- return { kind: 'success', url, token };
194
+ const tokenFromCloudStore = !!config && isCloudMode(config) && !opts.token && !!token;
195
+ return { kind: 'success', url, token, tokenFromCloudStore };
158
196
  }
159
197
  function serializeInput(input) {
160
198
  if (input === undefined || input === null)
@@ -1 +1 @@
1
- {"version":3,"file":"run-tool.js","sourceRoot":"","sources":["../../src/lib/run-tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-tool.js","sourceRoot":"","sources":["../../src/lib/run-tool.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;
@@ -558,11 +637,20 @@ export interface RunToolOptions {
558
637
  fetchImpl?: typeof fetch;
559
638
  /**
560
639
  * Optional injection point for the Cloud-mode Bearer credential read from the shared machine
561
- * credential store (`~/.ai-game-dev/credentials.json`). Only consulted when the resolved project
562
- * config is in Cloud mode and neither `url` nor `token` was supplied. Defaults to reading the real
563
- * per-machine store; tests inject a deterministic value.
640
+ * credential store. Only consulted when the resolved project config is in Cloud mode and neither
641
+ * `url` nor `token` was supplied. Defaults to cli-core's `MachineCredentialProvider` (proactive
642
+ * refresh under the cross-process lock — never a raw on-disk read); tests inject a deterministic
643
+ * value. Sync or async both work.
644
+ */
645
+ readCloudToken?: () => Promise<string | undefined> | string | undefined;
646
+ /**
647
+ * Optional injection point for the REACTIVE Cloud-mode refresh: invoked at most once per call
648
+ * when the server answers 401 to a machine-store Bearer (revocation / clock skew). Returns the
649
+ * rotated access token, or `undefined` when the credential family is dead (the call then fails
650
+ * with the original 401). Defaults to cli-core's `MachineCredentialProvider.refresh`. Never
651
+ * consulted for an explicit `token` / `url` override.
564
652
  */
565
- readCloudToken?: () => string | undefined;
653
+ refreshCloudToken?: () => Promise<string | undefined> | string | undefined;
566
654
  }
567
655
  /** Successful `runTool` / `runSystemTool` outcome. Narrow with `kind === 'success'`. */
568
656
  export interface RunToolSuccess {
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,43 @@
1
+ import { MachineCredentialProvider, MachineCredentialStore } from '@baizor/gamedev-cli-core';
2
+ /**
3
+ * The CLI's single seam onto cli-core's `MachineCredentialProvider` (unified-machine-auth 02/04,
4
+ * task d2 / W2). Every Cloud-mode Bearer the CLI presents comes through here — the provider owns
5
+ * proactive refresh (inside the 60 s expiry skew), reactive refresh (driven by a hub 401), the
6
+ * cross-process credential lock, and the family-aware machine-store view. The CLI never reads
7
+ * `accessToken` raw off disk: a raw read returns a token that may be seconds from expiry (or past
8
+ * it) with nobody refreshing, which is exactly the defect this module replaces
9
+ * (the pre-d2 `readMachineStoreCloudToken`).
10
+ */
11
+ /** Injectable construction options — tests point the provider at a temp store + a fake AS. */
12
+ export interface CloudCredentialProviderOptions {
13
+ /** The credential store to serve from; defaults to the shared per-machine store. */
14
+ store?: MachineCredentialStore;
15
+ /** Authorization-server base for the refresh endpoint; defaults to the hosted cloud. */
16
+ serverBaseUrl?: string;
17
+ /** Injectable `fetch` for the refresher (tests). */
18
+ fetchImpl?: typeof fetch;
19
+ }
20
+ /**
21
+ * Build a `MachineCredentialProvider` wired the way this CLI consumes it:
22
+ * `HttpTokenRefresher` against the AS root, and `unity-mcp-cli` as the component-default client
23
+ * id — used ONLY for `families.legacy` (a stored family's own `clientId` always wins, 04 §3).
24
+ */
25
+ export declare function createCloudCredentialProvider(options?: CloudCredentialProviderOptions): MachineCredentialProvider;
26
+ /** TEST-ONLY: drop the cached default provider (e.g. after re-pointing HOME). */
27
+ export declare function resetCloudCredentialProviderForTests(): void;
28
+ /**
29
+ * Read a valid plugin-plane access token for a Cloud-mode call, PROACTIVELY refreshing under the
30
+ * cross-process lock when the stored token is within the expiry skew. Returns `undefined` when the
31
+ * machine is effectively not signed in — no credential, a dead family, an unreadable store, or a
32
+ * lock that stayed contended — so callers surface their actionable "not logged in" error instead
33
+ * of issuing a silent unauthenticated request (defect E / D11). The precise reason is logged via
34
+ * `verbose()` (never token bytes).
35
+ */
36
+ export declare function readCloudAccessToken(options?: CloudCredentialProviderOptions): Promise<string | undefined>;
37
+ /**
38
+ * REACTIVELY refresh the plugin-plane family now — the hub answered 401 while the local expiry
39
+ * still looked fine (revocation, clock skew). Runs the same locked critical section as the
40
+ * proactive path. Returns the fresh access token, or `undefined` when the family is dead /
41
+ * signed out (the caller falls back to its "not logged in" error).
42
+ */
43
+ export declare function refreshCloudAccessToken(options?: CloudCredentialProviderOptions): Promise<string | undefined>;