godot-cli 0.1.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 (110) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +101 -0
  3. package/bin/godot-cli.js +2 -0
  4. package/dist/cli.d.ts +11 -0
  5. package/dist/cli.js +17 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/close.d.ts +18 -0
  8. package/dist/commands/close.js +112 -0
  9. package/dist/commands/close.js.map +1 -0
  10. package/dist/commands/configure.d.ts +2 -0
  11. package/dist/commands/configure.js +92 -0
  12. package/dist/commands/configure.js.map +1 -0
  13. package/dist/commands/install-plugin.d.ts +2 -0
  14. package/dist/commands/install-plugin.js +35 -0
  15. package/dist/commands/install-plugin.js.map +1 -0
  16. package/dist/commands/open.d.ts +16 -0
  17. package/dist/commands/open.js +124 -0
  18. package/dist/commands/open.js.map +1 -0
  19. package/dist/commands/remove-plugin.d.ts +2 -0
  20. package/dist/commands/remove-plugin.js +31 -0
  21. package/dist/commands/remove-plugin.js.map +1 -0
  22. package/dist/commands/run-system-tool.d.ts +1 -0
  23. package/dist/commands/run-system-tool.js +13 -0
  24. package/dist/commands/run-system-tool.js.map +1 -0
  25. package/dist/commands/run-tool-builder.d.ts +25 -0
  26. package/dist/commands/run-tool-builder.js +119 -0
  27. package/dist/commands/run-tool-builder.js.map +1 -0
  28. package/dist/commands/run-tool.d.ts +1 -0
  29. package/dist/commands/run-tool.js +13 -0
  30. package/dist/commands/run-tool.js.map +1 -0
  31. package/dist/commands/setup-mcp.d.ts +2 -0
  32. package/dist/commands/setup-mcp.js +58 -0
  33. package/dist/commands/setup-mcp.js.map +1 -0
  34. package/dist/commands/status.d.ts +2 -0
  35. package/dist/commands/status.js +64 -0
  36. package/dist/commands/status.js.map +1 -0
  37. package/dist/commands/update.d.ts +2 -0
  38. package/dist/commands/update.js +75 -0
  39. package/dist/commands/update.js.map +1 -0
  40. package/dist/commands/wait-for-ready.d.ts +2 -0
  41. package/dist/commands/wait-for-ready.js +57 -0
  42. package/dist/commands/wait-for-ready.js.map +1 -0
  43. package/dist/index.d.ts +1 -0
  44. package/dist/index.js +69 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/lib/install-plugin.d.ts +22 -0
  47. package/dist/lib/install-plugin.js +118 -0
  48. package/dist/lib/install-plugin.js.map +1 -0
  49. package/dist/lib/open.d.ts +34 -0
  50. package/dist/lib/open.js +198 -0
  51. package/dist/lib/open.js.map +1 -0
  52. package/dist/lib/progress.d.ts +7 -0
  53. package/dist/lib/progress.js +16 -0
  54. package/dist/lib/progress.js.map +1 -0
  55. package/dist/lib/run-tool.d.ts +12 -0
  56. package/dist/lib/run-tool.js +192 -0
  57. package/dist/lib/run-tool.js.map +1 -0
  58. package/dist/lib/setup-mcp.d.ts +16 -0
  59. package/dist/lib/setup-mcp.js +118 -0
  60. package/dist/lib/setup-mcp.js.map +1 -0
  61. package/dist/lib/types.d.ts +210 -0
  62. package/dist/lib/types.js +8 -0
  63. package/dist/lib/types.js.map +1 -0
  64. package/dist/lib/validation.d.ts +30 -0
  65. package/dist/lib/validation.js +44 -0
  66. package/dist/lib/validation.js.map +1 -0
  67. package/dist/lib.d.ts +5 -0
  68. package/dist/lib.js +19 -0
  69. package/dist/lib.js.map +1 -0
  70. package/dist/utils/agents.d.ts +31 -0
  71. package/dist/utils/agents.js +188 -0
  72. package/dist/utils/agents.js.map +1 -0
  73. package/dist/utils/config.d.ts +40 -0
  74. package/dist/utils/config.js +97 -0
  75. package/dist/utils/config.js.map +1 -0
  76. package/dist/utils/connection.d.ts +57 -0
  77. package/dist/utils/connection.js +129 -0
  78. package/dist/utils/connection.js.map +1 -0
  79. package/dist/utils/godot-editor.d.ts +42 -0
  80. package/dist/utils/godot-editor.js +184 -0
  81. package/dist/utils/godot-editor.js.map +1 -0
  82. package/dist/utils/godot-process.d.ts +10 -0
  83. package/dist/utils/godot-process.js +93 -0
  84. package/dist/utils/godot-process.js.map +1 -0
  85. package/dist/utils/godot-shutdown.d.ts +16 -0
  86. package/dist/utils/godot-shutdown.js +67 -0
  87. package/dist/utils/godot-shutdown.js.map +1 -0
  88. package/dist/utils/input.d.ts +13 -0
  89. package/dist/utils/input.js +72 -0
  90. package/dist/utils/input.js.map +1 -0
  91. package/dist/utils/json-parse.d.ts +25 -0
  92. package/dist/utils/json-parse.js +83 -0
  93. package/dist/utils/json-parse.js.map +1 -0
  94. package/dist/utils/probe.d.ts +18 -0
  95. package/dist/utils/probe.js +61 -0
  96. package/dist/utils/probe.js.map +1 -0
  97. package/dist/utils/project-godot.d.ts +41 -0
  98. package/dist/utils/project-godot.js +126 -0
  99. package/dist/utils/project-godot.js.map +1 -0
  100. package/dist/utils/semver.d.ts +4 -0
  101. package/dist/utils/semver.js +25 -0
  102. package/dist/utils/semver.js.map +1 -0
  103. package/dist/utils/ui.d.ts +61 -0
  104. package/dist/utils/ui.js +238 -0
  105. package/dist/utils/ui.js.map +1 -0
  106. package/dist/utils/update-check.d.ts +19 -0
  107. package/dist/utils/update-check.js +92 -0
  108. package/dist/utils/update-check.js.map +1 -0
  109. package/docs/README.md +7 -0
  110. package/package.json +73 -0
