gdharness 0.12.14 → 0.12.16
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 -6
- package/build/index.js +25 -6
- package/package.json +1 -1
package/build/cli.js
CHANGED
|
@@ -15759,7 +15759,7 @@ var init_tool_definitions = __esm(() => {
|
|
|
15759
15759
|
},
|
|
15760
15760
|
{
|
|
15761
15761
|
name: "editor_status",
|
|
15762
|
-
description: 'Whether the editor addon is connected, which Godot answers, whether the editor is playing something, and whether a game with the runtime addon is reachable. When connected is false, mayYetConnect says whether that is final: the editor dials this server rather than the other way round and backs off between tries, so for the first half-minute after a server starts, false means "not reached yet" as often as it means "no editor". True is worth waiting out; false is an editor that is not there.',
|
|
15762
|
+
description: 'Whether the editor addon is connected, which Godot answers, whether the editor is playing something, and whether a game with the runtime addon is reachable. When connected is false, mayYetConnect says whether that is final: the editor dials this server rather than the other way round and backs off between tries, so for the first half-minute after a server starts, false means "not reached yet" as often as it means "no editor". True is worth waiting out; false is an editor that is not there. listeningSince is when this server took the bridge port, which is what that window is measured from and what a caller wanting its own window should read.',
|
|
15763
15763
|
parameters: {},
|
|
15764
15764
|
requires: []
|
|
15765
15765
|
},
|
|
@@ -34406,7 +34406,7 @@ function servedPort(said) {
|
|
|
34406
34406
|
return typeof said === "number" && Number.isInteger(said) && said > 0 && said <= 65535 ? said : undefined;
|
|
34407
34407
|
}
|
|
34408
34408
|
function mayYetConnect(listeningSince, now = Date.now()) {
|
|
34409
|
-
return listeningSince === undefined || now - listeningSince < CONNECT_WINDOW_MS;
|
|
34409
|
+
return listeningSince === undefined || now - listeningSince.getTime() < CONNECT_WINDOW_MS;
|
|
34410
34410
|
}
|
|
34411
34411
|
function getDefaultBridge(ownProject = null) {
|
|
34412
34412
|
defaultBridge ??= new GodotBridge(resolveDefaultBridgePort(), resolveDefaultBridgeHost(), DEFAULT_TIMEOUT_MS, ownProject);
|
|
@@ -34482,7 +34482,7 @@ var init_godot_bridge = __esm(() => {
|
|
|
34482
34482
|
});
|
|
34483
34483
|
server.once("listening", () => {
|
|
34484
34484
|
settled = true;
|
|
34485
|
-
this.listeningSince = Date
|
|
34485
|
+
this.listeningSince = new Date;
|
|
34486
34486
|
this.httpServer = server;
|
|
34487
34487
|
this.godotWss = godotWss;
|
|
34488
34488
|
const bound = server.address();
|
|
@@ -36159,6 +36159,16 @@ function writeRunRecord(record) {
|
|
|
36159
36159
|
mkdirSync6(runsDirectory(), { recursive: true });
|
|
36160
36160
|
writeFileSync8(recordPath(), JSON.stringify(record, null, 2), "utf8");
|
|
36161
36161
|
}
|
|
36162
|
+
function recordRunEnded(pid, exitCode) {
|
|
36163
|
+
const path = recordPath();
|
|
36164
|
+
const record = recordAt(path);
|
|
36165
|
+
if (record === null || record.pid !== pid) {
|
|
36166
|
+
return;
|
|
36167
|
+
}
|
|
36168
|
+
try {
|
|
36169
|
+
writeFileSync8(path, JSON.stringify({ ...record, exitCode }, null, 2), "utf8");
|
|
36170
|
+
} catch {}
|
|
36171
|
+
}
|
|
36162
36172
|
function readRunRecord() {
|
|
36163
36173
|
for (const path of recordPaths()) {
|
|
36164
36174
|
const record = recordAt(path);
|
|
@@ -36192,7 +36202,8 @@ function recordAt(path) {
|
|
|
36192
36202
|
startedAt,
|
|
36193
36203
|
projectPath: typeof fields["projectPath"] === "string" ? fields["projectPath"] : "",
|
|
36194
36204
|
arguments: Array.isArray(args) ? args.filter((value) => typeof value === "string") : [],
|
|
36195
|
-
...typeof fields["command"] === "string" ? { command: fields["command"] } : {}
|
|
36205
|
+
...typeof fields["command"] === "string" ? { command: fields["command"] } : {},
|
|
36206
|
+
...typeof fields["exitCode"] === "number" ? { exitCode: fields["exitCode"] } : {}
|
|
36196
36207
|
};
|
|
36197
36208
|
}
|
|
36198
36209
|
function runningAs(pid) {
|
|
@@ -37343,8 +37354,11 @@ class GodotServer {
|
|
|
37343
37354
|
return this.createErrorResponse(`Cannot create ${dirname9(output.relativePath)} to export into: ${errorMessage(error)}`);
|
|
37344
37355
|
}
|
|
37345
37356
|
const debug = readBoolean(args, "debug") ?? false;
|
|
37357
|
+
const exportLogs = mkdtempSync3(join16(tmpdir5(), "gdharness-export-"));
|
|
37346
37358
|
const exportArgs = [
|
|
37347
37359
|
"--headless",
|
|
37360
|
+
"--log-file",
|
|
37361
|
+
join16(exportLogs, "engine.log"),
|
|
37348
37362
|
"--path",
|
|
37349
37363
|
project.value.path,
|
|
37350
37364
|
debug ? "--export-debug" : "--export-release",
|
|
@@ -37366,6 +37380,8 @@ class GodotServer {
|
|
|
37366
37380
|
log.append("stdout", failed.stdout);
|
|
37367
37381
|
log.append("stderr", failed.stderr);
|
|
37368
37382
|
exitCode = typeof failed.code === "number" ? failed.code : -1;
|
|
37383
|
+
} finally {
|
|
37384
|
+
rmSync9(exportLogs, { recursive: true, force: true });
|
|
37369
37385
|
}
|
|
37370
37386
|
log.finish();
|
|
37371
37387
|
const problems = log.select({ severity: "warning", sinceLastCall: false, limit: 200 });
|
|
@@ -38001,6 +38017,9 @@ class GodotServer {
|
|
|
38001
38017
|
this.logDebug(`Godot process exited with code ${code ?? "none"}`);
|
|
38002
38018
|
log.finish();
|
|
38003
38019
|
started.exitCode = code ?? -1;
|
|
38020
|
+
if (started.pid !== null) {
|
|
38021
|
+
recordRunEnded(started.pid, started.exitCode);
|
|
38022
|
+
}
|
|
38004
38023
|
});
|
|
38005
38024
|
child.on("error", (err) => {
|
|
38006
38025
|
console.error("Failed to start Godot process:", err);
|
|
@@ -38105,8 +38124,8 @@ class GodotServer {
|
|
|
38105
38124
|
this.drainTranscript(adopted);
|
|
38106
38125
|
if (!alive(record.pid) || !couldStillBeTheRecordedRun(record)) {
|
|
38107
38126
|
adopted.log.finish();
|
|
38108
|
-
adopted.exitCode = null;
|
|
38109
|
-
adopted.endedUnwatched =
|
|
38127
|
+
adopted.exitCode = record.exitCode ?? null;
|
|
38128
|
+
adopted.endedUnwatched = record.exitCode === undefined;
|
|
38110
38129
|
}
|
|
38111
38130
|
this.activeProcess = adopted;
|
|
38112
38131
|
return adopted;
|
package/build/index.js
CHANGED
|
@@ -25613,7 +25613,7 @@ function servedPort(said) {
|
|
|
25613
25613
|
}
|
|
25614
25614
|
var CONNECT_WINDOW_MS = 35000;
|
|
25615
25615
|
function mayYetConnect(listeningSince, now = Date.now()) {
|
|
25616
|
-
return listeningSince === undefined || now - listeningSince < CONNECT_WINDOW_MS;
|
|
25616
|
+
return listeningSince === undefined || now - listeningSince.getTime() < CONNECT_WINDOW_MS;
|
|
25617
25617
|
}
|
|
25618
25618
|
|
|
25619
25619
|
class GodotBridge extends EventEmitter {
|
|
@@ -25680,7 +25680,7 @@ class GodotBridge extends EventEmitter {
|
|
|
25680
25680
|
});
|
|
25681
25681
|
server.once("listening", () => {
|
|
25682
25682
|
settled = true;
|
|
25683
|
-
this.listeningSince = Date
|
|
25683
|
+
this.listeningSince = new Date;
|
|
25684
25684
|
this.httpServer = server;
|
|
25685
25685
|
this.godotWss = godotWss;
|
|
25686
25686
|
const bound = server.address();
|
|
@@ -27841,6 +27841,16 @@ function writeRunRecord(record) {
|
|
|
27841
27841
|
mkdirSync3(runsDirectory(), { recursive: true });
|
|
27842
27842
|
writeFileSync4(recordPath(), JSON.stringify(record, null, 2), "utf8");
|
|
27843
27843
|
}
|
|
27844
|
+
function recordRunEnded(pid, exitCode) {
|
|
27845
|
+
const path = recordPath();
|
|
27846
|
+
const record = recordAt(path);
|
|
27847
|
+
if (record === null || record.pid !== pid) {
|
|
27848
|
+
return;
|
|
27849
|
+
}
|
|
27850
|
+
try {
|
|
27851
|
+
writeFileSync4(path, JSON.stringify({ ...record, exitCode }, null, 2), "utf8");
|
|
27852
|
+
} catch {}
|
|
27853
|
+
}
|
|
27844
27854
|
function readRunRecord() {
|
|
27845
27855
|
for (const path of recordPaths()) {
|
|
27846
27856
|
const record = recordAt(path);
|
|
@@ -27874,7 +27884,8 @@ function recordAt(path) {
|
|
|
27874
27884
|
startedAt,
|
|
27875
27885
|
projectPath: typeof fields["projectPath"] === "string" ? fields["projectPath"] : "",
|
|
27876
27886
|
arguments: Array.isArray(args) ? args.filter((value) => typeof value === "string") : [],
|
|
27877
|
-
...typeof fields["command"] === "string" ? { command: fields["command"] } : {}
|
|
27887
|
+
...typeof fields["command"] === "string" ? { command: fields["command"] } : {},
|
|
27888
|
+
...typeof fields["exitCode"] === "number" ? { exitCode: fields["exitCode"] } : {}
|
|
27878
27889
|
};
|
|
27879
27890
|
}
|
|
27880
27891
|
function runningAs(pid) {
|
|
@@ -28662,7 +28673,7 @@ var TOOL_SPECS = [
|
|
|
28662
28673
|
},
|
|
28663
28674
|
{
|
|
28664
28675
|
name: "editor_status",
|
|
28665
|
-
description: 'Whether the editor addon is connected, which Godot answers, whether the editor is playing something, and whether a game with the runtime addon is reachable. When connected is false, mayYetConnect says whether that is final: the editor dials this server rather than the other way round and backs off between tries, so for the first half-minute after a server starts, false means "not reached yet" as often as it means "no editor". True is worth waiting out; false is an editor that is not there.',
|
|
28676
|
+
description: 'Whether the editor addon is connected, which Godot answers, whether the editor is playing something, and whether a game with the runtime addon is reachable. When connected is false, mayYetConnect says whether that is final: the editor dials this server rather than the other way round and backs off between tries, so for the first half-minute after a server starts, false means "not reached yet" as often as it means "no editor". True is worth waiting out; false is an editor that is not there. listeningSince is when this server took the bridge port, which is what that window is measured from and what a caller wanting its own window should read.',
|
|
28666
28677
|
parameters: {},
|
|
28667
28678
|
requires: []
|
|
28668
28679
|
},
|
|
@@ -30126,8 +30137,11 @@ class GodotServer {
|
|
|
30126
30137
|
return this.createErrorResponse(`Cannot create ${dirname4(output.relativePath)} to export into: ${errorMessage(error)}`);
|
|
30127
30138
|
}
|
|
30128
30139
|
const debug = readBoolean(args, "debug") ?? false;
|
|
30140
|
+
const exportLogs = mkdtempSync2(join10(tmpdir4(), "gdharness-export-"));
|
|
30129
30141
|
const exportArgs = [
|
|
30130
30142
|
"--headless",
|
|
30143
|
+
"--log-file",
|
|
30144
|
+
join10(exportLogs, "engine.log"),
|
|
30131
30145
|
"--path",
|
|
30132
30146
|
project.value.path,
|
|
30133
30147
|
debug ? "--export-debug" : "--export-release",
|
|
@@ -30149,6 +30163,8 @@ class GodotServer {
|
|
|
30149
30163
|
log.append("stdout", failed.stdout);
|
|
30150
30164
|
log.append("stderr", failed.stderr);
|
|
30151
30165
|
exitCode = typeof failed.code === "number" ? failed.code : -1;
|
|
30166
|
+
} finally {
|
|
30167
|
+
rmSync5(exportLogs, { recursive: true, force: true });
|
|
30152
30168
|
}
|
|
30153
30169
|
log.finish();
|
|
30154
30170
|
const problems = log.select({ severity: "warning", sinceLastCall: false, limit: 200 });
|
|
@@ -30784,6 +30800,9 @@ class GodotServer {
|
|
|
30784
30800
|
this.logDebug(`Godot process exited with code ${code ?? "none"}`);
|
|
30785
30801
|
log.finish();
|
|
30786
30802
|
started.exitCode = code ?? -1;
|
|
30803
|
+
if (started.pid !== null) {
|
|
30804
|
+
recordRunEnded(started.pid, started.exitCode);
|
|
30805
|
+
}
|
|
30787
30806
|
});
|
|
30788
30807
|
child.on("error", (err) => {
|
|
30789
30808
|
console.error("Failed to start Godot process:", err);
|
|
@@ -30888,8 +30907,8 @@ class GodotServer {
|
|
|
30888
30907
|
this.drainTranscript(adopted);
|
|
30889
30908
|
if (!alive(record.pid) || !couldStillBeTheRecordedRun(record)) {
|
|
30890
30909
|
adopted.log.finish();
|
|
30891
|
-
adopted.exitCode = null;
|
|
30892
|
-
adopted.endedUnwatched =
|
|
30910
|
+
adopted.exitCode = record.exitCode ?? null;
|
|
30911
|
+
adopted.endedUnwatched = record.exitCode === undefined;
|
|
30893
30912
|
}
|
|
30894
30913
|
this.activeProcess = adopted;
|
|
30895
30914
|
return adopted;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdharness",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.16",
|
|
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",
|