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.
- package/CHANGELOG.md +99 -0
- package/README.md +139 -16
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/check.d.ts +2 -0
- package/dist/commands/check.js +48 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/close.d.ts +3 -0
- package/dist/commands/close.js +82 -27
- package/dist/commands/close.js.map +1 -1
- package/dist/commands/commands.d.ts +3 -0
- package/dist/commands/commands.js +28 -0
- package/dist/commands/commands.js.map +1 -0
- package/dist/commands/exec.js +43 -28
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/export.d.ts +2 -0
- package/dist/commands/export.js +45 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/headless-common.d.ts +29 -0
- package/dist/commands/headless-common.js +69 -0
- package/dist/commands/headless-common.js.map +1 -0
- package/dist/commands/import.d.ts +2 -0
- package/dist/commands/import.js +32 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/open.js +38 -6
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/rql.d.ts +2 -0
- package/dist/commands/rql.js +81 -0
- package/dist/commands/rql.js.map +1 -0
- package/dist/commands/run-script.d.ts +2 -0
- package/dist/commands/run-script.js +33 -0
- package/dist/commands/run-script.js.map +1 -0
- package/dist/commands/run-system-tool.js +0 -1
- package/dist/commands/run-system-tool.js.map +1 -1
- package/dist/commands/run-tool-builder.d.ts +38 -4
- package/dist/commands/run-tool-builder.js +179 -56
- package/dist/commands/run-tool-builder.js.map +1 -1
- package/dist/commands/run-tool.js +0 -1
- package/dist/commands/run-tool.js.map +1 -1
- package/dist/commands/setup-skills.js +3 -2
- package/dist/commands/setup-skills.js.map +1 -1
- package/dist/commands/status.js +25 -19
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/test.d.ts +5 -0
- package/dist/commands/test.js +111 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/tools.d.ts +2 -0
- package/dist/commands/tools.js +120 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commands/update.js +1 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/wait-for-ready.js +18 -20
- package/dist/commands/wait-for-ready.js.map +1 -1
- package/dist/index.js +48 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/build.d.ts +1 -1
- package/dist/lib/build.js +21 -4
- package/dist/lib/build.js.map +1 -1
- package/dist/lib/check.d.ts +44 -0
- package/dist/lib/check.js +191 -0
- package/dist/lib/check.js.map +1 -0
- package/dist/lib/cli-guide.d.ts +26 -0
- package/dist/lib/cli-guide.js +51 -0
- package/dist/lib/cli-guide.js.map +1 -0
- package/dist/lib/exec.d.ts +19 -0
- package/dist/lib/exec.js +61 -10
- package/dist/lib/exec.js.map +1 -1
- package/dist/lib/export-project.d.ts +41 -0
- package/dist/lib/export-project.js +159 -0
- package/dist/lib/export-project.js.map +1 -0
- package/dist/lib/godot-log.d.ts +38 -0
- package/dist/lib/godot-log.js +145 -0
- package/dist/lib/godot-log.js.map +1 -0
- package/dist/lib/godot-run.d.ts +34 -0
- package/dist/lib/godot-run.js +113 -0
- package/dist/lib/godot-run.js.map +1 -0
- package/dist/lib/headless.d.ts +82 -0
- package/dist/lib/headless.js +117 -0
- package/dist/lib/headless.js.map +1 -0
- package/dist/lib/import-project.d.ts +9 -0
- package/dist/lib/import-project.js +15 -0
- package/dist/lib/import-project.js.map +1 -0
- package/dist/lib/junit.d.ts +36 -0
- package/dist/lib/junit.js +146 -0
- package/dist/lib/junit.js.map +1 -0
- package/dist/lib/list-tools.d.ts +51 -0
- package/dist/lib/list-tools.js +147 -0
- package/dist/lib/list-tools.js.map +1 -0
- package/dist/lib/open.js +3 -1
- package/dist/lib/open.js.map +1 -1
- package/dist/lib/progress.d.ts +1 -7
- package/dist/lib/progress.js +2 -15
- package/dist/lib/progress.js.map +1 -1
- package/dist/lib/rql.d.ts +32 -0
- package/dist/lib/rql.js +105 -0
- package/dist/lib/rql.js.map +1 -0
- package/dist/lib/run-script.d.ts +23 -0
- package/dist/lib/run-script.js +43 -0
- package/dist/lib/run-script.js.map +1 -0
- package/dist/lib/run-tests.d.ts +50 -0
- package/dist/lib/run-tests.js +181 -0
- package/dist/lib/run-tests.js.map +1 -0
- package/dist/lib/run-tool.js +6 -22
- package/dist/lib/run-tool.js.map +1 -1
- package/dist/lib/session.d.ts +8 -1
- package/dist/lib/session.js +36 -4
- package/dist/lib/session.js.map +1 -1
- package/dist/lib/setup-skills.d.ts +8 -13
- package/dist/lib/setup-skills.js +27 -24
- package/dist/lib/setup-skills.js.map +1 -1
- package/dist/lib/types.d.ts +7 -0
- package/dist/lib/update-project.js +1 -1
- package/dist/lib/update-project.js.map +1 -1
- package/dist/lib.d.ts +16 -0
- package/dist/lib.js +10 -0
- package/dist/lib.js.map +1 -1
- package/dist/utils/addon-deps.js +2 -2
- package/dist/utils/agents.d.ts +2 -6
- package/dist/utils/agents.js.map +1 -1
- package/dist/utils/connection.d.ts +59 -0
- package/dist/utils/connection.js +11 -10
- package/dist/utils/connection.js.map +1 -1
- package/dist/utils/csproj-deps.js +1 -1
- package/dist/utils/csproj-deps.js.map +1 -1
- package/dist/utils/editor-connection.d.ts +74 -0
- package/dist/utils/editor-connection.js +225 -0
- package/dist/utils/editor-connection.js.map +1 -0
- package/dist/utils/editor-mcp-server.d.ts +32 -0
- package/dist/utils/editor-mcp-server.js +134 -0
- package/dist/utils/editor-mcp-server.js.map +1 -0
- package/dist/utils/exit-codes.d.ts +2 -0
- package/dist/utils/exit-codes.js +4 -0
- package/dist/utils/exit-codes.js.map +1 -0
- package/dist/utils/godot-process.d.ts +5 -0
- package/dist/utils/godot-process.js +16 -0
- package/dist/utils/godot-process.js.map +1 -1
- package/dist/utils/godot-shutdown.d.ts +3 -1
- package/dist/utils/godot-shutdown.js +4 -2
- package/dist/utils/godot-shutdown.js.map +1 -1
- package/dist/utils/input.d.ts +3 -3
- package/dist/utils/input.js +22 -35
- package/dist/utils/input.js.map +1 -1
- package/dist/utils/output.d.ts +45 -0
- package/dist/utils/output.js +101 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/server-source.d.ts +1 -1
- package/dist/utils/server-source.js +1 -1
- package/dist/utils/skill-guides.d.ts +6 -9
- package/dist/utils/skill-guides.js +100 -43
- package/dist/utils/skill-guides.js.map +1 -1
- package/dist/utils/skills.d.ts +1 -14
- package/dist/utils/skills.js +0 -89
- package/dist/utils/skills.js.map +1 -1
- package/dist/utils/ui.d.ts +6 -1
- package/dist/utils/ui.js +72 -58
- package/dist/utils/ui.js.map +1 -1
- package/dist/utils/update-check.d.ts +6 -17
- package/dist/utils/update-check.js +10 -77
- package/dist/utils/update-check.js.map +1 -1
- package/package.json +2 -2
- package/dist/utils/json-parse.d.ts +0 -25
- package/dist/utils/json-parse.js +0 -83
- package/dist/utils/json-parse.js.map +0 -1
- package/dist/utils/semver.d.ts +0 -4
- package/dist/utils/semver.js +0 -25
- package/dist/utils/semver.js.map +0 -1
package/dist/commands/close.js
CHANGED
|
@@ -4,10 +4,11 @@ import * as path from 'path';
|
|
|
4
4
|
import { platform as nodePlatform } from 'os';
|
|
5
5
|
import * as ui from '../utils/ui.js';
|
|
6
6
|
import { verbose } from '../utils/ui.js';
|
|
7
|
-
import { findGodotProcess } from '../utils/godot-process.js';
|
|
7
|
+
import { childProcessIds, findGodotProcess } from '../utils/godot-process.js';
|
|
8
8
|
import { isProcessAlive, sendGracefulShutdown, sendForceKill, waitForExit, } from '../utils/godot-shutdown.js';
|
|
9
9
|
import { resolveSessionConnection } from '../utils/connection.js';
|
|
10
10
|
import { createGodotSession } from '../lib/session.js';
|
|
11
|
+
import { findEditorServers, stopOrphanedServers } from '../utils/editor-mcp-server.js';
|
|
11
12
|
const DEFAULT_TIMEOUT_SECONDS = 30;
|
|
12
13
|
/** Resolve the project path argument to an absolute, canonical path. */
|
|
13
14
|
export function resolveCloseProjectPath(positionalPath, cwd) {
|
|
@@ -40,23 +41,35 @@ export function parseTimeoutSeconds(raw) {
|
|
|
40
41
|
}
|
|
41
42
|
/** Resolve the editor PID for a given project path, or null when not running. */
|
|
42
43
|
export function resolveEditorPid(projectPath) {
|
|
44
|
+
return resolveEditorProcess(projectPath)?.pid ?? null;
|
|
45
|
+
}
|
|
46
|
+
/** The editor process of the project, and whether it is the `_console` wrapper (its child is the editor). */
|
|
47
|
+
function resolveEditorProcess(projectPath) {
|
|
43
48
|
const proc = findGodotProcess(projectPath);
|
|
44
|
-
if (proc)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
+
if (!proc)
|
|
50
|
+
return null;
|
|
51
|
+
verbose(`Godot editor PID ${proc.pid} matched for project`);
|
|
52
|
+
return { pid: proc.pid, consoleWrapper: isConsoleWrapper(proc.commandLine) };
|
|
53
|
+
}
|
|
54
|
+
/** Whether a command line runs Godot's `_console` build: a windowless wrapper whose child is the editor. */
|
|
55
|
+
export function isConsoleWrapper(commandLine) {
|
|
56
|
+
// Only the program itself: a project path such as `D:\games\space_console` must not count.
|
|
57
|
+
const program = commandLine.match(/^\s*(?:"([^"]+)"|(\S+))/);
|
|
58
|
+
const exe = program?.[1] ?? program?.[2] ?? '';
|
|
59
|
+
return /_console(\.exe)?$/i.test(path.basename(exe.replace(/\\/g, '/')));
|
|
49
60
|
}
|
|
50
61
|
export const closeCommand = new Command('close')
|
|
51
62
|
.description('Gracefully terminate the Godot editor instance running for a given project path')
|
|
52
63
|
.argument('[path]', 'Path to the Godot project (defaults to current directory)')
|
|
64
|
+
.option('--path <path>', 'Path to the Godot project (same as [path])')
|
|
53
65
|
.option('--timeout <seconds>', `Polite-quit timeout in seconds (default: ${DEFAULT_TIMEOUT_SECONDS})`, String(DEFAULT_TIMEOUT_SECONDS))
|
|
54
66
|
.option('--force', 'Hard-kill the editor if it does not exit within --timeout')
|
|
55
67
|
.option('--owned-only', 'Close only an editor started by godot-cli (exec / open --headless); never a user editor')
|
|
56
68
|
// Hidden fallback: a lease written by godot-cli 0.30.0 (cli-core 0.7.0) does not record the editor's server.
|
|
57
69
|
.addOption(new Option('--url <url>', 'With --owned-only: the local MCP server of that editor, for a lease without one').hideHelp())
|
|
58
70
|
.option('--token <token>', 'With --owned-only: bearer token (default: GODOT_MCP_TOKEN)')
|
|
59
|
-
.action(async (
|
|
71
|
+
.action(async (positionalArg, options) => {
|
|
72
|
+
const positionalPath = positionalArg ?? options.path;
|
|
60
73
|
const projectPath = resolveCloseProjectPath(positionalPath, process.cwd());
|
|
61
74
|
verbose(`close invoked for project: ${projectPath}`);
|
|
62
75
|
if (!fs.existsSync(projectPath)) {
|
|
@@ -72,13 +85,31 @@ export const closeCommand = new Command('close')
|
|
|
72
85
|
ui.error(`Invalid --timeout value: "${options.timeout}". Must be a positive integer (seconds).`);
|
|
73
86
|
process.exit(1);
|
|
74
87
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
88
|
+
const editor = resolveEditorProcess(projectPath);
|
|
89
|
+
// The addon runs its local MCP server as the editor's child: note it now, while the editor's tree still shows it.
|
|
90
|
+
const servers = editor ? await findEditorServers(editor.pid) : [];
|
|
91
|
+
/**
|
|
92
|
+
* After a close: stop the noted servers the plugin did not (a hard kill gives it no chance). Only once the editor
|
|
93
|
+
* we noted them under is gone — the lease may name the `_console` wrapper or its editor, so PIDs are not compared.
|
|
94
|
+
*/
|
|
95
|
+
const stopServers = async () => {
|
|
96
|
+
if (!editor)
|
|
97
|
+
return;
|
|
98
|
+
for (const serverPid of await stopOrphanedServers(editor.pid, servers)) {
|
|
99
|
+
ui.success(`MCP server (PID ${serverPid}) of the editor stopped`);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
// The local port is derived from the path as typed (exec / open --headless do not resolve links either).
|
|
103
|
+
const leasePath = path.resolve(positionalPath ?? process.cwd());
|
|
104
|
+
// An editor godot-cli started (exec, run-tool, tools, open --headless) is windowless: ask its plugin to save and
|
|
105
|
+
// quit through the lease instead of a window close it cannot receive. --owned-only stops there.
|
|
106
|
+
const closedOwned = await closeOwned(leasePath, timeoutSeconds, options, options.ownedOnly === true);
|
|
107
|
+
if (closedOwned)
|
|
108
|
+
await stopServers();
|
|
109
|
+
if (closedOwned || options.ownedOnly)
|
|
78
110
|
return;
|
|
79
|
-
}
|
|
80
111
|
const platform = nodePlatform();
|
|
81
|
-
const pid =
|
|
112
|
+
const pid = editor?.pid ?? null;
|
|
82
113
|
if (pid === null) {
|
|
83
114
|
ui.success(`no running editor for project at ${projectPath}`);
|
|
84
115
|
process.exit(0);
|
|
@@ -90,15 +121,32 @@ export const closeCommand = new Command('close')
|
|
|
90
121
|
ui.label('Force', options.force ? 'yes' : 'no');
|
|
91
122
|
ui.divider();
|
|
92
123
|
const spinner = ui.startSpinner(`Sending polite-quit to PID ${pid}...`);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
124
|
+
// A console-subsystem editor (the `_console` build) or a windowless one cannot be asked politely on Windows.
|
|
125
|
+
let sent = sendGracefulShutdown(pid, platform);
|
|
126
|
+
// The `_console` wrapper has no window, but the editor it runs has: ask that one, and wait for both to exit.
|
|
127
|
+
const waitPids = [pid];
|
|
128
|
+
if (!sent && editor.consoleWrapper) {
|
|
129
|
+
for (const child of childProcessIds(pid)) {
|
|
130
|
+
const ok = sendGracefulShutdown(child, platform);
|
|
131
|
+
verbose(`Polite-quit to editor child PID ${child}: ${ok ? 'sent' : 'failed'}`);
|
|
132
|
+
if (ok) {
|
|
133
|
+
sent = true;
|
|
134
|
+
waitPids.push(child);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (!sent && !options.force) {
|
|
139
|
+
spinner.error(`Could not ask PID ${pid} to quit (no window to close); re-run with --force to stop it.`);
|
|
96
140
|
process.exit(1);
|
|
97
141
|
}
|
|
98
|
-
|
|
99
|
-
|
|
142
|
+
if (sent)
|
|
143
|
+
spinner.text = `Waiting up to ${timeoutSeconds}s for PID ${pid} to exit...`;
|
|
144
|
+
const exited = sent
|
|
145
|
+
? (await Promise.all(waitPids.map((p) => waitForExit(p, timeoutSeconds * 1000, platform)))).every(Boolean)
|
|
146
|
+
: false;
|
|
100
147
|
if (exited) {
|
|
101
148
|
spinner.success(`Godot editor (PID ${pid}) exited cleanly`);
|
|
149
|
+
await stopServers();
|
|
102
150
|
process.exit(0);
|
|
103
151
|
}
|
|
104
152
|
if (!options.force) {
|
|
@@ -107,14 +155,17 @@ export const closeCommand = new Command('close')
|
|
|
107
155
|
process.exit(1);
|
|
108
156
|
}
|
|
109
157
|
spinner.text = `Force-killing PID ${pid}...`;
|
|
110
|
-
|
|
111
|
-
|
|
158
|
+
// Not /T for a user's GUI editor: its children may be a running game or an external script editor.
|
|
159
|
+
const killed = sendForceKill(pid, platform, editor.consoleWrapper);
|
|
160
|
+
// A failed kill of a process that is gone: the polite quit finished just after the timeout.
|
|
161
|
+
if (!killed && isProcessAlive(pid, platform)) {
|
|
112
162
|
spinner.error(`Failed to force-kill PID ${pid}`);
|
|
113
163
|
process.exit(1);
|
|
114
164
|
}
|
|
115
165
|
const reaped = await waitForExit(pid, 5000, platform);
|
|
116
166
|
if (reaped || !isProcessAlive(pid, platform)) {
|
|
117
167
|
spinner.success(`Godot editor (PID ${pid}) force-killed`);
|
|
168
|
+
await stopServers();
|
|
118
169
|
process.exit(0);
|
|
119
170
|
}
|
|
120
171
|
spinner.error(`Godot editor (PID ${pid}) is still alive after force-kill`);
|
|
@@ -123,28 +174,32 @@ export const closeCommand = new Command('close')
|
|
|
123
174
|
/**
|
|
124
175
|
* `close --owned-only`: ask the editor named by our lease (`.ai-game-dev/session.json`) to save and quit through
|
|
125
176
|
* its plugin (a windowless editor gets no WM_CLOSE). Anything else — no lease, a stale lease, a user's editor — is
|
|
126
|
-
* left alone.
|
|
177
|
+
* left alone. Returns whether it closed one.
|
|
127
178
|
*/
|
|
128
|
-
async function closeOwned(projectPath, timeoutSeconds, options) {
|
|
179
|
+
async function closeOwned(projectPath, timeoutSeconds, options, report) {
|
|
129
180
|
let session;
|
|
130
181
|
try {
|
|
131
182
|
session = createGodotSession({ projectPath, ...resolveSessionConnection(options) }).session;
|
|
132
183
|
}
|
|
133
184
|
catch (err) {
|
|
185
|
+
if (!report) {
|
|
186
|
+
verbose(`No usable session lease: ${err instanceof Error ? err.message : String(err)}`);
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
134
189
|
ui.error(err instanceof Error ? err.message : String(err));
|
|
135
190
|
process.exit(1);
|
|
136
191
|
}
|
|
137
|
-
const spinner = ui.startSpinner('Closing the editor started by godot-cli...');
|
|
138
192
|
const result = await session.closeOwned({ timeoutMs: timeoutSeconds * 1000, force: options.force === true });
|
|
139
193
|
switch (result.kind) {
|
|
140
194
|
case 'closed':
|
|
141
|
-
|
|
142
|
-
return;
|
|
195
|
+
ui.success(`Godot editor (PID ${result.pid}) ${result.forced ? 'force-killed' : 'closed'}`);
|
|
196
|
+
return true;
|
|
143
197
|
case 'not-owned':
|
|
144
|
-
|
|
145
|
-
|
|
198
|
+
if (report)
|
|
199
|
+
ui.success(`No editor started by godot-cli is running for ${projectPath}${result.staleLeaseRemoved ? ' (removed a stale lease)' : ''}`);
|
|
200
|
+
return false;
|
|
146
201
|
case 'still-running':
|
|
147
|
-
|
|
202
|
+
ui.error(`Godot editor (PID ${result.pid}) is still running after ${timeoutSeconds}s` + (options.force ? '' : '; re-run with --force'));
|
|
148
203
|
process.exit(1);
|
|
149
204
|
}
|
|
150
205
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"close.js","sourceRoot":"","sources":["../../src/commands/close.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"close.js","sourceRoot":"","sources":["../../src/commands/close.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import * as ui from '../utils/ui.js';
|
|
3
|
+
import { buildCommandManifest, toolFailureCodeLine } from '@baizor/gamedev-cli-core';
|
|
4
|
+
import { ExitCode } from '../utils/exit-codes.js';
|
|
5
|
+
import { CommandOutput, addFormatOption, parseFormat } from '../utils/output.js';
|
|
6
|
+
/** `commands`: needs the finished program, so it is created with a getter. */
|
|
7
|
+
export function createCommandsCommand(getProgram, version) {
|
|
8
|
+
return addFormatOption(new Command('commands').description('Print a machine-readable manifest of every command, its arguments, options and the exit codes')).action((options) => {
|
|
9
|
+
const output = new CommandOutput('commands', parseFormat(options.format));
|
|
10
|
+
const manifest = buildCommandManifest(getProgram(), version);
|
|
11
|
+
if (!output.machine) {
|
|
12
|
+
for (const c of manifest.commands) {
|
|
13
|
+
const args = c.arguments.map((a) => (a.required ? `<${a.name}${a.variadic ? '...' : ''}>` : `[${a.name}${a.variadic ? '...' : ''}]`)).join(' ');
|
|
14
|
+
console.log(`${c.name}${args ? ` ${args}` : ''} — ${c.description}`);
|
|
15
|
+
for (const o of c.options)
|
|
16
|
+
console.log(` ${o.flags}${o.default !== undefined ? ` (default: ${JSON.stringify(o.default)})` : ''}`);
|
|
17
|
+
}
|
|
18
|
+
ui.heading('Exit codes');
|
|
19
|
+
for (const e of manifest.exitCodes)
|
|
20
|
+
console.log(` ${String(e.code).padStart(2)} ${e.name}: ${e.description}`);
|
|
21
|
+
ui.heading('Error codes of a failed tool call (errors[].code)');
|
|
22
|
+
for (const e of manifest.errorCodes)
|
|
23
|
+
console.log(` ${toolFailureCodeLine(e)}`);
|
|
24
|
+
}
|
|
25
|
+
output.finish(ExitCode.Success, manifest);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/commands/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjF,8EAA8E;AAC9E,MAAM,UAAU,qBAAqB,CAAC,UAAyB,EAAE,OAAe;IAC9E,OAAO,eAAe,CACpB,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,+FAA+F,CAAC,CACrI,CAAC,MAAM,CAAC,CAAC,OAA4B,EAAE,EAAE;QACxC,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1E,MAAM,QAAQ,GAAG,oBAAoB,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBAClC,MAAM,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAChJ,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;gBACvE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO;oBAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvI,CAAC;YACD,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,SAAS;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YAChH,EAAE,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC;YAChE,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,UAAU;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClF,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/commands/exec.js
CHANGED
|
@@ -4,12 +4,14 @@ import * as ui from '../utils/ui.js';
|
|
|
4
4
|
import { verbose } from '../utils/ui.js';
|
|
5
5
|
import { DEFAULT_SESSION_IDLE_SECONDS, DEFAULT_SESSION_READY_TIMEOUT_MS } from '@baizor/gamedev-cli-core';
|
|
6
6
|
import { resolveAndValidateProjectPath, resolveSessionConnection } from '../utils/connection.js';
|
|
7
|
-
import {
|
|
7
|
+
import { collect } from '../utils/input.js';
|
|
8
|
+
import { ExitCode } from '../utils/exit-codes.js';
|
|
9
|
+
import { connectionForCommand } from '../utils/editor-connection.js';
|
|
10
|
+
import { isLocalhostUrl } from '../utils/project-marker.js';
|
|
11
|
+
import { CommandOutput, addFormatOption, parseFormat, parseIntFlag } from '../utils/output.js';
|
|
8
12
|
import { DEFAULT_EXEC_TIMEOUT_MS, execCode, readToolResponse } from '../lib/exec.js';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
return [...previous, value];
|
|
12
|
-
}
|
|
13
|
+
import { classifyToolFailure } from '@baizor/gamedev-cli-core';
|
|
14
|
+
import { buildFailureMessage, ensureFailureExit } from './run-tool-builder.js';
|
|
13
15
|
function readCode(code, file) {
|
|
14
16
|
if (code !== undefined && file !== undefined)
|
|
15
17
|
throw new Error('Pass the code either as an argument or with --file, not both.');
|
|
@@ -23,8 +25,8 @@ function readCode(code, file) {
|
|
|
23
25
|
throw new Error(fromStdin ? 'No code received from stdin.' : `The file is empty: ${file}`);
|
|
24
26
|
return text;
|
|
25
27
|
}
|
|
26
|
-
export const execCommand = new Command('exec')
|
|
27
|
-
.description('Run C# in the Godot editor; starts a headless editor when none is open and keeps it warm')
|
|
28
|
+
export const execCommand = addFormatOption(new Command('exec')
|
|
29
|
+
.description('Run C# in the Godot editor; starts a headless editor when none is open and keeps it warm (Cloud mode with a sign-in: runs in the editor connected to ai-game.dev, starting none)')
|
|
28
30
|
.argument('[code]', 'C# snippet: statements, the last expression is the result')
|
|
29
31
|
.option('--path <path>', 'Godot project path (default: current directory)')
|
|
30
32
|
.option('-f, --file <file>', 'Read the code from a file ("-" for stdin)')
|
|
@@ -38,21 +40,23 @@ export const execCommand = new Command('exec')
|
|
|
38
40
|
.option('--editor-path <path>', 'Explicit path to the Godot editor executable')
|
|
39
41
|
.option('--raw', 'Print the raw tool response JSON')
|
|
40
42
|
.option('--url <url>', 'Local MCP server URL (default: the project\'s local port)')
|
|
41
|
-
.option('--token <token>', 'Bearer token (default: GODOT_MCP_TOKEN)')
|
|
43
|
+
.option('--token <token>', 'Bearer token (default: GODOT_MCP_TOKEN)'))
|
|
42
44
|
.action(async (codeArg, options) => {
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const
|
|
45
|
+
const output = new CommandOutput('exec', parseFormat(options.format));
|
|
46
|
+
const idleSeconds = parseIntFlag(options.idle, '--idle', true);
|
|
47
|
+
const readyTimeoutMs = parseIntFlag(options.readyTimeout, '--ready-timeout');
|
|
48
|
+
const timeoutMs = parseIntFlag(options.timeout, '--timeout');
|
|
46
49
|
let code;
|
|
47
50
|
try {
|
|
48
51
|
code = readCode(codeArg, options.file);
|
|
49
52
|
}
|
|
50
53
|
catch (err) {
|
|
51
|
-
|
|
52
|
-
process.exit(1);
|
|
54
|
+
return output.fail(ExitCode.Usage, 'USAGE', err instanceof Error ? err.message : String(err));
|
|
53
55
|
}
|
|
54
56
|
const projectPath = resolveAndValidateProjectPath(undefined, { path: options.path });
|
|
55
|
-
|
|
57
|
+
// Cloud mode: through ai-game.dev with the sign-in (no editor is started); never signed in: the local server.
|
|
58
|
+
const conn = await connectionForCommand(output, projectPath, { ...(options.url ? { url: options.url } : {}), ...(options.token ? { token: options.token } : {}) });
|
|
59
|
+
const spinner = options.raw || output.machine ? null : ui.startSpinner('Connecting...');
|
|
56
60
|
const result = await execCode({
|
|
57
61
|
projectPath,
|
|
58
62
|
code,
|
|
@@ -64,37 +68,48 @@ export const execCommand = new Command('exec')
|
|
|
64
68
|
readyTimeoutMs,
|
|
65
69
|
timeoutMs,
|
|
66
70
|
...resolveSessionConnection(options),
|
|
71
|
+
// The cloud, or a non-local --url / GODOT_MCP_HOST: talk to that server and start nothing (a session is local only).
|
|
72
|
+
...(conn.cloud || !isLocalhostUrl(conn.url) ? { remoteUrl: conn.url, token: conn.token } : {}),
|
|
73
|
+
...(conn.localFallback ? { url: conn.url } : {}),
|
|
67
74
|
...(options.editorPath ? { editorPath: options.editorPath } : {}),
|
|
68
75
|
onStatus: (message) => {
|
|
69
76
|
verbose(message);
|
|
70
77
|
if (spinner)
|
|
71
78
|
spinner.text = message;
|
|
79
|
+
else if (output.machine)
|
|
80
|
+
output.progress(message);
|
|
72
81
|
},
|
|
73
82
|
});
|
|
74
83
|
spinner?.stop();
|
|
75
84
|
if (result.kind === 'failure') {
|
|
76
|
-
|
|
85
|
+
const mapped = result.toolFailure ? classifyToolFailure(result.toolFailure) : ensureFailureExit({ reason: result.reason, sessionReason: result.sessionReason });
|
|
86
|
+
// Timeout, refused, reset: the same hints as run-tool.
|
|
87
|
+
const message = result.toolFailure && result.toolFailure.reason !== 'http-error'
|
|
88
|
+
? buildFailureMessage(result.toolFailure, { toolName: 'script-execute', endpoint: result.toolFailure.endpoint, raw: false, timeoutMs, errorNoun: 'tool' })
|
|
89
|
+
: result.message;
|
|
90
|
+
if (output.machine)
|
|
91
|
+
output.finish(mapped.exitCode, result.toolFailure?.data ?? null, [{ code: mapped.code, message, httpStatus: mapped.httpStatus }]);
|
|
92
|
+
if (options.raw && result.toolFailure?.data !== undefined)
|
|
77
93
|
process.stdout.write(JSON.stringify(result.toolFailure.data));
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const failure = result.toolFailure;
|
|
82
|
-
ui.error(buildFailureMessage(failure, { toolName: 'script-execute', endpoint: failure.endpoint, raw: false, timeoutMs, errorNoun: 'tool' }));
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
ui.error(result.message);
|
|
86
|
-
}
|
|
87
|
-
process.exit(1);
|
|
94
|
+
else
|
|
95
|
+
ui.error(message);
|
|
96
|
+
process.exit(mapped.exitCode);
|
|
88
97
|
}
|
|
89
98
|
verbose(`Ran on ${result.baseUrl} (editor: ${result.editor})`);
|
|
99
|
+
const response = readToolResponse(result.data);
|
|
100
|
+
if (output.machine) {
|
|
101
|
+
const data = { editor: result.editor, url: result.baseUrl, output: response.text, response: result.data };
|
|
102
|
+
if (!response.ok)
|
|
103
|
+
output.finish(ExitCode.CommandFailed, data, [{ code: 'TOOL_FAILED', message: response.text }]);
|
|
104
|
+
output.finish(ExitCode.Success, data);
|
|
105
|
+
}
|
|
90
106
|
if (options.raw) {
|
|
91
107
|
process.stdout.write(typeof result.data === 'string' ? result.data : JSON.stringify(result.data));
|
|
92
|
-
|
|
108
|
+
process.exit(response.ok ? ExitCode.Success : ExitCode.CommandFailed);
|
|
93
109
|
}
|
|
94
|
-
const response = readToolResponse(result.data);
|
|
95
110
|
if (!response.ok) {
|
|
96
111
|
ui.error(response.text);
|
|
97
|
-
process.exit(
|
|
112
|
+
process.exit(ExitCode.CommandFailed);
|
|
98
113
|
}
|
|
99
114
|
console.log(response.text);
|
|
100
115
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/commands/exec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,4BAA4B,EAAE,gCAAgC,EAAE,MAAM,0BAA0B,CAAC;AAC1G,OAAO,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AACjG,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/commands/exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import * as ui from '../utils/ui.js';
|
|
3
|
+
import { CommandOutput, addFormatOption, exitWithError, parseFormat } from '../utils/output.js';
|
|
4
|
+
import { ExitCode } from '../utils/exit-codes.js';
|
|
5
|
+
import { exportProject } from '../lib/export-project.js';
|
|
6
|
+
import { addHeadlessOptions, diagnosticErrors, finishHeadless, headlessProjectPath, headlessTimeout, printSteps, } from './headless-common.js';
|
|
7
|
+
export const exportCommand = addFormatOption(addHeadlessOptions(new Command('export')
|
|
8
|
+
.description('Export a preset headless; checks the export templates first and the output file afterwards')
|
|
9
|
+
.argument('<preset>', 'Export preset name (export_presets.cfg)')
|
|
10
|
+
.argument('<output>', 'Output file path')
|
|
11
|
+
.option('--debug', 'Debug export (--export-debug)')
|
|
12
|
+
.option('--pack', 'Export only the .pck/.zip pack (--export-pack); needs no export templates'), 1800000)).action(async (preset, outputPath, options) => {
|
|
13
|
+
const output = new CommandOutput('export', parseFormat(options.format));
|
|
14
|
+
if (options.debug && options.pack)
|
|
15
|
+
exitWithError(ExitCode.Usage, 'USAGE', 'Pass either --debug or --pack, not both.');
|
|
16
|
+
const mode = options.pack ? 'pack' : options.debug ? 'debug' : 'release';
|
|
17
|
+
const result = await exportProject({
|
|
18
|
+
projectPath: headlessProjectPath(undefined, options),
|
|
19
|
+
timeoutMs: headlessTimeout(options),
|
|
20
|
+
allowOpenProject: options.allowOpen === true,
|
|
21
|
+
preset,
|
|
22
|
+
output: outputPath,
|
|
23
|
+
mode,
|
|
24
|
+
...(options.editorPath ? { editorPath: options.editorPath } : {}),
|
|
25
|
+
onProgress: (m) => output.progress(m),
|
|
26
|
+
});
|
|
27
|
+
if (!output.machine) {
|
|
28
|
+
ui.heading('Godot Export');
|
|
29
|
+
ui.label('Preset', `${preset} (${mode})`);
|
|
30
|
+
if (result.output)
|
|
31
|
+
ui.label('Output', result.output);
|
|
32
|
+
printSteps(result.steps ?? []);
|
|
33
|
+
}
|
|
34
|
+
const data = result.projectPath ? {
|
|
35
|
+
projectPath: result.projectPath,
|
|
36
|
+
preset,
|
|
37
|
+
mode,
|
|
38
|
+
output: result.output,
|
|
39
|
+
sizeBytes: result.sizeBytes ?? null,
|
|
40
|
+
templatesDir: result.templatesDir ?? null,
|
|
41
|
+
steps: result.steps,
|
|
42
|
+
} : null;
|
|
43
|
+
finishHeadless(output, result, data, result.kind === 'failure' ? diagnosticErrors('EXPORT_FAILED', (result.diagnostics ?? []).slice(0, 20)) : [], result.sizeBytes !== undefined ? `Exported ${result.output} (${result.sizeBytes} bytes)` : 'Exported');
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { CommandOutput, type EnvelopeError, type ErrorCode } from '../utils/output.js';
|
|
3
|
+
import { type Diagnostic } from '../lib/godot-log.js';
|
|
4
|
+
import type { HeadlessFailureReason, HeadlessStep } from '../lib/headless.js';
|
|
5
|
+
export interface HeadlessCliOptions {
|
|
6
|
+
path?: string;
|
|
7
|
+
editorPath?: string;
|
|
8
|
+
timeout: string;
|
|
9
|
+
allowOpen?: boolean;
|
|
10
|
+
format?: string;
|
|
11
|
+
}
|
|
12
|
+
/** `[path]`, `--path`, `--editor-path`, `--timeout`, `--allow-open`. */
|
|
13
|
+
export declare function addHeadlessOptions(cmd: Command, defaultTimeoutMs: number, allowOpen?: boolean): Command;
|
|
14
|
+
/** The project path from `[path]` / `--path` / cwd (validated by the library). */
|
|
15
|
+
export declare function headlessProjectPath(positional: string | undefined, options: HeadlessCliOptions): string;
|
|
16
|
+
export declare function headlessTimeout(options: HeadlessCliOptions): number;
|
|
17
|
+
/** Diagnostics as the envelope's error entries, one per diagnostic; `code` picks each one's error code. */
|
|
18
|
+
export declare function diagnosticErrors(code: ErrorCode | ((d: Diagnostic) => ErrorCode), diagnostics: Diagnostic[]): EnvelopeError[];
|
|
19
|
+
export declare function printDiagnostics(diagnostics: Diagnostic[]): void;
|
|
20
|
+
export declare function printSteps(steps: HeadlessStep[]): void;
|
|
21
|
+
/**
|
|
22
|
+
* Finish a headless command from its library result: `failure` → the reason's exit code with `errors` (the summary
|
|
23
|
+
* first), success → 0. Text output (beyond the final line) is printed by the caller first.
|
|
24
|
+
*/
|
|
25
|
+
export declare function finishHeadless(output: CommandOutput<string>, result: {
|
|
26
|
+
kind: 'success' | 'failure';
|
|
27
|
+
reason?: HeadlessFailureReason;
|
|
28
|
+
message?: string;
|
|
29
|
+
}, data: unknown, extraErrors?: EnvelopeError[], successLine?: string): never;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Shared CLI plumbing of the headless commands (check, import, test, export, run-script).
|
|
2
|
+
import * as ui from '../utils/ui.js';
|
|
3
|
+
import { ExitCode } from '../utils/exit-codes.js';
|
|
4
|
+
import { parseIntFlag } from '../utils/output.js';
|
|
5
|
+
import { formatDiagnostic } from '../lib/godot-log.js';
|
|
6
|
+
const REASON_EXIT = {
|
|
7
|
+
'invalid-options': { exitCode: ExitCode.Usage, code: 'USAGE' },
|
|
8
|
+
'not-found': { exitCode: ExitCode.CommandFailed, code: 'NOT_FOUND' },
|
|
9
|
+
'project-open': { exitCode: ExitCode.CommandFailed, code: 'PROJECT_OPEN' },
|
|
10
|
+
timeout: { exitCode: ExitCode.Timeout, code: 'TIMEOUT' },
|
|
11
|
+
'script-errors': { exitCode: ExitCode.CommandFailed, code: 'SCRIPT_ERRORS' },
|
|
12
|
+
'compilation-failed': { exitCode: ExitCode.CommandFailed, code: 'COMPILATION_FAILED' },
|
|
13
|
+
'import-failed': { exitCode: ExitCode.CommandFailed, code: 'IMPORT_FAILED' },
|
|
14
|
+
'export-failed': { exitCode: ExitCode.CommandFailed, code: 'EXPORT_FAILED' },
|
|
15
|
+
'tests-failed': { exitCode: ExitCode.TestsFailed, code: 'TESTS_FAILED' },
|
|
16
|
+
'test-run-error': { exitCode: ExitCode.CommandFailed, code: 'TEST_RUN_ERROR' },
|
|
17
|
+
// Ctrl+C / SIGTERM: not a verdict on the project.
|
|
18
|
+
interrupted: { exitCode: ExitCode.Error, code: 'ERROR' },
|
|
19
|
+
};
|
|
20
|
+
/** `[path]`, `--path`, `--editor-path`, `--timeout`, `--allow-open`. */
|
|
21
|
+
export function addHeadlessOptions(cmd, defaultTimeoutMs, allowOpen = true) {
|
|
22
|
+
cmd
|
|
23
|
+
.option('--path <path>', 'Godot project path (default: current directory)')
|
|
24
|
+
.option('--editor-path <path>', 'Godot editor executable (default: GODOT_BIN, PATH, common install locations)')
|
|
25
|
+
.option('--timeout <ms>', 'Hard timeout for the whole command; the Godot process tree is killed when it expires', String(defaultTimeoutMs));
|
|
26
|
+
if (allowOpen)
|
|
27
|
+
cmd.option('--allow-open', 'Run even when an editor has the project open (it may fight that editor over .godot/)');
|
|
28
|
+
return cmd;
|
|
29
|
+
}
|
|
30
|
+
/** The project path from `[path]` / `--path` / cwd (validated by the library). */
|
|
31
|
+
export function headlessProjectPath(positional, options) {
|
|
32
|
+
return positional ?? options.path ?? process.cwd();
|
|
33
|
+
}
|
|
34
|
+
export function headlessTimeout(options) {
|
|
35
|
+
return parseIntFlag(options.timeout, '--timeout');
|
|
36
|
+
}
|
|
37
|
+
/** Diagnostics as the envelope's error entries, one per diagnostic; `code` picks each one's error code. */
|
|
38
|
+
export function diagnosticErrors(code, diagnostics) {
|
|
39
|
+
return diagnostics.map((d) => ({ code: typeof code === 'function' ? code(d) : code, message: formatDiagnostic(d) }));
|
|
40
|
+
}
|
|
41
|
+
export function printDiagnostics(diagnostics) {
|
|
42
|
+
for (const d of diagnostics) {
|
|
43
|
+
if (d.severity === 'error')
|
|
44
|
+
ui.error(formatDiagnostic(d));
|
|
45
|
+
else
|
|
46
|
+
ui.warn(formatDiagnostic(d));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function printSteps(steps) {
|
|
50
|
+
for (const s of steps) {
|
|
51
|
+
ui.label(s.name, `${s.timedOut ? 'timed out' : `exit ${s.exitCode}`} in ${(s.durationMs / 1000).toFixed(1)}s`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Finish a headless command from its library result: `failure` → the reason's exit code with `errors` (the summary
|
|
56
|
+
* first), success → 0. Text output (beyond the final line) is printed by the caller first.
|
|
57
|
+
*/
|
|
58
|
+
export function finishHeadless(output, result, data, extraErrors = [], successLine) {
|
|
59
|
+
if (result.kind === 'success') {
|
|
60
|
+
if (!output.machine && successLine)
|
|
61
|
+
ui.success(successLine);
|
|
62
|
+
return output.finish(ExitCode.Success, data);
|
|
63
|
+
}
|
|
64
|
+
const mapped = REASON_EXIT[result.reason];
|
|
65
|
+
if (!output.machine)
|
|
66
|
+
ui.error(result.message ?? 'failed');
|
|
67
|
+
return output.finish(mapped.exitCode, data, [{ code: mapped.code, message: result.message ?? 'failed' }, ...extraErrors]);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=headless-common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headless-common.js","sourceRoot":"","sources":["../../src/commands/headless-common.ts"],"names":[],"mappings":"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"}
|