gdharness 1.0.19 → 1.0.20
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 +25 -15
- package/build/index.js +25 -15
- package/package.json +1 -1
package/build/cli.js
CHANGED
|
@@ -38110,6 +38110,9 @@ function stillRunning(run) {
|
|
|
38110
38110
|
if (run?.exitCode !== null || run.endedUnwatched === true) {
|
|
38111
38111
|
return false;
|
|
38112
38112
|
}
|
|
38113
|
+
if (typeof run.endedHere === "string") {
|
|
38114
|
+
return false;
|
|
38115
|
+
}
|
|
38113
38116
|
if (!run.throughEditor && run.process === null && run.pid !== null) {
|
|
38114
38117
|
return alive(run.pid);
|
|
38115
38118
|
}
|
|
@@ -38122,6 +38125,9 @@ function runIsUp(run, editorSays, now = Date.now()) {
|
|
|
38122
38125
|
if (run?.throughEditor !== true) {
|
|
38123
38126
|
return stillRunning(run);
|
|
38124
38127
|
}
|
|
38128
|
+
if (typeof run.endedHere === "string") {
|
|
38129
|
+
return false;
|
|
38130
|
+
}
|
|
38125
38131
|
if (run.announcedPid !== undefined && !alive(run.announcedPid)) {
|
|
38126
38132
|
return false;
|
|
38127
38133
|
}
|
|
@@ -38135,9 +38141,12 @@ function noCodeWillCome(run) {
|
|
|
38135
38141
|
}
|
|
38136
38142
|
function endedWithoutACode(run) {
|
|
38137
38143
|
if (!run.throughEditor) {
|
|
38138
|
-
return "This run was started by another server, the one this server replaced or one running beside it, and it ended with nothing here waiting on it, so its exit code was never collected. Everything it printed is below, read back from its transcript.";
|
|
38144
|
+
return run.endedHere ? "This run was started by another server, so nothing here held it and its exit code was never collected. Everything it printed is below, read back from its transcript." : "This run was started by another server, the one this server replaced or one running beside it, and it ended with nothing here waiting on it, so its exit code was never collected. Everything it printed is below, read back from its transcript.";
|
|
38139
38145
|
}
|
|
38140
38146
|
const kept = "A game the editor plays is the editor's own child, so its exit code stays with the editor and none was collected here.";
|
|
38147
|
+
if (run.endedHere) {
|
|
38148
|
+
return `${kept} What it printed is below.`;
|
|
38149
|
+
}
|
|
38141
38150
|
if (!run.announced && run.couldAnnounce) {
|
|
38142
38151
|
return `The editor stopped playing this run before its game announced a runtime, so the game ended while it was starting or was closed in the editor. ${kept} What it printed is below, and editor_output with op "editor" has what the editor said about it.`;
|
|
38143
38152
|
}
|
|
@@ -40140,7 +40149,7 @@ class GodotServer {
|
|
|
40140
40149
|
if (before !== null && await this.runStillGoing(before)) {
|
|
40141
40150
|
this.logDebug("Ending the running game before starting another");
|
|
40142
40151
|
ended = { pid: before.pid ?? this.announcedPidOf(before) ?? null };
|
|
40143
|
-
await this.endActiveGame("editor_run start, which ends the run that was going before it starts another");
|
|
40152
|
+
await this.endActiveGame("editor_run start, which ends the run that was going before it starts another", true);
|
|
40144
40153
|
}
|
|
40145
40154
|
const alreadyPlaying = new Set(discoverRuntimes().map((endpoint) => endpoint.pid));
|
|
40146
40155
|
const wereHereFirst = this.everyRuntimeOfOurs();
|
|
@@ -40381,12 +40390,11 @@ class GodotServer {
|
|
|
40381
40390
|
game.brokeOn = halt.text;
|
|
40382
40391
|
game.log.record("error", halt.text);
|
|
40383
40392
|
}
|
|
40384
|
-
async endActiveGame(reason) {
|
|
40393
|
+
async endActiveGame(reason, going) {
|
|
40385
40394
|
const running = this.activeProcess;
|
|
40386
|
-
this.activeProcess = null;
|
|
40387
40395
|
const recorded = running?.process === null ? readRunRecord() : null;
|
|
40388
40396
|
clearRunRecord((record) => this.couldBeOurs(record.projectPath));
|
|
40389
|
-
if (!running) {
|
|
40397
|
+
if (!running || !going) {
|
|
40390
40398
|
return;
|
|
40391
40399
|
}
|
|
40392
40400
|
running.endedHere = reason;
|
|
@@ -40550,7 +40558,8 @@ class GodotServer {
|
|
|
40550
40558
|
return;
|
|
40551
40559
|
}
|
|
40552
40560
|
const going = this.activeProcess;
|
|
40553
|
-
|
|
40561
|
+
const givesWay = going !== null && !stillRunning(going) && typeof going.endedHere === "string";
|
|
40562
|
+
if (going !== null && !givesWay) {
|
|
40554
40563
|
if (going.throughEditor && going.consoleLost === true && (await this.editorPlayingState())?.playing) {
|
|
40555
40564
|
try {
|
|
40556
40565
|
await this.dap().connect();
|
|
@@ -40957,11 +40966,17 @@ class GodotServer {
|
|
|
40957
40966
|
if (waitedMs !== undefined) {
|
|
40958
40967
|
notes.push(`The wait of ${waitedMs}ms ran out and the run is still going, so this is what it had printed by then rather than everything it will print. editor_run wait again to keep waiting.`);
|
|
40959
40968
|
}
|
|
40969
|
+
if (typeof run.endedHere === "string") {
|
|
40970
|
+
notes.push(`This run was ended here, by ${run.endedHere}.`);
|
|
40971
|
+
} else if (!stillRunning(run) && !run.throughEditor && run.exitCode !== null) {
|
|
40972
|
+
notes.push(run.exitCode === 0 ? "This run quit on its own, cleanly: exit code 0." : "Nothing here ended this run: it stopped on its own or something outside this server stopped it.");
|
|
40973
|
+
}
|
|
40960
40974
|
if (run.endedUnwatched === true) {
|
|
40961
40975
|
notes.push(endedWithoutACode({
|
|
40962
40976
|
throughEditor: run.throughEditor,
|
|
40963
40977
|
announced: announced !== undefined || run.announcedPid !== undefined,
|
|
40964
|
-
couldAnnounce: run.projectPath !== null && existsSync15(join23(run.projectPath, RUNTIME_AUTOLOAD2.path))
|
|
40978
|
+
couldAnnounce: run.projectPath !== null && existsSync15(join23(run.projectPath, RUNTIME_AUTOLOAD2.path)),
|
|
40979
|
+
endedHere: typeof run.endedHere === "string"
|
|
40965
40980
|
}));
|
|
40966
40981
|
}
|
|
40967
40982
|
if (run.pickedUpPlaying === true) {
|
|
@@ -40971,11 +40986,6 @@ class GodotServer {
|
|
|
40971
40986
|
const back = this.dapClient?.isConnected() === true;
|
|
40972
40987
|
notes.push(`The debug adapter this run's console arrives over went away while the run was going, so what is below has a hole in it and the counts are of what was heard rather than of what was printed. ${back ? "It is connected again, and the line marking where is in the log." : "It is still gone, so nothing further will arrive here."} The project's own user://logs/godot.log has the rest, and "no entries" here means "not heard" rather than a quiet run.`);
|
|
40973
40988
|
}
|
|
40974
|
-
if (typeof run.endedHere === "string") {
|
|
40975
|
-
notes.push(`This run was ended here, by ${run.endedHere}.`);
|
|
40976
|
-
} else if (!stillRunning(run) && !run.throughEditor && run.exitCode !== null) {
|
|
40977
|
-
notes.push(run.exitCode === 0 ? "This run quit on its own, cleanly: exit code 0." : "Nothing here ended this run: it stopped on its own or something outside this server stopped it.");
|
|
40978
|
-
}
|
|
40979
40989
|
if (run.transcript !== null && selected.omitted > 0) {
|
|
40980
40990
|
notes.push(`Everything this run has printed is in ${run.transcript}, uncapped and still being written. Read it for output, not for whether the run is alive: a transcript that stops growing is a run between prints. running above is asked of the operating system while there is a process to ask about, and for an editor-played run that announced no runtime it is the editor's answer instead, which can lag after the game has gone.`);
|
|
40981
40991
|
}
|
|
@@ -41014,7 +41024,7 @@ class GodotServer {
|
|
|
41014
41024
|
const endedPid = stopped.pid ?? announcedPid;
|
|
41015
41025
|
const children = readBoolean(args, "andChildren") === true && wasRunning ? await this.whatTheRunStarted(stopped) : null;
|
|
41016
41026
|
this.logDebug("Stopping the running game");
|
|
41017
|
-
await this.endActiveGame("editor_run stop");
|
|
41027
|
+
await this.endActiveGame("editor_run stop", wasRunning);
|
|
41018
41028
|
const ended = children === null ? null : endChildrenAmong(children);
|
|
41019
41029
|
if (wasRunning) {
|
|
41020
41030
|
for (const pid of new Set([endedPid, announcedPid])) {
|
|
@@ -41033,12 +41043,12 @@ class GodotServer {
|
|
|
41033
41043
|
childrenLeft: ended.left.length === 0 ? undefined : ended.left,
|
|
41034
41044
|
childrenUnknown: ended.unknown === false ? undefined : true
|
|
41035
41045
|
},
|
|
41036
|
-
exitedBeforeStop:
|
|
41046
|
+
exitedBeforeStop: !wasRunning,
|
|
41037
41047
|
exitCode: stopped.exitCode,
|
|
41038
41048
|
errors: stopped.log.count("error"),
|
|
41039
41049
|
warnings: stopped.log.count("warning"),
|
|
41040
41050
|
clean: stopped.log.count("error") === 0,
|
|
41041
|
-
note: !wasRunning ? "This run was over before the stop, so nothing was ended here: editor_output has what it printed and how it ended. Anything that game started for itself, with OS.create_process or otherwise, is a separate process and may still be running." : `${stopped.throughEditor ? "The editor was asked to stop the scene it is playing." : "The process named under endedPid was ended."} ${aboutTheChildren(ended, stopped.throughEditor)}`,
|
|
41051
|
+
note: !wasRunning ? "This run was over before the stop, so nothing was ended here: editor_output has what it printed and how it ended. Anything that game started for itself, with OS.create_process or otherwise, is a separate process and may still be running." : `${stopped.throughEditor ? endedPid === null ? "The editor was asked to stop the scene it is playing. Its game had not announced a runtime, so no process was named under endedPid, and its exit code stays with the editor." : "The editor was asked to stop the scene it is playing." : "The process named under endedPid was ended."} ${aboutTheChildren(ended, stopped.throughEditor)}`,
|
|
41042
41052
|
entries: forAnswer(stopped.log.select({ severity: "warning", sinceLastCall: false, limit: 200 }).entries)
|
|
41043
41053
|
});
|
|
41044
41054
|
}
|
package/build/index.js
CHANGED
|
@@ -30797,6 +30797,9 @@ function stillRunning(run) {
|
|
|
30797
30797
|
if (run?.exitCode !== null || run.endedUnwatched === true) {
|
|
30798
30798
|
return false;
|
|
30799
30799
|
}
|
|
30800
|
+
if (typeof run.endedHere === "string") {
|
|
30801
|
+
return false;
|
|
30802
|
+
}
|
|
30800
30803
|
if (!run.throughEditor && run.process === null && run.pid !== null) {
|
|
30801
30804
|
return alive(run.pid);
|
|
30802
30805
|
}
|
|
@@ -30810,6 +30813,9 @@ function runIsUp(run, editorSays, now = Date.now()) {
|
|
|
30810
30813
|
if (run?.throughEditor !== true) {
|
|
30811
30814
|
return stillRunning(run);
|
|
30812
30815
|
}
|
|
30816
|
+
if (typeof run.endedHere === "string") {
|
|
30817
|
+
return false;
|
|
30818
|
+
}
|
|
30813
30819
|
if (run.announcedPid !== undefined && !alive(run.announcedPid)) {
|
|
30814
30820
|
return false;
|
|
30815
30821
|
}
|
|
@@ -30823,9 +30829,12 @@ function noCodeWillCome(run) {
|
|
|
30823
30829
|
}
|
|
30824
30830
|
function endedWithoutACode(run) {
|
|
30825
30831
|
if (!run.throughEditor) {
|
|
30826
|
-
return "This run was started by another server, the one this server replaced or one running beside it, and it ended with nothing here waiting on it, so its exit code was never collected. Everything it printed is below, read back from its transcript.";
|
|
30832
|
+
return run.endedHere ? "This run was started by another server, so nothing here held it and its exit code was never collected. Everything it printed is below, read back from its transcript." : "This run was started by another server, the one this server replaced or one running beside it, and it ended with nothing here waiting on it, so its exit code was never collected. Everything it printed is below, read back from its transcript.";
|
|
30827
30833
|
}
|
|
30828
30834
|
const kept = "A game the editor plays is the editor's own child, so its exit code stays with the editor and none was collected here.";
|
|
30835
|
+
if (run.endedHere) {
|
|
30836
|
+
return `${kept} What it printed is below.`;
|
|
30837
|
+
}
|
|
30829
30838
|
if (!run.announced && run.couldAnnounce) {
|
|
30830
30839
|
return `The editor stopped playing this run before its game announced a runtime, so the game ended while it was starting or was closed in the editor. ${kept} What it printed is below, and editor_output with op "editor" has what the editor said about it.`;
|
|
30831
30840
|
}
|
|
@@ -32873,7 +32882,7 @@ class GodotServer {
|
|
|
32873
32882
|
if (before !== null && await this.runStillGoing(before)) {
|
|
32874
32883
|
this.logDebug("Ending the running game before starting another");
|
|
32875
32884
|
ended = { pid: before.pid ?? this.announcedPidOf(before) ?? null };
|
|
32876
|
-
await this.endActiveGame("editor_run start, which ends the run that was going before it starts another");
|
|
32885
|
+
await this.endActiveGame("editor_run start, which ends the run that was going before it starts another", true);
|
|
32877
32886
|
}
|
|
32878
32887
|
const alreadyPlaying = new Set(discoverRuntimes().map((endpoint) => endpoint.pid));
|
|
32879
32888
|
const wereHereFirst = this.everyRuntimeOfOurs();
|
|
@@ -33114,12 +33123,11 @@ class GodotServer {
|
|
|
33114
33123
|
game.brokeOn = halt.text;
|
|
33115
33124
|
game.log.record("error", halt.text);
|
|
33116
33125
|
}
|
|
33117
|
-
async endActiveGame(reason) {
|
|
33126
|
+
async endActiveGame(reason, going) {
|
|
33118
33127
|
const running = this.activeProcess;
|
|
33119
|
-
this.activeProcess = null;
|
|
33120
33128
|
const recorded = running?.process === null ? readRunRecord() : null;
|
|
33121
33129
|
clearRunRecord((record) => this.couldBeOurs(record.projectPath));
|
|
33122
|
-
if (!running) {
|
|
33130
|
+
if (!running || !going) {
|
|
33123
33131
|
return;
|
|
33124
33132
|
}
|
|
33125
33133
|
running.endedHere = reason;
|
|
@@ -33283,7 +33291,8 @@ class GodotServer {
|
|
|
33283
33291
|
return;
|
|
33284
33292
|
}
|
|
33285
33293
|
const going = this.activeProcess;
|
|
33286
|
-
|
|
33294
|
+
const givesWay = going !== null && !stillRunning(going) && typeof going.endedHere === "string";
|
|
33295
|
+
if (going !== null && !givesWay) {
|
|
33287
33296
|
if (going.throughEditor && going.consoleLost === true && (await this.editorPlayingState())?.playing) {
|
|
33288
33297
|
try {
|
|
33289
33298
|
await this.dap().connect();
|
|
@@ -33690,11 +33699,17 @@ class GodotServer {
|
|
|
33690
33699
|
if (waitedMs !== undefined) {
|
|
33691
33700
|
notes.push(`The wait of ${waitedMs}ms ran out and the run is still going, so this is what it had printed by then rather than everything it will print. editor_run wait again to keep waiting.`);
|
|
33692
33701
|
}
|
|
33702
|
+
if (typeof run.endedHere === "string") {
|
|
33703
|
+
notes.push(`This run was ended here, by ${run.endedHere}.`);
|
|
33704
|
+
} else if (!stillRunning(run) && !run.throughEditor && run.exitCode !== null) {
|
|
33705
|
+
notes.push(run.exitCode === 0 ? "This run quit on its own, cleanly: exit code 0." : "Nothing here ended this run: it stopped on its own or something outside this server stopped it.");
|
|
33706
|
+
}
|
|
33693
33707
|
if (run.endedUnwatched === true) {
|
|
33694
33708
|
notes.push(endedWithoutACode({
|
|
33695
33709
|
throughEditor: run.throughEditor,
|
|
33696
33710
|
announced: announced !== undefined || run.announcedPid !== undefined,
|
|
33697
|
-
couldAnnounce: run.projectPath !== null && existsSync10(join16(run.projectPath, RUNTIME_AUTOLOAD.path))
|
|
33711
|
+
couldAnnounce: run.projectPath !== null && existsSync10(join16(run.projectPath, RUNTIME_AUTOLOAD.path)),
|
|
33712
|
+
endedHere: typeof run.endedHere === "string"
|
|
33698
33713
|
}));
|
|
33699
33714
|
}
|
|
33700
33715
|
if (run.pickedUpPlaying === true) {
|
|
@@ -33704,11 +33719,6 @@ class GodotServer {
|
|
|
33704
33719
|
const back = this.dapClient?.isConnected() === true;
|
|
33705
33720
|
notes.push(`The debug adapter this run's console arrives over went away while the run was going, so what is below has a hole in it and the counts are of what was heard rather than of what was printed. ${back ? "It is connected again, and the line marking where is in the log." : "It is still gone, so nothing further will arrive here."} The project's own user://logs/godot.log has the rest, and "no entries" here means "not heard" rather than a quiet run.`);
|
|
33706
33721
|
}
|
|
33707
|
-
if (typeof run.endedHere === "string") {
|
|
33708
|
-
notes.push(`This run was ended here, by ${run.endedHere}.`);
|
|
33709
|
-
} else if (!stillRunning(run) && !run.throughEditor && run.exitCode !== null) {
|
|
33710
|
-
notes.push(run.exitCode === 0 ? "This run quit on its own, cleanly: exit code 0." : "Nothing here ended this run: it stopped on its own or something outside this server stopped it.");
|
|
33711
|
-
}
|
|
33712
33722
|
if (run.transcript !== null && selected.omitted > 0) {
|
|
33713
33723
|
notes.push(`Everything this run has printed is in ${run.transcript}, uncapped and still being written. Read it for output, not for whether the run is alive: a transcript that stops growing is a run between prints. running above is asked of the operating system while there is a process to ask about, and for an editor-played run that announced no runtime it is the editor's answer instead, which can lag after the game has gone.`);
|
|
33714
33724
|
}
|
|
@@ -33747,7 +33757,7 @@ class GodotServer {
|
|
|
33747
33757
|
const endedPid = stopped.pid ?? announcedPid;
|
|
33748
33758
|
const children = readBoolean(args, "andChildren") === true && wasRunning ? await this.whatTheRunStarted(stopped) : null;
|
|
33749
33759
|
this.logDebug("Stopping the running game");
|
|
33750
|
-
await this.endActiveGame("editor_run stop");
|
|
33760
|
+
await this.endActiveGame("editor_run stop", wasRunning);
|
|
33751
33761
|
const ended = children === null ? null : endChildrenAmong(children);
|
|
33752
33762
|
if (wasRunning) {
|
|
33753
33763
|
for (const pid of new Set([endedPid, announcedPid])) {
|
|
@@ -33766,12 +33776,12 @@ class GodotServer {
|
|
|
33766
33776
|
childrenLeft: ended.left.length === 0 ? undefined : ended.left,
|
|
33767
33777
|
childrenUnknown: ended.unknown === false ? undefined : true
|
|
33768
33778
|
},
|
|
33769
|
-
exitedBeforeStop:
|
|
33779
|
+
exitedBeforeStop: !wasRunning,
|
|
33770
33780
|
exitCode: stopped.exitCode,
|
|
33771
33781
|
errors: stopped.log.count("error"),
|
|
33772
33782
|
warnings: stopped.log.count("warning"),
|
|
33773
33783
|
clean: stopped.log.count("error") === 0,
|
|
33774
|
-
note: !wasRunning ? "This run was over before the stop, so nothing was ended here: editor_output has what it printed and how it ended. Anything that game started for itself, with OS.create_process or otherwise, is a separate process and may still be running." : `${stopped.throughEditor ? "The editor was asked to stop the scene it is playing." : "The process named under endedPid was ended."} ${aboutTheChildren(ended, stopped.throughEditor)}`,
|
|
33784
|
+
note: !wasRunning ? "This run was over before the stop, so nothing was ended here: editor_output has what it printed and how it ended. Anything that game started for itself, with OS.create_process or otherwise, is a separate process and may still be running." : `${stopped.throughEditor ? endedPid === null ? "The editor was asked to stop the scene it is playing. Its game had not announced a runtime, so no process was named under endedPid, and its exit code stays with the editor." : "The editor was asked to stop the scene it is playing." : "The process named under endedPid was ended."} ${aboutTheChildren(ended, stopped.throughEditor)}`,
|
|
33775
33785
|
entries: forAnswer(stopped.log.select({ severity: "warning", sinceLastCall: false, limit: 200 }).entries)
|
|
33776
33786
|
});
|
|
33777
33787
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdharness",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20",
|
|
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",
|