gdharness 1.3.25 → 1.3.26

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 CHANGED
@@ -11591,8 +11591,54 @@ var init_call_signal = __esm(() => {
11591
11591
  current = new AsyncLocalStorage;
11592
11592
  });
11593
11593
 
11594
+ // src/whole-file.ts
11595
+ import { renameSync, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "node:fs";
11596
+ function writeWhole(path, text) {
11597
+ const partial = `${path}.${process.pid}.partial`;
11598
+ try {
11599
+ writeFileSync5(partial, text, "utf8");
11600
+ } catch {
11601
+ return false;
11602
+ }
11603
+ const until = Date.now() + HELD_FILE_MS;
11604
+ for (;; ) {
11605
+ try {
11606
+ renameSync(partial, path);
11607
+ return true;
11608
+ } catch (error) {
11609
+ const code = error.code ?? "";
11610
+ if (!HELD_BY_A_READER.has(code) || Date.now() >= until) {
11611
+ try {
11612
+ rmSync5(partial, { force: true });
11613
+ } catch {}
11614
+ return false;
11615
+ }
11616
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, HELD_FILE_RETRY_MS);
11617
+ }
11618
+ }
11619
+ }
11620
+ function removeWhole(path) {
11621
+ const until = Date.now() + HELD_FILE_MS;
11622
+ for (;; ) {
11623
+ try {
11624
+ rmSync5(path, { force: true });
11625
+ return true;
11626
+ } catch (error) {
11627
+ const code = error.code ?? "";
11628
+ if (!HELD_BY_A_READER.has(code) || Date.now() >= until) {
11629
+ return false;
11630
+ }
11631
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, HELD_FILE_RETRY_MS);
11632
+ }
11633
+ }
11634
+ }
11635
+ var HELD_FILE_MS = 1000, HELD_FILE_RETRY_MS = 10, HELD_BY_A_READER;
11636
+ var init_whole_file = __esm(() => {
11637
+ HELD_BY_A_READER = new Set(["EPERM", "EACCES", "EBUSY"]);
11638
+ });
11639
+
11594
11640
  // src/engine-slots.ts
11595
- import { closeSync as closeSync3, mkdirSync as mkdirSync3, openSync as openSync3, readFileSync as readFileSync7, rmSync as rmSync5, statSync as statSync6, writeSync as writeSync2 } from "node:fs";
11641
+ import { closeSync as closeSync3, mkdirSync as mkdirSync3, openSync as openSync3, readFileSync as readFileSync7, rmSync as rmSync6, statSync as statSync6, writeSync as writeSync2 } from "node:fs";
11596
11642
  import { availableParallelism as availableParallelism2, homedir as homedir2 } from "node:os";
11597
11643
  import { join as join8, resolve as resolve4 } from "node:path";
11598
11644
  import process7 from "node:process";