@@ -0,0 +1,188 @@
1
+ import chalk from 'chalk';
2
+ import * as fs from 'fs';
3
+ import * as os from 'os';
4
+ import * as path from 'path';
5
+ // ---------------------------------------------------------------------------
6
+ // Platform helpers
7
+ // ---------------------------------------------------------------------------
8
+ function appData() {
9
+ return process.env['APPDATA'] ?? path.join(os.homedir(), 'AppData', 'Roaming');
10
+ }
11
+ function home() {
12
+ return os.homedir();
13
+ }
14
+ function isWindows() {
15
+ return process.platform === 'win32';
16
+ }
17
+ function isMac() {
18
+ return process.platform === 'darwin';
19
+ }
20
+ function authHeaders(token, authRequired) {
21
+ if (authRequired && token) {
22
+ return { Authorization: `Bearer ${token}` };
23
+ }
24
+ return undefined;
25
+ }
26
+ // ---------------------------------------------------------------------------
27
+ // Agent Registry
28
+ // ---------------------------------------------------------------------------
29
+ const MCP_SERVER_NAME = 'ai-game-developer';
30
+ export const agentRegistry = [
31
+ // ── Claude Code ──────────────────────────────────────────────
32
+ {
33
+ id: 'claude-code',
34
+ name: 'Claude Code',
35
+ configPathDisplay: '.mcp.json',
36
+ bodyPath: 'mcpServers',
37
+ getConfigPath: (p) => path.join(p, '.mcp.json'),
38
+ getHttpProps: (url, token, authRequired) => ({
39
+ type: 'http',
40
+ url,
41
+ ...(authHeaders(token, authRequired) ? { headers: authHeaders(token, authRequired) } : {}),
42
+ }),
43
+ httpRemoveKeys: ['command', 'args'],
44
+ },
45
+ // ── Claude Desktop ───────────────────────────────────────────
46
+ {
47
+ id: 'claude-desktop',
48
+ name: 'Claude Desktop',
49
+ configPathDisplay: '~/Claude/claude_desktop_config.json',
50
+ bodyPath: 'mcpServers',
51
+ getConfigPath: () => {
52
+ if (isWindows()) {
53
+ return path.join(appData(), 'Claude', 'claude_desktop_config.json');
54
+ }
55
+ if (isMac()) {
56
+ return path.join(home(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
57
+ }
58
+ return path.join(home(), '.config', 'Claude', 'claude_desktop_config.json');
59
+ },
60
+ getHttpProps: (url, token, authRequired) => ({
61
+ type: 'http',
62
+ url,
63
+ ...(authHeaders(token, authRequired) ? { headers: authHeaders(token, authRequired) } : {}),
64
+ }),
65
+ httpRemoveKeys: ['command', 'args'],
66
+ },
67
+ // ── Cursor ───────────────────────────────────────────────────
68
+ {
69
+ id: 'cursor',
70
+ name: 'Cursor',
71
+ configPathDisplay: '.cursor/mcp.json',
72
+ bodyPath: 'mcpServers',
73
+ getConfigPath: (p) => path.join(p, '.cursor', 'mcp.json'),
74
+ getHttpProps: (url, token, authRequired) => ({
75
+ type: 'http',
76
+ url,
77
+ ...(authHeaders(token, authRequired) ? { headers: authHeaders(token, authRequired) } : {}),
78
+ }),
79
+ httpRemoveKeys: ['command', 'args'],
80
+ },
81
+ // ── VS Code (Copilot) ────────────────────────────────────────
82
+ {
83
+ id: 'vscode',
84
+ name: 'Visual Studio Code (Copilot)',
85
+ configPathDisplay: '.vscode/mcp.json',
86
+ bodyPath: 'servers',
87
+ getConfigPath: (p) => path.join(p, '.vscode', 'mcp.json'),
88
+ getHttpProps: (url, token, authRequired) => ({
89
+ type: 'http',
90
+ url,
91
+ ...(authHeaders(token, authRequired) ? { headers: authHeaders(token, authRequired) } : {}),
92
+ }),
93
+ httpRemoveKeys: ['command', 'args'],
94
+ },
95
+ // ── Custom (generic mcpServers entry written to a caller path) ─
96
+ {
97
+ id: 'custom',
98
+ name: 'Custom (generic MCP client)',
99
+ configPathDisplay: 'mcp.json',
100
+ bodyPath: 'mcpServers',
101
+ getConfigPath: (p) => path.join(p, 'mcp.json'),
102
+ getHttpProps: (url, token, authRequired) => ({
103
+ type: 'http',
104
+ url,
105
+ ...(authHeaders(token, authRequired) ? { headers: authHeaders(token, authRequired) } : {}),
106
+ }),
107
+ httpRemoveKeys: ['command', 'args'],
108
+ },
109
+ ];
110
+ // ---------------------------------------------------------------------------
111
+ // Lookup helpers
112
+ // ---------------------------------------------------------------------------
113
+ export function getAgentById(id) {
114
+ return agentRegistry.find((a) => a.id === id);
115
+ }
116
+ export function getAgentIds() {
117
+ return agentRegistry.map((a) => a.id);
118
+ }
119
+ export function listAgentTable(heading, locationLabel, locationFn) {
120
+ const sorted = [...agentRegistry].sort((a, b) => a.id.localeCompare(b.id));
121
+ const colId = 'ID';
122
+ const colLoc = locationLabel;
123
+ const wId = Math.max(colId.length, ...sorted.map((a) => a.id.length));
124
+ const wLoc = Math.max(colLoc.length, ...sorted.map((a) => locationFn(a).length));
125
+ const sep = chalk.dim;
126
+ const hBar = (w) => '─'.repeat(w);
127
+ console.log(`\n${chalk.bold.cyan(heading)}\n`);
128
+ // Header
129
+ console.log(sep(' ┌─') + sep(hBar(wId)) + sep('─┬─') + sep(hBar(wLoc)) + sep('─┐'));
130
+ console.log(sep(' │ ') + chalk.bold.white(colId.padEnd(wId)) + sep(' │ ') + chalk.bold.white(colLoc.padEnd(wLoc)) + sep(' │'));
131
+ console.log(sep(' ├─') + sep(hBar(wId)) + sep('─┼─') + sep(hBar(wLoc)) + sep('─┤'));
132
+ // Rows
133
+ for (const agent of sorted) {
134
+ const loc = locationFn(agent);
135
+ console.log(sep(' │ ') + chalk.yellow(agent.id.padEnd(wId)) + sep(' │ ') + chalk.green(loc.padEnd(wLoc)) + sep(' │'));
136
+ }
137
+ // Footer
138
+ console.log(sep(' └─') + sep(hBar(wId)) + sep('─┴─') + sep(hBar(wLoc)) + sep('─┘'));
139
+ console.log('');
140
+ }
141
+ // ---------------------------------------------------------------------------
142
+ // Config file writing — JSON
143
+ // ---------------------------------------------------------------------------
144
+ export function writeJsonAgentConfig(configPath, bodyPath, serverName, props, removeKeys) {
145
+ const dir = path.dirname(configPath);
146
+ if (!fs.existsSync(dir)) {
147
+ fs.mkdirSync(dir, { recursive: true });
148
+ }
149
+ let root = {};
150
+ if (fs.existsSync(configPath)) {
151
+ try {
152
+ root = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
153
+ }
154
+ catch {
155
+ // If the file is malformed, start fresh
156
+ root = {};
157
+ }
158
+ if (!root || typeof root !== 'object' || Array.isArray(root)) {
159
+ root = {};
160
+ }
161
+ }
162
+ // Navigate/create bodyPath
163
+ let body = root[bodyPath];
164
+ if (!body || typeof body !== 'object' || Array.isArray(body)) {
165
+ body = {};
166
+ root[bodyPath] = body;
167
+ }
168
+ // Remove deprecated "Godot-MCP" entries
169
+ delete body['Godot-MCP'];
170
+ // Get or create the server entry
171
+ let entry = body[serverName];
172
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
173
+ entry = {};
174
+ }
175
+ // Remove stale keys
176
+ for (const key of removeKeys) {
177
+ delete entry[key];
178
+ }
179
+ // Merge new properties
180
+ for (const [key, value] of Object.entries(props)) {
181
+ entry[key] = value;
182
+ }
183
+ body[serverName] = entry;
184
+ root[bodyPath] = body;
185
+ fs.writeFileSync(configPath, JSON.stringify(root, null, 2) + '\n');
186
+ }
187
+ export { MCP_SERVER_NAME };
188
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/utils/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Project-local feature-override config the CLI manages. Godot's plugin
3
+ * persists its live config in `user://godot-mcp-config.json` (outside the
4
+ * project tree), which the CLI cannot reliably reach. This file is the CLI's
5
+ * own in-project surface for declaring which tools/prompts/resources should be
6
+ * enabled/disabled — a small, explicit, version-controllable override list a
7
+ * user can commit alongside the project.
8
+ */
9
+ export declare const CONFIG_RELATIVE_PATH = ".godot-mcp/features.json";
10
+ export interface McpFeature {
11
+ name: string;
12
+ enabled: boolean;
13
+ }
14
+ export interface GodotMcpFeaturesConfig {
15
+ tools?: McpFeature[];
16
+ prompts?: McpFeature[];
17
+ resources?: McpFeature[];
18
+ [key: string]: unknown;
19
+ }
20
+ export declare function getConfigPath(projectPath: string): string;
21
+ /** Create a default (empty) features config. */
22
+ export declare function createDefaultConfig(): GodotMcpFeaturesConfig;
23
+ /** Read the features config from a project. Returns null when absent. */
24
+ export declare function readConfig(projectPath: string): GodotMcpFeaturesConfig | null;
25
+ /** Write the features config, creating the parent directory if needed. */
26
+ export declare function writeConfig(projectPath: string, config: GodotMcpFeaturesConfig): void;
27
+ /** Read the config, creating it with defaults if it does not exist. */
28
+ export declare function getOrCreateConfig(projectPath: string): GodotMcpFeaturesConfig;
29
+ /**
30
+ * Update a feature group (tools / prompts / resources) in the config.
31
+ * - enableNames: set these to enabled=true
32
+ * - disableNames: set these to enabled=false
33
+ * - enableAll / disableAll: override every feature already present
34
+ */
35
+ export declare function updateFeatures(config: GodotMcpFeaturesConfig, featureType: 'tools' | 'prompts' | 'resources', options: {
36
+ enableNames?: string[];
37
+ disableNames?: string[];
38
+ enableAll?: boolean;
39
+ disableAll?: boolean;
40
+ }): void;
@@ -0,0 +1,97 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ /**
4
+ * Project-local feature-override config the CLI manages. Godot's plugin
5
+ * persists its live config in `user://godot-mcp-config.json` (outside the
6
+ * project tree), which the CLI cannot reliably reach. This file is the CLI's
7
+ * own in-project surface for declaring which tools/prompts/resources should be
8
+ * enabled/disabled — a small, explicit, version-controllable override list a
9
+ * user can commit alongside the project.
10
+ */
11
+ export const CONFIG_RELATIVE_PATH = '.godot-mcp/features.json';
12
+ export function getConfigPath(projectPath) {
13
+ return path.join(projectPath, CONFIG_RELATIVE_PATH);
14
+ }
15
+ /** Create a default (empty) features config. */
16
+ export function createDefaultConfig() {
17
+ return { tools: [], prompts: [], resources: [] };
18
+ }
19
+ /** Read the features config from a project. Returns null when absent. */
20
+ export function readConfig(projectPath) {
21
+ const configPath = getConfigPath(projectPath);
22
+ if (!fs.existsSync(configPath)) {
23
+ return null;
24
+ }
25
+ const json = fs.readFileSync(configPath, 'utf-8');
26
+ try {
27
+ return JSON.parse(json);
28
+ }
29
+ catch (err) {
30
+ if (err instanceof SyntaxError) {
31
+ throw new SyntaxError(`Malformed JSON in config file: ${configPath}\n${err.message}`);
32
+ }
33
+ throw err;
34
+ }
35
+ }
36
+ /** Write the features config, creating the parent directory if needed. */
37
+ export function writeConfig(projectPath, config) {
38
+ const configPath = getConfigPath(projectPath);
39
+ const dir = path.dirname(configPath);
40
+ if (!fs.existsSync(dir)) {
41
+ fs.mkdirSync(dir, { recursive: true });
42
+ }
43
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
44
+ }
45
+ /** Read the config, creating it with defaults if it does not exist. */
46
+ export function getOrCreateConfig(projectPath) {
47
+ if (fs.existsSync(getConfigPath(projectPath))) {
48
+ return readConfig(projectPath);
49
+ }
50
+ const config = createDefaultConfig();
51
+ writeConfig(projectPath, config);
52
+ return config;
53
+ }
54
+ /**
55
+ * Update a feature group (tools / prompts / resources) in the config.
56
+ * - enableNames: set these to enabled=true
57
+ * - disableNames: set these to enabled=false
58
+ * - enableAll / disableAll: override every feature already present
59
+ */
60
+ export function updateFeatures(config, featureType, options) {
61
+ const rawFeatures = config[featureType];
62
+ const features = Array.isArray(rawFeatures)
63
+ ? rawFeatures.filter((f) => typeof f === 'object' && f !== null && typeof f.name === 'string' && typeof f.enabled === 'boolean')
64
+ : [];
65
+ if (options.enableAll) {
66
+ for (const f of features)
67
+ f.enabled = true;
68
+ config[featureType] = features;
69
+ return;
70
+ }
71
+ if (options.disableAll) {
72
+ for (const f of features)
73
+ f.enabled = false;
74
+ config[featureType] = features;
75
+ return;
76
+ }
77
+ if (options.enableNames) {
78
+ for (const name of options.enableNames) {
79
+ const existing = features.find((f) => f.name === name);
80
+ if (existing)
81
+ existing.enabled = true;
82
+ else
83
+ features.push({ name, enabled: true });
84
+ }
85
+ }
86
+ if (options.disableNames) {
87
+ for (const name of options.disableNames) {
88
+ const existing = features.find((f) => f.name === name);
89
+ if (existing)
90
+ existing.enabled = false;
91
+ else
92
+ features.push({ name, enabled: false });
93
+ }
94
+ }
95
+ config[featureType] = features;
96
+ }
97
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /** Default hosted cloud base URL (GodotMcpConfig.DefaultCloudBaseUrl). */
2
+ export declare const DEFAULT_CLOUD_BASE_URL = "https://ai-game.dev";
3
+ /** The MCP hub path appended to a base host (GodotMcpConfig.CloudHubPath). */
4
+ export declare const MCP_HUB_PATH = "/mcp";
5
+ /** Resolved cloud MCP-client URL (base + /mcp). */
6
+ export declare const CLOUD_MCP_URL = "https://ai-game.dev/mcp";
7
+ /** Default custom-mode host (GodotMcpConfig.DefaultCustomHost). */
8
+ export declare const DEFAULT_CUSTOM_HOST = "http://localhost:8080";
9
+ export declare const ENV_CLOUD_URL = "GODOT_MCP_CLOUD_URL";
10
+ export declare const ENV_HOST = "GODOT_MCP_HOST";
11
+ export declare const ENV_TOKEN = "GODOT_MCP_TOKEN";
12
+ export declare const ENV_CONNECTION_MODE = "GODOT_MCP_CONNECTION_MODE";
13
+ export declare const ENV_AUTH_OPTION = "GODOT_MCP_AUTH_OPTION";
14
+ export declare const ENV_LOG_LEVEL = "GODOT_MCP_LOG_LEVEL";
15
+ export interface ConnectionOptions {
16
+ path?: string;
17
+ url?: string;
18
+ token?: string;
19
+ }
20
+ /**
21
+ * Returns true if the given directory looks like a Godot project — i.e.
22
+ * it contains a `project.godot` file. Pure / no I/O beyond `fs.existsSync`.
23
+ */
24
+ export declare function isGodotProject(dir: string): boolean;
25
+ /**
26
+ * Resolve the project path from positional arg, --path option, or cwd.
27
+ */
28
+ export declare function resolveProjectPath(positionalPath: string | undefined, options: ConnectionOptions): string;
29
+ /**
30
+ * Resolve the project path and validate it is a Godot project.
31
+ * Skips validation when --url is provided (explicit server override).
32
+ */
33
+ export declare function resolveAndValidateProjectPath(positionalPath: string | undefined, options: ConnectionOptions): string;
34
+ /**
35
+ * Resolve the MCP server base URL + auth token for direct-tool-call requests
36
+ * (the `<base>/api/tools/<name>` HTTP API exposed by a Godot-MCP server).
37
+ *
38
+ * URL priority:
39
+ * 1. --url flag (explicit override)
40
+ * 2. GODOT_MCP_HOST env (Custom-mode host)
41
+ * 3. GODOT_MCP_CLOUD_URL env / Cloud mode → cloud base (https://ai-game.dev)
42
+ * 4. default custom host (http://localhost:8080)
43
+ *
44
+ * Token priority:
45
+ * 1. --token flag (explicit override)
46
+ * 2. GODOT_MCP_TOKEN env
47
+ *
48
+ * Unlike the Unity CLI, there is NO deterministic project-path→port hash:
49
+ * the Godot plugin is a server-less client whose persisted config lives in
50
+ * `user://` (outside the project tree), so the CLI cannot read a project-local
51
+ * config file. Resolution is therefore env-var + cloud-default based, and
52
+ * `--url` is the authoritative override for a local/self-hosted server.
53
+ */
54
+ export declare function resolveConnection(_projectPath: string, options: ConnectionOptions): {
55
+ url: string;
56
+ token: string | undefined;
57
+ };
@@ -0,0 +1,129 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { verbose } from './ui.js';
4
+ import * as ui from './ui.js';
5
+ // --- Godot MCP connection constants (mirror addons/godot_mcp GodotMcpConfig). ---
6
+ /** Default hosted cloud base URL (GodotMcpConfig.DefaultCloudBaseUrl). */
7
+ export const DEFAULT_CLOUD_BASE_URL = 'https://ai-game.dev';
8
+ /** The MCP hub path appended to a base host (GodotMcpConfig.CloudHubPath). */
9
+ export const MCP_HUB_PATH = '/mcp';
10
+ /** Resolved cloud MCP-client URL (base + /mcp). */
11
+ export const CLOUD_MCP_URL = `${DEFAULT_CLOUD_BASE_URL}${MCP_HUB_PATH}`;
12
+ /** Default custom-mode host (GodotMcpConfig.DefaultCustomHost). */
13
+ export const DEFAULT_CUSTOM_HOST = 'http://localhost:8080';
14
+ // --- Environment-variable names the addon reads (GodotMcpConfig EnvX consts). ---
15
+ export const ENV_CLOUD_URL = 'GODOT_MCP_CLOUD_URL';
16
+ export const ENV_HOST = 'GODOT_MCP_HOST';
17
+ export const ENV_TOKEN = 'GODOT_MCP_TOKEN';
18
+ export const ENV_CONNECTION_MODE = 'GODOT_MCP_CONNECTION_MODE';
19
+ export const ENV_AUTH_OPTION = 'GODOT_MCP_AUTH_OPTION';
20
+ export const ENV_LOG_LEVEL = 'GODOT_MCP_LOG_LEVEL';
21
+ /**
22
+ * Returns true if the given directory looks like a Godot project — i.e.
23
+ * it contains a `project.godot` file. Pure / no I/O beyond `fs.existsSync`.
24
+ */
25
+ export function isGodotProject(dir) {
26
+ return fs.existsSync(path.join(dir, 'project.godot'));
27
+ }
28
+ /**
29
+ * Resolve the project path from positional arg, --path option, or cwd.
30
+ */
31
+ export function resolveProjectPath(positionalPath, options) {
32
+ const resolved = path.resolve(positionalPath ?? options.path ?? process.cwd());
33
+ if ((positionalPath !== undefined || options.path !== undefined) && !fs.existsSync(resolved)) {
34
+ ui.error(`Project path does not exist: ${resolved}`);
35
+ process.exit(1);
36
+ }
37
+ return resolved;
38
+ }
39
+ /**
40
+ * Resolve the project path and validate it is a Godot project.
41
+ * Skips validation when --url is provided (explicit server override).
42
+ */
43
+ export function resolveAndValidateProjectPath(positionalPath, options) {
44
+ const resolved = resolveProjectPath(positionalPath, options);
45
+ // Skip Godot project validation when --url is explicitly provided
46
+ if (options.url) {
47
+ return resolved;
48
+ }
49
+ if (!isGodotProject(resolved)) {
50
+ ui.error(`Not a Godot project (missing project.godot): ${resolved}`);
51
+ ui.info('Provide a Godot project path as an argument, or use --url to connect to a server directly.');
52
+ process.exit(1);
53
+ }
54
+ return resolved;
55
+ }
56
+ /**
57
+ * Strip a single pair of wrapping double-quotes and surrounding whitespace
58
+ * from an environment value, mirroring the addon's `GodotMcpConfig.NormalizeEnv`
59
+ * so `GODOT_MCP_TOKEN="abc"` yields `abc`.
60
+ */
61
+ function normalizeEnv(raw) {
62
+ if (raw === undefined)
63
+ return undefined;
64
+ const trimmed = raw.trim();
65
+ if (trimmed.length === 0)
66
+ return undefined;
67
+ return trimmed.replace(/^"(.*)"$/, '$1');
68
+ }
69
+ /** True when the configured/env mode is Cloud (case-insensitive, name only). */
70
+ function isCloudMode() {
71
+ const mode = normalizeEnv(process.env[ENV_CONNECTION_MODE]);
72
+ return mode !== undefined && mode.toLowerCase() === 'cloud';
73
+ }
74
+ /**
75
+ * Resolve the MCP server base URL + auth token for direct-tool-call requests
76
+ * (the `<base>/api/tools/<name>` HTTP API exposed by a Godot-MCP server).
77
+ *
78
+ * URL priority:
79
+ * 1. --url flag (explicit override)
80
+ * 2. GODOT_MCP_HOST env (Custom-mode host)
81
+ * 3. GODOT_MCP_CLOUD_URL env / Cloud mode → cloud base (https://ai-game.dev)
82
+ * 4. default custom host (http://localhost:8080)
83
+ *
84
+ * Token priority:
85
+ * 1. --token flag (explicit override)
86
+ * 2. GODOT_MCP_TOKEN env
87
+ *
88
+ * Unlike the Unity CLI, there is NO deterministic project-path→port hash:
89
+ * the Godot plugin is a server-less client whose persisted config lives in
90
+ * `user://` (outside the project tree), so the CLI cannot read a project-local
91
+ * config file. Resolution is therefore env-var + cloud-default based, and
92
+ * `--url` is the authoritative override for a local/self-hosted server.
93
+ */
94
+ export function resolveConnection(_projectPath, options) {
95
+ let url;
96
+ if (options.url) {
97
+ url = options.url.replace(/\/$/, '');
98
+ verbose(`Using explicit --url: ${url}`);
99
+ }
100
+ else {
101
+ const envHost = normalizeEnv(process.env[ENV_HOST]);
102
+ const envCloud = normalizeEnv(process.env[ENV_CLOUD_URL]);
103
+ if (envHost) {
104
+ url = envHost.replace(/\/$/, '');
105
+ verbose(`Using ${ENV_HOST}: ${url}`);
106
+ }
107
+ else if (envCloud) {
108
+ url = envCloud.replace(new RegExp(`${MCP_HUB_PATH}$`), '').replace(/\/$/, '');
109
+ verbose(`Using ${ENV_CLOUD_URL} base: ${url}`);
110
+ }
111
+ else if (isCloudMode()) {
112
+ url = DEFAULT_CLOUD_BASE_URL;
113
+ verbose(`Using default cloud base URL: ${url}`);
114
+ }
115
+ else {
116
+ url = DEFAULT_CUSTOM_HOST;
117
+ verbose(`Using default custom host: ${url}`);
118
+ }
119
+ }
120
+ const token = options.token ?? normalizeEnv(process.env[ENV_TOKEN]);
121
+ if (options.token) {
122
+ verbose('Using explicit --token');
123
+ }
124
+ else if (token) {
125
+ verbose(`Using ${ENV_TOKEN}`);
126
+ }
127
+ return { url, token };
128
+ }
129
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/utils/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Environment variables that, when set, point directly at a Godot editor
3
+ * binary. Checked before PATH and common install dirs. `GODOT_BIN` is the
4
+ * conventional name; `GODOT4_BIN` is honored for setups that pin a Godot 4
5
+ * binary alongside a legacy Godot 3 one.
6
+ */
7
+ export declare const GODOT_BIN_ENV_VARS: readonly ["GODOT_BIN", "GODOT4_BIN"];
8
+ /**
9
+ * Resolve the Godot editor binary path.
10
+ *
11
+ * Resolution order (first hit wins):
12
+ * 1. An explicit `editorPath` argument (validated to be an existing file).
13
+ * 2. `GODOT_BIN` / `GODOT4_BIN` environment variables.
14
+ * 3. The first matching Godot binary on `PATH`.
15
+ * 4. Per-OS common install directories (Windows prefers the mono build;
16
+ * macOS resolves the `.app/Contents/MacOS` binary; Linux scans common
17
+ * extracted-binary locations).
18
+ *
19
+ * Returns the absolute path, or `null` when no Godot binary can be located.
20
+ * Pure / no spawn — exported for unit tests (the `os`/env are injectable via
21
+ * the running process; tests stub `fs` + env).
22
+ */
23
+ export declare function findGodotBinary(editorPath?: string, os?: NodeJS.Platform): string | null;
24
+ export interface LaunchEditorCallbacks {
25
+ /** Fired once the OS reports the child process has spawned. */
26
+ onSpawn?: (pid: number | undefined) => void;
27
+ /** Fired if the spawn itself fails (binary missing, permission denied, …). */
28
+ onError?: (err: Error) => void;
29
+ }
30
+ /**
31
+ * Spawn the Godot editor binary opening the given project, optionally with
32
+ * `GODOT_MCP_*` connection environment variables. Mirrors the Unity CLI's
33
+ * `launchEditor`: spawns detached, with `stdio: 'ignore'`, and `unref()`s so
34
+ * the parent process can exit without waiting on the editor.
35
+ *
36
+ * Godot's editor-open invocation is `--editor --path <project>` (the
37
+ * `--editor` flag forces the project to open in the editor rather than run).
38
+ *
39
+ * Library-safe (no process.exit, no stdout/stderr writes — observability is
40
+ * the caller's responsibility via the optional callbacks).
41
+ */
42
+ export declare function launchEditor(editorPath: string, projectPath: string, env?: Record<string, string>, callbacks?: LaunchEditorCallbacks): import('child_process').ChildProcess;