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.
- package/CHANGELOG.md +25 -0
- package/README.md +101 -0
- package/bin/godot-cli.js +2 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +17 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/close.d.ts +18 -0
- package/dist/commands/close.js +112 -0
- package/dist/commands/close.js.map +1 -0
- package/dist/commands/configure.d.ts +2 -0
- package/dist/commands/configure.js +92 -0
- package/dist/commands/configure.js.map +1 -0
- package/dist/commands/install-plugin.d.ts +2 -0
- package/dist/commands/install-plugin.js +35 -0
- package/dist/commands/install-plugin.js.map +1 -0
- package/dist/commands/open.d.ts +16 -0
- package/dist/commands/open.js +124 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/remove-plugin.d.ts +2 -0
- package/dist/commands/remove-plugin.js +31 -0
- package/dist/commands/remove-plugin.js.map +1 -0
- package/dist/commands/run-system-tool.d.ts +1 -0
- package/dist/commands/run-system-tool.js +13 -0
- package/dist/commands/run-system-tool.js.map +1 -0
- package/dist/commands/run-tool-builder.d.ts +25 -0
- package/dist/commands/run-tool-builder.js +119 -0
- package/dist/commands/run-tool-builder.js.map +1 -0
- package/dist/commands/run-tool.d.ts +1 -0
- package/dist/commands/run-tool.js +13 -0
- package/dist/commands/run-tool.js.map +1 -0
- package/dist/commands/setup-mcp.d.ts +2 -0
- package/dist/commands/setup-mcp.js +58 -0
- package/dist/commands/setup-mcp.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +64 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.js +75 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/wait-for-ready.d.ts +2 -0
- package/dist/commands/wait-for-ready.js +57 -0
- package/dist/commands/wait-for-ready.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/install-plugin.d.ts +22 -0
- package/dist/lib/install-plugin.js +118 -0
- package/dist/lib/install-plugin.js.map +1 -0
- package/dist/lib/open.d.ts +34 -0
- package/dist/lib/open.js +198 -0
- package/dist/lib/open.js.map +1 -0
- package/dist/lib/progress.d.ts +7 -0
- package/dist/lib/progress.js +16 -0
- package/dist/lib/progress.js.map +1 -0
- package/dist/lib/run-tool.d.ts +12 -0
- package/dist/lib/run-tool.js +192 -0
- package/dist/lib/run-tool.js.map +1 -0
- package/dist/lib/setup-mcp.d.ts +16 -0
- package/dist/lib/setup-mcp.js +118 -0
- package/dist/lib/setup-mcp.js.map +1 -0
- package/dist/lib/types.d.ts +210 -0
- package/dist/lib/types.js +8 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/validation.d.ts +30 -0
- package/dist/lib/validation.js +44 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/lib.d.ts +5 -0
- package/dist/lib.js +19 -0
- package/dist/lib.js.map +1 -0
- package/dist/utils/agents.d.ts +31 -0
- package/dist/utils/agents.js +188 -0
- package/dist/utils/agents.js.map +1 -0
- package/dist/utils/config.d.ts +40 -0
- package/dist/utils/config.js +97 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/connection.d.ts +57 -0
- package/dist/utils/connection.js +129 -0
- package/dist/utils/connection.js.map +1 -0
- package/dist/utils/godot-editor.d.ts +42 -0
- package/dist/utils/godot-editor.js +184 -0
- package/dist/utils/godot-editor.js.map +1 -0
- package/dist/utils/godot-process.d.ts +10 -0
- package/dist/utils/godot-process.js +93 -0
- package/dist/utils/godot-process.js.map +1 -0
- package/dist/utils/godot-shutdown.d.ts +16 -0
- package/dist/utils/godot-shutdown.js +67 -0
- package/dist/utils/godot-shutdown.js.map +1 -0
- package/dist/utils/input.d.ts +13 -0
- package/dist/utils/input.js +72 -0
- package/dist/utils/input.js.map +1 -0
- package/dist/utils/json-parse.d.ts +25 -0
- package/dist/utils/json-parse.js +83 -0
- package/dist/utils/json-parse.js.map +1 -0
- package/dist/utils/probe.d.ts +18 -0
- package/dist/utils/probe.js +61 -0
- package/dist/utils/probe.js.map +1 -0
- package/dist/utils/project-godot.d.ts +41 -0
- package/dist/utils/project-godot.js +126 -0
- package/dist/utils/project-godot.js.map +1 -0
- package/dist/utils/semver.d.ts +4 -0
- package/dist/utils/semver.js +25 -0
- package/dist/utils/semver.js.map +1 -0
- package/dist/utils/ui.d.ts +61 -0
- package/dist/utils/ui.js +238 -0
- package/dist/utils/ui.js.map +1 -0
- package/dist/utils/update-check.d.ts +19 -0
- package/dist/utils/update-check.js +92 -0
- package/dist/utils/update-check.js.map +1 -0
- package/docs/README.md +7 -0
- package/package.json +73 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { verbose } from './ui.js';
|
|
2
|
+
export const PING_ENDPOINT = '/api/tools/ping';
|
|
3
|
+
/**
|
|
4
|
+
* Probe a Godot-MCP server's ping endpoint (`<base>/api/tools/ping`).
|
|
5
|
+
* Returns a structured result. The `ping` tool is registered by the
|
|
6
|
+
* `Tool_Ping` family (pure-managed, no editor required), so a connected
|
|
7
|
+
* plugin responds `{ "structured": { "result": "pong" } }`.
|
|
8
|
+
*/
|
|
9
|
+
export async function probe(baseUrl, headers, timeoutMs) {
|
|
10
|
+
const endpoint = `${baseUrl}${PING_ENDPOINT}`;
|
|
11
|
+
const controller = new AbortController();
|
|
12
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
13
|
+
try {
|
|
14
|
+
const response = await fetch(endpoint, {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
headers,
|
|
17
|
+
body: '{}',
|
|
18
|
+
signal: controller.signal,
|
|
19
|
+
});
|
|
20
|
+
const text = await response.text();
|
|
21
|
+
if (response.ok) {
|
|
22
|
+
let data;
|
|
23
|
+
try {
|
|
24
|
+
data = JSON.parse(text);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
data = text;
|
|
28
|
+
}
|
|
29
|
+
return { ok: true, baseUrl, data };
|
|
30
|
+
}
|
|
31
|
+
verbose(`[${baseUrl}] HTTP ${response.status} — not ready yet`);
|
|
32
|
+
return { ok: false, reason: `HTTP ${response.status}` };
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
const cause = err instanceof Error && 'cause' in err ? err.cause : null;
|
|
36
|
+
const code = cause?.code ?? '';
|
|
37
|
+
const isAbort = err instanceof Error && err.name === 'AbortError';
|
|
38
|
+
let reason;
|
|
39
|
+
if (isAbort) {
|
|
40
|
+
reason = 'timed out';
|
|
41
|
+
verbose(`[${baseUrl}] probe timed out`);
|
|
42
|
+
}
|
|
43
|
+
else if (code === 'ECONNREFUSED') {
|
|
44
|
+
reason = 'connection refused';
|
|
45
|
+
verbose(`[${baseUrl}] connection refused`);
|
|
46
|
+
}
|
|
47
|
+
else if (code === 'ECONNRESET') {
|
|
48
|
+
reason = 'connection reset';
|
|
49
|
+
verbose(`[${baseUrl}] connection reset`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
reason = err instanceof Error ? err.message : String(err);
|
|
53
|
+
verbose(`[${baseUrl}] probe failed: ${reason}`);
|
|
54
|
+
}
|
|
55
|
+
return { ok: false, reason };
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
clearTimeout(timer);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/utils/probe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,CAAC,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAe/C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,OAAe,EACf,OAA+B,EAC/B,SAAiB;IAEjB,MAAM,QAAQ,GAAG,GAAG,OAAO,GAAG,aAAa,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;IAE9D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,IAAI,IAAa,CAAC;YAClB,IAAI,CAAC;gBAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,IAAI,GAAG,IAAI,CAAC;YAAC,CAAC;YACvD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACrC,CAAC;QAED,OAAO,CAAC,IAAI,OAAO,UAAU,QAAQ,CAAC,MAAM,kBAAkB,CAAC,CAAC;QAChE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;IAC1D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,IAAI,OAAO,IAAI,GAAG,CAAC,CAAC,CAAE,GAAG,CAAC,KAAmC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvG,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC;QAElE,IAAI,MAAc,CAAC;QACnB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,GAAG,WAAW,CAAC;YACrB,OAAO,CAAC,IAAI,OAAO,mBAAmB,CAAC,CAAC;QAC1C,CAAC;aAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YACnC,MAAM,GAAG,oBAAoB,CAAC;YAC9B,OAAO,CAAC,IAAI,OAAO,sBAAsB,CAAC,CAAC;QAC7C,CAAC;aAAM,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YACjC,MAAM,GAAG,kBAAkB,CAAC;YAC5B,OAAO,CAAC,IAAI,OAAO,oBAAoB,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1D,OAAO,CAAC,IAAI,OAAO,mBAAmB,MAAM,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plugin.cfg resource path Godot uses to identify the godot_mcp addon in
|
|
3
|
+
* the `[editor_plugins]` `enabled` array.
|
|
4
|
+
*/
|
|
5
|
+
export declare const GODOT_MCP_PLUGIN_PATH = "res://addons/godot_mcp/plugin.cfg";
|
|
6
|
+
/** Absolute path to a project's `project.godot` manifest. */
|
|
7
|
+
export declare function projectGodotPath(projectRoot: string): string;
|
|
8
|
+
/** True when `<projectRoot>/project.godot` exists. */
|
|
9
|
+
export declare function isGodotProjectRoot(projectRoot: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Parse the `enabled=PackedStringArray("a", "b")` entry inside the
|
|
12
|
+
* `[editor_plugins]` section of a `project.godot` file body, returning the
|
|
13
|
+
* ordered list of enabled plugin.cfg paths. Returns an empty array when the
|
|
14
|
+
* section or the `enabled` key is absent.
|
|
15
|
+
*
|
|
16
|
+
* Pure — operates on the file text only. Exported for unit tests.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseEnabledPlugins(projectGodotText: string): string[];
|
|
19
|
+
export type PluginToggleResult = {
|
|
20
|
+
kind: 'changed';
|
|
21
|
+
enabled: string[];
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'unchanged';
|
|
24
|
+
enabled: string[];
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Return a new `project.godot` body with the godot_mcp plugin path added to
|
|
28
|
+
* (enable) or removed from (disable) the `[editor_plugins]` `enabled` array.
|
|
29
|
+
*
|
|
30
|
+
* - Creates the `[editor_plugins]` section / `enabled` line when enabling and
|
|
31
|
+
* they are absent.
|
|
32
|
+
* - Idempotent: enabling an already-enabled plugin (or disabling an
|
|
33
|
+
* already-disabled one) returns `{ kind: 'unchanged' }` with the original
|
|
34
|
+
* text untouched.
|
|
35
|
+
*
|
|
36
|
+
* Pure — returns the new text; never touches the filesystem. Exported for
|
|
37
|
+
* unit tests.
|
|
38
|
+
*/
|
|
39
|
+
export declare function togglePluginInText(projectGodotText: string, enable: boolean, pluginPath?: string): {
|
|
40
|
+
text: string;
|
|
41
|
+
} & PluginToggleResult;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* The plugin.cfg resource path Godot uses to identify the godot_mcp addon in
|
|
5
|
+
* the `[editor_plugins]` `enabled` array.
|
|
6
|
+
*/
|
|
7
|
+
export const GODOT_MCP_PLUGIN_PATH = 'res://addons/godot_mcp/plugin.cfg';
|
|
8
|
+
/** Absolute path to a project's `project.godot` manifest. */
|
|
9
|
+
export function projectGodotPath(projectRoot) {
|
|
10
|
+
return path.join(projectRoot, 'project.godot');
|
|
11
|
+
}
|
|
12
|
+
/** True when `<projectRoot>/project.godot` exists. */
|
|
13
|
+
export function isGodotProjectRoot(projectRoot) {
|
|
14
|
+
return fs.existsSync(projectGodotPath(projectRoot));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parse the `enabled=PackedStringArray("a", "b")` entry inside the
|
|
18
|
+
* `[editor_plugins]` section of a `project.godot` file body, returning the
|
|
19
|
+
* ordered list of enabled plugin.cfg paths. Returns an empty array when the
|
|
20
|
+
* section or the `enabled` key is absent.
|
|
21
|
+
*
|
|
22
|
+
* Pure — operates on the file text only. Exported for unit tests.
|
|
23
|
+
*/
|
|
24
|
+
export function parseEnabledPlugins(projectGodotText) {
|
|
25
|
+
const section = extractEditorPluginsSection(projectGodotText);
|
|
26
|
+
if (section === null)
|
|
27
|
+
return [];
|
|
28
|
+
const match = section.match(/enabled\s*=\s*PackedStringArray\(([^)]*)\)/);
|
|
29
|
+
if (!match)
|
|
30
|
+
return [];
|
|
31
|
+
const inner = match[1];
|
|
32
|
+
const paths = [];
|
|
33
|
+
// Match each double-quoted string literal in the array.
|
|
34
|
+
const re = /"([^"]*)"/g;
|
|
35
|
+
let m;
|
|
36
|
+
while ((m = re.exec(inner)) !== null) {
|
|
37
|
+
paths.push(m[1]);
|
|
38
|
+
}
|
|
39
|
+
return paths;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Extract the raw text of the `[editor_plugins]` section (everything between
|
|
43
|
+
* its header and the next `[section]` header or EOF). Returns null when the
|
|
44
|
+
* section is absent.
|
|
45
|
+
*/
|
|
46
|
+
function extractEditorPluginsSection(text) {
|
|
47
|
+
const lines = text.split('\n');
|
|
48
|
+
const headerIdx = lines.findIndex((l) => l.trim() === '[editor_plugins]');
|
|
49
|
+
if (headerIdx === -1)
|
|
50
|
+
return null;
|
|
51
|
+
let endIdx = headerIdx + 1;
|
|
52
|
+
while (endIdx < lines.length && !lines[endIdx].trim().startsWith('[')) {
|
|
53
|
+
endIdx++;
|
|
54
|
+
}
|
|
55
|
+
return lines.slice(headerIdx + 1, endIdx).join('\n');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Render a PackedStringArray literal from a list of plugin paths.
|
|
59
|
+
*/
|
|
60
|
+
function renderEnabledLine(paths) {
|
|
61
|
+
const quoted = paths.map((p) => `"${p}"`).join(', ');
|
|
62
|
+
return `enabled=PackedStringArray(${quoted})`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Return a new `project.godot` body with the godot_mcp plugin path added to
|
|
66
|
+
* (enable) or removed from (disable) the `[editor_plugins]` `enabled` array.
|
|
67
|
+
*
|
|
68
|
+
* - Creates the `[editor_plugins]` section / `enabled` line when enabling and
|
|
69
|
+
* they are absent.
|
|
70
|
+
* - Idempotent: enabling an already-enabled plugin (or disabling an
|
|
71
|
+
* already-disabled one) returns `{ kind: 'unchanged' }` with the original
|
|
72
|
+
* text untouched.
|
|
73
|
+
*
|
|
74
|
+
* Pure — returns the new text; never touches the filesystem. Exported for
|
|
75
|
+
* unit tests.
|
|
76
|
+
*/
|
|
77
|
+
export function togglePluginInText(projectGodotText, enable, pluginPath = GODOT_MCP_PLUGIN_PATH) {
|
|
78
|
+
const current = parseEnabledPlugins(projectGodotText);
|
|
79
|
+
const has = current.includes(pluginPath);
|
|
80
|
+
if (enable && has) {
|
|
81
|
+
return { text: projectGodotText, kind: 'unchanged', enabled: current };
|
|
82
|
+
}
|
|
83
|
+
if (!enable && !has) {
|
|
84
|
+
return { text: projectGodotText, kind: 'unchanged', enabled: current };
|
|
85
|
+
}
|
|
86
|
+
const next = enable
|
|
87
|
+
? [...current, pluginPath]
|
|
88
|
+
: current.filter((p) => p !== pluginPath);
|
|
89
|
+
const newText = writeEnabledArray(projectGodotText, next);
|
|
90
|
+
return { text: newText, kind: 'changed', enabled: next };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Write the `enabled=PackedStringArray(...)` line into the `[editor_plugins]`
|
|
94
|
+
* section, creating the section/line if needed. The Godot `[editor_plugins]`
|
|
95
|
+
* section is conventionally written with a blank line between the header and
|
|
96
|
+
* the `enabled` line; this preserves that shape on creation.
|
|
97
|
+
*/
|
|
98
|
+
function writeEnabledArray(text, paths) {
|
|
99
|
+
const lines = text.split('\n');
|
|
100
|
+
const headerIdx = lines.findIndex((l) => l.trim() === '[editor_plugins]');
|
|
101
|
+
const enabledLine = renderEnabledLine(paths);
|
|
102
|
+
if (headerIdx === -1) {
|
|
103
|
+
// Append a fresh [editor_plugins] section.
|
|
104
|
+
const prefix = text.length > 0 && !text.endsWith('\n') ? '\n' : '';
|
|
105
|
+
const sep = text.trim().length > 0 ? '\n' : '';
|
|
106
|
+
return `${text}${prefix}${sep}[editor_plugins]\n\n${enabledLine}\n`;
|
|
107
|
+
}
|
|
108
|
+
// Find an existing `enabled` line within the section.
|
|
109
|
+
let endIdx = headerIdx + 1;
|
|
110
|
+
while (endIdx < lines.length && !lines[endIdx].trim().startsWith('[')) {
|
|
111
|
+
endIdx++;
|
|
112
|
+
}
|
|
113
|
+
const enabledIdx = lines.findIndex((l, i) => i > headerIdx && i < endIdx && /^\s*enabled\s*=/.test(l));
|
|
114
|
+
if (enabledIdx >= 0) {
|
|
115
|
+
lines[enabledIdx] = enabledLine;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// Insert after the header (and a following blank line if present).
|
|
119
|
+
const insertAt = headerIdx + 1 < lines.length && lines[headerIdx + 1].trim() === ''
|
|
120
|
+
? headerIdx + 2
|
|
121
|
+
: headerIdx + 1;
|
|
122
|
+
lines.splice(insertAt, 0, enabledLine);
|
|
123
|
+
}
|
|
124
|
+
return lines.join('\n');
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=project-godot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-godot.js","sourceRoot":"","sources":["../../src/utils/project-godot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Returns true if the string is a valid numeric semver (e.g. "1.2.3"). */
|
|
2
|
+
export declare function isValidVersion(version: string): boolean;
|
|
3
|
+
/** Returns true if `latest` is strictly greater than `current`. */
|
|
4
|
+
export declare function isNewerVersion(current: string, latest: string): boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const SEMVER_NUMERIC = /^\d+(\.\d+)*$/;
|
|
2
|
+
/** Returns true if the string is a valid numeric semver (e.g. "1.2.3"). */
|
|
3
|
+
export function isValidVersion(version) {
|
|
4
|
+
return SEMVER_NUMERIC.test(version);
|
|
5
|
+
}
|
|
6
|
+
/** Returns -1 if a < b, 0 if equal, 1 if a > b. */
|
|
7
|
+
function compareVersions(a, b) {
|
|
8
|
+
const pa = a.split('.').map(Number);
|
|
9
|
+
const pb = b.split('.').map(Number);
|
|
10
|
+
const len = Math.max(pa.length, pb.length);
|
|
11
|
+
for (let i = 0; i < len; i++) {
|
|
12
|
+
const na = pa[i] ?? 0;
|
|
13
|
+
const nb = pb[i] ?? 0;
|
|
14
|
+
if (na < nb)
|
|
15
|
+
return -1;
|
|
16
|
+
if (na > nb)
|
|
17
|
+
return 1;
|
|
18
|
+
}
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
/** Returns true if `latest` is strictly greater than `current`. */
|
|
22
|
+
export function isNewerVersion(current, latest) {
|
|
23
|
+
return compareVersions(current, latest) < 0;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=semver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semver.js","sourceRoot":"","sources":["../../src/utils/semver.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG,eAAe,CAAC;AAEvC,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED,mDAAmD;AACnD,SAAS,eAAe,CAAC,CAAS,EAAE,CAAS;IAC3C,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAE3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,CAAC,CAAC,CAAC;QACvB,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,MAAc;IAC5D,OAAO,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type Spinner } from 'yocto-spinner';
|
|
2
|
+
import type { Command } from 'commander';
|
|
3
|
+
export declare function setVerbose(enabled: boolean): void;
|
|
4
|
+
export declare function verbose(msg: string): void;
|
|
5
|
+
/**
|
|
6
|
+
* Apply styled help formatting to a Commander command.
|
|
7
|
+
* Call this on every Command instance (root and subcommands)
|
|
8
|
+
* so that --help / -h always renders the fancy UI.
|
|
9
|
+
*
|
|
10
|
+
* @param appVersion - The CLI version string, shown in the root banner.
|
|
11
|
+
*/
|
|
12
|
+
export declare function configureStyledHelp(cmd: Command, appVersion?: string): Command;
|
|
13
|
+
/**
|
|
14
|
+
* Print a success message with a green checkmark.
|
|
15
|
+
* In non-TTY mode, uses plain text prefix.
|
|
16
|
+
*/
|
|
17
|
+
export declare function success(msg: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Print an error message with a red cross to stderr.
|
|
20
|
+
* In non-TTY mode, uses plain text prefix.
|
|
21
|
+
*/
|
|
22
|
+
export declare function error(msg: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Print an info message with a blue info symbol.
|
|
25
|
+
* In non-TTY mode, uses plain text prefix.
|
|
26
|
+
*/
|
|
27
|
+
export declare function info(msg: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Print a warning message with a yellow warning symbol.
|
|
30
|
+
* In non-TTY mode, uses plain text prefix.
|
|
31
|
+
*/
|
|
32
|
+
export declare function warn(msg: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Print a bold cyan section heading.
|
|
35
|
+
*/
|
|
36
|
+
export declare function heading(msg: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Print a formatted key-value label.
|
|
39
|
+
*/
|
|
40
|
+
export declare function label(key: string, value: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Start a spinner with the given text. Returns a wrapped spinner instance
|
|
43
|
+
* whose success/error/warning/info methods add an extra space after the symbol
|
|
44
|
+
* for consistent formatting.
|
|
45
|
+
*
|
|
46
|
+
* In non-TTY environments (CI pipelines, piped output), returns a no-op
|
|
47
|
+
* spinner that outputs plain text without ANSI escape codes.
|
|
48
|
+
*/
|
|
49
|
+
export declare function startSpinner(text: string): Spinner;
|
|
50
|
+
/**
|
|
51
|
+
* Format a status badge (enabled/disabled).
|
|
52
|
+
*/
|
|
53
|
+
export declare function badge(enabled: boolean): string;
|
|
54
|
+
/**
|
|
55
|
+
* Print a feature row with a styled badge and name.
|
|
56
|
+
*/
|
|
57
|
+
export declare function featureRow(name: string, enabled: boolean): void;
|
|
58
|
+
/**
|
|
59
|
+
* Print a divider line.
|
|
60
|
+
*/
|
|
61
|
+
export declare function divider(): void;
|
package/dist/utils/ui.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import yoctoSpinner from 'yocto-spinner';
|
|
3
|
+
// --- Verbose mode ---
|
|
4
|
+
let verboseEnabled = false;
|
|
5
|
+
export function setVerbose(enabled) {
|
|
6
|
+
verboseEnabled = enabled;
|
|
7
|
+
}
|
|
8
|
+
export function verbose(msg) {
|
|
9
|
+
if (verboseEnabled) {
|
|
10
|
+
if (isTTY()) {
|
|
11
|
+
console.log(chalk.dim(`[verbose] ${msg}`));
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
console.log(`[verbose] ${msg}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// --- TTY detection ---
|
|
19
|
+
function isTTY() {
|
|
20
|
+
return !!process.stdout.isTTY;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Draw a Unicode rounded box around text with cyan borders.
|
|
24
|
+
*/
|
|
25
|
+
function drawBox(text) {
|
|
26
|
+
const lines = text.split('\n');
|
|
27
|
+
const padding = 2;
|
|
28
|
+
const maxLen = Math.max(...lines.map(l => stripAnsi(l).length));
|
|
29
|
+
const innerWidth = maxLen + padding * 2;
|
|
30
|
+
const pad = ' '.repeat(padding);
|
|
31
|
+
const top = chalk.cyan('╭' + '─'.repeat(innerWidth) + '╮');
|
|
32
|
+
const bottom = chalk.cyan('╰' + '─'.repeat(innerWidth) + '╯');
|
|
33
|
+
const middle = lines.map(l => {
|
|
34
|
+
const visible = stripAnsi(l).length;
|
|
35
|
+
const right = ' '.repeat(maxLen - visible);
|
|
36
|
+
return chalk.cyan('│') + pad + l + right + pad + chalk.cyan('│');
|
|
37
|
+
});
|
|
38
|
+
return [top, ...middle, bottom].join('\n');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Strip ANSI escape codes from a string.
|
|
42
|
+
*/
|
|
43
|
+
function stripAnsi(str) {
|
|
44
|
+
// eslint-disable-next-line no-control-regex
|
|
45
|
+
return str.replace(/\x1B\[[0-9;]*m/g, '');
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Apply styled help formatting to a Commander command.
|
|
49
|
+
* Call this on every Command instance (root and subcommands)
|
|
50
|
+
* so that --help / -h always renders the fancy UI.
|
|
51
|
+
*
|
|
52
|
+
* @param appVersion - The CLI version string, shown in the root banner.
|
|
53
|
+
*/
|
|
54
|
+
export function configureStyledHelp(cmd, appVersion) {
|
|
55
|
+
cmd.configureHelp({
|
|
56
|
+
formatHelp(target, helper) {
|
|
57
|
+
const isRoot = !target.parent;
|
|
58
|
+
const lines = [];
|
|
59
|
+
// Banner for root, styled title for subcommands
|
|
60
|
+
if (isRoot && appVersion) {
|
|
61
|
+
lines.push(drawBox(`${chalk.bold.cyan('Godot-MCP CLI')} ${chalk.dim(`v${appVersion}`)}\n${chalk.dim('Bridge LLMs with Godot via Model Context Protocol')}`));
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
lines.push(drawBox(`${chalk.bold.cyan(target.name())} ${chalk.dim('—')} ${target.description()}`));
|
|
65
|
+
}
|
|
66
|
+
lines.push('');
|
|
67
|
+
// Usage
|
|
68
|
+
lines.push(`${chalk.bold('Usage:')} ${chalk.yellow(helper.commandUsage(target))}`);
|
|
69
|
+
lines.push('');
|
|
70
|
+
// Subcommands
|
|
71
|
+
const subcommands = helper.visibleCommands(target);
|
|
72
|
+
if (subcommands.length > 0) {
|
|
73
|
+
lines.push(chalk.bold('Commands:'));
|
|
74
|
+
for (const sub of subcommands) {
|
|
75
|
+
lines.push(` ${chalk.yellow(sub.name().padEnd(20))} ${chalk.dim(sub.description() || '')}`);
|
|
76
|
+
}
|
|
77
|
+
lines.push('');
|
|
78
|
+
}
|
|
79
|
+
// Arguments
|
|
80
|
+
const args = helper.visibleArguments(target);
|
|
81
|
+
if (args.length > 0) {
|
|
82
|
+
lines.push(chalk.bold('Arguments:'));
|
|
83
|
+
for (const arg of args) {
|
|
84
|
+
lines.push(` ${chalk.green(helper.argumentTerm(arg).padEnd(30))} ${chalk.dim(helper.argumentDescription(arg))}`);
|
|
85
|
+
}
|
|
86
|
+
lines.push('');
|
|
87
|
+
}
|
|
88
|
+
// Options
|
|
89
|
+
const options = helper.visibleOptions(target);
|
|
90
|
+
if (options.length > 0) {
|
|
91
|
+
lines.push(chalk.bold('Options:'));
|
|
92
|
+
for (const opt of options) {
|
|
93
|
+
lines.push(` ${chalk.green(helper.optionTerm(opt).padEnd(30))} ${chalk.dim(helper.optionDescription(opt))}`);
|
|
94
|
+
}
|
|
95
|
+
lines.push('');
|
|
96
|
+
}
|
|
97
|
+
// Footer
|
|
98
|
+
if (isRoot) {
|
|
99
|
+
lines.push(chalk.dim('Run ') +
|
|
100
|
+
chalk.yellow('godot-cli <command> --help') +
|
|
101
|
+
chalk.dim(' for detailed usage of each command.'));
|
|
102
|
+
lines.push('');
|
|
103
|
+
}
|
|
104
|
+
return lines.join('\n');
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
return cmd;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Print a success message with a green checkmark.
|
|
111
|
+
* In non-TTY mode, uses plain text prefix.
|
|
112
|
+
*/
|
|
113
|
+
export function success(msg) {
|
|
114
|
+
if (isTTY()) {
|
|
115
|
+
console.log(`${chalk.green('✔')} ${msg}`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
console.log(`SUCCESS: ${msg}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Print an error message with a red cross to stderr.
|
|
123
|
+
* In non-TTY mode, uses plain text prefix.
|
|
124
|
+
*/
|
|
125
|
+
export function error(msg) {
|
|
126
|
+
if (isTTY()) {
|
|
127
|
+
console.error(`${chalk.red('✖')} ${chalk.red(msg)}`);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
console.error(`ERROR: ${msg}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Print an info message with a blue info symbol.
|
|
135
|
+
* In non-TTY mode, uses plain text prefix.
|
|
136
|
+
*/
|
|
137
|
+
export function info(msg) {
|
|
138
|
+
if (isTTY()) {
|
|
139
|
+
console.log(`${chalk.blue('ℹ')} ${msg}`);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
console.log(`INFO: ${msg}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Print a warning message with a yellow warning symbol.
|
|
147
|
+
* In non-TTY mode, uses plain text prefix.
|
|
148
|
+
*/
|
|
149
|
+
export function warn(msg) {
|
|
150
|
+
if (isTTY()) {
|
|
151
|
+
console.log(`${chalk.yellow('⚠')} ${chalk.yellow(msg)}`);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
console.log(`WARN: ${msg}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Print a bold cyan section heading.
|
|
159
|
+
*/
|
|
160
|
+
export function heading(msg) {
|
|
161
|
+
console.log(`\n${chalk.bold.cyan(msg)}`);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Print a formatted key-value label.
|
|
165
|
+
*/
|
|
166
|
+
export function label(key, value) {
|
|
167
|
+
console.log(` ${chalk.bold(key + ':')} ${value}`);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Create a no-op spinner for non-TTY environments.
|
|
171
|
+
* Methods are safe to call but produce no ANSI output.
|
|
172
|
+
*/
|
|
173
|
+
function createNoOpSpinner(text) {
|
|
174
|
+
console.log(text);
|
|
175
|
+
const self = {
|
|
176
|
+
start: () => self,
|
|
177
|
+
stop: () => self,
|
|
178
|
+
success: (msg) => { if (msg)
|
|
179
|
+
console.log(`SUCCESS: ${msg}`); return self; },
|
|
180
|
+
error: (msg) => { if (msg)
|
|
181
|
+
console.error(`ERROR: ${msg}`); return self; },
|
|
182
|
+
warning: (msg) => { if (msg)
|
|
183
|
+
console.log(`WARN: ${msg}`); return self; },
|
|
184
|
+
info: (msg) => { if (msg)
|
|
185
|
+
console.log(`INFO: ${msg}`); return self; },
|
|
186
|
+
clear: () => self,
|
|
187
|
+
get text() { return text; },
|
|
188
|
+
set text(value) { text = value; },
|
|
189
|
+
get isSpinning() { return false; },
|
|
190
|
+
get color() { return 'cyan'; },
|
|
191
|
+
set color(_) { },
|
|
192
|
+
};
|
|
193
|
+
return self;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Start a spinner with the given text. Returns a wrapped spinner instance
|
|
197
|
+
* whose success/error/warning/info methods add an extra space after the symbol
|
|
198
|
+
* for consistent formatting.
|
|
199
|
+
*
|
|
200
|
+
* In non-TTY environments (CI pipelines, piped output), returns a no-op
|
|
201
|
+
* spinner that outputs plain text without ANSI escape codes.
|
|
202
|
+
*/
|
|
203
|
+
export function startSpinner(text) {
|
|
204
|
+
if (!isTTY()) {
|
|
205
|
+
return createNoOpSpinner(text);
|
|
206
|
+
}
|
|
207
|
+
const spinner = yoctoSpinner({ text, color: 'cyan' }).start();
|
|
208
|
+
const origSuccess = spinner.success.bind(spinner);
|
|
209
|
+
const origError = spinner.error.bind(spinner);
|
|
210
|
+
const origWarning = spinner.warning.bind(spinner);
|
|
211
|
+
const origInfo = spinner.info.bind(spinner);
|
|
212
|
+
spinner.success = (msg) => origSuccess(msg ? ` ${msg}` : undefined);
|
|
213
|
+
spinner.error = (msg) => origError(msg ? ` ${msg}` : undefined);
|
|
214
|
+
spinner.warning = (msg) => origWarning(msg ? ` ${msg}` : undefined);
|
|
215
|
+
spinner.info = (msg) => origInfo(msg ? ` ${msg}` : undefined);
|
|
216
|
+
return spinner;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Format a status badge (enabled/disabled).
|
|
220
|
+
*/
|
|
221
|
+
export function badge(enabled) {
|
|
222
|
+
return enabled
|
|
223
|
+
? chalk.bgGreen.black('[enabled]')
|
|
224
|
+
: chalk.bgRed.white('[disabled]');
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Print a feature row with a styled badge and name.
|
|
228
|
+
*/
|
|
229
|
+
export function featureRow(name, enabled) {
|
|
230
|
+
console.log(` ${badge(enabled)} ${name}`);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Print a divider line.
|
|
234
|
+
*/
|
|
235
|
+
export function divider() {
|
|
236
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface UpdateInfo {
|
|
2
|
+
current: string;
|
|
3
|
+
latest: string;
|
|
4
|
+
}
|
|
5
|
+
/** Fetch the latest version string from the npm registry. */
|
|
6
|
+
export declare function fetchLatestVersion(): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Check if a newer version is available on npm.
|
|
9
|
+
* Returns update info if available, null otherwise.
|
|
10
|
+
* Never throws — all errors are silently caught.
|
|
11
|
+
*/
|
|
12
|
+
export declare function checkForUpdate(currentVersion: string): Promise<UpdateInfo | null>;
|
|
13
|
+
/** Format the "update available" message with chalk styling. */
|
|
14
|
+
export declare function formatUpdateAvailable(current: string, latest: string): string;
|
|
15
|
+
/** Print a styled update notification to stderr (does not interfere with stdout piping). */
|
|
16
|
+
export declare function printUpdateNotification(current: string, latest: string): void;
|
|
17
|
+
/** Returns true if the CLI was likely invoked via npx. */
|
|
18
|
+
export declare function isRunningViaNpx(): boolean;
|
|
19
|
+
export {};
|