godot-cli 0.38.0 → 0.39.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 (167) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/README.md +139 -16
  3. package/dist/cli.d.ts +7 -0
  4. package/dist/cli.js +7 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commands/check.d.ts +2 -0
  7. package/dist/commands/check.js +48 -0
  8. package/dist/commands/check.js.map +1 -0
  9. package/dist/commands/close.d.ts +3 -0
  10. package/dist/commands/close.js +82 -27
  11. package/dist/commands/close.js.map +1 -1
  12. package/dist/commands/commands.d.ts +3 -0
  13. package/dist/commands/commands.js +28 -0
  14. package/dist/commands/commands.js.map +1 -0
  15. package/dist/commands/exec.js +43 -28
  16. package/dist/commands/exec.js.map +1 -1
  17. package/dist/commands/export.d.ts +2 -0
  18. package/dist/commands/export.js +45 -0
  19. package/dist/commands/export.js.map +1 -0
  20. package/dist/commands/headless-common.d.ts +29 -0
  21. package/dist/commands/headless-common.js +69 -0
  22. package/dist/commands/headless-common.js.map +1 -0
  23. package/dist/commands/import.d.ts +2 -0
  24. package/dist/commands/import.js +32 -0
  25. package/dist/commands/import.js.map +1 -0
  26. package/dist/commands/open.js +38 -6
  27. package/dist/commands/open.js.map +1 -1
  28. package/dist/commands/rql.d.ts +2 -0
  29. package/dist/commands/rql.js +81 -0
  30. package/dist/commands/rql.js.map +1 -0
  31. package/dist/commands/run-script.d.ts +2 -0
  32. package/dist/commands/run-script.js +33 -0
  33. package/dist/commands/run-script.js.map +1 -0
  34. package/dist/commands/run-system-tool.js +0 -1
  35. package/dist/commands/run-system-tool.js.map +1 -1
  36. package/dist/commands/run-tool-builder.d.ts +38 -4
  37. package/dist/commands/run-tool-builder.js +179 -56
  38. package/dist/commands/run-tool-builder.js.map +1 -1
  39. package/dist/commands/run-tool.js +0 -1
  40. package/dist/commands/run-tool.js.map +1 -1
  41. package/dist/commands/setup-skills.js +3 -2
  42. package/dist/commands/setup-skills.js.map +1 -1
  43. package/dist/commands/status.js +25 -19
  44. package/dist/commands/status.js.map +1 -1
  45. package/dist/commands/test.d.ts +5 -0
  46. package/dist/commands/test.js +111 -0
  47. package/dist/commands/test.js.map +1 -0
  48. package/dist/commands/tools.d.ts +2 -0
  49. package/dist/commands/tools.js +120 -0
  50. package/dist/commands/tools.js.map +1 -0
  51. package/dist/commands/update.js +1 -1
  52. package/dist/commands/update.js.map +1 -1
  53. package/dist/commands/wait-for-ready.js +18 -20
  54. package/dist/commands/wait-for-ready.js.map +1 -1
  55. package/dist/index.js +48 -3
  56. package/dist/index.js.map +1 -1
  57. package/dist/lib/build.d.ts +1 -1
  58. package/dist/lib/build.js +21 -4
  59. package/dist/lib/build.js.map +1 -1
  60. package/dist/lib/check.d.ts +44 -0
  61. package/dist/lib/check.js +191 -0
  62. package/dist/lib/check.js.map +1 -0
  63. package/dist/lib/cli-guide.d.ts +26 -0
  64. package/dist/lib/cli-guide.js +51 -0
  65. package/dist/lib/cli-guide.js.map +1 -0
  66. package/dist/lib/exec.d.ts +19 -0
  67. package/dist/lib/exec.js +61 -10
  68. package/dist/lib/exec.js.map +1 -1
  69. package/dist/lib/export-project.d.ts +41 -0
  70. package/dist/lib/export-project.js +159 -0
  71. package/dist/lib/export-project.js.map +1 -0
  72. package/dist/lib/godot-log.d.ts +38 -0
  73. package/dist/lib/godot-log.js +145 -0
  74. package/dist/lib/godot-log.js.map +1 -0
  75. package/dist/lib/godot-run.d.ts +34 -0
  76. package/dist/lib/godot-run.js +113 -0
  77. package/dist/lib/godot-run.js.map +1 -0
  78. package/dist/lib/headless.d.ts +82 -0
  79. package/dist/lib/headless.js +117 -0
  80. package/dist/lib/headless.js.map +1 -0
  81. package/dist/lib/import-project.d.ts +9 -0
  82. package/dist/lib/import-project.js +15 -0
  83. package/dist/lib/import-project.js.map +1 -0
  84. package/dist/lib/junit.d.ts +36 -0
  85. package/dist/lib/junit.js +146 -0
  86. package/dist/lib/junit.js.map +1 -0
  87. package/dist/lib/list-tools.d.ts +51 -0
  88. package/dist/lib/list-tools.js +147 -0
  89. package/dist/lib/list-tools.js.map +1 -0
  90. package/dist/lib/open.js +3 -1
  91. package/dist/lib/open.js.map +1 -1
  92. package/dist/lib/progress.d.ts +1 -7
  93. package/dist/lib/progress.js +2 -15
  94. package/dist/lib/progress.js.map +1 -1
  95. package/dist/lib/rql.d.ts +32 -0
  96. package/dist/lib/rql.js +105 -0
  97. package/dist/lib/rql.js.map +1 -0
  98. package/dist/lib/run-script.d.ts +23 -0
  99. package/dist/lib/run-script.js +43 -0
  100. package/dist/lib/run-script.js.map +1 -0
  101. package/dist/lib/run-tests.d.ts +50 -0
  102. package/dist/lib/run-tests.js +181 -0
  103. package/dist/lib/run-tests.js.map +1 -0
  104. package/dist/lib/run-tool.js +6 -22
  105. package/dist/lib/run-tool.js.map +1 -1
  106. package/dist/lib/session.d.ts +8 -1
  107. package/dist/lib/session.js +36 -4
  108. package/dist/lib/session.js.map +1 -1
  109. package/dist/lib/setup-skills.d.ts +8 -13
  110. package/dist/lib/setup-skills.js +27 -24
  111. package/dist/lib/setup-skills.js.map +1 -1
  112. package/dist/lib/types.d.ts +7 -0
  113. package/dist/lib/update-project.js +1 -1
  114. package/dist/lib/update-project.js.map +1 -1
  115. package/dist/lib.d.ts +16 -0
  116. package/dist/lib.js +10 -0
  117. package/dist/lib.js.map +1 -1
  118. package/dist/utils/addon-deps.js +2 -2
  119. package/dist/utils/agents.d.ts +2 -6
  120. package/dist/utils/agents.js.map +1 -1
  121. package/dist/utils/connection.d.ts +59 -0
  122. package/dist/utils/connection.js +11 -10
  123. package/dist/utils/connection.js.map +1 -1
  124. package/dist/utils/csproj-deps.js +1 -1
  125. package/dist/utils/csproj-deps.js.map +1 -1
  126. package/dist/utils/editor-connection.d.ts +74 -0
  127. package/dist/utils/editor-connection.js +225 -0
  128. package/dist/utils/editor-connection.js.map +1 -0
  129. package/dist/utils/editor-mcp-server.d.ts +32 -0
  130. package/dist/utils/editor-mcp-server.js +134 -0
  131. package/dist/utils/editor-mcp-server.js.map +1 -0
  132. package/dist/utils/exit-codes.d.ts +2 -0
  133. package/dist/utils/exit-codes.js +4 -0
  134. package/dist/utils/exit-codes.js.map +1 -0
  135. package/dist/utils/godot-process.d.ts +5 -0
  136. package/dist/utils/godot-process.js +16 -0
  137. package/dist/utils/godot-process.js.map +1 -1
  138. package/dist/utils/godot-shutdown.d.ts +3 -1
  139. package/dist/utils/godot-shutdown.js +4 -2
  140. package/dist/utils/godot-shutdown.js.map +1 -1
  141. package/dist/utils/input.d.ts +3 -3
  142. package/dist/utils/input.js +22 -35
  143. package/dist/utils/input.js.map +1 -1
  144. package/dist/utils/output.d.ts +45 -0
  145. package/dist/utils/output.js +101 -0
  146. package/dist/utils/output.js.map +1 -0
  147. package/dist/utils/server-source.d.ts +1 -1
  148. package/dist/utils/server-source.js +1 -1
  149. package/dist/utils/skill-guides.d.ts +6 -9
  150. package/dist/utils/skill-guides.js +100 -43
  151. package/dist/utils/skill-guides.js.map +1 -1
  152. package/dist/utils/skills.d.ts +1 -14
  153. package/dist/utils/skills.js +0 -89
  154. package/dist/utils/skills.js.map +1 -1
  155. package/dist/utils/ui.d.ts +6 -1
  156. package/dist/utils/ui.js +72 -58
  157. package/dist/utils/ui.js.map +1 -1
  158. package/dist/utils/update-check.d.ts +6 -17
  159. package/dist/utils/update-check.js +10 -77
  160. package/dist/utils/update-check.js.map +1 -1
  161. package/package.json +2 -2
  162. package/dist/utils/json-parse.d.ts +0 -25
  163. package/dist/utils/json-parse.js +0 -83
  164. package/dist/utils/json-parse.js.map +0 -1
  165. package/dist/utils/semver.d.ts +0 -4
  166. package/dist/utils/semver.js +0 -25
  167. package/dist/utils/semver.js.map +0 -1