@@ -11657,6 +11703,7 @@ async function ownStart() {
11657
11703
  class EngineSlots {
11658
11704
  starts = new Map;
11659
11705
  held = new Set;
11706
+ marks = new Set;
11660
11707
  saidAt = Number.NEGATIVE_INFINITY;
11661
11708
  directory;
11662
11709
  count;
@@ -11672,38 +11719,65 @@ class EngineSlots {
11672
11719
  mkdirSync3(this.directory, { recursive: true });
11673
11720
  const began = Date.now();
11674
11721
  let said = Number.NEGATIVE_INFINITY;
11675
- for (;; ) {
11676
- signal?.throwIfAborted();
11677
- for (let slot = 0;slot < this.count; slot += 1) {
11678
- const lock = join8(this.directory, `${String(slot)}.lock`);
11679
- if (this.made(lock) || await this.takenOver(lock)) {
11680
- this.held.add(lock);
11681
- return lock;
11722
+ let mark;
11723
+ try {
11724
+ for (;; ) {
11725
+ signal?.throwIfAborted();
11726
+ for (let slot = 0;slot < this.count; slot += 1) {
11727
+ const lock = join8(this.directory, `${String(slot)}.lock`);
11728
+ if (this.made(lock) || await this.takenOver(lock)) {
11729
+ this.held.add(lock);
11730
+ return lock;
11731
+ }
11682
11732
  }
11683
- }
11684
- const now = Date.now();
11685
- if (waiting !== undefined) {
11686
- if (now - said >= WAIT_SAID_MS) {
11687
- said = now;
11688
- waiting(now - began);
11733
+ mark ??= this.waitMarked();
11734
+ const now = Date.now();
11735
+ if (waiting !== undefined) {
11736
+ if (now - said >= WAIT_SAID_MS) {
11737
+ said = now;
11738
+ waiting(now - began);
11739
+ }
11740
+ } else if (this.say !== undefined && this.held.size === 0 && now - began >= COMMAND_WAIT_SAID_MS && now - this.saidAt >= WAIT_SAID_MS) {
11741
+ this.saidAt = now;
11742
+ this.say(slotWaitSaid(now - began, this.count, this.directory));
11689
11743
  }
11690
- } else if (this.say !== undefined && this.held.size === 0 && now - began >= COMMAND_WAIT_SAID_MS && now - this.saidAt >= WAIT_SAID_MS) {
11691
- this.saidAt = now;
11692
- this.say(slotWaitSaid(now - began, this.count, this.directory));
11744
+ await delay3(SLOT_WAIT_MS, undefined, signal === undefined ? {} : { signal });
11745
+ }
11746
+ } finally {
11747
+ if (mark !== undefined && this.marks.delete(mark)) {
11748
+ removeWhole(mark);
11693
11749
  }
11694
- await delay3(SLOT_WAIT_MS, undefined, signal === undefined ? {} : { signal });
11695
11750
  }
11696
11751
  }
11752
+ waitMarked() {
11753
+ const marks = join8(this.directory, WAITING_FOLDER);
11754
+ waitsMarked += 1;
11755
+ const mark = join8(marks, `${String(this.holder.pid)}-${String(waitsMarked)}.json`);
11756
+ try {
11757
+ mkdirSync3(marks, { recursive: true });
11758
+ } catch {
11759
+ return;
11760
+ }
11761
+ if (!this.made(mark)) {
11762
+ return;
11763
+ }
11764
+ this.marks.add(mark);
11765
+ return mark;
11766
+ }
11697
11767
  releaseAll() {
11698
11768
  for (const lock of this.held) {
11699
11769
  this.release(lock);
11700
11770
  }
11771
+ for (const mark of this.marks) {
11772
+ this.marks.delete(mark);
11773
+ removeWhole(mark);
11774
+ }
11701
11775
  }
11702
11776
  release(lock) {
11703
11777
  this.held.delete(lock);
11704
11778
  try {
11705
11779
  if (holderOf(readFileSync7(lock, "utf8"))?.pid === this.holder.pid) {
11706
- rmSync5(lock, { force: true });
11780
+ removeWhole(lock);
11707
11781
  }
11708
11782
  } catch {}
11709
11783
  }
@@ -11729,7 +11803,7 @@ class EngineSlots {
11729
11803
  if (!this.made(steal)) {
11730
11804
  try {
11731
11805
  if (Date.now() - statSync6(steal).mtimeMs > UNWRITTEN_MS) {
11732
- rmSync5(steal, { force: true });
11806
+ rmSync6(steal, { force: true });
11733
11807
  }
11734
11808
  } catch {}
11735
11809
  return false;
@@ -11739,13 +11813,13 @@ class EngineSlots {
11739
11813
  return false;
11740
11814
  }
11741
11815
  try {
11742
- rmSync5(lock, { force: true });
11816
+ rmSync6(lock, { force: true });
11743
11817
  } catch {
11744
11818
  return false;
11745
11819
  }
11746
11820
  return this.made(lock);
11747
11821
  } finally {
11748
- rmSync5(steal, { force: true });
11822
+ rmSync6(steal, { force: true });
11749
11823
  }
11750
11824
  }
11751
11825
  async free(lock) {
@@ -11808,12 +11882,13 @@ async function inASlot(body) {
11808
11882
  held.release();
11809
11883
  }
11810
11884
  }
11811
- var SLOTS_VARIABLE = "GODOT_ENGINE_SLOTS", SLOT_COUNT_VARIABLE = "GODOT_ENGINE_SLOT_COUNT", PROCESSORS_A_SLOT = 5, START_TOLERANCE_MS = 2000, UNWRITTEN_MS = 1e4, SLOT_WAIT_MS = 50, WAIT_SAID_MS = 20000, COMMAND_WAIT_SAID_MS = 2000, START_READ_MS = 1e4, ours, saidTo;
11885
+ var SLOTS_VARIABLE = "GODOT_ENGINE_SLOTS", SLOT_COUNT_VARIABLE = "GODOT_ENGINE_SLOT_COUNT", PROCESSORS_A_SLOT = 5, START_TOLERANCE_MS = 2000, UNWRITTEN_MS = 1e4, SLOT_WAIT_MS = 50, WAIT_SAID_MS = 20000, COMMAND_WAIT_SAID_MS = 2000, START_READ_MS = 1e4, WAITING_FOLDER = "waiting", waitsMarked = 0, ours, saidTo;
11812
11886
  var init_engine_slots = __esm(() => {
11813
11887
  init_alive();
11814
11888
  init_call_signal();
11815
11889
  init_engine_launch();
11816
11890
  init_process_children();
11891
+ init_whole_file();
11817
11892
  });
11818
11893
 
11819
11894
  // src/detection.ts
@@ -13061,9 +13136,9 @@ import {
13061
13136
  mkdirSync as mkdirSync4,
13062
13137
  readdirSync as readdirSync8,
13063
13138
  readFileSync as readFileSync10,
13064
- renameSync,
13139
+ renameSync as renameSync2,
13065
13140
  unlinkSync,
13066
- writeFileSync as writeFileSync5
13141
+ writeFileSync as writeFileSync6
13067
13142
  } from "node:fs";
13068
13143
  import { basename as basename6, dirname as dirname6, isAbsolute as isAbsolute6, join as join13 } from "node:path";
13069
13144
  function freeLibraryCopies(projectPath, platform = process.platform) {
@@ -13078,7 +13153,7 @@ function freeLibraryCopies(projectPath, platform = process.platform) {
13078
13153
  if (existsSync11(join13(folder, copy))) {
13079
13154
  const aside = join13(folder, `${copy}.aside-${process.pid}-${Date.now()}`);
13080
13155
  try {
13081
- renameSync(join13(folder, copy), aside);
13156
+ renameSync2(join13(folder, copy), aside);
13082
13157
  setAside.push(aside);
13083
13158
  } catch {}
13084
13159
  }
@@ -13132,7 +13207,7 @@ function seedExtensionList(projectPath) {
13132
13207
  }
13133
13208
  found.sort();
13134
13209
  mkdirSync4(dirname6(list), { recursive: true });
13135
- writeFileSync5(list, `${found.join(`
13210
+ writeFileSync6(list, `${found.join(`
13136
13211
  `)}
13137
13212
  `);
13138
13213
  return found;
@@ -13185,7 +13260,7 @@ var init_library_copies = () => {};
13185
13260
 
13186
13261
  // src/reimport.ts
13187
13262
  import { createHash as createHash3 } from "node:crypto";
13188
- import { existsSync as existsSync12, readFileSync as readFileSync11, rmSync as rmSync6, statSync as statSync11, utimesSync, writeFileSync as writeFileSync6 } from "node:fs";
13263
+ import { existsSync as existsSync12, readFileSync as readFileSync11, rmSync as rmSync7, statSync as statSync11, utimesSync, writeFileSync as writeFileSync7 } from "node:fs";
13189
13264
  import { basename as basename7, join as join14 } from "node:path";
13190
13265
  function forceNextImport(projectPath, resourcePath) {
13191
13266
  const relative = resourcePath.replace(/^res:\/\//, "");
@@ -13194,9 +13269,9 @@ function forceNextImport(projectPath, resourcePath) {
13194
13269
  return;
13195
13270
  }
13196
13271
  const { atime, mtimeMs } = statSync11(sidecar);
13197
- writeFileSync6(sidecar, readFileSync11(sidecar, "utf8").replace(/^valid=false\r?\n/m, ""));
13272
+ writeFileSync7(sidecar, readFileSync11(sidecar, "utf8").replace(/^valid=false\r?\n/m, ""));
13198
13273
  utimesSync(sidecar, atime, new Date(mtimeMs + 2000));
13199
- rmSync6(importRecord(projectPath, resourcePath), { force: true });
13274
+ rmSync7(importRecord(projectPath, resourcePath), { force: true });
13200
13275
  }
13201
13276
  function importRecord(projectPath, resourcePath) {
13202
13277
  const digest = createHash3("md5").update(resourcePath).digest("hex");
@@ -13205,7 +13280,7 @@ function importRecord(projectPath, resourcePath) {
13205
13280
  var init_reimport = () => {};
13206
13281
 
13207
13282
  // src/scratch.ts
13208
- import { existsSync as existsSync13, mkdtempSync as mkdtempSync2, readdirSync as readdirSync9, rmSync as rmSync7 } from "node:fs";
13283
+ import { existsSync as existsSync13, mkdtempSync as mkdtempSync2, readdirSync as readdirSync9, rmSync as rmSync8 } from "node:fs";
13209
13284
  import { tmpdir as tmpdir3 } from "node:os";
13210
13285
  import { join as join15 } from "node:path";
13211
13286
  import process10 from "node:process";
@@ -13252,7 +13327,7 @@ function discard(...paths) {
13252
13327
  return left;
13253
13328
  }
13254
13329
  function remove(path) {
13255
- rmSync7(path, SWEPT);
13330
+ rmSync8(path, SWEPT);
13256
13331
  }
13257
13332
  function tryAgain(path, attempt) {
13258
13333
  if (attempt === 0) {
@@ -13420,7 +13495,7 @@ var init_script_origins = __esm(() => {
13420
13495
  });
13421
13496
 
13422
13497
  // src/headless.ts
13423
- import { existsSync as existsSync14, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "node:fs";
13498
+ import { existsSync as existsSync14, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "node:fs";
13424
13499
  import { dirname as dirname7, join as join17 } from "node:path";
13425
13500
  function snakeCased(params) {
13426
13501
  const result = emptyRecord();
@@ -13615,7 +13690,7 @@ async function operationOutcome(engine, operation, params, projectPath) {
13615
13690
  const paramsDir = scratchDirectory("params");
13616
13691
  const paramsFile = join17(paramsDir, `${operation}.json`);
13617
13692
  const answerFile = join17(paramsDir, "answer.json");
13618
- writeFileSync7(paramsFile, JSON.stringify(snakeCased(params)), "utf8");
13693
+ writeFileSync8(paramsFile, JSON.stringify(snakeCased(params)), "utf8");
13619
13694
  const args = [
13620
13695
  "--headless",
13621
13696
  ...engine.editor === true ? ["--editor"] : [],
@@ -13736,7 +13811,7 @@ var init_headless = __esm(() => {
13736
13811
  });
13737
13812
 
13738
13813
  // src/update-check.ts
13739
- import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync8 } from "node:fs";
13814
+ import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
13740
13815
  import { homedir as homedir5, tmpdir as tmpdir4 } from "node:os";
13741
13816
  import { join as join18 } from "node:path";
13742
13817
  function packageUrl(root) {
@@ -13798,7 +13873,7 @@ function readCache(path) {
13798
13873
  }
13799
13874
  function writeCache(path, entry) {
13800
13875
  try {
13801
- writeFileSync8(path, JSON.stringify(entry), { encoding: "utf8", mode: 384 });
13876
+ writeFileSync9(path, JSON.stringify(entry), { encoding: "utf8", mode: 384 });
13802
13877
  } catch {}
13803
13878
  }
13804
13879
  function parts(version) {
@@ -15453,9 +15528,9 @@ import {
15453
15528
  readdirSync as readdirSync11,
15454
15529
  readFileSync as readFileSync17,
15455
15530
  rmdirSync,
15456
- rmSync as rmSync8,
15531
+ rmSync as rmSync9,
15457
15532
  statSync as statSync12,
15458
- writeFileSync as writeFileSync9
15533
+ writeFileSync as writeFileSync10
15459
15534
  } from "node:fs";
15460
15535
  import { dirname as dirname9, join as join21 } from "node:path";
15461
15536
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -15543,7 +15618,7 @@ function writeLoader(projectPath) {
15543
15618
  }
15544
15619
  const copy = join21(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
15545
15620
  mkdirSync6(dirname9(copy), { recursive: true });
15546
- writeFileSync9(copy, readFileSync17(shippedLoader()));
15621
+ writeFileSync10(copy, readFileSync17(shippedLoader()));
15547
15622
  return true;
15548
15623
  }
15549
15624
  function removeLoader(projectPath) {
@@ -15551,8 +15626,8 @@ function removeLoader(projectPath) {
15551
15626
  if (!existsSync18(copy)) {
15552
15627
  return false;
15553
15628
  }
15554
- rmSync8(copy);
15555
- rmSync8(`${copy}.uid`, { force: true });
15629
+ rmSync9(copy);
15630
+ rmSync9(`${copy}.uid`, { force: true });
15556
15631
  const folder = dirname9(copy);
15557
15632
  if (readdirSync11(folder).length === 0) {
15558
15633
  rmdirSync(folder);
@@ -15584,16 +15659,16 @@ function installAddons(projectPath, from = shippedAddonsDirectory()) {
15584
15659
  }
15585
15660
  const target = join21(projectPath, "addons", name);
15586
15661
  const replaced = existsSync18(target);
15587
- rmSync8(target, { recursive: true, force: true });
15662
+ rmSync9(target, { recursive: true, force: true });
15588
15663
  mkdirSync6(dirname9(target), { recursive: true });
15589
15664
  cpSync(source, target, { recursive: true });
15590
- writeFileSync9(join21(target, VERSION_MARKER), `${SERVER_VERSION}
15665
+ writeFileSync10(join21(target, VERSION_MARKER), `${SERVER_VERSION}
15591
15666
  `);
15592
15667
  installed.push({ name, path: target, replaced });
15593
15668
  }
15594
- writeFileSync9(join21(projectPath, "addons", ADDONS[0], DIGEST_MARKER), `${editorAddonDigest(from)}
15669
+ writeFileSync10(join21(projectPath, "addons", ADDONS[0], DIGEST_MARKER), `${editorAddonDigest(from)}
15595
15670
  `);
15596
- writeFileSync9(join21(projectPath, "addons", RUNTIME_ADDON, DIGEST_MARKER), `${runtimeAddonDigest(from)}
15671
+ writeFileSync10(join21(projectPath, "addons", RUNTIME_ADDON, DIGEST_MARKER), `${runtimeAddonDigest(from)}
15597
15672
  `);
15598
15673
  return installed;
15599
15674
  }
@@ -15610,7 +15685,7 @@ function removeAddons(projectPath) {
15610
15685
  for (const name of ADDONS) {
15611
15686
  const target = join21(projectPath, "addons", name);
15612
15687
  if (existsSync18(target)) {
15613
- rmSync8(target, { recursive: true, force: true });
15688
+ rmSync9(target, { recursive: true, force: true });
15614
15689
  removed.push(target);
15615
15690
  }
15616
15691
  }
@@ -18248,37 +18323,6 @@ var init_tool_reference = __esm(() => {
18248
18323
  init_tool_definitions();
18249
18324
  });
18250
18325
 
18251
- // src/whole-file.ts
18252
- import { renameSync as renameSync2, rmSync as rmSync11, writeFileSync as writeFileSync11 } from "node:fs";
18253
- function writeWhole(path, text) {
18254
- const partial = `${path}.${process.pid}.partial`;
18255
- try {
18256
- writeFileSync11(partial, text, "utf8");
18257
- } catch {
18258
- return false;
18259
- }
18260
- const until = Date.now() + HELD_FILE_MS;
18261
- for (;; ) {
18262
- try {
18263
- renameSync2(partial, path);
18264
- return true;
18265
- } catch (error) {
18266
- const code = error.code ?? "";
18267
- if (!HELD_BY_A_READER.has(code) || Date.now() >= until) {
18268
- try {
18269
- rmSync11(partial, { force: true });
18270
- } catch {}
18271
- return false;
18272
- }
18273
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, HELD_FILE_RETRY_MS);
18274
- }
18275
- }
18276
- }
18277
- var HELD_FILE_MS = 1000, HELD_FILE_RETRY_MS = 10, HELD_BY_A_READER;
18278
- var init_whole_file = __esm(() => {
18279
- HELD_BY_A_READER = new Set(["EPERM", "EACCES", "EBUSY"]);
18280
- });
18281
-
18282
18326
  // src/suite-plan.ts
18283
18327
  import { existsSync as existsSync22, mkdirSync as mkdirSync9, readFileSync as readFileSync20 } from "node:fs";
18284
18328
  import { dirname as dirname11, join as join25, posix as posix3 } from "node:path";
@@ -57543,7 +57587,7 @@ init_setup();
57543
57587
  init_setup();
57544
57588
  init_tool_definitions();
57545
57589
  init_tool_reference();
57546
- import { existsSync as existsSync19, mkdirSync as mkdirSync7, readdirSync as readdirSync12, rmSync as rmSync9, writeFileSync as writeFileSync10 } from "node:fs";
57590
+ import { existsSync as existsSync19, mkdirSync as mkdirSync7, readdirSync as readdirSync12, rmSync as rmSync10, writeFileSync as writeFileSync11 } from "node:fs";
57547
57591
  import { basename as basename8, dirname as dirname10, join as join22 } from "node:path";
57548
57592
  var SKILL_NAME = "gdharness";
57549
57593
  var SHARED_SKILLS = join22(".agents", "skills");
@@ -57816,7 +57860,7 @@ function removeSkill(directories, projectPath) {
57816
57860
  const removed = [];
57817
57861
  for (const directory of directories) {
57818
57862
  if (existsSync19(directory)) {
57819
- rmSync9(directory, { recursive: true, force: true });
57863
+ rmSync10(directory, { recursive: true, force: true });
57820
57864
  pruneEmpty(dirname10(directory), projectPath);
57821
57865
  removed.push(directory);
57822
57866
  }
@@ -57830,7 +57874,7 @@ function pruneEmpty(directory, projectPath) {
57830
57874
  if (readdirSync12(path).length > 0) {
57831
57875
  return;
57832
57876
  }
57833
- rmSync9(path, { recursive: true, force: true });
57877
+ rmSync10(path, { recursive: true, force: true });
57834
57878
  path = dirname10(path);
57835
57879
  }
57836
57880
  }
@@ -57838,11 +57882,11 @@ function writeSkill(directories, version) {
57838
57882
  const files = skillFiles(version);
57839
57883
  return directories.map((directory) => {
57840
57884
  const replaced = existsSync19(directory);
57841
- rmSync9(directory, { recursive: true, force: true });
57885
+ rmSync10(directory, { recursive: true, force: true });
57842
57886
  for (const [name, contents] of files) {
57843
57887
  const path = join22(directory, name);
57844
57888
  mkdirSync7(dirname10(path), { recursive: true });
57845
- writeFileSync10(path, contents, "utf8");
57889
+ writeFileSync11(path, contents, "utf8");
57846
57890
  }
57847
57891
  return { path: directory, replaced };
57848
57892
  });
@@ -57853,7 +57897,7 @@ init_engine_launch();
57853
57897
  init_engine_slots();
57854
57898
  init_setup();
57855
57899
  init_suite_judge();
57856
- import { existsSync as existsSync20, mkdirSync as mkdirSync8, readFileSync as readFileSync18, rmSync as rmSync10 } from "node:fs";
57900
+ import { existsSync as existsSync20, mkdirSync as mkdirSync8, readFileSync as readFileSync18, rmSync as rmSync11 } from "node:fs";
57857
57901
  import { availableParallelism as availableParallelism3 } from "node:os";
57858
57902
  import { join as join23, resolve as resolve9 } from "node:path";
57859
57903
  import process13 from "node:process";
@@ -58063,7 +58107,7 @@ async function runSpreadCommand(options, godotPath) {
58063
58107
  const longest = Math.max(0, ...left.map((worker) => worker.seconds));
58064
58108
  console.log("");
58065
58109
  console.log(`Spread: ${plural(runs, "run")} in ${plural((arms[0] ?? []).length, "arm")} over ${plural(workers, "worker")}, ${((Date.now() - startedAt) / 1000).toFixed(1)} s; the longest worker took ${longest.toFixed(1)} s.`);
58066
- rmSync10(runDirectory, { recursive: true, force: true });
58110
+ rmSync11(runDirectory, { recursive: true, force: true });
58067
58111
  return 0;
58068
58112
  } finally {
58069
58113
  process13.off("SIGINT", interrupted);
package/build/keeper.js CHANGED
@@ -8482,6 +8482,36 @@ function commandWords(command) {
8482
8482
  return words;
8483
8483
  }
8484
8484
 
8485
+ // src/whole-file.ts
8486
+ import { renameSync, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
8487
+ var HELD_FILE_MS = 1000;
8488
+ var HELD_FILE_RETRY_MS = 10;
8489
+ var HELD_BY_A_READER = new Set(["EPERM", "EACCES", "EBUSY"]);
8490
+ function writeWhole(path, text) {
8491
+ const partial = `${path}.${process.pid}.partial`;
8492
+ try {
8493
+ writeFileSync2(partial, text, "utf8");
8494
+ } catch {
8495
+ return false;
8496
+ }
8497
+ const until = Date.now() + HELD_FILE_MS;
8498
+ for (;; ) {
8499
+ try {
8500
+ renameSync(partial, path);
8501
+ return true;
8502
+ } catch (error) {
8503
+ const code = error.code ?? "";
8504
+ if (!HELD_BY_A_READER.has(code) || Date.now() >= until) {
8505
+ try {
8506
+ rmSync2(partial, { force: true });
8507
+ } catch {}
8508
+ return false;
8509
+ }
8510
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, HELD_FILE_RETRY_MS);
8511
+ }
8512
+ }
8513
+ }
8514
+
8485
8515
  // src/game-log.ts
8486
8516
  var COLOUR_CODE = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
8487
8517
  var ADMITTED = {
@@ -8589,7 +8619,7 @@ var IMPORTABLE = new Set(IMPORTABLE_EXTENSIONS);
8589
8619
  var hashes = new Map;
8590
8620
 
8591
8621
  // src/scratch.ts
8592
- import { existsSync as existsSync2, mkdtempSync as mkdtempSync2, readdirSync, rmSync as rmSync2 } from "node:fs";
8622
+ import { existsSync as existsSync2, mkdtempSync as mkdtempSync2, readdirSync, rmSync as rmSync3 } from "node:fs";
8593
8623
  import { tmpdir as tmpdir2 } from "node:os";
8594
8624
  import { join as join4 } from "node:path";
8595
8625
  import process4 from "node:process";
@@ -8622,7 +8652,7 @@ function discard(...paths) {
8622
8652
  return left;
8623
8653
  }
8624
8654
  function remove(path) {
8625
- rmSync2(path, SWEPT);
8655
+ rmSync3(path, SWEPT);
8626
8656
  }
8627
8657
  function tryAgain(path, attempt) {
8628
8658
  if (attempt === 0) {
@@ -9453,7 +9483,7 @@ class GameDebugger {
9453
9483
 
9454
9484
  // src/keeper-channel.ts
9455
9485
  import { randomUUID } from "node:crypto";
9456
- import { mkdtempSync as mkdtempSync3, rmSync as rmSync3 } from "node:fs";
9486
+ import { mkdtempSync as mkdtempSync3, rmSync as rmSync4 } from "node:fs";
9457
9487
  import { connect, createServer as createServer2 } from "node:net";
9458
9488
  import { tmpdir as tmpdir3 } from "node:os";
9459
9489
  import { join as join7 } from "node:path";
@@ -9521,13 +9551,13 @@ async function listenForTheServer(end, debug) {
9521
9551
  close: () => {
9522
9552
  server.close();
9523
9553
  if (made !== null) {
9524
- rmSync3(made, { recursive: true, force: true });
9554
+ rmSync4(made, { recursive: true, force: true });
9525
9555
  }
9526
9556
  }
9527
9557
  };
9528
9558
  } catch {
9529
9559
  if (directory !== null) {
9530
- rmSync3(directory, { recursive: true, force: true });
9560
+ rmSync4(directory, { recursive: true, force: true });
9531
9561
  }
9532
9562
  return null;
9533
9563
  }
@@ -9636,36 +9666,6 @@ var LATE_ANSWER_MS = 30 * 60000;
9636
9666
  var lateAnswers = new Map;
9637
9667
  var untaken = new Map;
9638
9668
 
9639
- // src/whole-file.ts
9640
- import { renameSync, rmSync as rmSync4, writeFileSync as writeFileSync2 } from "node:fs";
9641
- var HELD_FILE_MS = 1000;
9642
- var HELD_FILE_RETRY_MS = 10;
9643
- var HELD_BY_A_READER = new Set(["EPERM", "EACCES", "EBUSY"]);
9644
- function writeWhole(path, text) {
9645
- const partial = `${path}.${process.pid}.partial`;
9646
- try {
9647
- writeFileSync2(partial, text, "utf8");
9648
- } catch {
9649
- return false;
9650
- }
9651
- const until = Date.now() + HELD_FILE_MS;
9652
- for (;; ) {
9653
- try {
9654
- renameSync(partial, path);
9655
- return true;
9656
- } catch (error) {
9657
- const code = error.code ?? "";
9658
- if (!HELD_BY_A_READER.has(code) || Date.now() >= until) {
9659
- try {
9660
- rmSync4(partial, { force: true });
9661
- } catch {}
9662
- return false;
9663
- }
9664
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, HELD_FILE_RETRY_MS);
9665
- }
9666
- }
9667
- }
9668
-
9669
9669
  // src/run-record.ts
9670
9670
  function runsDirectory() {
9671
9671
  return join9(runtimeDirectory(), "runs");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdharness",
3
- "version": "1.3.25",
3
+ "version": "1.3.26",
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",