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,22 @@
1
+ import { projectGodotPath as resolveProjectGodotPath } from '../utils/project-godot.js';
2
+ import type { InstallPluginOptions, InstallPluginResult, RemovePluginOptions, RemovePluginResult } from './types.js';
3
+ /**
4
+ * Enable the `godot_mcp` addon in a project's `project.godot` `[editor_plugins]`
5
+ * `enabled` array. Library-safe: no stdout noise, no process.exit, no throws
6
+ * past the public boundary.
7
+ *
8
+ * v1 is intentionally minimal — it only flips the project.godot plugin-enable
9
+ * state. It does NOT copy addon files or patch the consumer `.csproj` with the
10
+ * NuGet PackageReferences the addon needs (that is the consumer's responsibility
11
+ * per the addon's install docs); a warning surfaces that requirement.
12
+ *
13
+ * Idempotent: enabling an already-enabled plugin returns `changed: false`.
14
+ */
15
+ export declare function installPlugin(opts: InstallPluginOptions): Promise<InstallPluginResult>;
16
+ /**
17
+ * Disable the `godot_mcp` addon in a project's `project.godot`
18
+ * `[editor_plugins]` `enabled` array. Idempotent: disabling an already-absent
19
+ * plugin returns `changed: false`. Does NOT delete addon files.
20
+ */
21
+ export declare function removePlugin(opts: RemovePluginOptions): Promise<RemovePluginResult>;
22
+ export { resolveProjectGodotPath };
@@ -0,0 +1,118 @@
1
+ import * as fs from 'fs';
2
+ import { GODOT_MCP_PLUGIN_PATH, projectGodotPath as resolveProjectGodotPath, togglePluginInText, } from '../utils/project-godot.js';
3
+ import { emitProgress } from './progress.js';
4
+ import { requireGodotProject } from './validation.js';
5
+ /**
6
+ * Enable the `godot_mcp` addon in a project's `project.godot` `[editor_plugins]`
7
+ * `enabled` array. Library-safe: no stdout noise, no process.exit, no throws
8
+ * past the public boundary.
9
+ *
10
+ * v1 is intentionally minimal — it only flips the project.godot plugin-enable
11
+ * state. It does NOT copy addon files or patch the consumer `.csproj` with the
12
+ * NuGet PackageReferences the addon needs (that is the consumer's responsibility
13
+ * per the addon's install docs); a warning surfaces that requirement.
14
+ *
15
+ * Idempotent: enabling an already-enabled plugin returns `changed: false`.
16
+ */
17
+ export async function installPlugin(opts) {
18
+ const warnings = [];
19
+ try {
20
+ const validated = requireGodotProject(opts?.godotProjectPath);
21
+ if (!validated.ok) {
22
+ return {
23
+ kind: 'failure',
24
+ success: false,
25
+ projectGodotPath: validated.projectGodotPath,
26
+ warnings,
27
+ error: validated.error,
28
+ };
29
+ }
30
+ const { projectPath, projectGodotPath } = validated;
31
+ emitProgress(opts.onProgress, {
32
+ phase: 'start',
33
+ message: `Enabling godot_mcp addon for ${projectPath}`,
34
+ });
35
+ const text = fs.readFileSync(projectGodotPath, 'utf-8');
36
+ const result = togglePluginInText(text, true, GODOT_MCP_PLUGIN_PATH);
37
+ if (result.kind === 'changed') {
38
+ fs.writeFileSync(projectGodotPath, result.text);
39
+ emitProgress(opts.onProgress, {
40
+ phase: 'manifest-patched',
41
+ message: `Wrote ${projectGodotPath}`,
42
+ manifestPath: projectGodotPath,
43
+ });
44
+ }
45
+ warnings.push('Ensure the project .csproj declares the com.IvanMurzak.ReflectorNet and com.IvanMurzak.McpPlugin PackageReferences the addon needs (see the addon README).');
46
+ emitProgress(opts.onProgress, { phase: 'done', message: 'godot_mcp addon enabled.' });
47
+ return {
48
+ kind: 'success',
49
+ success: true,
50
+ changed: result.kind === 'changed',
51
+ projectGodotPath,
52
+ enabledPlugins: result.enabled,
53
+ warnings,
54
+ };
55
+ }
56
+ catch (err) {
57
+ return {
58
+ kind: 'failure',
59
+ success: false,
60
+ warnings,
61
+ error: err instanceof Error ? err : new Error(String(err)),
62
+ };
63
+ }
64
+ }
65
+ /**
66
+ * Disable the `godot_mcp` addon in a project's `project.godot`
67
+ * `[editor_plugins]` `enabled` array. Idempotent: disabling an already-absent
68
+ * plugin returns `changed: false`. Does NOT delete addon files.
69
+ */
70
+ export async function removePlugin(opts) {
71
+ const warnings = [];
72
+ try {
73
+ const validated = requireGodotProject(opts?.godotProjectPath);
74
+ if (!validated.ok) {
75
+ return {
76
+ kind: 'failure',
77
+ success: false,
78
+ projectGodotPath: validated.projectGodotPath,
79
+ warnings,
80
+ error: validated.error,
81
+ };
82
+ }
83
+ const { projectPath, projectGodotPath } = validated;
84
+ emitProgress(opts.onProgress, {
85
+ phase: 'start',
86
+ message: `Disabling godot_mcp addon for ${projectPath}`,
87
+ });
88
+ const text = fs.readFileSync(projectGodotPath, 'utf-8');
89
+ const result = togglePluginInText(text, false, GODOT_MCP_PLUGIN_PATH);
90
+ if (result.kind === 'changed') {
91
+ fs.writeFileSync(projectGodotPath, result.text);
92
+ emitProgress(opts.onProgress, {
93
+ phase: 'manifest-patched',
94
+ message: `Wrote ${projectGodotPath}`,
95
+ manifestPath: projectGodotPath,
96
+ });
97
+ }
98
+ emitProgress(opts.onProgress, { phase: 'done', message: 'godot_mcp addon disabled.' });
99
+ return {
100
+ kind: 'success',
101
+ success: true,
102
+ changed: result.kind === 'changed',
103
+ projectGodotPath,
104
+ enabledPlugins: result.enabled,
105
+ warnings,
106
+ };
107
+ }
108
+ catch (err) {
109
+ return {
110
+ kind: 'failure',
111
+ success: false,
112
+ warnings,
113
+ error: err instanceof Error ? err : new Error(String(err)),
114
+ };
115
+ }
116
+ }
117
+ export { resolveProjectGodotPath };
118
+ //# sourceMappingURL=install-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-plugin.js","sourceRoot":"","sources":["../../src/lib/install-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,IAAI,uBAAuB,EAC3C,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAQtD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAA0B;IAC5D,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,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,KAAK;gBACd,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;gBAC5C,QAAQ;gBACR,KAAK,EAAE,SAAS,CAAC,KAAK;aACvB,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,SAAS,CAAC;QAEpD,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE;YAC5B,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,gCAAgC,WAAW,EAAE;SACvD,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC;QAErE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAChD,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE;gBAC5B,KAAK,EAAE,kBAAkB;gBACzB,OAAO,EAAE,SAAS,gBAAgB,EAAE;gBACpC,YAAY,EAAE,gBAAgB;aAC/B,CAAC,CAAC;QACL,CAAC;QAED,QAAQ,CAAC,IAAI,CACX,4JAA4J,CAC7J,CAAC;QAEF,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC;QAEtF,OAAO;YACL,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,MAAM,CAAC,IAAI,KAAK,SAAS;YAClC,gBAAgB;YAChB,cAAc,EAAE,MAAM,CAAC,OAAO;YAC9B,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,SAAS;YACf,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;AAED;;;;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,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,KAAK;gBACd,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;gBAC5C,QAAQ;gBACR,KAAK,EAAE,SAAS,CAAC,KAAK;aACvB,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,SAAS,CAAC;QAEpD,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE;YAC5B,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,iCAAiC,WAAW,EAAE;SACxD,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;QAEtE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAChD,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE;gBAC5B,KAAK,EAAE,kBAAkB;gBACzB,OAAO,EAAE,SAAS,gBAAgB,EAAE;gBACpC,YAAY,EAAE,gBAAgB;aAC/B,CAAC,CAAC;QACL,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAEvF,OAAO;YACL,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,MAAM,CAAC,IAAI,KAAK,SAAS;YAClC,gBAAgB;YAChB,cAAc,EAAE,MAAM,CAAC,OAAO;YAC9B,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,SAAS;YACf,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;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { OpenEnvInputs, OpenProjectOptions, OpenProjectResult } from './types.js';
2
+ /**
3
+ * Resolve the project path from an explicit option or fall back to the supplied
4
+ * cwd. Returns an absolute path plus a flag indicating whether the cwd fallback
5
+ * was used. Pure / no I/O.
6
+ */
7
+ export declare function resolveProjectPath(optionPath: string | undefined, cwd: string): {
8
+ projectPath: string;
9
+ usedCwdFallback: boolean;
10
+ };
11
+ /**
12
+ * Returns true if `projectPath` looks like a Godot project — i.e. it contains a
13
+ * `project.godot` file. Pure / no I/O beyond `fs.existsSync`.
14
+ */
15
+ export declare function isGodotProjectDir(projectPath: string): boolean;
16
+ /**
17
+ * Build the `GODOT_MCP_*` env-var map propagated to the editor process when
18
+ * `noConnect !== true`. Pure (returns a fresh object); validates `auth` /
19
+ * `mode` enums and throws on bad input — the `openProject` boundary catches the
20
+ * throw and returns it as a `{ kind: 'failure' }` result.
21
+ *
22
+ * Exported for tests so the env-var assembly can be exercised without a real
23
+ * editor launch.
24
+ */
25
+ export declare function buildOpenEnv(options: OpenEnvInputs): Record<string, string> | undefined;
26
+ /**
27
+ * Open a Godot project in the Godot editor — the library-callable equivalent of
28
+ * the `open` CLI command. Library-safe: never calls `process.exit`, never
29
+ * prints to stdout/stderr, never throws past the public boundary.
30
+ *
31
+ * Launches `<godot> --editor --path <project>` with the `GODOT_MCP_*` connection
32
+ * env vars wired on.
33
+ */
34
+ export declare function openProject(options: OpenProjectOptions): Promise<OpenProjectResult>;
@@ -0,0 +1,198 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { findGodotBinary, launchEditor } from '../utils/godot-editor.js';
4
+ import { findGodotProcess } from '../utils/godot-process.js';
5
+ import { ENV_AUTH_OPTION, ENV_CLOUD_URL, ENV_CONNECTION_MODE, ENV_HOST, ENV_LOG_LEVEL, ENV_TOKEN, } from '../utils/connection.js';
6
+ import { emitProgress } from './progress.js';
7
+ /**
8
+ * Resolve the project path from an explicit option or fall back to the supplied
9
+ * cwd. Returns an absolute path plus a flag indicating whether the cwd fallback
10
+ * was used. Pure / no I/O.
11
+ */
12
+ export function resolveProjectPath(optionPath, cwd) {
13
+ const explicit = optionPath;
14
+ const resolvedPath = explicit ?? cwd;
15
+ return {
16
+ projectPath: path.resolve(resolvedPath),
17
+ usedCwdFallback: explicit === undefined,
18
+ };
19
+ }
20
+ /**
21
+ * Returns true if `projectPath` looks like a Godot project — i.e. it contains a
22
+ * `project.godot` file. Pure / no I/O beyond `fs.existsSync`.
23
+ */
24
+ export function isGodotProjectDir(projectPath) {
25
+ return fs.existsSync(path.join(projectPath, 'project.godot'));
26
+ }
27
+ function isValidAuth(v) {
28
+ return v === 'None' || v === 'Required';
29
+ }
30
+ function isValidMode(v) {
31
+ return v === 'Cloud' || v === 'Custom';
32
+ }
33
+ /**
34
+ * Build the `GODOT_MCP_*` env-var map propagated to the editor process when
35
+ * `noConnect !== true`. Pure (returns a fresh object); validates `auth` /
36
+ * `mode` enums and throws on bad input — the `openProject` boundary catches the
37
+ * throw and returns it as a `{ kind: 'failure' }` result.
38
+ *
39
+ * Exported for tests so the env-var assembly can be exercised without a real
40
+ * editor launch.
41
+ */
42
+ export function buildOpenEnv(options) {
43
+ if (options.noConnect === true)
44
+ return undefined;
45
+ const env = {};
46
+ if (options.url !== undefined)
47
+ env[ENV_HOST] = options.url;
48
+ if (options.cloudUrl !== undefined)
49
+ env[ENV_CLOUD_URL] = options.cloudUrl;
50
+ if (options.token !== undefined)
51
+ env[ENV_TOKEN] = options.token;
52
+ if (options.logLevel !== undefined)
53
+ env[ENV_LOG_LEVEL] = options.logLevel;
54
+ if (options.auth !== undefined) {
55
+ if (!isValidAuth(options.auth)) {
56
+ throw new Error('auth must be "None" or "Required"');
57
+ }
58
+ env[ENV_AUTH_OPTION] = options.auth;
59
+ }
60
+ if (options.mode !== undefined) {
61
+ if (!isValidMode(options.mode)) {
62
+ throw new Error('mode must be "Cloud" or "Custom"');
63
+ }
64
+ env[ENV_CONNECTION_MODE] = options.mode;
65
+ }
66
+ return Object.keys(env).length > 0 ? env : undefined;
67
+ }
68
+ /**
69
+ * Open a Godot project in the Godot editor — the library-callable equivalent of
70
+ * the `open` CLI command. Library-safe: never calls `process.exit`, never
71
+ * prints to stdout/stderr, never throws past the public boundary.
72
+ *
73
+ * Launches `<godot> --editor --path <project>` with the `GODOT_MCP_*` connection
74
+ * env vars wired on.
75
+ */
76
+ export async function openProject(options) {
77
+ const warnings = [];
78
+ let resolvedProjectPath;
79
+ let resolvedEditorPath;
80
+ try {
81
+ const { projectPath } = resolveProjectPath(options.projectPath, process.cwd());
82
+ resolvedProjectPath = projectPath;
83
+ if (!fs.existsSync(projectPath)) {
84
+ throw new Error(`Project path does not exist: ${projectPath}`);
85
+ }
86
+ if (!isGodotProjectDir(projectPath)) {
87
+ throw new Error(`Not a Godot project (missing project.godot): ${projectPath}`);
88
+ }
89
+ emitProgress(options.onProgress, {
90
+ phase: 'start',
91
+ message: `Opening Godot project at ${projectPath}`,
92
+ });
93
+ // Validate auth/mode BEFORE editor resolution so a typo fails fast.
94
+ const env = buildOpenEnv(options);
95
+ // Already-running short-circuit.
96
+ const existingProcess = findGodotProcess(projectPath);
97
+ if (existingProcess) {
98
+ warnings.push(`Godot is already running with this project (PID: ${existingProcess.pid}). Skipping launch.`);
99
+ emitProgress(options.onProgress, {
100
+ phase: 'done',
101
+ message: 'Godot is already running for this project — launch skipped.',
102
+ });
103
+ return {
104
+ kind: 'success',
105
+ success: true,
106
+ editorPath: existingProcess.commandLine.split(/\s+/)[0] ?? '',
107
+ editorPid: existingProcess.pid,
108
+ projectPath,
109
+ warnings,
110
+ alreadyRunning: true,
111
+ };
112
+ }
113
+ // Locate the Godot binary.
114
+ const editorPath = findGodotBinary(options.editorPath);
115
+ if (!editorPath) {
116
+ throw new Error('No Godot editor binary found. Set GODOT_BIN (or GODOT4_BIN), add godot to PATH, or pass --editor-path.');
117
+ }
118
+ resolvedEditorPath = editorPath;
119
+ emitProgress(options.onProgress, {
120
+ phase: 'editor-resolved',
121
+ message: `Resolved Godot editor at ${editorPath}`,
122
+ editorPath,
123
+ });
124
+ emitProgress(options.onProgress, {
125
+ phase: 'connection-details',
126
+ message: env
127
+ ? 'MCP connection environment variables prepared'
128
+ : 'No MCP connection environment variables (--no-connect or no options provided)',
129
+ projectPath,
130
+ editorPath,
131
+ envVars: env ?? {},
132
+ });
133
+ emitProgress(options.onProgress, {
134
+ phase: 'launching-editor',
135
+ message: 'Launching Godot editor',
136
+ editorPath,
137
+ projectPath,
138
+ });
139
+ const child = launchEditor(editorPath, projectPath, env, {
140
+ onSpawn: (pid) => {
141
+ emitProgress(options.onProgress, {
142
+ phase: 'editor-launched',
143
+ message: `Launched Godot editor (PID: ${pid ?? 'unknown'})`,
144
+ pid,
145
+ });
146
+ },
147
+ onError: (err) => {
148
+ warnings.push(`Editor spawn reported error: ${err.message}`);
149
+ },
150
+ });
151
+ const pid = await waitForSpawn(child);
152
+ emitProgress(options.onProgress, { phase: 'done', message: 'Editor launched.' });
153
+ return {
154
+ kind: 'success',
155
+ success: true,
156
+ editorPath,
157
+ editorPid: pid,
158
+ projectPath,
159
+ warnings,
160
+ };
161
+ }
162
+ catch (err) {
163
+ const errorObj = err instanceof Error ? err : new Error(String(err));
164
+ return {
165
+ kind: 'failure',
166
+ success: false,
167
+ projectPath: resolvedProjectPath,
168
+ editorPath: resolvedEditorPath,
169
+ warnings,
170
+ errorMessage: errorObj.message,
171
+ error: errorObj,
172
+ };
173
+ }
174
+ }
175
+ /**
176
+ * Resolve to the spawned PID once the child process emits its `spawn` event, or
177
+ * to `undefined` if a short timeout elapses or the process emits `error` first.
178
+ * Library-safe: never throws, never blocks process exit (the caller detached).
179
+ */
180
+ function waitForSpawn(child, timeoutMs = 2000) {
181
+ return new Promise((resolve) => {
182
+ if (child.pid !== undefined && child.pid !== null) {
183
+ resolve(child.pid);
184
+ return;
185
+ }
186
+ let settled = false;
187
+ const finish = (pid) => {
188
+ if (settled)
189
+ return;
190
+ settled = true;
191
+ resolve(pid);
192
+ };
193
+ child.once('spawn', () => finish(child.pid ?? undefined));
194
+ child.once('error', () => finish(undefined));
195
+ setTimeout(() => finish(child.pid ?? undefined), timeoutMs).unref();
196
+ });
197
+ }
198
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/lib/open.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ProgressCallback, ProgressEvent } from './types.js';
2
+ /**
3
+ * Forward a single progress event to the caller's optional callback,
4
+ * swallowing any exception the callback throws. A broken onProgress handler
5
+ * must never abort the underlying library operation.
6
+ */
7
+ export declare function emitProgress(onProgress: ProgressCallback | undefined, event: ProgressEvent): void;
@@ -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 handler
4
+ * 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,12 @@
1
+ import type { RunToolOptions, RunToolResult } from './types.js';
2
+ /**
3
+ * Invoke a regular MCP tool over the Godot plugin's HTTP API.
4
+ * POSTs to `<url>/api/tools/{name}`. No console output, no `process.exit`;
5
+ * errors are returned in the `kind: 'failure'` variant.
6
+ */
7
+ export declare function runTool(opts: RunToolOptions): Promise<RunToolResult>;
8
+ /**
9
+ * Invoke a system tool (not exposed to MCP clients) over the Godot plugin's
10
+ * HTTP API. POSTs to `<url>/api/system-tools/{name}`.
11
+ */
12
+ export declare function runSystemTool(opts: RunToolOptions): Promise<RunToolResult>;
@@ -0,0 +1,192 @@
1
+ // Library-safe `runTool` / `runSystemTool` implementations.
2
+ //
3
+ // Constraints (same contract as the rest of `lib/*.ts`):
4
+ // - No commander, no spinners, no process.exit, no console output.
5
+ // - Errors are returned in `{ kind: 'failure', success: false, ... }`,
6
+ // never thrown past the public boundary.
7
+ const DEFAULT_TIMEOUT_MS = 60000;
8
+ /**
9
+ * Invoke a regular MCP tool over the Godot plugin's HTTP API.
10
+ * POSTs to `<url>/api/tools/{name}`. No console output, no `process.exit`;
11
+ * errors are returned in the `kind: 'failure'` variant.
12
+ */
13
+ export async function runTool(opts) {
14
+ return invokeTool('/api/tools', opts);
15
+ }
16
+ /**
17
+ * Invoke a system tool (not exposed to MCP clients) over the Godot plugin's
18
+ * HTTP API. POSTs to `<url>/api/system-tools/{name}`.
19
+ */
20
+ export async function runSystemTool(opts) {
21
+ return invokeTool('/api/system-tools', opts);
22
+ }
23
+ async function invokeTool(routePrefix, opts) {
24
+ const validationFailure = validateOptions(opts);
25
+ if (validationFailure)
26
+ return validationFailure;
27
+ const url = opts.url.replace(/\/$/, '');
28
+ const token = opts.token;
29
+ const body = serializeInput(opts.input);
30
+ if ('error' in body) {
31
+ return makeFailure({
32
+ endpoint: '',
33
+ reason: 'invalid-input',
34
+ message: body.error.message,
35
+ error: body.error,
36
+ });
37
+ }
38
+ const endpoint = `${url}${routePrefix}/${encodeURIComponent(opts.toolName)}`;
39
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
40
+ const timeoutMs = typeof opts.timeoutMs === 'number' && opts.timeoutMs > 0 ? opts.timeoutMs : DEFAULT_TIMEOUT_MS;
41
+ const controller = new AbortController();
42
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
43
+ const externalAbort = () => controller.abort();
44
+ if (opts.signal) {
45
+ if (opts.signal.aborted)
46
+ controller.abort();
47
+ else
48
+ opts.signal.addEventListener('abort', externalAbort, { once: true });
49
+ }
50
+ const headers = { 'Content-Type': 'application/json' };
51
+ if (token)
52
+ headers['Authorization'] = `Bearer ${token}`;
53
+ try {
54
+ const response = await fetchImpl(endpoint, {
55
+ method: 'POST',
56
+ headers,
57
+ body: body.json,
58
+ signal: controller.signal,
59
+ });
60
+ const text = await safeReadText(response);
61
+ const data = parseJsonOrText(text);
62
+ if (!response.ok) {
63
+ return makeFailure({
64
+ endpoint,
65
+ reason: 'http-error',
66
+ httpStatus: response.status,
67
+ data,
68
+ message: response.statusText || `HTTP ${response.status}`,
69
+ });
70
+ }
71
+ const success = {
72
+ kind: 'success',
73
+ success: true,
74
+ endpoint,
75
+ httpStatus: response.status,
76
+ data,
77
+ };
78
+ return success;
79
+ }
80
+ catch (err) {
81
+ return classifyFetchError(err, endpoint, timeoutMs);
82
+ }
83
+ finally {
84
+ clearTimeout(timer);
85
+ opts.signal?.removeEventListener('abort', externalAbort);
86
+ }
87
+ }
88
+ function validateOptions(opts) {
89
+ if (!opts || typeof opts !== 'object') {
90
+ return makeFailure({
91
+ endpoint: '',
92
+ reason: 'invalid-input',
93
+ message: 'options object is required.',
94
+ });
95
+ }
96
+ if (typeof opts.toolName !== 'string' || opts.toolName.trim().length === 0) {
97
+ return makeFailure({
98
+ endpoint: '',
99
+ reason: 'invalid-input',
100
+ message: 'toolName is required and must be a non-empty string.',
101
+ });
102
+ }
103
+ const hasUrl = typeof opts.url === 'string' && opts.url.length > 0;
104
+ if (!hasUrl) {
105
+ return makeFailure({
106
+ endpoint: '',
107
+ reason: 'invalid-input',
108
+ message: 'url is required (the Godot-MCP server base URL).',
109
+ });
110
+ }
111
+ return null;
112
+ }
113
+ function serializeInput(input) {
114
+ if (input === undefined || input === null)
115
+ return { json: '{}' };
116
+ if (typeof input === 'string') {
117
+ try {
118
+ JSON.parse(input);
119
+ return { json: input };
120
+ }
121
+ catch (err) {
122
+ return {
123
+ error: new Error(`input string is not valid JSON: ${err instanceof Error ? err.message : String(err)}`),
124
+ };
125
+ }
126
+ }
127
+ if (typeof input !== 'object') {
128
+ return {
129
+ error: new Error('input must be a plain object, JSON string, undefined, or null.'),
130
+ };
131
+ }
132
+ try {
133
+ return { json: JSON.stringify(input) };
134
+ }
135
+ catch (err) {
136
+ return {
137
+ error: new Error(`input could not be serialized to JSON: ${err instanceof Error ? err.message : String(err)}`),
138
+ };
139
+ }
140
+ }
141
+ async function safeReadText(response) {
142
+ try {
143
+ return await response.text();
144
+ }
145
+ catch {
146
+ return '';
147
+ }
148
+ }
149
+ function parseJsonOrText(text) {
150
+ if (text.length === 0)
151
+ return undefined;
152
+ try {
153
+ return JSON.parse(text);
154
+ }
155
+ catch {
156
+ return text;
157
+ }
158
+ }
159
+ function getCause(err) {
160
+ if (!(err instanceof Error) || !('cause' in err))
161
+ return undefined;
162
+ return err.cause;
163
+ }
164
+ function classifyFetchError(err, endpoint, timeoutMs) {
165
+ if (err instanceof Error && err.name === 'AbortError') {
166
+ return makeFailure({
167
+ endpoint,
168
+ reason: 'timeout',
169
+ message: `Tool call timed out after ${timeoutMs}ms.`,
170
+ error: err,
171
+ });
172
+ }
173
+ const error = err instanceof Error ? err : new Error(String(err));
174
+ const causeCode = getCause(err)?.code;
175
+ let reason = 'unknown';
176
+ if (causeCode === 'ECONNREFUSED')
177
+ reason = 'connection-refused';
178
+ else if (causeCode === 'ECONNRESET')
179
+ reason = 'connection-reset';
180
+ else if (causeCode === 'ENOTFOUND' || causeCode === 'EAI_AGAIN')
181
+ reason = 'network-error';
182
+ return makeFailure({
183
+ endpoint,
184
+ reason,
185
+ message: error.message,
186
+ error,
187
+ });
188
+ }
189
+ function makeFailure(fields) {
190
+ return { kind: 'failure', success: false, ...fields };
191
+ }
192
+ //# sourceMappingURL=run-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-tool.js","sourceRoot":"","sources":["../../src/lib/run-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { CLOUD_MCP_URL, DEFAULT_CUSTOM_HOST } from '../utils/connection.js';
2
+ import type { SetupMcpOptions, SetupMcpResult } from './types.js';
3
+ /**
4
+ * Write MCP configuration for the given AI agent so it can talk to a Godot-MCP
5
+ * server. Library-safe: no stdout noise, no process.exit, no throws past the
6
+ * public boundary.
7
+ *
8
+ * Writes an HTTP server entry pointing at the resolved MCP-client URL. The
9
+ * Godot config body shape mirrors the addon's `AgentConfigJson` / `AgentConfigPaths`
10
+ * conventions (`.mcp.json` under `mcpServers` for Claude Code, `.vscode/mcp.json`
11
+ * under `servers` for VS Code, etc.).
12
+ */
13
+ export declare function setupMcp(opts: SetupMcpOptions): Promise<SetupMcpResult>;
14
+ /** List every agent id known to `setupMcp`. */
15
+ export declare function listAgentIds(): string[];
16
+ export { CLOUD_MCP_URL, DEFAULT_CUSTOM_HOST };