gdharness 0.12.1 → 0.12.3
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/build/cli.js +50 -5
- package/build/index.js +10 -2
- package/package.json +1 -1
package/build/cli.js
CHANGED
|
@@ -15714,7 +15714,7 @@ var init_tool_definitions = __esm(() => {
|
|
|
15714
15714
|
},
|
|
15715
15715
|
{
|
|
15716
15716
|
name: "editor_output",
|
|
15717
|
-
description: "What the project started by editor_run has printed, as entries with a severity: the errors and warnings the engine reported, each with where it happened, and everything else as info. Answers with the counts and the verdict as well as the entries. A run that has quit still answers here, with running false and its exit code, until the next one starts.",
|
|
15717
|
+
description: "What the project started by editor_run has printed, as entries with a severity: the errors and warnings the engine reported, each with where it happened, and everything else as info. Answers with the counts and the verdict as well as the entries. A run that has quit still answers here, with running false and its exit code, until the next one starts. A run this server started also answers with transcript, the file both its streams are written to: uncapped, written while the run is going, and the thing to read or tail for a long run rather than the engine's own log, which every engine start rotates away.",
|
|
15718
15718
|
parameters: {
|
|
15719
15719
|
severity: {
|
|
15720
15720
|
type: "string",
|
|
@@ -38002,6 +38002,13 @@ class GodotServer {
|
|
|
38002
38002
|
limit: readPositiveNumber(args, "limit") ?? 200
|
|
38003
38003
|
});
|
|
38004
38004
|
const halt = run.throughEditor ? this.dapClient?.whereItStopped() ?? null : null;
|
|
38005
|
+
const notes = [];
|
|
38006
|
+
if (run.endedUnwatched === true) {
|
|
38007
|
+
notes.push("This run outlived the server that started it and is over now, so its exit code was never collected. Everything it printed is below, read back from its transcript.");
|
|
38008
|
+
}
|
|
38009
|
+
if (run.transcript !== null && selected.omitted > 0) {
|
|
38010
|
+
notes.push(`Everything this run has printed is in ${run.transcript}, uncapped and still being written.`);
|
|
38011
|
+
}
|
|
38005
38012
|
return this.jsonTextResponse({
|
|
38006
38013
|
running: stillRunning(run),
|
|
38007
38014
|
exitCode: run.exitCode,
|
|
@@ -38013,7 +38020,8 @@ class GodotServer {
|
|
|
38013
38020
|
heldAt: halt,
|
|
38014
38021
|
endedUnwatched: run.endedUnwatched === true ? true : undefined,
|
|
38015
38022
|
project: !run.throughEditor && run.process === null ? run.projectPath ?? undefined : undefined,
|
|
38016
|
-
|
|
38023
|
+
transcript: run.transcript ?? undefined,
|
|
38024
|
+
note: notes.length > 0 ? notes.join(" ") : undefined,
|
|
38017
38025
|
omitted: selected.omitted,
|
|
38018
38026
|
entries: selected.entries
|
|
38019
38027
|
});
|
|
@@ -39483,6 +39491,23 @@ function autoloadIsOurs(named) {
|
|
|
39483
39491
|
async function setRuntime(engine, projectPath, on) {
|
|
39484
39492
|
return on ? await runOperation2(engine, "add_autoload", { name: RUNTIME_AUTOLOAD.name, path: `res://${RUNTIME_AUTOLOAD.path}`, enabled: true }, projectPath) : await runOperation2(engine, "remove_autoload", { name: RUNTIME_AUTOLOAD.name }, projectPath);
|
|
39485
39493
|
}
|
|
39494
|
+
function loaderAmong(projectPath, named) {
|
|
39495
|
+
let byName = null;
|
|
39496
|
+
for (const [entry, path] of named) {
|
|
39497
|
+
if (entry === RUNTIME_AUTOLOAD.name || path === RUNTIME_AUTOLOAD.path) {
|
|
39498
|
+
continue;
|
|
39499
|
+
}
|
|
39500
|
+
let source = "";
|
|
39501
|
+
try {
|
|
39502
|
+
source = readFileSync7(join8(projectPath, path), "utf8");
|
|
39503
|
+
} catch {}
|
|
39504
|
+
if (source.includes(RUNTIME_AUTOLOAD.path)) {
|
|
39505
|
+
return { name: entry, path };
|
|
39506
|
+
}
|
|
39507
|
+
byName ??= path.toLowerCase().includes("gdharness") ? { name: entry, path } : null;
|
|
39508
|
+
}
|
|
39509
|
+
return byName;
|
|
39510
|
+
}
|
|
39486
39511
|
function autoloadPaths(settings) {
|
|
39487
39512
|
const named = new Map;
|
|
39488
39513
|
for (const [name, value] of Object.entries(settings["autoload"] ?? {})) {
|
|
@@ -39537,9 +39562,10 @@ function inspectProject(projectPath) {
|
|
|
39537
39562
|
}
|
|
39538
39563
|
const autoload = settings["autoload"];
|
|
39539
39564
|
const registered = autoload === undefined ? undefined : readString(autoload, RUNTIME_AUTOLOAD.name);
|
|
39540
|
-
const runtimeAutoload = typeof registered === "string";
|
|
39541
39565
|
const runtimeAutoloadPath = typeof registered === "string" ? registered.replace(/^\*/, "") : null;
|
|
39542
39566
|
const named = autoloadPaths(settings);
|
|
39567
|
+
const runtimeLoaderAutoload = loaderAmong(projectPath, named);
|
|
39568
|
+
const runtimeAutoload = runtimeAutoloadPath !== null || runtimeLoaderAutoload !== null;
|
|
39543
39569
|
const tracked = trackedByGit(projectPath, [...named.values()]);
|
|
39544
39570
|
for (const [name, path] of named) {
|
|
39545
39571
|
if (tracked !== null && !tracked.has(path) && existsSync7(join8(projectPath, path))) {
|
|
@@ -39559,6 +39585,7 @@ function inspectProject(projectPath) {
|
|
|
39559
39585
|
pluginsEnabled,
|
|
39560
39586
|
runtimeAutoload,
|
|
39561
39587
|
runtimeAutoloadPath,
|
|
39588
|
+
runtimeLoaderAutoload,
|
|
39562
39589
|
staleClasses,
|
|
39563
39590
|
classCacheExists: cached !== null,
|
|
39564
39591
|
problems
|
|
@@ -39846,7 +39873,13 @@ function said2(outcome, what) {
|
|
|
39846
39873
|
}
|
|
39847
39874
|
}
|
|
39848
39875
|
async function registerRuntime(godot, projectPath) {
|
|
39849
|
-
const
|
|
39876
|
+
const report = inspectProject(projectPath);
|
|
39877
|
+
const named = report.runtimeAutoloadPath;
|
|
39878
|
+
const loader = report.runtimeLoaderAutoload;
|
|
39879
|
+
if (named === null && loader !== null) {
|
|
39880
|
+
console.log(`${loader.name} autoload already names res://${loader.path}, which is this project bringing the runtime up its own way, so ${RUNTIME_AUTOLOAD.name} was not added: a second entry would come up beside it without whatever that file refuses. If it is not a loader, add ${RUNTIME_AUTOLOAD.name} yourself.`);
|
|
39881
|
+
return;
|
|
39882
|
+
}
|
|
39850
39883
|
if (autoloadIsOurs(named)) {
|
|
39851
39884
|
said2(await setRuntime(godot, projectPath, true), "registering the runtime autoload");
|
|
39852
39885
|
console.log(`${RUNTIME_AUTOLOAD.name} autoload registered at res://${RUNTIME_AUTOLOAD.path}`);
|
|
@@ -40092,7 +40125,7 @@ function doctorReport(projectPath) {
|
|
|
40092
40125
|
console.log(`addons/${addon.name}: ${addon.installed ? `installed, ${addon.version ?? "unknown version"}${addon.current ? "" : " (not this version)"}` : "missing"}`);
|
|
40093
40126
|
}
|
|
40094
40127
|
console.log(`editor plugins enabled: ${report.pluginsEnabled.join(", ") || "none"}`);
|
|
40095
|
-
console.log(`runtime autoload: ${report.runtimeAutoload ? "registered" : "not registered"}`);
|
|
40128
|
+
console.log(`runtime autoload: ${report.runtimeLoaderAutoload === null ? report.runtimeAutoload ? "registered" : "not registered" : `registered through res://${report.runtimeLoaderAutoload.path}, as ${report.runtimeLoaderAutoload.name}`}`);
|
|
40096
40129
|
console.log(report.classCacheExists ? `class cache: ${report.staleClasses.length === 0 ? "current" : `stale for ${report.staleClasses.join(", ")}`}` : "class cache: missing");
|
|
40097
40130
|
for (const problem of report.problems) {
|
|
40098
40131
|
console.log(`problem: ${problem}`);
|
|
@@ -40113,8 +40146,20 @@ async function runtime3() {
|
|
|
40113
40146
|
await registerRuntime(godot, projectPath);
|
|
40114
40147
|
return;
|
|
40115
40148
|
}
|
|
40149
|
+
const before = inspectProject(projectPath);
|
|
40150
|
+
const loader = before.runtimeLoaderAutoload;
|
|
40151
|
+
if (before.runtimeAutoloadPath === null) {
|
|
40152
|
+
console.log(`${RUNTIME_AUTOLOAD.name} autoload is not registered, so there was nothing to remove`);
|
|
40153
|
+
if (loader !== null) {
|
|
40154
|
+
console.log(` ${loader.name} names res://${loader.path}, which brings the runtime up its own way. That line is this project's, not this tool's, so nothing here has changed it: whatever that file decides about a release build still decides it.`);
|
|
40155
|
+
}
|
|
40156
|
+
return;
|
|
40157
|
+
}
|
|
40116
40158
|
said2(await setRuntime(godot, projectPath, false), "turning the runtime off");
|
|
40117
40159
|
console.log(`${RUNTIME_AUTOLOAD.name} autoload removed`);
|
|
40160
|
+
if (loader !== null) {
|
|
40161
|
+
console.log(` ${loader.name} still names res://${loader.path}, which brings the runtime up its own way: this command has not touched it, so whatever that file decides about a release build still decides it`);
|
|
40162
|
+
}
|
|
40118
40163
|
}
|
|
40119
40164
|
async function classes() {
|
|
40120
40165
|
const projectPath = projectArgument(1);
|
package/build/index.js
CHANGED
|
@@ -28518,7 +28518,7 @@ var TOOL_SPECS = [
|
|
|
28518
28518
|
},
|
|
28519
28519
|
{
|
|
28520
28520
|
name: "editor_output",
|
|
28521
|
-
description: "What the project started by editor_run has printed, as entries with a severity: the errors and warnings the engine reported, each with where it happened, and everything else as info. Answers with the counts and the verdict as well as the entries. A run that has quit still answers here, with running false and its exit code, until the next one starts.",
|
|
28521
|
+
description: "What the project started by editor_run has printed, as entries with a severity: the errors and warnings the engine reported, each with where it happened, and everything else as info. Answers with the counts and the verdict as well as the entries. A run that has quit still answers here, with running false and its exit code, until the next one starts. A run this server started also answers with transcript, the file both its streams are written to: uncapped, written while the run is going, and the thing to read or tail for a long run rather than the engine's own log, which every engine start rotates away.",
|
|
28522
28522
|
parameters: {
|
|
28523
28523
|
severity: {
|
|
28524
28524
|
type: "string",
|
|
@@ -30784,6 +30784,13 @@ class GodotServer {
|
|
|
30784
30784
|
limit: readPositiveNumber(args, "limit") ?? 200
|
|
30785
30785
|
});
|
|
30786
30786
|
const halt = run.throughEditor ? this.dapClient?.whereItStopped() ?? null : null;
|
|
30787
|
+
const notes = [];
|
|
30788
|
+
if (run.endedUnwatched === true) {
|
|
30789
|
+
notes.push("This run outlived the server that started it and is over now, so its exit code was never collected. Everything it printed is below, read back from its transcript.");
|
|
30790
|
+
}
|
|
30791
|
+
if (run.transcript !== null && selected.omitted > 0) {
|
|
30792
|
+
notes.push(`Everything this run has printed is in ${run.transcript}, uncapped and still being written.`);
|
|
30793
|
+
}
|
|
30787
30794
|
return this.jsonTextResponse({
|
|
30788
30795
|
running: stillRunning(run),
|
|
30789
30796
|
exitCode: run.exitCode,
|
|
@@ -30795,7 +30802,8 @@ class GodotServer {
|
|
|
30795
30802
|
heldAt: halt,
|
|
30796
30803
|
endedUnwatched: run.endedUnwatched === true ? true : undefined,
|
|
30797
30804
|
project: !run.throughEditor && run.process === null ? run.projectPath ?? undefined : undefined,
|
|
30798
|
-
|
|
30805
|
+
transcript: run.transcript ?? undefined,
|
|
30806
|
+
note: notes.length > 0 ? notes.join(" ") : undefined,
|
|
30799
30807
|
omitted: selected.omitted,
|
|
30800
30808
|
entries: selected.entries
|
|
30801
30809
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdharness",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.3",
|
|
4
4
|
"mcpName": "io.github.Aureliolo/gdharness",
|
|
5
5
|
"description": "A harness for driving a Godot 4 project from an agent: editor addons, a runtime bridge into the running game, an MCP server in front of them, and a CLI that installs and diagnoses the Godot side.",
|
|
6
6
|
"type": "module",
|