gdharness 1.0.4 → 1.0.6
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 +46 -23
- package/build/index.js +46 -23
- package/package.json +1 -1
package/build/cli.js
CHANGED
|
@@ -31601,11 +31601,13 @@ function announcedIn(directory) {
|
|
|
31601
31601
|
}
|
|
31602
31602
|
const strangers = strangersAmong(candidates, Date.now());
|
|
31603
31603
|
for (const { file, pid, alive } of entries) {
|
|
31604
|
-
const
|
|
31604
|
+
const gone = !alive || strangers.has(file);
|
|
31605
|
+
const announced = gone ? { kind: "rubbish" } : parseAnnouncement(file, pid);
|
|
31605
31606
|
if (announced.kind === "rubbish") {
|
|
31606
|
-
if (!
|
|
31607
|
-
|
|
31607
|
+
if (!gone) {
|
|
31608
|
+
continue;
|
|
31608
31609
|
}
|
|
31610
|
+
wentAway(file, pid);
|
|
31609
31611
|
try {
|
|
31610
31612
|
unlinkSync(file);
|
|
31611
31613
|
} catch {}
|
|
@@ -31856,11 +31858,14 @@ function writeBootNote(projectPath, announcedAfterMs) {
|
|
|
31856
31858
|
writeFileSync8(path, JSON.stringify({ announcedAfterMs: Math.round(announcedAfterMs), at: new Date().toISOString() }, null, 2), "utf8");
|
|
31857
31859
|
} catch {}
|
|
31858
31860
|
}
|
|
31861
|
+
function halfAsLongAgain(lastBootMs) {
|
|
31862
|
+
return Math.round(lastBootMs * 1.5);
|
|
31863
|
+
}
|
|
31859
31864
|
function waitSizedTo(lastBootMs, usual = ANNOUNCE_BUDGET_MS) {
|
|
31860
31865
|
if (lastBootMs === null) {
|
|
31861
31866
|
return usual;
|
|
31862
31867
|
}
|
|
31863
|
-
return Math.min(LONGEST_SIZED_WAIT_MS, Math.max(usual,
|
|
31868
|
+
return Math.min(LONGEST_SIZED_WAIT_MS, Math.max(usual, halfAsLongAgain(lastBootMs)));
|
|
31864
31869
|
}
|
|
31865
31870
|
var LONGEST_SIZED_WAIT_MS = 60000;
|
|
31866
31871
|
var init_boot_note = __esm(() => {
|
|
@@ -37707,6 +37712,13 @@ function aboutTheChildren(ended, throughEditor) {
|
|
|
37707
37712
|
const leftToo = ended.left.length === 0 ? "" : ` ${counted(ended.left.length)} it had started ${ended.left.length === 1 ? "was" : "were"} left, named under childrenLeft: neither announced as a game of this project nor this project's engine run with --path on it, so what ${ended.left.length === 1 ? "it is" : "they are"} cannot be told from here.`;
|
|
37708
37713
|
return `${endedToo}${leftToo}`;
|
|
37709
37714
|
}
|
|
37715
|
+
function uidsLeftNote(left) {
|
|
37716
|
+
if (left === 0) {
|
|
37717
|
+
return "No scene was written: this reads the project and imports it, and does not resave anything.";
|
|
37718
|
+
}
|
|
37719
|
+
const them = left === 1 ? "it" : "them";
|
|
37720
|
+
return `${left === 1 ? "One file" : `${left} files`} still ${left === 1 ? "has" : "have"} no .uid, named under stillWithoutUid, which is the engine declining to import ${them} rather than this op skipping ${them}. No scene was written.`;
|
|
37721
|
+
}
|
|
37710
37722
|
function endedToStartThis(ended) {
|
|
37711
37723
|
if (ended === null) {
|
|
37712
37724
|
return "";
|
|
@@ -37734,7 +37746,7 @@ function runtimeVerdict(endpoint, after) {
|
|
|
37734
37746
|
};
|
|
37735
37747
|
}
|
|
37736
37748
|
const state = after.playingSeen === false ? "the editor has not yet reported the game as playing, which a restarted editor does not until its scan is over" : "the game is still running";
|
|
37737
|
-
const sized = after.sizedToMs === undefined ? "" : `, half as long again as the ${after.sizedToMs}ms its last game took,`;
|
|
37749
|
+
const sized = after.sizedToMs === undefined ? "" : halfAsLongAgain(after.sizedToMs) > after.budgetMs ? `, the longest a start waits unasked though its last game took ${after.sizedToMs}ms to announce,` : `, half as long again as the ${after.sizedToMs}ms its last game took,`;
|
|
37738
37750
|
return {
|
|
37739
37751
|
listening: false,
|
|
37740
37752
|
mayYetAnnounce: after.running,
|
|
@@ -37838,7 +37850,10 @@ function aboveTheRunner(entry) {
|
|
|
37838
37850
|
const cut = entry.detail.length - runner;
|
|
37839
37851
|
return {
|
|
37840
37852
|
...entry,
|
|
37841
|
-
detail: [
|
|
37853
|
+
detail: [
|
|
37854
|
+
...entry.detail.slice(0, runner),
|
|
37855
|
+
`[and ${cut === 1 ? "one frame" : `${cut} frames`} inside ${RUNNER_DIRECTORY}]`
|
|
37856
|
+
]
|
|
37842
37857
|
};
|
|
37843
37858
|
}
|
|
37844
37859
|
function elsewhereIn(projectPath, asked) {
|
|
@@ -38726,7 +38741,7 @@ class GodotServer {
|
|
|
38726
38741
|
payload: {
|
|
38727
38742
|
uidsCreated: given,
|
|
38728
38743
|
stillWithoutUid: after,
|
|
38729
|
-
note: after.length
|
|
38744
|
+
note: uidsLeftNote(after.length)
|
|
38730
38745
|
}
|
|
38731
38746
|
});
|
|
38732
38747
|
}
|
|
@@ -39642,11 +39657,11 @@ class GodotServer {
|
|
|
39642
39657
|
return !editorSaysGoing;
|
|
39643
39658
|
}
|
|
39644
39659
|
});
|
|
39645
|
-
|
|
39660
|
+
const asked = editorAsks === 0 ? "editor not asked" : `editor asked ${editorAsks === 1 ? "once" : `${editorAsks} times`}, last said ${lastSaid()}`;
|
|
39661
|
+
this.logDebug(`announce wait ended after ${Date.now() - waitBegan}ms: ${endpoint === null ? "nothing announced" : `pid ${endpoint.pid} announced`}, ${asked}`);
|
|
39646
39662
|
const going = this.currentRun();
|
|
39647
39663
|
if (endpoint !== null && going !== null && going.announcedPid === undefined) {
|
|
39648
|
-
going
|
|
39649
|
-
this.noteBootOf(going, endpoint);
|
|
39664
|
+
this.tie(going, endpoint);
|
|
39650
39665
|
}
|
|
39651
39666
|
return runtimeVerdict(endpoint, {
|
|
39652
39667
|
addon: true,
|
|
@@ -39678,6 +39693,7 @@ class GodotServer {
|
|
|
39678
39693
|
return;
|
|
39679
39694
|
}
|
|
39680
39695
|
const took = announcedAt - run.startedAt;
|
|
39696
|
+
this.logDebug(`boot of pid ${endpoint.pid} announced ${Math.round(took)}ms after the start of ${run.projectPath}`);
|
|
39681
39697
|
if (took > 0 && took <= LONGEST_BOOT_NOTED_MS) {
|
|
39682
39698
|
writeBootNote(run.projectPath, took);
|
|
39683
39699
|
}
|
|
@@ -40002,16 +40018,16 @@ class GodotServer {
|
|
|
40002
40018
|
return run.announcedPid;
|
|
40003
40019
|
}
|
|
40004
40020
|
const ours = this.announcedOfTheRunsProject(run, announced ?? runtimesAnnounced().running);
|
|
40005
|
-
|
|
40006
|
-
|
|
40021
|
+
const own = ours.find((one) => one.pid === run.pid);
|
|
40022
|
+
if (own !== undefined) {
|
|
40023
|
+
this.tie(run, own);
|
|
40007
40024
|
return run.announcedPid;
|
|
40008
40025
|
}
|
|
40009
40026
|
const before = run.announcedBefore ?? new Set;
|
|
40010
40027
|
const candidates = ours.filter((one) => !before.has(one.pid) && this.isTheGameOf(run, one, run.projectPath));
|
|
40011
40028
|
const theOne = candidates.length === 1 ? candidates[0] : undefined;
|
|
40012
40029
|
if (theOne !== undefined) {
|
|
40013
|
-
run
|
|
40014
|
-
this.noteBootOf(run, theOne);
|
|
40030
|
+
this.tie(run, theOne);
|
|
40015
40031
|
}
|
|
40016
40032
|
return run.announcedPid;
|
|
40017
40033
|
}
|
|
@@ -40049,7 +40065,7 @@ class GodotServer {
|
|
|
40049
40065
|
if (tree === undefined) {
|
|
40050
40066
|
return;
|
|
40051
40067
|
}
|
|
40052
|
-
return this.tieThroughTheTree(run, tree,
|
|
40068
|
+
return this.tieThroughTheTree(run, tree, ours);
|
|
40053
40069
|
}
|
|
40054
40070
|
async gameProcessOf(run) {
|
|
40055
40071
|
if (run.gamePid !== undefined) {
|
|
@@ -40070,21 +40086,28 @@ class GodotServer {
|
|
|
40070
40086
|
}
|
|
40071
40087
|
return found;
|
|
40072
40088
|
}
|
|
40073
|
-
tieThroughTheTree(run, tree,
|
|
40089
|
+
tieThroughTheTree(run, tree, announced) {
|
|
40074
40090
|
const root = run.pid ?? (run.throughEditor ? this.godotBridge.getStatus().editorPid : undefined);
|
|
40075
40091
|
if (root === undefined) {
|
|
40076
40092
|
return;
|
|
40077
40093
|
}
|
|
40078
|
-
|
|
40079
|
-
|
|
40080
|
-
|
|
40094
|
+
const games = new Set(announced.map((one) => one.pid));
|
|
40095
|
+
const own = announced.find((one) => one.pid === root);
|
|
40096
|
+
if (own !== undefined) {
|
|
40097
|
+
this.tie(run, own);
|
|
40098
|
+
return own.pid;
|
|
40081
40099
|
}
|
|
40082
|
-
const
|
|
40100
|
+
const under = new Set(descendantsIn(tree, root));
|
|
40101
|
+
const nearest = announced.filter((one) => under.has(one.pid) && !gameBetween(tree, one.pid, root, games));
|
|
40083
40102
|
const theOne = nearest.length === 1 ? nearest[0] : undefined;
|
|
40084
40103
|
if (theOne !== undefined) {
|
|
40085
|
-
run
|
|
40104
|
+
this.tie(run, theOne);
|
|
40086
40105
|
}
|
|
40087
|
-
return theOne;
|
|
40106
|
+
return theOne?.pid;
|
|
40107
|
+
}
|
|
40108
|
+
tie(run, endpoint) {
|
|
40109
|
+
run.announcedPid = endpoint.pid;
|
|
40110
|
+
this.noteBootOf(run, endpoint);
|
|
40088
40111
|
}
|
|
40089
40112
|
playedByOurEditor(endpoint, projectPath) {
|
|
40090
40113
|
const editor = this.godotBridge.getStatus().editorPid;
|
|
@@ -40385,7 +40408,7 @@ class GodotServer {
|
|
|
40385
40408
|
}
|
|
40386
40409
|
const announced = this.announcedOfTheRunsProject(run, runtimesAnnounced().running);
|
|
40387
40410
|
const games = new Set(announced.map((one) => one.pid));
|
|
40388
|
-
const own = this.announcedPidOf(run, announced) ?? this.tieThroughTheTree(run, tree,
|
|
40411
|
+
const own = this.announcedPidOf(run, announced) ?? this.tieThroughTheTree(run, tree, announced) ?? run.gamePid ?? this.gameByCommandLineIn(run, tree);
|
|
40389
40412
|
if (own !== undefined && run.announcedPid === undefined) {
|
|
40390
40413
|
run.gamePid = own;
|
|
40391
40414
|
}
|
package/build/index.js
CHANGED
|
@@ -25233,11 +25233,13 @@ function announcedIn(directory) {
|
|
|
25233
25233
|
}
|
|
25234
25234
|
const strangers = strangersAmong(candidates, Date.now());
|
|
25235
25235
|
for (const { file, pid, alive } of entries) {
|
|
25236
|
-
const
|
|
25236
|
+
const gone = !alive || strangers.has(file);
|
|
25237
|
+
const announced = gone ? { kind: "rubbish" } : parseAnnouncement(file, pid);
|
|
25237
25238
|
if (announced.kind === "rubbish") {
|
|
25238
|
-
if (!
|
|
25239
|
-
|
|
25239
|
+
if (!gone) {
|
|
25240
|
+
continue;
|
|
25240
25241
|
}
|
|
25242
|
+
wentAway(file, pid);
|
|
25241
25243
|
try {
|
|
25242
25244
|
unlinkSync(file);
|
|
25243
25245
|
} catch {}
|
|
@@ -25482,11 +25484,14 @@ function writeBootNote(projectPath, announcedAfterMs) {
|
|
|
25482
25484
|
} catch {}
|
|
25483
25485
|
}
|
|
25484
25486
|
var LONGEST_SIZED_WAIT_MS = 60000;
|
|
25487
|
+
function halfAsLongAgain(lastBootMs) {
|
|
25488
|
+
return Math.round(lastBootMs * 1.5);
|
|
25489
|
+
}
|
|
25485
25490
|
function waitSizedTo(lastBootMs, usual = ANNOUNCE_BUDGET_MS) {
|
|
25486
25491
|
if (lastBootMs === null) {
|
|
25487
25492
|
return usual;
|
|
25488
25493
|
}
|
|
25489
|
-
return Math.min(LONGEST_SIZED_WAIT_MS, Math.max(usual,
|
|
25494
|
+
return Math.min(LONGEST_SIZED_WAIT_MS, Math.max(usual, halfAsLongAgain(lastBootMs)));
|
|
25490
25495
|
}
|
|
25491
25496
|
|
|
25492
25497
|
// src/breakpoint-note.ts
|
|
@@ -30402,6 +30407,13 @@ function aboutTheChildren(ended, throughEditor) {
|
|
|
30402
30407
|
const leftToo = ended.left.length === 0 ? "" : ` ${counted(ended.left.length)} it had started ${ended.left.length === 1 ? "was" : "were"} left, named under childrenLeft: neither announced as a game of this project nor this project's engine run with --path on it, so what ${ended.left.length === 1 ? "it is" : "they are"} cannot be told from here.`;
|
|
30403
30408
|
return `${endedToo}${leftToo}`;
|
|
30404
30409
|
}
|
|
30410
|
+
function uidsLeftNote(left) {
|
|
30411
|
+
if (left === 0) {
|
|
30412
|
+
return "No scene was written: this reads the project and imports it, and does not resave anything.";
|
|
30413
|
+
}
|
|
30414
|
+
const them = left === 1 ? "it" : "them";
|
|
30415
|
+
return `${left === 1 ? "One file" : `${left} files`} still ${left === 1 ? "has" : "have"} no .uid, named under stillWithoutUid, which is the engine declining to import ${them} rather than this op skipping ${them}. No scene was written.`;
|
|
30416
|
+
}
|
|
30405
30417
|
function endedToStartThis(ended) {
|
|
30406
30418
|
if (ended === null) {
|
|
30407
30419
|
return "";
|
|
@@ -30430,7 +30442,7 @@ function runtimeVerdict(endpoint, after) {
|
|
|
30430
30442
|
};
|
|
30431
30443
|
}
|
|
30432
30444
|
const state = after.playingSeen === false ? "the editor has not yet reported the game as playing, which a restarted editor does not until its scan is over" : "the game is still running";
|
|
30433
|
-
const sized = after.sizedToMs === undefined ? "" : `, half as long again as the ${after.sizedToMs}ms its last game took,`;
|
|
30445
|
+
const sized = after.sizedToMs === undefined ? "" : halfAsLongAgain(after.sizedToMs) > after.budgetMs ? `, the longest a start waits unasked though its last game took ${after.sizedToMs}ms to announce,` : `, half as long again as the ${after.sizedToMs}ms its last game took,`;
|
|
30434
30446
|
return {
|
|
30435
30447
|
listening: false,
|
|
30436
30448
|
mayYetAnnounce: after.running,
|
|
@@ -30576,7 +30588,10 @@ function aboveTheRunner(entry) {
|
|
|
30576
30588
|
const cut = entry.detail.length - runner;
|
|
30577
30589
|
return {
|
|
30578
30590
|
...entry,
|
|
30579
|
-
detail: [
|
|
30591
|
+
detail: [
|
|
30592
|
+
...entry.detail.slice(0, runner),
|
|
30593
|
+
`[and ${cut === 1 ? "one frame" : `${cut} frames`} inside ${RUNNER_DIRECTORY}]`
|
|
30594
|
+
]
|
|
30580
30595
|
};
|
|
30581
30596
|
}
|
|
30582
30597
|
function elsewhereIn(projectPath, asked) {
|
|
@@ -31464,7 +31479,7 @@ class GodotServer {
|
|
|
31464
31479
|
payload: {
|
|
31465
31480
|
uidsCreated: given,
|
|
31466
31481
|
stillWithoutUid: after,
|
|
31467
|
-
note: after.length
|
|
31482
|
+
note: uidsLeftNote(after.length)
|
|
31468
31483
|
}
|
|
31469
31484
|
});
|
|
31470
31485
|
}
|
|
@@ -32380,11 +32395,11 @@ class GodotServer {
|
|
|
32380
32395
|
return !editorSaysGoing;
|
|
32381
32396
|
}
|
|
32382
32397
|
});
|
|
32383
|
-
|
|
32398
|
+
const asked = editorAsks === 0 ? "editor not asked" : `editor asked ${editorAsks === 1 ? "once" : `${editorAsks} times`}, last said ${lastSaid()}`;
|
|
32399
|
+
this.logDebug(`announce wait ended after ${Date.now() - waitBegan}ms: ${endpoint === null ? "nothing announced" : `pid ${endpoint.pid} announced`}, ${asked}`);
|
|
32384
32400
|
const going = this.currentRun();
|
|
32385
32401
|
if (endpoint !== null && going !== null && going.announcedPid === undefined) {
|
|
32386
|
-
going
|
|
32387
|
-
this.noteBootOf(going, endpoint);
|
|
32402
|
+
this.tie(going, endpoint);
|
|
32388
32403
|
}
|
|
32389
32404
|
return runtimeVerdict(endpoint, {
|
|
32390
32405
|
addon: true,
|
|
@@ -32416,6 +32431,7 @@ class GodotServer {
|
|
|
32416
32431
|
return;
|
|
32417
32432
|
}
|
|
32418
32433
|
const took = announcedAt - run.startedAt;
|
|
32434
|
+
this.logDebug(`boot of pid ${endpoint.pid} announced ${Math.round(took)}ms after the start of ${run.projectPath}`);
|
|
32419
32435
|
if (took > 0 && took <= LONGEST_BOOT_NOTED_MS) {
|
|
32420
32436
|
writeBootNote(run.projectPath, took);
|
|
32421
32437
|
}
|
|
@@ -32740,16 +32756,16 @@ class GodotServer {
|
|
|
32740
32756
|
return run.announcedPid;
|
|
32741
32757
|
}
|
|
32742
32758
|
const ours = this.announcedOfTheRunsProject(run, announced ?? runtimesAnnounced().running);
|
|
32743
|
-
|
|
32744
|
-
|
|
32759
|
+
const own = ours.find((one) => one.pid === run.pid);
|
|
32760
|
+
if (own !== undefined) {
|
|
32761
|
+
this.tie(run, own);
|
|
32745
32762
|
return run.announcedPid;
|
|
32746
32763
|
}
|
|
32747
32764
|
const before = run.announcedBefore ?? new Set;
|
|
32748
32765
|
const candidates = ours.filter((one) => !before.has(one.pid) && this.isTheGameOf(run, one, run.projectPath));
|
|
32749
32766
|
const theOne = candidates.length === 1 ? candidates[0] : undefined;
|
|
32750
32767
|
if (theOne !== undefined) {
|
|
32751
|
-
run
|
|
32752
|
-
this.noteBootOf(run, theOne);
|
|
32768
|
+
this.tie(run, theOne);
|
|
32753
32769
|
}
|
|
32754
32770
|
return run.announcedPid;
|
|
32755
32771
|
}
|
|
@@ -32787,7 +32803,7 @@ class GodotServer {
|
|
|
32787
32803
|
if (tree === undefined) {
|
|
32788
32804
|
return;
|
|
32789
32805
|
}
|
|
32790
|
-
return this.tieThroughTheTree(run, tree,
|
|
32806
|
+
return this.tieThroughTheTree(run, tree, ours);
|
|
32791
32807
|
}
|
|
32792
32808
|
async gameProcessOf(run) {
|
|
32793
32809
|
if (run.gamePid !== undefined) {
|
|
@@ -32808,21 +32824,28 @@ class GodotServer {
|
|
|
32808
32824
|
}
|
|
32809
32825
|
return found;
|
|
32810
32826
|
}
|
|
32811
|
-
tieThroughTheTree(run, tree,
|
|
32827
|
+
tieThroughTheTree(run, tree, announced) {
|
|
32812
32828
|
const root = run.pid ?? (run.throughEditor ? this.godotBridge.getStatus().editorPid : undefined);
|
|
32813
32829
|
if (root === undefined) {
|
|
32814
32830
|
return;
|
|
32815
32831
|
}
|
|
32816
|
-
|
|
32817
|
-
|
|
32818
|
-
|
|
32832
|
+
const games = new Set(announced.map((one) => one.pid));
|
|
32833
|
+
const own = announced.find((one) => one.pid === root);
|
|
32834
|
+
if (own !== undefined) {
|
|
32835
|
+
this.tie(run, own);
|
|
32836
|
+
return own.pid;
|
|
32819
32837
|
}
|
|
32820
|
-
const
|
|
32838
|
+
const under = new Set(descendantsIn(tree, root));
|
|
32839
|
+
const nearest = announced.filter((one) => under.has(one.pid) && !gameBetween(tree, one.pid, root, games));
|
|
32821
32840
|
const theOne = nearest.length === 1 ? nearest[0] : undefined;
|
|
32822
32841
|
if (theOne !== undefined) {
|
|
32823
|
-
run
|
|
32842
|
+
this.tie(run, theOne);
|
|
32824
32843
|
}
|
|
32825
|
-
return theOne;
|
|
32844
|
+
return theOne?.pid;
|
|
32845
|
+
}
|
|
32846
|
+
tie(run, endpoint) {
|
|
32847
|
+
run.announcedPid = endpoint.pid;
|
|
32848
|
+
this.noteBootOf(run, endpoint);
|
|
32826
32849
|
}
|
|
32827
32850
|
playedByOurEditor(endpoint, projectPath) {
|
|
32828
32851
|
const editor = this.godotBridge.getStatus().editorPid;
|
|
@@ -33123,7 +33146,7 @@ class GodotServer {
|
|
|
33123
33146
|
}
|
|
33124
33147
|
const announced = this.announcedOfTheRunsProject(run, runtimesAnnounced().running);
|
|
33125
33148
|
const games = new Set(announced.map((one) => one.pid));
|
|
33126
|
-
const own = this.announcedPidOf(run, announced) ?? this.tieThroughTheTree(run, tree,
|
|
33149
|
+
const own = this.announcedPidOf(run, announced) ?? this.tieThroughTheTree(run, tree, announced) ?? run.gamePid ?? this.gameByCommandLineIn(run, tree);
|
|
33127
33150
|
if (own !== undefined && run.announcedPid === undefined) {
|
|
33128
33151
|
run.gamePid = own;
|
|
33129
33152
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdharness",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
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",
|