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
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Forward a single progress event to the caller's optional callback,
3
+ * swallowing any exception the callback throws. A broken onProgress
4
+ * handler must never abort the underlying library operation.
5
+ */
6
+ export function emitProgress(onProgress, event) {
7
+ if (!onProgress)
8
+ return;
9
+ try {
10
+ onProgress(event);
11
+ }
12
+ catch {
13
+ // Intentionally ignored — see doc comment.
14
+ }
15
+ }
16
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/lib/progress.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,UAAwC,EAAE,KAAoB;IACzF,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,IAAI,CAAC;QACH,UAAU,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,2CAA2C;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { RemovePluginOptions, RemoveResult } from './types.js';
2
+ /**
3
+ * Remove the Unity-MCP plugin from a Unity project. Library-safe:
4
+ * never calls `process.exit`, never prints to stdout / stderr, never
5
+ * throws past the public boundary.
6
+ */
7
+ export declare function removePlugin(opts: RemovePluginOptions): Promise<RemoveResult>;
@@ -0,0 +1,51 @@
1
+ import { removePluginFromManifest } from '../utils/manifest.js';
2
+ import { silentLogger } from './logger.js';
3
+ import { emitProgress } from './progress.js';
4
+ import { requireUnityProject } from './validation.js';
5
+ /**
6
+ * Remove the Unity-MCP plugin from a Unity project. Library-safe:
7
+ * never calls `process.exit`, never prints to stdout / stderr, never
8
+ * throws past the public boundary.
9
+ */
10
+ export async function removePlugin(opts) {
11
+ const warnings = [];
12
+ try {
13
+ const validated = requireUnityProject(opts?.unityProjectPath);
14
+ if (!validated.ok) {
15
+ return {
16
+ success: false,
17
+ manifestPath: validated.manifestPath,
18
+ warnings,
19
+ error: validated.error,
20
+ };
21
+ }
22
+ const { projectPath } = validated;
23
+ emitProgress(opts.onProgress, { phase: 'start', message: `Removing Unity-MCP plugin from ${projectPath}` });
24
+ const result = removePluginFromManifest(projectPath, silentLogger);
25
+ if (!result.removed) {
26
+ warnings.push('Unity-MCP plugin was not installed. Nothing was removed.');
27
+ }
28
+ emitProgress(opts.onProgress, {
29
+ phase: 'manifest-patched',
30
+ message: result.removed
31
+ ? `Removed plugin from ${result.manifestPath}`
32
+ : 'manifest.json left untouched (plugin not installed).',
33
+ manifestPath: result.manifestPath,
34
+ });
35
+ emitProgress(opts.onProgress, { phase: 'done', message: 'Remove complete.' });
36
+ return {
37
+ success: true,
38
+ removed: result.removed,
39
+ manifestPath: result.manifestPath,
40
+ warnings,
41
+ };
42
+ }
43
+ catch (err) {
44
+ return {
45
+ success: false,
46
+ warnings,
47
+ error: err instanceof Error ? err : new Error(String(err)),
48
+ };
49
+ }
50
+ }
51
+ //# sourceMappingURL=remove-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-plugin.js","sourceRoot":"","sources":["../../src/lib/remove-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAyB;IAC1D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;YAClB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,SAAS,CAAC,YAAY;gBACpC,QAAQ;gBACR,KAAK,EAAE,SAAS,CAAC,KAAK;aACvB,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;QAElC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,kCAAkC,WAAW,EAAE,EAAE,CAAC,CAAC;QAE5G,MAAM,MAAM,GAAG,wBAAwB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAEnE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;QAC5E,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE;YAC5B,KAAK,EAAE,kBAAkB;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACrB,CAAC,CAAC,uBAAuB,MAAM,CAAC,YAAY,EAAE;gBAC9C,CAAC,CAAC,sDAAsD;YAC1D,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC,CAAC;QAEH,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAE9E,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,QAAQ;YACR,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;SAC3D,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { SetupMcpOptions, SetupMcpResult } from './types.js';
2
+ /**
3
+ * Write MCP configuration for the given AI agent, so it can talk to
4
+ * Unity-MCP. Library-safe: no stdout noise, no process.exit, no throws
5
+ * past the public boundary.
6
+ */
7
+ export declare function setupMcp(opts: SetupMcpOptions): Promise<SetupMcpResult>;
8
+ /**
9
+ * List every agent id known to the `setupMcp` function. Useful for
10
+ * consumer UIs that want to render a picker.
11
+ */
12
+ export declare function listAgentIds(): string[];
@@ -0,0 +1,141 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { generatePortFromDirectory } from '../utils/port.js';
4
+ import { readConfig, resolveConnectionFromConfig } from '../utils/config.js';
5
+ import { getAgentById, getAgentIds, resolveServerBinaryPath, writeJsonAgentConfig, writeTomlAgentConfig, MCP_SERVER_NAME, } from '../utils/agents.js';
6
+ import { emitProgress } from './progress.js';
7
+ import { requireExistingPath } from './validation.js';
8
+ function isValidTransport(t) {
9
+ return t === 'stdio' || t === 'http';
10
+ }
11
+ /**
12
+ * Extract a port from a `host` URL string, falling back to the
13
+ * project-directory-derived deterministic port on any parse failure.
14
+ */
15
+ function portFromHost(host, projectPath) {
16
+ if (!host)
17
+ return generatePortFromDirectory(projectPath);
18
+ try {
19
+ return parseInt(new URL(host).port, 10) || generatePortFromDirectory(projectPath);
20
+ }
21
+ catch {
22
+ return generatePortFromDirectory(projectPath);
23
+ }
24
+ }
25
+ /**
26
+ * Write MCP configuration for the given AI agent, so it can talk to
27
+ * Unity-MCP. Library-safe: no stdout noise, no process.exit, no throws
28
+ * past the public boundary.
29
+ */
30
+ export async function setupMcp(opts) {
31
+ const warnings = [];
32
+ const nextSteps = [];
33
+ try {
34
+ if (!opts || typeof opts.agentId !== 'string' || opts.agentId.length === 0) {
35
+ return {
36
+ success: false,
37
+ warnings,
38
+ nextSteps,
39
+ error: new Error(`agentId is required. Available agent IDs: ${getAgentIds().join(', ')}`),
40
+ };
41
+ }
42
+ const agent = getAgentById(opts.agentId);
43
+ if (!agent) {
44
+ return {
45
+ success: false,
46
+ warnings,
47
+ nextSteps,
48
+ error: new Error(`Unknown agent: "${opts.agentId}". Available agent IDs: ${getAgentIds().join(', ')}`),
49
+ };
50
+ }
51
+ const transport = opts.transport ?? 'http';
52
+ if (!isValidTransport(transport)) {
53
+ return {
54
+ success: false,
55
+ warnings,
56
+ nextSteps,
57
+ error: new Error(`Invalid transport: "${transport}". Must be "stdio" or "http".`),
58
+ };
59
+ }
60
+ // Resolve project path. If the caller supplied one explicitly it
61
+ // must exist; otherwise fall back to cwd (matches CLI behaviour).
62
+ let projectPath;
63
+ if (opts.unityProjectPath) {
64
+ const validated = requireExistingPath(opts.unityProjectPath);
65
+ if (!validated.ok) {
66
+ return { success: false, warnings, nextSteps, error: validated.error };
67
+ }
68
+ projectPath = validated.projectPath;
69
+ }
70
+ else {
71
+ projectPath = path.resolve(process.cwd());
72
+ }
73
+ emitProgress(opts.onProgress, {
74
+ phase: 'start',
75
+ message: `Configuring ${agent.name} (${transport}) for ${projectPath}`,
76
+ });
77
+ const config = readConfig(projectPath);
78
+ const fromConfig = config
79
+ ? resolveConnectionFromConfig(config)
80
+ : { url: undefined, token: undefined };
81
+ const port = portFromHost(config?.host, projectPath);
82
+ const timeout = config?.timeoutMs ?? 10000;
83
+ const auth = config?.authOption ?? 'none';
84
+ const token = opts.token ?? fromConfig.token ?? '';
85
+ const authRequired = auth === 'required';
86
+ const serverPath = resolveServerBinaryPath(projectPath).replace(/\\/g, '/');
87
+ // Resolve URL for HTTP — explicit override, then config, then
88
+ // deterministic localhost fallback. Trailing slash stripped.
89
+ const serverUrl = (opts.url ?? fromConfig.url ?? `http://localhost:${port}`).replace(/\/$/, '');
90
+ const configPath = agent.getConfigPath(projectPath);
91
+ let props;
92
+ let removeKeys;
93
+ if (transport === 'stdio') {
94
+ props = agent.getStdioProps(serverPath, port, timeout, auth, token);
95
+ removeKeys = agent.stdioRemoveKeys;
96
+ }
97
+ else {
98
+ props = agent.getHttpProps(serverUrl, token, authRequired);
99
+ removeKeys = agent.httpRemoveKeys;
100
+ }
101
+ if (agent.configFormat === 'toml') {
102
+ writeTomlAgentConfig(configPath, agent.bodyPath, MCP_SERVER_NAME, props, removeKeys);
103
+ }
104
+ else {
105
+ writeJsonAgentConfig(configPath, agent.bodyPath, MCP_SERVER_NAME, props, removeKeys);
106
+ }
107
+ emitProgress(opts.onProgress, {
108
+ phase: 'manifest-patched',
109
+ message: `Wrote ${configPath}`,
110
+ manifestPath: configPath,
111
+ });
112
+ if (transport === 'stdio' && !fs.existsSync(serverPath.replace(/\//g, path.sep))) {
113
+ warnings.push('Server binary not found. Open Unity with the MCP plugin to download it automatically.');
114
+ }
115
+ emitProgress(opts.onProgress, { phase: 'done', message: `${agent.name} configured successfully.` });
116
+ return {
117
+ success: true,
118
+ agentId: agent.id,
119
+ configPath,
120
+ transport,
121
+ warnings,
122
+ nextSteps,
123
+ };
124
+ }
125
+ catch (err) {
126
+ return {
127
+ success: false,
128
+ warnings,
129
+ nextSteps,
130
+ error: err instanceof Error ? err : new Error(String(err)),
131
+ };
132
+ }
133
+ }
134
+ /**
135
+ * List every agent id known to the `setupMcp` function. Useful for
136
+ * consumer UIs that want to render a picker.
137
+ */
138
+ export function listAgentIds() {
139
+ return getAgentIds();
140
+ }
141
+ //# sourceMappingURL=setup-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-mcp.js","sourceRoot":"","sources":["../../src/lib/setup-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EACL,YAAY,EACZ,WAAW,EACX,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAOtD,SAAS,gBAAgB,CAAC,CAAqB;IAC7C,OAAO,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,MAAM,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,IAAwB,EAAE,WAAmB;IACjE,IAAI,CAAC,IAAI;QAAE,OAAO,yBAAyB,CAAC,WAAW,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,yBAAyB,CAAC,WAAW,CAAC,CAAC;IACpF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,yBAAyB,CAAC,WAAW,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAqB;IAClD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3E,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ;gBACR,SAAS;gBACT,KAAK,EAAE,IAAI,KAAK,CACd,6CAA6C,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxE;aACF,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ;gBACR,SAAS;gBACT,KAAK,EAAE,IAAI,KAAK,CACd,mBAAmB,IAAI,CAAC,OAAO,2BAA2B,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAiB,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;QACzD,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ;gBACR,SAAS;gBACT,KAAK,EAAE,IAAI,KAAK,CAAC,uBAAuB,SAAS,+BAA+B,CAAC;aAClF,CAAC;QACJ,CAAC;QAED,iEAAiE;QACjE,kEAAkE;QAClE,IAAI,WAAmB,CAAC;QACxB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC7D,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;gBAClB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC;YACzE,CAAC;YACD,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE;YAC5B,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,eAAe,KAAK,CAAC,IAAI,KAAK,SAAS,SAAS,WAAW,EAAE;SACvE,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,MAAM;YACvB,CAAC,CAAC,2BAA2B,CAAC,MAAM,CAAC;YACrC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAEzC,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;QAErD,MAAM,OAAO,GAAI,MAAM,EAAE,SAAoB,IAAI,KAAK,CAAC;QACvD,MAAM,IAAI,GAAI,MAAM,EAAE,UAAqB,IAAI,MAAM,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC;QACnD,MAAM,YAAY,GAAG,IAAI,KAAK,UAAU,CAAC;QAEzC,MAAM,UAAU,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAE5E,8DAA8D;QAC9D,6DAA6D;QAC7D,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,IAAI,oBAAoB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEhG,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAEpD,IAAI,KAA8B,CAAC;QACnC,IAAI,UAAoB,CAAC;QAEzB,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;YAC1B,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACpE,UAAU,GAAG,KAAK,CAAC,eAAe,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;YAC3D,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC;QACpC,CAAC;QAED,IAAI,KAAK,CAAC,YAAY,KAAK,MAAM,EAAE,CAAC;YAClC,oBAAoB,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QACvF,CAAC;aAAM,CAAC;YACN,oBAAoB,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QACvF,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE;YAC5B,KAAK,EAAE,kBAAkB;YACzB,OAAO,EAAE,SAAS,UAAU,EAAE;YAC9B,YAAY,EAAE,UAAU;SACzB,CAAC,CAAC;QAEH,IAAI,SAAS,KAAK,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACjF,QAAQ,CAAC,IAAI,CACX,uFAAuF,CACxF,CAAC;QACJ,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,2BAA2B,EAAE,CAAC,CAAC;QAEpG,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,UAAU;YACV,SAAS;YACT,QAAQ;YACR,SAAS;SACV,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,QAAQ;YACR,SAAS;YACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;SAC3D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,WAAW,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Discriminated union describing every progress event the library can
3
+ * emit to the optional `onProgress` callback.
4
+ *
5
+ * Consumers can narrow on `event.phase` to decide what to render.
6
+ */
7
+ export type ProgressEvent = {
8
+ phase: 'start';
9
+ message: string;
10
+ } | {
11
+ phase: 'manifest-patched';
12
+ message: string;
13
+ manifestPath: string;
14
+ } | {
15
+ phase: 'dependencies-resolved';
16
+ message: string;
17
+ version: string;
18
+ } | {
19
+ phase: 'done';
20
+ message: string;
21
+ };
22
+ export type ProgressCallback = (event: ProgressEvent) => void;
23
+ export interface InstallPluginOptions {
24
+ /** Absolute or relative path to the Unity project's root. */
25
+ unityProjectPath: string;
26
+ /**
27
+ * Plugin version to install. When omitted, the latest version is
28
+ * resolved from OpenUPM.
29
+ */
30
+ version?: string;
31
+ /**
32
+ * Optional progress callback — fires for `start`,
33
+ * `dependencies-resolved` (when the version was auto-resolved),
34
+ * `manifest-patched`, and `done`.
35
+ */
36
+ onProgress?: ProgressCallback;
37
+ }
38
+ export interface InstallResult {
39
+ /** `true` when the manifest was updated (or already correct); `false` on error. */
40
+ success: boolean;
41
+ /** Final plugin version in the manifest. Populated on success. */
42
+ installedVersion?: string;
43
+ /** Absolute path to the manifest.json that was inspected / written. */
44
+ manifestPath?: string;
45
+ /** Non-fatal warnings collected during the run (e.g. skipped downgrade). */
46
+ warnings: string[];
47
+ /** Suggested next steps for the caller to surface to a human user. */
48
+ nextSteps: string[];
49
+ /** Populated when `success === false`. Never thrown past this boundary. */
50
+ error?: Error;
51
+ }
52
+ export interface RemovePluginOptions {
53
+ unityProjectPath: string;
54
+ onProgress?: ProgressCallback;
55
+ }
56
+ export interface RemoveResult {
57
+ success: boolean;
58
+ /** `true` when the plugin dependency was present and has been removed. */
59
+ removed?: boolean;
60
+ manifestPath?: string;
61
+ warnings: string[];
62
+ error?: Error;
63
+ }
64
+ /** Action applied to a set of MCP features (tools, prompts, or resources). */
65
+ export interface FeatureAction {
66
+ /** Explicit names to enable. */
67
+ enableNames?: string[];
68
+ /** Explicit names to disable. */
69
+ disableNames?: string[];
70
+ /** Enable every feature already present in the config. */
71
+ enableAll?: boolean;
72
+ /** Disable every feature already present in the config. */
73
+ disableAll?: boolean;
74
+ }
75
+ export interface ConfigureOptions {
76
+ unityProjectPath: string;
77
+ /** Whether to apply changes to tools. Omit to leave tools untouched. */
78
+ tools?: FeatureAction;
79
+ prompts?: FeatureAction;
80
+ resources?: FeatureAction;
81
+ onProgress?: ProgressCallback;
82
+ }
83
+ export interface McpFeatureSnapshot {
84
+ name: string;
85
+ enabled: boolean;
86
+ }
87
+ export interface ConfigureResult {
88
+ success: boolean;
89
+ /** Absolute path to the `AI-Game-Developer-Config.json` that was written. */
90
+ configPath?: string;
91
+ /** A read-only snapshot of the post-write config. */
92
+ snapshot?: {
93
+ host?: string;
94
+ keepConnected?: boolean;
95
+ transportMethod?: string;
96
+ authOption?: string;
97
+ tools: McpFeatureSnapshot[];
98
+ prompts: McpFeatureSnapshot[];
99
+ resources: McpFeatureSnapshot[];
100
+ };
101
+ warnings: string[];
102
+ error?: Error;
103
+ }
104
+ export type McpTransport = 'stdio' | 'http';
105
+ export interface SetupMcpOptions {
106
+ /**
107
+ * Agent to configure. Use `listAgentIds()` to discover valid values
108
+ * (e.g. `'claude-code'`, `'cursor'`, `'codex'`, …).
109
+ */
110
+ agentId: string;
111
+ /** Optional Unity project path. Defaults to `process.cwd()` if omitted. */
112
+ unityProjectPath?: string;
113
+ /** Transport to write — defaults to `'http'`. */
114
+ transport?: McpTransport;
115
+ /** Explicit server URL override (for http transport). */
116
+ url?: string;
117
+ /** Auth token override. */
118
+ token?: string;
119
+ onProgress?: ProgressCallback;
120
+ }
121
+ export interface SetupMcpResult {
122
+ success: boolean;
123
+ /** The agent whose config file was written (undefined on error). */
124
+ agentId?: string;
125
+ /** Absolute path to the agent config file that was written. */
126
+ configPath?: string;
127
+ /** Transport actually written. */
128
+ transport?: McpTransport;
129
+ warnings: string[];
130
+ nextSteps: string[];
131
+ error?: Error;
132
+ }
@@ -0,0 +1,8 @@
1
+ // Shared public types for the unity-mcp-cli library API.
2
+ //
3
+ // This file is re-exported from `lib.ts` — consumers should import
4
+ // from `unity-mcp-cli` (the package root), NOT from deep paths.
5
+ //
6
+ // No top-level side effects, no runtime deps beyond TypeScript types.
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,mEAAmE;AACnE,gEAAgE;AAChE,EAAE;AACF,sEAAsE"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Small, side-effect-free input-validation helpers shared by the
3
+ * library-facing API functions. Each helper returns a discriminated
4
+ * union so call sites can pattern-match without throwing across the
5
+ * public boundary.
6
+ */
7
+ export type ValidatedPath = {
8
+ ok: true;
9
+ projectPath: string;
10
+ } | {
11
+ ok: false;
12
+ error: Error;
13
+ };
14
+ export type ValidatedUnityProject = {
15
+ ok: true;
16
+ projectPath: string;
17
+ manifestPath: string;
18
+ } | {
19
+ ok: false;
20
+ manifestPath?: string;
21
+ error: Error;
22
+ };
23
+ /**
24
+ * Require a non-empty string and resolve it to an absolute path.
25
+ */
26
+ export declare function requireProjectPath(raw: unknown): ValidatedPath;
27
+ /**
28
+ * Require a non-empty path AND that the path hosts a Unity project
29
+ * (identified by the presence of `Packages/manifest.json`).
30
+ */
31
+ export declare function requireUnityProject(raw: unknown): ValidatedUnityProject;
32
+ /**
33
+ * Require that the given path exists on disk (does not need to host a
34
+ * Unity manifest). Used by `configure()` which only needs a directory
35
+ * to drop a config file into.
36
+ */
37
+ export declare function requireExistingPath(raw: unknown): ValidatedPath;
@@ -0,0 +1,50 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ /**
4
+ * Require a non-empty string and resolve it to an absolute path.
5
+ */
6
+ export function requireProjectPath(raw) {
7
+ if (typeof raw !== 'string' || raw.length === 0) {
8
+ return {
9
+ ok: false,
10
+ error: new Error('unityProjectPath is required and must be a non-empty string.'),
11
+ };
12
+ }
13
+ return { ok: true, projectPath: path.resolve(raw) };
14
+ }
15
+ /**
16
+ * Require a non-empty path AND that the path hosts a Unity project
17
+ * (identified by the presence of `Packages/manifest.json`).
18
+ */
19
+ export function requireUnityProject(raw) {
20
+ const outer = requireProjectPath(raw);
21
+ if (!outer.ok)
22
+ return outer;
23
+ const manifestPath = path.join(outer.projectPath, 'Packages', 'manifest.json');
24
+ if (!fs.existsSync(manifestPath)) {
25
+ return {
26
+ ok: false,
27
+ manifestPath,
28
+ error: new Error(`Not a valid Unity project (missing Packages/manifest.json): ${outer.projectPath}`),
29
+ };
30
+ }
31
+ return { ok: true, projectPath: outer.projectPath, manifestPath };
32
+ }
33
+ /**
34
+ * Require that the given path exists on disk (does not need to host a
35
+ * Unity manifest). Used by `configure()` which only needs a directory
36
+ * to drop a config file into.
37
+ */
38
+ export function requireExistingPath(raw) {
39
+ const outer = requireProjectPath(raw);
40
+ if (!outer.ok)
41
+ return outer;
42
+ if (!fs.existsSync(outer.projectPath)) {
43
+ return {
44
+ ok: false,
45
+ error: new Error(`Project path does not exist: ${outer.projectPath}`),
46
+ };
47
+ }
48
+ return outer;
49
+ }
50
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAiB7B;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,IAAI,KAAK,CAAC,8DAA8D,CAAC;SACjF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IAC/E,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,YAAY;YACZ,KAAK,EAAE,IAAI,KAAK,CACd,+DAA+D,KAAK,CAAC,WAAW,EAAE,CACnF;SACF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,YAAY,EAAE,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC5B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QACtC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,WAAW,EAAE,CAAC;SACtE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
package/dist/lib.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { installPlugin } from './lib/install-plugin.js';
2
+ export { removePlugin } from './lib/remove-plugin.js';
3
+ export { configure } from './lib/configure.js';
4
+ export { setupMcp, listAgentIds } from './lib/setup-mcp.js';
5
+ export type { ProgressEvent, ProgressCallback, InstallPluginOptions, InstallResult, RemovePluginOptions, RemoveResult, ConfigureOptions, ConfigureResult, FeatureAction, McpFeatureSnapshot, SetupMcpOptions, SetupMcpResult, McpTransport, } from './lib/types.js';
package/dist/lib.js ADDED
@@ -0,0 +1,18 @@
1
+ // Library entry point for `unity-mcp-cli`.
2
+ //
3
+ // Constraints (enforced by review — see issue #678):
4
+ // - NO top-level side effects. Importing this file must not open
5
+ // sockets, spin up spinners, write to stdout/stderr, or parse argv.
6
+ // - NO `commander` import reachable from this file.
7
+ // - Errors are returned in `{ success: false, error }` results — never
8
+ // thrown past the public boundary.
9
+ // - Progress is surfaced via an optional `onProgress` callback, not
10
+ // globals or singletons.
11
+ //
12
+ // Consumers: `import { installPlugin } from 'unity-mcp-cli'` (maps to
13
+ // this file via the `exports` field in package.json).
14
+ export { installPlugin } from './lib/install-plugin.js';
15
+ export { removePlugin } from './lib/remove-plugin.js';
16
+ export { configure } from './lib/configure.js';
17
+ export { setupMcp, listAgentIds } from './lib/setup-mcp.js';
18
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +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,uEAAuE;AACvE,qCAAqC;AACrC,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"}
@@ -1,14 +1,28 @@
1
+ import { type LibLogger } from '../lib/logger.js';
1
2
  /**
2
3
  * Resolve the latest plugin version from the OpenUPM registry.
3
4
  * Throws an error with actionable suggestions if the network request fails.
5
+ *
6
+ * @param logger Optional logger. Defaults to `silentLogger` so library
7
+ * callers stay side-effect-free; CLI call sites must pass a chalk-
8
+ * styled logger adapter explicitly to preserve the historical output.
4
9
  */
5
- export declare function resolveLatestVersion(): Promise<string>;
10
+ export declare function resolveLatestVersion(logger?: LibLogger): Promise<string>;
6
11
  /**
7
12
  * Determines if the version should be updated.
8
13
  * Only update if the new version is higher than the current version.
9
14
  * Ports the C# Installer.ShouldUpdateVersion() logic.
10
15
  */
11
16
  export declare function shouldUpdateVersion(currentVersion: string, newVersion: string): boolean;
17
+ export interface AddPluginResult {
18
+ /** Whether the file was modified on disk (false = already up to date). */
19
+ modified: boolean;
20
+ /** Final plugin version in the manifest (may differ from the requested
21
+ * version if the existing version was higher and force was false). */
22
+ resolvedVersion: string;
23
+ /** Absolute path to the manifest.json that was inspected / written. */
24
+ manifestPath: string;
25
+ }
12
26
  /**
13
27
  * Add Unity-MCP plugin to a Unity project's Packages/manifest.json.
14
28
  * Ports the C# Installer.Manifest.cs logic:
@@ -16,11 +30,25 @@ export declare function shouldUpdateVersion(currentVersion: string, newVersion:
16
30
  * - Adds/updates the plugin dependency
17
31
  * - When force is false (auto-resolved version): never downgrades
18
32
  * - When force is true (user-specified --plugin-version): allows downgrade
33
+ *
34
+ * @param logger Optional logger. Defaults to `silentLogger` so library
35
+ * callers stay side-effect-free; CLI call sites must pass a chalk-
36
+ * styled logger adapter explicitly to preserve the historical output.
19
37
  */
20
- export declare function addPluginToManifest(projectPath: string, version: string, force?: boolean): void;
38
+ export declare function addPluginToManifest(projectPath: string, version: string, force?: boolean, logger?: LibLogger): AddPluginResult;
39
+ export interface RemovePluginResult {
40
+ /** Whether the plugin was present and has been removed. */
41
+ removed: boolean;
42
+ /** Absolute path to the manifest.json that was inspected. */
43
+ manifestPath: string;
44
+ }
21
45
  /**
22
46
  * Remove Unity-MCP plugin from a Unity project's Packages/manifest.json.
23
47
  * Only removes the plugin dependency — scoped registries and scopes are
24
48
  * left untouched because other packages may depend on them.
49
+ *
50
+ * @param logger Optional logger. Defaults to `silentLogger` so library
51
+ * callers stay side-effect-free; CLI call sites must pass a chalk-
52
+ * styled logger adapter explicitly to preserve the historical output.
25
53
  */
26
- export declare function removePluginFromManifest(projectPath: string): void;
54
+ export declare function removePluginFromManifest(projectPath: string, logger?: LibLogger): RemovePluginResult;