@@ -0,0 +1,134 @@
1
+ import { execFileSync } from 'child_process';
2
+ import * as path from 'path';
3
+ import { platform } from 'os';
4
+ import { isProcessAlive, killProcessTree, readProcessStart } from '@baizor/gamedev-cli-core';
5
+ import { waitForExit } from './godot-shutdown.js';
6
+ import { verbose } from './ui.js';
7
+ /**
8
+ * The local MCP server is launched by the addon (`GodotMcpServerManager.StartServer`) as a child process of the
9
+ * editor. The plugin stops it when the editor quits cleanly, but a hard-killed editor leaves it running. `close`
10
+ * finds it BEFORE the editor goes away — by process parentage, never by command line — and stops it afterwards.
11
+ * A stopgap for `close` only: a server that watched its parent PID itself would also cover editor crashes.
12
+ */
13
+ /** File name of the server binary (`GodotMcpServerView.ExecutableName`), without `.exe`. */
14
+ const MCP_SERVER_EXECUTABLE = 'gamedev-mcp-server';
15
+ /** True for the server binary's process name: `gamedev-mcp-server[.exe]`, a full path, or Linux's 15-char `comm`. */
16
+ export function isMcpServerName(name) {
17
+ const base = path.basename(name.trim().replace(/\\/g, '/')).toLowerCase().replace(/\.exe$/, '');
18
+ return base === MCP_SERVER_EXECUTABLE || (base.length === 15 && MCP_SERVER_EXECUTABLE.startsWith(base));
19
+ }
20
+ /**
21
+ * Every process below `rootPid`: children, grandchildren (the `_console` wrapper runs the editor as its child). A
22
+ * Windows parent PID can name a dead process whose PID was reused, so a child that started before its supposed parent
23
+ * is not its child.
24
+ */
25
+ function descendantsOf(table, rootPid) {
26
+ const byPid = new Map(table.map((e) => [e.pid, e]));
27
+ const children = new Map();
28
+ for (const e of table)
29
+ children.set(e.ppid, [...(children.get(e.ppid) ?? []), e]);
30
+ const found = [];
31
+ const seen = new Set([rootPid]);
32
+ const queue = [rootPid];
33
+ while (queue.length > 0) {
34
+ const parent = queue.shift();
35
+ const parentStarted = byPid.get(parent)?.startedMs;
36
+ for (const entry of children.get(parent) ?? []) {
37
+ if (seen.has(entry.pid))
38
+ continue;
39
+ if (parentStarted !== undefined && entry.startedMs !== undefined && entry.startedMs < parentStarted)
40
+ continue;
41
+ seen.add(entry.pid);
42
+ queue.push(entry.pid);
43
+ found.push(entry);
44
+ }
45
+ }
46
+ return found;
47
+ }
48
+ /** The PIDs of the processes below `rootPid` that run the server binary. */
49
+ export function findServerDescendants(table, rootPid) {
50
+ return descendantsOf(table, rootPid).filter((e) => isMcpServerName(e.name)).map((e) => e.pid);
51
+ }
52
+ /** Parse `pid ppid [startedTicks] name` lines (Windows rows carry UTC .NET ticks). */
53
+ export function parseProcessTable(output, withStart) {
54
+ const rows = [];
55
+ const pattern = withStart ? /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(.+?)\s*$/ : /^\s*(\d+)\s+(\d+)\s+(.+?)\s*$/;
56
+ for (const line of output.split(/\r?\n/)) {
57
+ const m = line.match(pattern);
58
+ if (!m)
59
+ continue;
60
+ const entry = { pid: Number(m[1]), ppid: Number(m[2]), name: withStart ? m[4] : m[3] };
61
+ // .NET ticks (100 ns since 0001-01-01) to epoch ms; only ever compared with each other.
62
+ if (withStart)
63
+ entry.startedMs = Number((BigInt(m[3]) - 621355968000000000n) / 10000n);
64
+ rows.push(entry);
65
+ }
66
+ return rows;
67
+ }
68
+ const EXEC_OPTIONS = { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: 16 * 1024 * 1024 };
69
+ /**
70
+ * The process table (PID, parent PID, name), or empty when it cannot be read. On Windows only Godot and server rows:
71
+ * the addon starts the server straight from the editor, which the `_console` wrapper runs, so no other process sits
72
+ * between them.
73
+ */
74
+ export function listProcessTable() {
75
+ try {
76
+ if (platform() === 'win32') {
77
+ const script = `Get-CimInstance Win32_Process -Filter "Name LIKE '%godot%' OR Name LIKE '${MCP_SERVER_EXECUTABLE}%'" | ` +
78
+ 'ForEach-Object { "$($_.ProcessId) $($_.ParentProcessId) ' +
79
+ '$(if ($_.CreationDate) { $_.CreationDate.ToUniversalTime().Ticks } else { 0 }) $($_.Name)" }';
80
+ const out = execFileSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script], { ...EXEC_OPTIONS, timeout: 20000 });
81
+ return parseProcessTable(out, true);
82
+ }
83
+ const out = execFileSync('ps', ['-A', '-o', 'pid=,ppid=,comm='], { ...EXEC_OPTIONS, timeout: 10000 });
84
+ return parseProcessTable(out, false);
85
+ }
86
+ catch (err) {
87
+ verbose(`Failed to list processes: ${err instanceof Error ? err.message : String(err)}`);
88
+ return [];
89
+ }
90
+ }
91
+ /** The MCP server processes the editor `editorPid` started (its own descendants only), with their start tokens. */
92
+ export async function findEditorServers(editorPid) {
93
+ const pids = findServerDescendants(listProcessTable(), editorPid);
94
+ const servers = await Promise.all(pids.map(async (pid) => ({ pid, start: await readProcessStart(pid) })));
95
+ for (const s of servers)
96
+ verbose(`Editor PID ${editorPid} runs MCP server PID ${s.pid}`);
97
+ return servers;
98
+ }
99
+ /**
100
+ * Once the editor `editorPid` is gone, kill each of its servers still running, with the processes it started. A server
101
+ * is skipped while its editor is alive, and when its PID now belongs to another process (start token changed). Returns
102
+ * the PIDs stopped.
103
+ */
104
+ export async function stopOrphanedServers(editorPid, servers) {
105
+ if (servers.length === 0 || isProcessAlive(editorPid))
106
+ return [];
107
+ const stopped = [];
108
+ for (const server of servers) {
109
+ if (!isProcessAlive(server.pid))
110
+ continue;
111
+ if (server.start === undefined || (await readProcessStart(server.pid)) !== server.start) {
112
+ verbose(`MCP server PID ${server.pid} cannot be proven to be the same process; left alone`);
113
+ continue;
114
+ }
115
+ // POSIX: the server leads no process group (.NET's Process.Start keeps the editor's), so killProcessTree reaches only
116
+ // the server itself; its children are taken from the table. Windows: `taskkill /T` covers them.
117
+ const children = platform() === 'win32' ? [] : descendantsOf(listProcessTable(), server.pid);
118
+ await killProcessTree(server.pid);
119
+ for (const child of children) {
120
+ try {
121
+ process.kill(child.pid, 'SIGKILL');
122
+ }
123
+ catch {
124
+ /* already gone */
125
+ }
126
+ }
127
+ if (await waitForExit(server.pid, 5000))
128
+ stopped.push(server.pid);
129
+ else
130
+ verbose(`MCP server PID ${server.pid} is still alive after the kill`);
131
+ }
132
+ return stopped;
133
+ }
134
+ //# sourceMappingURL=editor-mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-mcp-server.js","sourceRoot":"","sources":["../../src/utils/editor-mcp-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { ExitCode, EXIT_CODES as EXIT_CODE_TABLE } from '@baizor/gamedev-cli-core';
2
+ export type { ExitCodeValue } from '@baizor/gamedev-cli-core';
@@ -0,0 +1,4 @@
1
+ // Process exit codes shared by godot-cli, unity-mcp-cli and unreal-mcp-cli: the contract lives in
2
+ // @baizor/gamedev-cli-core.
3
+ export { ExitCode, EXIT_CODES as EXIT_CODE_TABLE } from '@baizor/gamedev-cli-core';
4
+ //# sourceMappingURL=exit-codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../../src/utils/exit-codes.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,4BAA4B;AAE5B,OAAO,EAAE,QAAQ,EAAE,UAAU,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
@@ -8,3 +8,8 @@ export interface GodotProcess {
8
8
  * Returns process info if found, null otherwise.
9
9
  */
10
10
  export declare function findGodotProcess(projectPath: string): GodotProcess | null;
11
+ /**
12
+ * Windows: the PIDs of a process's direct Godot children (the `_console` wrapper's editor; not its conhost).
13
+ * Empty elsewhere or on error.
14
+ */
15
+ export declare function childProcessIds(pid: number): number[];
@@ -36,6 +36,22 @@ export function findGodotProcess(projectPath) {
36
36
  verbose(`No Godot process found for project: ${projectPath}`);
37
37
  return null;
38
38
  }
39
+ /**
40
+ * Windows: the PIDs of a process's direct Godot children (the `_console` wrapper's editor; not its conhost).
41
+ * Empty elsewhere or on error.
42
+ */
43
+ export function childProcessIds(pid) {
44
+ if (platform() !== 'win32')
45
+ return [];
46
+ try {
47
+ const filter = `ParentProcessId=${pid} AND Name LIKE '%godot%'`;
48
+ const out = execFileSync('powershell.exe', ['-NoProfile', '-Command', `(Get-CimInstance Win32_Process -Filter "${filter}").ProcessId`], { encoding: 'utf-8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] });
49
+ return out.split(/\s+/).map((s) => parseInt(s, 10)).filter((n) => Number.isFinite(n) && n > 0);
50
+ }
51
+ catch {
52
+ return [];
53
+ }
54
+ }
39
55
  /**
40
56
  * List all running Godot editor processes with their project paths. Matches
41
57
  * any process whose name contains "godot" (covers `Godot.exe`, `Godot_mono.exe`,
@@ -1 +1 @@
1
- {"version":3,"file":"godot-process.js","sourceRoot":"","sources":["../../src/utils/godot-process.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"godot-process.js","sourceRoot":"","sources":["../../src/utils/godot-process.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,9 @@ export declare function isProcessAlive(pid: number, os?: SupportedPlatform): boo
8
8
  */
9
9
  export declare function sendGracefulShutdown(pid: number, os?: SupportedPlatform): boolean;
10
10
  /** Hard-kill the process. SIGKILL on POSIX; `taskkill /F` on Windows. */
11
- export declare function sendForceKill(pid: number, os?: SupportedPlatform): boolean;
11
+ export declare function sendForceKill(pid: number, os?: SupportedPlatform,
12
+ /** Windows: also its child processes (`/T`) — for the `_console` wrapper, whose child is the editor itself. */
13
+ tree?: boolean): boolean;
12
14
  /**
13
15
  * Poll for the process to exit, up to `timeoutMs`. Resolves true when the
14
16
  * process is gone, false on timeout.
@@ -37,10 +37,12 @@ export function sendGracefulShutdown(pid, os = platform()) {
37
37
  }
38
38
  }
39
39
  /** Hard-kill the process. SIGKILL on POSIX; `taskkill /F` on Windows. */
40
- export function sendForceKill(pid, os = platform()) {
40
+ export function sendForceKill(pid, os = platform(),
41
+ /** Windows: also its child processes (`/T`) — for the `_console` wrapper, whose child is the editor itself. */
42
+ tree = false) {
41
43
  try {
42
44
  if (os === 'win32') {
43
- execFileSync('taskkill', ['/PID', String(pid), '/F'], { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
45
+ execFileSync('taskkill', tree ? ['/PID', String(pid), '/T', '/F'] : ['/PID', String(pid), '/F'], { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
44
46
  return true;
45
47
  }
46
48
  process.kill(pid, 'SIGKILL');
@@ -1 +1 @@
1
- {"version":3,"file":"godot-shutdown.js","sourceRoot":"","sources":["../../src/utils/godot-shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAI9B,mEAAmE;AACnE,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,KAAwB,QAAQ,EAAuB;IACjG,IAAI,CAAC;QACH,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,EAAE,EAAE,KAAK,CAAC,EAAE;gBACpE,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YACH,OAAO,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACnC,CAAC;QACD,gEAAgE;QAChE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAW,EACX,KAAwB,QAAQ,EAAuB;IAEvD,IAAI,CAAC;QACH,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YACnB,YAAY,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACrG,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,aAAa,CAC3B,GAAW,EACX,KAAwB,QAAQ,EAAuB;IAEvD,IAAI,CAAC;QACH,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YACnB,YAAY,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3G,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,GAAW,EACX,SAAiB,EACjB,KAAwB,QAAQ,EAAuB;IAEvD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,QAAQ,GAAG,GAAG,CAAC;IACrB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,EAAE,CAAC;QACtC,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,CAAC,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"godot-shutdown.js","sourceRoot":"","sources":["../../src/utils/godot-shutdown.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ export interface InputOptions {
3
3
  inputFile?: string;
4
4
  }
5
5
  /**
6
- * Parse tool input from --input, --input-file, or stdin.
6
+ * Parse tool input from --input, --input-file, or stdin. Bad input is a usage error (exit 2).
7
7
  *
8
8
  * - `--input-file -` or `--input-file /dev/stdin` reads from stdin (cross-platform).
9
9
  * - `--input-file <path>` reads from a file.
@@ -11,5 +11,5 @@ export interface InputOptions {
11
11
  * - Falls back to `{}` if nothing provided.
12
12
  */
13
13
  export declare function parseInput(options: InputOptions): string;
14
- /** A whole-number flag value (commander supplies the default as text), or exit with an error. */
15
- export declare function parsePositiveIntFlag(raw: string, flagName: string, allowZero?: boolean): number;
14
+ /** Commander accumulator for a repeatable option. */
15
+ export declare function collect(value: string, previous: string[]): string[];
@@ -1,10 +1,14 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
- import * as ui from './ui.js';
4
3
  import { verbose } from './ui.js';
5
- import { parseJsonStrict, JsonParseError } from './json-parse.js';
4
+ import { parseJsonStrict, JsonParseError } from '@baizor/gamedev-cli-core';
5
+ import { ExitCode } from './exit-codes.js';
6
+ import { exitWithError } from './output.js';
7
+ function usage(message) {
8
+ return exitWithError(ExitCode.Usage, 'USAGE', message);
9
+ }
6
10
  /**
7
- * Parse tool input from --input, --input-file, or stdin.
11
+ * Parse tool input from --input, --input-file, or stdin. Bad input is a usage error (exit 2).
8
12
  *
9
13
  * - `--input-file -` or `--input-file /dev/stdin` reads from stdin (cross-platform).
10
14
  * - `--input-file <path>` reads from a file.
@@ -21,34 +25,28 @@ export function parseInput(options) {
21
25
  content = fs.readFileSync(0, 'utf-8');
22
26
  }
23
27
  catch {
24
- ui.error('Failed to read from stdin.');
25
- process.exit(1);
26
- }
27
- if (!content.trim()) {
28
- ui.error('No input received from stdin.');
29
- process.exit(1);
28
+ usage('Failed to read from stdin.');
30
29
  }
30
+ if (!content.trim())
31
+ usage('No input received from stdin.');
31
32
  }
32
33
  else {
33
34
  const filePath = path.resolve(options.inputFile);
34
- if (!fs.existsSync(filePath)) {
35
- ui.error(`Input file does not exist: ${filePath}`);
36
- process.exit(1);
35
+ if (!fs.existsSync(filePath))
36
+ usage(`Input file does not exist: ${filePath}`);
37
+ try {
38
+ content = fs.readFileSync(filePath, 'utf-8');
39
+ }
40
+ catch (err) {
41
+ usage(`Cannot read --input-file ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
37
42
  }
38
- content = fs.readFileSync(filePath, 'utf-8');
39
43
  }
40
44
  try {
41
45
  parseJsonStrict(content);
42
46
  }
43
47
  catch (err) {
44
48
  const source = isStdin ? 'stdin' : options.inputFile;
45
- if (err instanceof JsonParseError) {
46
- ui.error(`--input-file content from '${source}' must be valid JSON\n${err.message}`);
47
- }
48
- else {
49
- ui.error(`--input-file content from '${source}' must be valid JSON`);
50
- }
51
- process.exit(1);
49
+ usage(`--input-file content from '${source}' must be valid JSON` + (err instanceof JsonParseError ? `\n${err.message}` : ''));
52
50
  }
53
51
  return content;
54
52
  }
@@ -58,24 +56,13 @@ export function parseInput(options) {
58
56
  return result.raw;
59
57
  }
60
58
  catch (err) {
61
- if (err instanceof JsonParseError) {
62
- ui.error(`--input must be valid JSON\n${err.message}`);
63
- }
64
- else {
65
- ui.error('--input must be valid JSON');
66
- }
67
- process.exit(1);
59
+ usage('--input must be valid JSON' + (err instanceof JsonParseError ? `\n${err.message}` : ''));
68
60
  }
69
61
  }
70
62
  return '{}';
71
63
  }
72
- /** A whole-number flag value (commander supplies the default as text), or exit with an error. */
73
- export function parsePositiveIntFlag(raw, flagName, allowZero = false) {
74
- const value = Number(raw);
75
- if (!Number.isInteger(value) || value < 0 || (value === 0 && !allowZero)) {
76
- ui.error(`${flagName} must be a ${allowZero ? 'non-negative' : 'positive'} whole number, got "${raw}"`);
77
- process.exit(1);
78
- }
79
- return value;
64
+ /** Commander accumulator for a repeatable option. */
65
+ export function collect(value, previous) {
66
+ return [...previous, value];
80
67
  }
81
68
  //# sourceMappingURL=input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/utils/input.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/utils/input.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { Command } from 'commander';
2
+ import { CommandOutput as ContractOutput, type EnvelopeError as ContractEnvelopeError, type OutputFormat } from '@baizor/gamedev-cli-core';
3
+ import { type ExitCodeValue } from './exit-codes.js';
4
+ export { CommandExit, OUTPUT_FORMATS, formatFromArgv } from '@baizor/gamedev-cli-core';
5
+ export type { OutputFormat } from '@baizor/gamedev-cli-core';
6
+ /** Upper-snake error codes of the envelope. */
7
+ export type ErrorCode = 'USAGE' | 'TOOL_FAILED' | 'UNREACHABLE' | 'TIMEOUT' | 'BUSY' | 'AWAITING_INPUT' | 'TESTS_FAILED' | 'TEST_RUN_ERROR' | 'COMPILATION_FAILED' | 'SCRIPT_ERRORS' | 'IMPORT_FAILED' | 'PROJECT_OPEN' | 'NOT_FOUND' | 'EXPORT_FAILED' | 'NOT_AUTHENTICATED' | 'ERROR';
8
+ /** One envelope error (`{code, message, httpStatus?}`): the shared contract's, with this CLI's codes. */
9
+ export type EnvelopeError = ContractEnvelopeError<ErrorCode>;
10
+ /** Add `--format` to a command. `extra` lists command-specific formats (e.g. `github`). */
11
+ export declare function addFormatOption(cmd: Command, extra?: readonly string[]): Command;
12
+ /**
13
+ * The output of one command run. Created at the start of an action; in json/ndjson it switches `ui` to stderr so
14
+ * stdout carries only the envelope. Exactly one `finish` per run.
15
+ */
16
+ export declare class CommandOutput<F extends string = OutputFormat> extends ContractOutput<ErrorCode> {
17
+ readonly format: F;
18
+ constructor(command: string, format: F);
19
+ /** A progress line: ndjson event on stderr, plain stderr line in json, `ui.info` in text. */
20
+ progress(message: string): void;
21
+ /**
22
+ * Emit the envelope (machine formats) and end the command. Text output is the caller's job before calling this.
23
+ * The process exits once stdout is flushed; until then a `CommandExit` unwinds the action.
24
+ */
25
+ finish(exitCode: ExitCodeValue, data?: unknown, errors?: EnvelopeError[]): never;
26
+ /** Fail with one error: printed with `ui.error` in text, in the envelope otherwise. */
27
+ fail(exitCode: ExitCodeValue, code: ErrorCode, message: string, data?: unknown): never;
28
+ }
29
+ /**
30
+ * An unexpected error escaped a command: report it through the active command's envelope (exit 1) when one runs
31
+ * in a machine format. Returns false when there is none (the caller prints it).
32
+ */
33
+ export declare function failActive(err: unknown): boolean;
34
+ /**
35
+ * Exit from a shared helper (path / input validation): through the active command's envelope when one runs in a
36
+ * machine format, else `ui.error`.
37
+ */
38
+ export declare function exitWithError(exitCode: ExitCodeValue, code: ErrorCode, message: string): never;
39
+ /**
40
+ * Parse a `--format` value. An unknown value is a usage error (exit 2), reported in text since the format itself
41
+ * is what is wrong.
42
+ */
43
+ export declare function parseFormat<F extends string = never>(raw: string | undefined, extra?: readonly F[]): OutputFormat | F;
44
+ /** Parse a positive (or, with `allowZero`, non-negative) whole-number flag, or exit 2. */
45
+ export declare function parseIntFlag(raw: string | undefined, flagName: string, allowZero?: boolean): number;
@@ -0,0 +1,101 @@
1
+ // `--format text|json|ndjson` output contract shared by godot-cli, unity-mcp-cli and unreal-mcp-cli (it lives in
2
+ // @baizor/gamedev-cli-core).
3
+ //
4
+ // json: stdout carries exactly one pretty-printed envelope; every human-readable line goes to stderr.
5
+ // ndjson: progress lines `{"type":"progress",...}` on stderr, the envelope as one line on stdout.
6
+ // text: the usual human output.
7
+ import { CommandOutput as ContractOutput, OUTPUT_FORMATS, UsageError, activeCommandOutput, exitAfterFlush, parseFormat as parseContractFormat, } from '@baizor/gamedev-cli-core';
8
+ import * as ui from './ui.js';
9
+ import { ExitCode } from './exit-codes.js';
10
+ export { CommandExit, OUTPUT_FORMATS, formatFromArgv } from '@baizor/gamedev-cli-core';
11
+ /** Add `--format` to a command. `extra` lists command-specific formats (e.g. `github`). */
12
+ export function addFormatOption(cmd, extra = []) {
13
+ const formats = [...OUTPUT_FORMATS, ...extra].join('|');
14
+ return cmd.option('--format <format>', `Output format: ${formats}`, 'text');
15
+ }
16
+ /**
17
+ * The output of one command run. Created at the start of an action; in json/ndjson it switches `ui` to stderr so
18
+ * stdout carries only the envelope. Exactly one `finish` per run.
19
+ */
20
+ export class CommandOutput extends ContractOutput {
21
+ constructor(command, format) {
22
+ super(command, format);
23
+ // ndjson: every human line on stderr is an event too, so stderr stays parseable line by line.
24
+ ui.setMachineOutput(this.machine, format === 'ndjson'
25
+ ? (level, message) => JSON.stringify({ type: 'log', command, level, message })
26
+ : undefined);
27
+ }
28
+ /** A progress line: ndjson event on stderr, plain stderr line in json, `ui.info` in text. */
29
+ progress(message) {
30
+ if (this.format === 'ndjson')
31
+ super.progress(message);
32
+ else if (this.format === 'json')
33
+ process.stderr.write(message + '\n');
34
+ else
35
+ ui.info(message);
36
+ }
37
+ /**
38
+ * Emit the envelope (machine formats) and end the command. Text output is the caller's job before calling this.
39
+ * The process exits once stdout is flushed; until then a `CommandExit` unwinds the action.
40
+ */
41
+ finish(exitCode, data = null, errors = []) {
42
+ for (const err of errors)
43
+ this.record(err.code, err.message, err.httpStatus);
44
+ this.emit(exitCode, data);
45
+ exitAfterFlush(exitCode);
46
+ }
47
+ /** Fail with one error: printed with `ui.error` in text, in the envelope otherwise. */
48
+ fail(exitCode, code, message, data = null) {
49
+ if (!this.machine)
50
+ ui.error(message);
51
+ return this.finish(exitCode, data, [{ code, message }]);
52
+ }
53
+ }
54
+ /** The godot-cli output of the command being run, if one was created. */
55
+ function active() {
56
+ const output = activeCommandOutput();
57
+ return output instanceof CommandOutput ? output : undefined;
58
+ }
59
+ /**
60
+ * An unexpected error escaped a command: report it through the active command's envelope (exit 1) when one runs
61
+ * in a machine format. Returns false when there is none (the caller prints it).
62
+ */
63
+ export function failActive(err) {
64
+ const output = active();
65
+ if (!output?.machine)
66
+ return false;
67
+ return output.fail(ExitCode.Error, 'ERROR', err instanceof Error ? err.message : String(err));
68
+ }
69
+ /**
70
+ * Exit from a shared helper (path / input validation): through the active command's envelope when one runs in a
71
+ * machine format, else `ui.error`.
72
+ */
73
+ export function exitWithError(exitCode, code, message) {
74
+ active()?.fail(exitCode, code, message);
75
+ ui.error(message);
76
+ process.exit(exitCode);
77
+ }
78
+ /**
79
+ * Parse a `--format` value. An unknown value is a usage error (exit 2), reported in text since the format itself
80
+ * is what is wrong.
81
+ */
82
+ export function parseFormat(raw, extra = []) {
83
+ try {
84
+ return parseContractFormat(raw, extra);
85
+ }
86
+ catch (err) {
87
+ if (!(err instanceof UsageError))
88
+ throw err;
89
+ ui.error(err.message);
90
+ process.exit(ExitCode.Usage);
91
+ }
92
+ }
93
+ /** Parse a positive (or, with `allowZero`, non-negative) whole-number flag, or exit 2. */
94
+ export function parseIntFlag(raw, flagName, allowZero = false) {
95
+ const value = Number(raw);
96
+ if (raw === undefined || raw.trim() === '' || !Number.isInteger(value) || value < 0 || (value === 0 && !allowZero)) {
97
+ exitWithError(ExitCode.Usage, 'USAGE', `Invalid ${flagName} value: "${raw}". Must be a ${allowZero ? 'non-negative' : 'positive'} whole number.`);
98
+ }
99
+ return value;
100
+ }
101
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  * download entirely (offline / CI). Bumping the addon's server pin requires
6
6
  * bumping this in the same PR or the parity test goes red.
7
7
  */
8
- export declare const DEFAULT_SERVER_VERSION = "9.4.4";
8
+ export declare const DEFAULT_SERVER_VERSION = "9.5.0";
9
9
  /** GitHub-release host the server zip + manifest are downloaded from. NOTHING else is trusted. */
10
10
  export declare const TRUSTED_DOWNLOAD_HOST = "github.com";
11
11
  /** The `owner/repo` the shared server releases live under. */
@@ -18,7 +18,7 @@ import { createHash } from 'crypto';
18
18
  * download entirely (offline / CI). Bumping the addon's server pin requires
19
19
  * bumping this in the same PR or the parity test goes red.
20
20
  */
21
- export const DEFAULT_SERVER_VERSION = '9.4.4';
21
+ export const DEFAULT_SERVER_VERSION = '9.5.0';
22
22
  /** GitHub-release host the server zip + manifest are downloaded from. NOTHING else is trusted. */
23
23
  export const TRUSTED_DOWNLOAD_HOST = 'github.com';
24
24
  /** The `owner/repo` the shared server releases live under. */
@@ -1,16 +1,13 @@
1
- export declare const CLI_SKILL_NAME = "godot-cli";
2
- export declare const APP_SKILL_NAME = "ai-game-dev-app";
3
- export declare const APP_SKILL_DESCRIPTION = "AI Game Dev App: image, texture, 3D model, audio and video generation; animation, rigging, Blender, music and sound effects. Consult when a game-development task needs creative tools unavailable in the current environment, or an integrated workflow for Unity, Unreal Engine or Godot.";
4
- export declare const CLI_SKILL_DESCRIPTION = "Install and use godot-cli: Node.js requirements, npm installation, npx, tool calls, JSON input files and troubleshooting.";
1
+ /** Skill folders earlier versions generated from a hand-written catalog (`godot-mcp`, `godot-mcp-<family>`). */
2
+ export declare function isRetiredSkillName(name: string): boolean;
5
3
  export declare const SKILL_METADATA: {
6
4
  readonly 'generated-by': "godot-mcp";
7
5
  readonly 'ai-game-dev': "exclude";
8
6
  };
9
- export declare function skillMetadataLines(): string[];
10
- export declare const SKILL_REFERENCES = "> CLI installation and usage: see the `godot-cli` skill.\n> If this task needs unavailable asset-generation or Blender tools, consult `ai-game-dev-app` for an optional integrated workflow.\n";
11
- export declare function buildCliGuide(platform?: NodeJS.Platform): string;
12
- export declare const CLI_GUIDE: string;
13
- export declare const APP_GUIDE: string;
7
+ /** What each failing exit code asks of the agent (0 and 1 need nothing). A test keeps the codes in the core contract. */
8
+ export declare const EXIT_CODE_ACTIONS: Readonly<Record<number, string>>;
9
+ export declare function buildInstallGuide(platform?: NodeJS.Platform): string;
10
+ /** Every file `setup-skills` writes, relative to the agent's skills folder. Pure and deterministic. */
14
11
  export declare function buildGuideFiles(platform?: NodeJS.Platform): {
15
12
  relativePath: string;
16
13
  content: string;