gdharness 1.3.44 → 1.3.45

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
@@ -11818,6 +11818,16 @@ var init_engine_launch = __esm(() => {
11818
11818
  MEMORY_PER_ENGINE = 1.5 * 1024 ** 3;
11819
11819
  });
11820
11820
 
11821
+ // src/cache-home.ts
11822
+ import { homedir as homedir2 } from "node:os";
11823
+ import { join as join8 } from "node:path";
11824
+ function cacheHome(env = process.env, platform = process.platform, home = homedir2()) {
11825
+ const set = (name) => env[name] === "" ? undefined : env[name];
11826
+ const local = platform === "win32" ? set("LOCALAPPDATA") : undefined;
11827
+ return join8(set("XDG_CACHE_HOME") ?? local ?? join8(home, ".cache"), "gdharness");
11828
+ }
11829
+ var init_cache_home = () => {};
11830
+
11821
11831
  // src/call-signal.ts
11822
11832
  import { AsyncLocalStorage } from "node:async_hooks";
11823
11833
  function stillGoingSaid(tool, op, elapsedMs) {
@@ -11889,8 +11899,8 @@ import {
11889
11899
  watch,
11890
11900
  writeSync as writeSync3
11891
11901
  } from "node:fs";
11892
- import { availableParallelism as availableParallelism2, homedir as homedir2 } from "node:os";
11893
- import { join as join8, resolve as resolve4 } from "node:path";
11902
+ import { availableParallelism as availableParallelism2, homedir as homedir3 } from "node:os";
11903
+ import { join as join9, resolve as resolve4 } from "node:path";
11894
11904
  import process7 from "node:process";
11895
11905
  import { setTimeout as delay3 } from "node:timers/promises";
11896
11906
  function machineSlots(asked = {
@@ -11900,15 +11910,13 @@ function machineSlots(asked = {
11900
11910
  env: process7.env,
11901
11911
  platform: process7.platform,
11902
11912
  processors: availableParallelism2(),
11903
- home: homedir2(),
11913
+ home: homedir3(),
11904
11914
  cwd: process7.cwd()
11905
11915
  }) {
11906
11916
  const { env } = machine;
11907
11917
  const named = nonEmpty(env[SLOTS_VARIABLE]);
11908
- const xdg = nonEmpty(env["XDG_CACHE_HOME"]);
11909
- const local = machine.platform === "win32" ? nonEmpty(env["LOCALAPPDATA"]) : undefined;
11910
- const cache = join8(xdg ?? local ?? join8(machine.home, ".cache"), "gdharness");
11911
- const directory = asked.directory ?? (named === undefined ? join8(cache, "slots") : resolve4(machine.cwd, named));
11918
+ const cache = cacheHome(env, machine.platform, machine.home);
11919
+ const directory = asked.directory ?? (named === undefined ? join9(cache, "slots") : resolve4(machine.cwd, named));
11912
11920
  const counted = nonEmpty(env[SLOT_COUNT_VARIABLE]);
11913
11921
  let count = asked.count;
11914
11922
  if (count === null && counted !== undefined) {
@@ -12056,7 +12064,7 @@ class EngineSlots {
12056
12064
  async takeFree() {
12057
12065
  mkdirSync3(this.directory, { recursive: true });
12058
12066
  for (let slot = 0;slot < this.count; slot += 1) {
12059
- const lock = join8(this.directory, `${String(slot)}.lock`);
12067
+ const lock = join9(this.directory, `${String(slot)}.lock`);
12060
12068
  if (this.made(lock) || await this.takenOver(lock)) {
12061
12069
  this.held.add(lock);
12062
12070
  return lock;
@@ -12065,9 +12073,9 @@ class EngineSlots {
12065
12073
  return null;
12066
12074
  }
12067
12075
  waitMarked() {
12068
- const marks = join8(this.directory, WAITING_FOLDER);
12076
+ const marks = join9(this.directory, WAITING_FOLDER);
12069
12077
  waitsMarked += 1;
12070
- const mark = join8(marks, `${String(this.holder.pid)}-${String(waitsMarked)}.json`);
12078
+ const mark = join9(marks, `${String(this.holder.pid)}-${String(waitsMarked)}.json`);
12071
12079
  try {
12072
12080
  mkdirSync3(marks, { recursive: true });
12073
12081
  } catch {
@@ -12083,7 +12091,7 @@ class EngineSlots {
12083
12091
  const found = [];
12084
12092
  for (let slot = 0;slot < this.count; slot += 1) {
12085
12093
  try {
12086
- const holder = holderOf(readFileSync8(join8(this.directory, `${String(slot)}.lock`), "utf8"));
12094
+ const holder = holderOf(readFileSync8(join9(this.directory, `${String(slot)}.lock`), "utf8"));
12087
12095
  if (holder !== null) {
12088
12096
  found.push(holder);
12089
12097
  }
@@ -12257,6 +12265,7 @@ async function inASlot(body) {
12257
12265
  var SLOTS_VARIABLE = "GODOT_ENGINE_SLOTS", SLOT_COUNT_VARIABLE = "GODOT_ENGINE_SLOT_COUNT", PROCESSORS_A_SLOT = 2, START_TOLERANCE_MS = 2000, UNWRITTEN_MS = 1e4, SLOT_LOOK_MS = 1000, SLOT_SETTLE_MS = 50, WAIT_SAID_MS = 20000, COMMAND_WAIT_SAID_MS = 2000, START_READ_MS = 1e4, WAITING_FOLDER = "waiting", waitsMarked = 0, ours, saidTo, takenBy;
12258
12266
  var init_engine_slots = __esm(() => {
12259
12267
  init_alive();
12268
+ init_cache_home();
12260
12269
  init_call_signal();
12261
12270
  init_engine_launch();
12262
12271
  init_process_children();
@@ -12265,11 +12274,11 @@ var init_engine_slots = __esm(() => {
12265
12274
 
12266
12275
  // src/detection.ts
12267
12276
  import { existsSync as existsSync6, readdirSync as readdirSync4, statSync as statSync7 } from "node:fs";
12268
- import { homedir as homedir3 } from "node:os";
12269
- import { join as join9 } from "node:path";
12277
+ import { homedir as homedir4 } from "node:os";
12278
+ import { join as join10 } from "node:path";
12270
12279
  function resolveHomeDirectory() {
12271
12280
  try {
12272
- return homedir3();
12281
+ return homedir4();
12273
12282
  } catch {
12274
12283
  return "";
12275
12284
  }
@@ -12290,7 +12299,7 @@ function scanDirectoryForGodotBinaries(directory, platform) {
12290
12299
  if (!pattern.test(name)) {
12291
12300
  continue;
12292
12301
  }
12293
- const fullPath = join9(directory, name);
12302
+ const fullPath = join10(directory, name);
12294
12303
  try {
12295
12304
  const stat = statSync7(fullPath);
12296
12305
  if (stat.isFile()) {
@@ -12299,7 +12308,7 @@ function scanDirectoryForGodotBinaries(directory, platform) {
12299
12308
  } catch {}
12300
12309
  }
12301
12310
  matches.sort((a, b) => b.mtime - a.mtime);
12302
- return matches.map((m) => join9(directory, m.name));
12311
+ return matches.map((m) => join10(directory, m.name));
12303
12312
  }
12304
12313
  function conventionalPaths(platform, home) {
12305
12314
  const paths = ["godot"];
@@ -12954,26 +12963,26 @@ var init_engine_run = __esm(() => {
12954
12963
 
12955
12964
  // src/doc-cache.ts
12956
12965
  import { existsSync as existsSync8, readdirSync as readdirSync5, statSync as statSync8 } from "node:fs";
12957
- import { homedir as homedir4 } from "node:os";
12958
- import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute5, join as join10 } from "node:path";
12966
+ import { homedir as homedir5 } from "node:os";
12967
+ import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute5, join as join11 } from "node:path";
12959
12968
  import process9 from "node:process";
12960
- function editorCacheDirectory(godotPath, platform = process9.platform, env = process9.env, home = homedir4()) {
12969
+ function editorCacheDirectory(godotPath, platform = process9.platform, env = process9.env, home = homedir5()) {
12961
12970
  const beside = dirname5(godotPath);
12962
12971
  const bundle = platform === "darwin" && basename4(beside) === "MacOS" && basename4(dirname5(beside)) === "Contents" ? dirname5(dirname5(dirname5(beside))) : null;
12963
12972
  for (const folder of bundle === null ? [beside] : [beside, bundle]) {
12964
- if (existsSync8(join10(folder, "._sc_")) || existsSync8(join10(folder, "_sc_"))) {
12965
- return join10(folder, "editor_data", "cache");
12973
+ if (existsSync8(join11(folder, "._sc_")) || existsSync8(join11(folder, "_sc_"))) {
12974
+ return join11(folder, "editor_data", "cache");
12966
12975
  }
12967
12976
  }
12968
12977
  if (platform === "win32") {
12969
12978
  const set = (name) => env[name] === "" ? undefined : env[name];
12970
- return join10(set("LOCALAPPDATA") ?? set("TEMP") ?? join10(home, "AppData", "Local"), "Godot");
12979
+ return join11(set("LOCALAPPDATA") ?? set("TEMP") ?? join11(home, "AppData", "Local"), "Godot");
12971
12980
  }
12972
12981
  if (platform === "darwin") {
12973
- return join10(home, "Library", "Caches", "Godot");
12982
+ return join11(home, "Library", "Caches", "Godot");
12974
12983
  }
12975
12984
  const xdg = env["XDG_CACHE_HOME"];
12976
- return join10(xdg !== undefined && isAbsolute5(xdg) ? xdg : join10(home, ".cache"), "godot");
12985
+ return join11(xdg !== undefined && isAbsolute5(xdg) ? xdg : join11(home, ".cache"), "godot");
12977
12986
  }
12978
12987
  function docCachesWritten(directory) {
12979
12988
  const written = new Map;
@@ -12985,7 +12994,7 @@ function docCachesWritten(directory) {
12985
12994
  }
12986
12995
  for (const name of names.filter((one) => CACHE_FILE.test(one))) {
12987
12996
  try {
12988
- written.set(join10(directory, name), statSync8(join10(directory, name)).mtimeMs);
12997
+ written.set(join11(directory, name), statSync8(join11(directory, name)).mtimeMs);
12989
12998
  } catch {}
12990
12999
  }
12991
13000
  return written;
@@ -13010,7 +13019,7 @@ var init_doc_cache = __esm(() => {
13010
13019
 
13011
13020
  // src/project-scan.ts
13012
13021
  import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as readFileSync9, statSync as statSync9 } from "node:fs";
13013
- import { basename as basename5, extname, join as join11, relative as relative4, sep as sep3 } from "node:path";
13022
+ import { basename as basename5, extname, join as join12, relative as relative4, sep as sep3 } from "node:path";
13014
13023
  function skipped(name) {
13015
13024
  return name.startsWith(".") || SKIPPED.has(name);
13016
13025
  }
@@ -13018,10 +13027,10 @@ function steppedOver(directory) {
13018
13027
  return gdignored(directory) || installedByUs(directory);
13019
13028
  }
13020
13029
  function gdignored(directory) {
13021
- return existsSync9(join11(directory, ".gdignore"));
13030
+ return existsSync9(join12(directory, ".gdignore"));
13022
13031
  }
13023
13032
  function installedByUs(directory) {
13024
- return existsSync9(join11(directory, VERSION_MARKER));
13033
+ return existsSync9(join12(directory, VERSION_MARKER));
13025
13034
  }
13026
13035
  function projectStructure(projectPath) {
13027
13036
  const structure = { scenes: 0, scripts: 0, assets: 0, other: 0 };
@@ -13034,7 +13043,7 @@ function projectStructure(projectPath) {
13034
13043
  continue;
13035
13044
  }
13036
13045
  if (entry.isDirectory()) {
13037
- visit(join11(directory, entry.name));
13046
+ visit(join12(directory, entry.name));
13038
13047
  } else if (entry.isFile()) {
13039
13048
  const extension = entry.name.split(".").pop()?.toLowerCase() ?? "";
13040
13049
  if (SIDECAR_EXTENSIONS.has(extension)) {
@@ -13064,7 +13073,7 @@ function folderFiles(directory, extensions) {
13064
13073
  function underGdignore(projectPath, relative) {
13065
13074
  const folders = relative.split("/").slice(0, -1);
13066
13075
  for (let depth = 1;depth <= folders.length; depth += 1) {
13067
- if (gdignored(join11(projectPath, ...folders.slice(0, depth)))) {
13076
+ if (gdignored(join12(projectPath, ...folders.slice(0, depth)))) {
13068
13077
  return true;
13069
13078
  }
13070
13079
  }
@@ -13081,7 +13090,7 @@ function steppedOverIn(directory) {
13081
13090
  continue;
13082
13091
  }
13083
13092
  const spelled = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
13084
- const path = join11(at, entry.name);
13093
+ const path = join12(at, entry.name);
13085
13094
  if (gdignored(path)) {
13086
13095
  found.push({ folder: spelled, why: "gdignore" });
13087
13096
  } else if (installedByUs(path)) {
@@ -13102,7 +13111,7 @@ function filesBelow(root, extensions) {
13102
13111
  continue;
13103
13112
  }
13104
13113
  const spelled = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
13105
- const path = join11(directory, entry.name);
13114
+ const path = join12(directory, entry.name);
13106
13115
  if (entry.isDirectory()) {
13107
13116
  if (!steppedOver(path)) {
13108
13117
  visit(path, spelled);
@@ -13127,14 +13136,14 @@ function scriptsWithoutUid(projectPath) {
13127
13136
  }
13128
13137
  const spelled = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
13129
13138
  if (entry.isDirectory()) {
13130
- visit(join11(directory, entry.name), spelled);
13139
+ visit(join12(directory, entry.name), spelled);
13131
13140
  continue;
13132
13141
  }
13133
13142
  if (!entry.isFile()) {
13134
13143
  continue;
13135
13144
  }
13136
13145
  const extension = entry.name.split(".").pop()?.toLowerCase() ?? "";
13137
- if (CARRIES_A_UID.has(extension) && !existsSync9(join11(directory, `${entry.name}.uid`))) {
13146
+ if (CARRIES_A_UID.has(extension) && !existsSync9(join12(directory, `${entry.name}.uid`))) {
13138
13147
  found.push(spelled);
13139
13148
  }
13140
13149
  }
@@ -13145,7 +13154,7 @@ function scriptsWithoutUid(projectPath) {
13145
13154
  function pathsInUidCache(projectPath) {
13146
13155
  let data;
13147
13156
  try {
13148
- data = readFileSync9(join11(projectPath, ".godot", "uid_cache.bin"));
13157
+ data = readFileSync9(join12(projectPath, ".godot", "uid_cache.bin"));
13149
13158
  } catch {
13150
13159
  return null;
13151
13160
  }
@@ -13173,7 +13182,7 @@ function pathsInUidCache(projectPath) {
13173
13182
  function steppedOverAround(projectPath, place) {
13174
13183
  let at = projectPath;
13175
13184
  for (const step of relative4(projectPath, place).split(sep3).filter((part) => part !== "")) {
13176
- at = join11(at, step);
13185
+ at = join12(at, step);
13177
13186
  if (!statSync9(at).isDirectory()) {
13178
13187
  break;
13179
13188
  }
@@ -13197,7 +13206,7 @@ function projectTexts(projectPath) {
13197
13206
  if (skipped(entry.name)) {
13198
13207
  continue;
13199
13208
  }
13200
- const absolute = join11(directory, entry.name);
13209
+ const absolute = join12(directory, entry.name);
13201
13210
  const spelled = `${prefix}${entry.name}`;
13202
13211
  if (entry.isDirectory()) {
13203
13212
  visit(absolute, `${spelled}/`);
@@ -13227,7 +13236,7 @@ function ignoredTexts(projectPath) {
13227
13236
  if (skipped(entry.name)) {
13228
13237
  continue;
13229
13238
  }
13230
- const absolute = join11(directory, entry.name);
13239
+ const absolute = join12(directory, entry.name);
13231
13240
  const spelled = `${prefix}${entry.name}`;
13232
13241
  if (entry.isDirectory()) {
13233
13242
  visit(absolute, `${spelled}/`, under);
@@ -13325,7 +13334,7 @@ function searchProject(projectPath, options) {
13325
13334
  if (skipped(entry.name)) {
13326
13335
  continue;
13327
13336
  }
13328
- const entryPath = join11(directory, entry.name);
13337
+ const entryPath = join12(directory, entry.name);
13329
13338
  if (entry.isDirectory()) {
13330
13339
  visit(entryPath);
13331
13340
  } else if (entry.isFile()) {
@@ -13402,7 +13411,7 @@ var init_project_scan = __esm(() => {
13402
13411
  // src/import-freshness.ts
13403
13412
  import { createHash as createHash2 } from "node:crypto";
13404
13413
  import { existsSync as existsSync10, readdirSync as readdirSync7, readFileSync as readFileSync10, statSync as statSync10 } from "node:fs";
13405
- import { join as join12 } from "node:path";
13414
+ import { join as join13 } from "node:path";
13406
13415
  function md5Of(file) {
13407
13416
  let stats;
13408
13417
  try {
@@ -13462,7 +13471,7 @@ function importedIntoTheProject(projectPath, resPaths) {
13462
13471
  return wrote;
13463
13472
  }
13464
13473
  function onDisk(projectPath, resPath) {
13465
- return join12(projectPath, resPath.slice("res://".length));
13474
+ return join13(projectPath, resPath.slice("res://".length));
13466
13475
  }
13467
13476
  function behind(projectPath, resPath, sidecar) {
13468
13477
  const remap = sectionOf(sidecar, "remap");
@@ -13475,7 +13484,7 @@ function behind(projectPath, resPath, sidecar) {
13475
13484
  return "its imported output is not on disk";
13476
13485
  }
13477
13486
  const name = resPath.slice(resPath.lastIndexOf("/") + 1);
13478
- const record = join12(projectPath, ".godot", "imported", `${name}-${createHash2("md5").update(resPath, "utf8").digest("hex")}.md5`);
13487
+ const record = join13(projectPath, ".godot", "imported", `${name}-${createHash2("md5").update(resPath, "utf8").digest("hex")}.md5`);
13479
13488
  let recorded = "";
13480
13489
  try {
13481
13490
  recorded = /^source_md5="([0-9a-f]*)"/m.exec(readFileSync10(record, "utf8"))?.[1] ?? "";
@@ -13491,7 +13500,7 @@ function behind(projectPath, resPath, sidecar) {
13491
13500
  function staleImports(projectPath) {
13492
13501
  const stale = [];
13493
13502
  const visit = (directory, resDirectory) => {
13494
- if (existsSync10(join12(directory, ".gdignore")) || existsSync10(join12(directory, VERSION_MARKER))) {
13503
+ if (existsSync10(join13(directory, ".gdignore")) || existsSync10(join13(directory, VERSION_MARKER))) {
13495
13504
  return;
13496
13505
  }
13497
13506
  let entries;
@@ -13507,7 +13516,7 @@ function staleImports(projectPath) {
13507
13516
  }
13508
13517
  const resPath = `${resDirectory}${entry.name}`;
13509
13518
  if (entry.isDirectory()) {
13510
- visit(join12(directory, entry.name), `${resPath}/`);
13519
+ visit(join13(directory, entry.name), `${resPath}/`);
13511
13520
  continue;
13512
13521
  }
13513
13522
  if (!entry.isFile()) {
@@ -13520,7 +13529,7 @@ function staleImports(projectPath) {
13520
13529
  }
13521
13530
  let sidecar;
13522
13531
  try {
13523
- sidecar = readFileSync10(join12(directory, entry.name), "utf8");
13532
+ sidecar = readFileSync10(join13(directory, entry.name), "utf8");
13524
13533
  } catch {
13525
13534
  continue;
13526
13535
  }
@@ -13589,7 +13598,7 @@ import {
13589
13598
  unlinkSync,
13590
13599
  writeFileSync as writeFileSync6
13591
13600
  } from "node:fs";
13592
- import { basename as basename6, dirname as dirname6, isAbsolute as isAbsolute6, join as join13 } from "node:path";
13601
+ import { basename as basename6, dirname as dirname6, isAbsolute as isAbsolute6, join as join14 } from "node:path";
13593
13602
  function freeLibraryCopies(projectPath, platform = process.platform) {
13594
13603
  const setAside = [];
13595
13604
  const swept = [];
@@ -13599,10 +13608,10 @@ function freeLibraryCopies(projectPath, platform = process.platform) {
13599
13608
  for (const library of windowsLibraries(projectPath)) {
13600
13609
  const folder = dirname6(library);
13601
13610
  const copy = `~${basename6(library)}`;
13602
- if (existsSync11(join13(folder, copy))) {
13603
- const aside = join13(folder, `${copy}.aside-${process.pid}-${Date.now()}`);
13611
+ if (existsSync11(join14(folder, copy))) {
13612
+ const aside = join14(folder, `${copy}.aside-${process.pid}-${Date.now()}`);
13604
13613
  try {
13605
- renameSync2(join13(folder, copy), aside);
13614
+ renameSync2(join14(folder, copy), aside);
13606
13615
  setAside.push(aside);
13607
13616
  } catch {}
13608
13617
  }
@@ -13615,8 +13624,8 @@ function freeLibraryCopies(projectPath, platform = process.platform) {
13615
13624
  for (const name of names) {
13616
13625
  if (name.length > copy.length && name.toLowerCase().startsWith(copy.toLowerCase())) {
13617
13626
  try {
13618
- unlinkSync(join13(folder, name));
13619
- swept.push(join13(folder, name));
13627
+ unlinkSync(join14(folder, name));
13628
+ swept.push(join14(folder, name));
13620
13629
  } catch {}
13621
13630
  }
13622
13631
  }
@@ -13624,13 +13633,13 @@ function freeLibraryCopies(projectPath, platform = process.platform) {
13624
13633
  return { setAside, swept };
13625
13634
  }
13626
13635
  function seedExtensionList(projectPath) {
13627
- const list = join13(projectPath, ".godot", "extension_list.cfg");
13636
+ const list = join14(projectPath, ".godot", "extension_list.cfg");
13628
13637
  if (existsSync11(list)) {
13629
13638
  return null;
13630
13639
  }
13631
13640
  const found = [];
13632
13641
  const visit = (directory, resDirectory) => {
13633
- if (existsSync11(join13(directory, ".gdignore"))) {
13642
+ if (existsSync11(join14(directory, ".gdignore"))) {
13634
13643
  return;
13635
13644
  }
13636
13645
  let entries;
@@ -13644,7 +13653,7 @@ function seedExtensionList(projectPath) {
13644
13653
  continue;
13645
13654
  }
13646
13655
  if (entry.isDirectory()) {
13647
- visit(join13(directory, entry.name), `${resDirectory}${entry.name}/`);
13656
+ visit(join14(directory, entry.name), `${resDirectory}${entry.name}/`);
13648
13657
  } else if (entry.name.endsWith(".gdextension")) {
13649
13658
  found.push(`${resDirectory}${entry.name}`);
13650
13659
  }
@@ -13662,7 +13671,7 @@ function seedExtensionList(projectPath) {
13662
13671
  return found;
13663
13672
  }
13664
13673
  function windowsLibraries(projectPath) {
13665
- const listed = readOrNull(join13(projectPath, ".godot", "extension_list.cfg"));
13674
+ const listed = readOrNull(join14(projectPath, ".godot", "extension_list.cfg"));
13666
13675
  if (listed === null) {
13667
13676
  return [];
13668
13677
  }
@@ -13694,9 +13703,9 @@ function resolveResource(projectPath, relativeTo, path) {
13694
13703
  return null;
13695
13704
  }
13696
13705
  if (path.startsWith("res://")) {
13697
- return join13(projectPath, path.slice("res://".length));
13706
+ return join14(projectPath, path.slice("res://".length));
13698
13707
  }
13699
- return isAbsolute6(path) ? path : join13(relativeTo, path);
13708
+ return isAbsolute6(path) ? path : join14(relativeTo, path);
13700
13709
  }
13701
13710
  function readOrNull(path) {
13702
13711
  try {
@@ -13710,10 +13719,10 @@ var init_library_copies = () => {};
13710
13719
  // src/reimport.ts
13711
13720
  import { createHash as createHash3 } from "node:crypto";
13712
13721
  import { existsSync as existsSync12, readFileSync as readFileSync12, rmSync as rmSync7, statSync as statSync11, utimesSync, writeFileSync as writeFileSync7 } from "node:fs";
13713
- import { basename as basename7, join as join14 } from "node:path";
13722
+ import { basename as basename7, join as join15 } from "node:path";
13714
13723
  function forceNextImport(projectPath, resourcePath) {
13715
13724
  const relative = resourcePath.replace(/^res:\/\//, "");
13716
- const sidecar = join14(projectPath, `${relative}.import`);
13725
+ const sidecar = join15(projectPath, `${relative}.import`);
13717
13726
  if (!existsSync12(sidecar)) {
13718
13727
  return;
13719
13728
  }
@@ -13724,17 +13733,17 @@ function forceNextImport(projectPath, resourcePath) {
13724
13733
  }
13725
13734
  function importRecord(projectPath, resourcePath) {
13726
13735
  const digest = createHash3("md5").update(resourcePath).digest("hex");
13727
- return join14(projectPath, ".godot", "imported", `${basename7(resourcePath)}-${digest}.md5`);
13736
+ return join15(projectPath, ".godot", "imported", `${basename7(resourcePath)}-${digest}.md5`);
13728
13737
  }
13729
13738
  var init_reimport = () => {};
13730
13739
 
13731
13740
  // src/scratch.ts
13732
13741
  import { existsSync as existsSync13, mkdtempSync as mkdtempSync2, readdirSync as readdirSync9, rmSync as rmSync8 } from "node:fs";
13733
13742
  import { tmpdir as tmpdir3 } from "node:os";
13734
- import { join as join15 } from "node:path";
13743
+ import { join as join16 } from "node:path";
13735
13744
  import process10 from "node:process";
13736
13745
  function scratchDirectory(kind) {
13737
- return mkdtempSync2(join15(tmpdir3(), `gdharness-${kind}-${process10.pid}-`));
13746
+ return mkdtempSync2(join16(tmpdir3(), `gdharness-${kind}-${process10.pid}-`));
13738
13747
  }
13739
13748
  function sweepAbandonedScratch(directory = tmpdir3()) {
13740
13749
  let entries;
@@ -13750,7 +13759,7 @@ function sweepAbandonedScratch(directory = tmpdir3()) {
13750
13759
  continue;
13751
13760
  }
13752
13761
  try {
13753
- remove(join15(directory, entry));
13762
+ remove(join16(directory, entry));
13754
13763
  } catch {}
13755
13764
  }
13756
13765
  }
@@ -13836,7 +13845,7 @@ var init_scratch = __esm(() => {
13836
13845
  });
13837
13846
 
13838
13847
  // src/script-origins.ts
13839
- import { join as join16 } from "node:path";
13848
+ import { join as join17 } from "node:path";
13840
13849
  function unresolvedClassIn(message) {
13841
13850
  return UNRESOLVED.exec(message)?.[1] ?? null;
13842
13851
  }
@@ -13898,7 +13907,7 @@ function checkWithEngine(godotPath, projectPath) {
13898
13907
  const ran = await runEngine(godotPath, [
13899
13908
  "--headless",
13900
13909
  "--log-file",
13901
- join16(logDir, "engine.log"),
13910
+ join17(logDir, "engine.log"),
13902
13911
  "--path",
13903
13912
  projectPath,
13904
13913
  "--check-only",
@@ -13945,7 +13954,7 @@ var init_script_origins = __esm(() => {
13945
13954
 
13946
13955
  // src/headless.ts
13947
13956
  import { existsSync as existsSync14, readFileSync as readFileSync13, writeFileSync as writeFileSync8 } from "node:fs";
13948
- import { dirname as dirname7, join as join17 } from "node:path";
13957
+ import { dirname as dirname7, join as join18 } from "node:path";
13949
13958
  function snakeCased(params) {
13950
13959
  const result = emptyRecord();
13951
13960
  for (const [key, value] of Object.entries(params)) {
@@ -14101,7 +14110,7 @@ async function importOnce(godotPath, projectPath) {
14101
14110
  ran = await runEngine(godotPath, [
14102
14111
  "--headless",
14103
14112
  "--log-file",
14104
- join17(logDir, "engine.log"),
14113
+ join18(logDir, "engine.log"),
14105
14114
  "--path",
14106
14115
  projectPath,
14107
14116
  "--import"
@@ -14137,14 +14146,14 @@ async function runOperation(engine, operation, params, projectPath) {
14137
14146
  }
14138
14147
  async function operationOutcome(engine, operation, params, projectPath) {
14139
14148
  const paramsDir = scratchDirectory("params");
14140
- const paramsFile = join17(paramsDir, `${operation}.json`);
14141
- const answerFile = join17(paramsDir, "answer.json");
14149
+ const paramsFile = join18(paramsDir, `${operation}.json`);
14150
+ const answerFile = join18(paramsDir, "answer.json");
14142
14151
  writeFileSync8(paramsFile, JSON.stringify(snakeCased(params)), "utf8");
14143
14152
  const args = [
14144
14153
  "--headless",
14145
14154
  ...engine.editor === true ? ["--editor"] : [],
14146
14155
  "--log-file",
14147
- join17(paramsDir, "engine.log"),
14156
+ join18(paramsDir, "engine.log"),
14148
14157
  "--path",
14149
14158
  projectPath,
14150
14159
  "--script",
@@ -14261,8 +14270,8 @@ var init_headless = __esm(() => {
14261
14270
 
14262
14271
  // src/update-check.ts
14263
14272
  import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "node:fs";
14264
- import { homedir as homedir5, tmpdir as tmpdir4 } from "node:os";
14265
- import { join as join18 } from "node:path";
14273
+ import { homedir as homedir6, tmpdir as tmpdir4 } from "node:os";
14274
+ import { join as join19 } from "node:path";
14266
14275
  function packageUrl(root) {
14267
14276
  return `${root.replace(/\/+$/, "")}/gdharness/latest`;
14268
14277
  }
@@ -14282,22 +14291,22 @@ function cacheDirectory(environment) {
14282
14291
  const value = environment[name];
14283
14292
  return value !== undefined && value !== "" ? value : null;
14284
14293
  };
14285
- const home = set("HOME") ?? homedir5();
14294
+ const home = set("HOME") ?? homedir6();
14286
14295
  if (process.platform === "win32") {
14287
- return join18(set("LOCALAPPDATA") ?? home, "gdharness");
14296
+ return join19(set("LOCALAPPDATA") ?? home, "gdharness");
14288
14297
  }
14289
14298
  if (process.platform === "darwin") {
14290
- return join18(home, "Library", "Caches", "gdharness");
14299
+ return join19(home, "Library", "Caches", "gdharness");
14291
14300
  }
14292
- return join18(set("XDG_CACHE_HOME") ?? join18(home, ".cache"), "gdharness");
14301
+ return join19(set("XDG_CACHE_HOME") ?? join19(home, ".cache"), "gdharness");
14293
14302
  }
14294
14303
  function cacheFile(environment = process.env) {
14295
14304
  try {
14296
14305
  const directory = cacheDirectory(environment);
14297
14306
  mkdirSync5(directory, { recursive: true, mode: 448 });
14298
- return join18(directory, "update-check.json");
14307
+ return join19(directory, "update-check.json");
14299
14308
  } catch {
14300
- return join18(tmpdir4(), "gdharness-update-check.json");
14309
+ return join19(tmpdir4(), "gdharness-update-check.json");
14301
14310
  }
14302
14311
  }
14303
14312
  function readCache(path) {
@@ -14785,7 +14794,7 @@ var init_ports = __esm(() => {
14785
14794
  import { existsSync as existsSync16, realpathSync as realpathSync2 } from "node:fs";
14786
14795
  import { readFile, realpath } from "node:fs/promises";
14787
14796
  import { createConnection } from "node:net";
14788
- import { dirname as dirname8, join as join19, resolve as resolve6 } from "node:path";
14797
+ import { dirname as dirname8, join as join20, resolve as resolve6 } from "node:path";
14789
14798
  import { setTimeout as delay4 } from "node:timers/promises";
14790
14799
  import { fileURLToPath, pathToFileURL } from "node:url";
14791
14800
  function initializeTimeoutMs() {
@@ -15463,7 +15472,7 @@ async function resolveLSPPaths(projectPathValue, scriptPathValue) {
15463
15472
  } catch {
15464
15473
  throw new ArgumentRefusal(`Project path does not exist: ${requestedProjectPath}`);
15465
15474
  }
15466
- if (!existsSync16(join19(projectPath, "project.godot"))) {
15475
+ if (!existsSync16(join20(projectPath, "project.godot"))) {
15467
15476
  throw new ArgumentRefusal(`Not a Godot project: ${projectPath}. Point projectPath at the directory holding project.godot.`);
15468
15477
  }
15469
15478
  const contained = resolveWithinProject(projectPath, scriptPathValue);
@@ -15981,7 +15990,7 @@ import {
15981
15990
  statSync as statSync12,
15982
15991
  writeFileSync as writeFileSync10
15983
15992
  } from "node:fs";
15984
- import { dirname as dirname9, join as join21 } from "node:path";
15993
+ import { dirname as dirname9, join as join22 } from "node:path";
15985
15994
  import { fileURLToPath as fileURLToPath2 } from "node:url";
15986
15995
  function addonMarking(name) {
15987
15996
  if (name === RUNTIME_ADDON) {
@@ -16002,7 +16011,7 @@ function addonsDigest(names, from) {
16002
16011
  if (name === VERSION_MARKER || name === DIGEST_MARKER) {
16003
16012
  continue;
16004
16013
  }
16005
- const path = join21(directory, name);
16014
+ const path = join22(directory, name);
16006
16015
  const inside = `${relative}/${name}`;
16007
16016
  if (statSync12(path).isDirectory()) {
16008
16017
  walk(path, inside);
@@ -16016,7 +16025,7 @@ function addonsDigest(names, from) {
16016
16025
  }
16017
16026
  };
16018
16027
  for (const name of names) {
16019
- walk(join21(from, name), name);
16028
+ walk(join22(from, name), name);
16020
16029
  }
16021
16030
  return hash.digest("hex");
16022
16031
  }
@@ -16035,7 +16044,7 @@ function installedRuntimeDigest(projectPath) {
16035
16044
  return digestMarker(projectPath, RUNTIME_ADDON);
16036
16045
  }
16037
16046
  function digestMarker(projectPath, addon) {
16038
- const marker = join21(projectPath, "addons", addon, DIGEST_MARKER);
16047
+ const marker = join22(projectPath, "addons", addon, DIGEST_MARKER);
16039
16048
  if (!existsSync18(marker)) {
16040
16049
  return null;
16041
16050
  }
@@ -16043,16 +16052,16 @@ function digestMarker(projectPath, addon) {
16043
16052
  return said === "" ? null : said;
16044
16053
  }
16045
16054
  function shippedAddonsDirectory() {
16046
- return join21(dirname9(fileURLToPath2(import.meta.url)), "godot", "addons");
16055
+ return join22(dirname9(fileURLToPath2(import.meta.url)), "godot", "addons");
16047
16056
  }
16048
16057
  function shippedOperationsScript() {
16049
- return join21(dirname9(fileURLToPath2(import.meta.url)), "godot", "operations", "godot_operations.gd");
16058
+ return join22(dirname9(fileURLToPath2(import.meta.url)), "godot", "operations", "godot_operations.gd");
16050
16059
  }
16051
16060
  function shippedLoader() {
16052
- return join21(dirname9(fileURLToPath2(import.meta.url)), "godot", "loader", "loader.gd");
16061
+ return join22(dirname9(fileURLToPath2(import.meta.url)), "godot", "loader", "loader.gd");
16053
16062
  }
16054
16063
  function loaderState(projectPath) {
16055
- const copy = join21(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
16064
+ const copy = join22(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
16056
16065
  if (!existsSync18(copy)) {
16057
16066
  return "missing";
16058
16067
  }
@@ -16065,13 +16074,13 @@ function writeLoader(projectPath) {
16065
16074
  if (loaderState(projectPath) === "current") {
16066
16075
  return false;
16067
16076
  }
16068
- const copy = join21(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
16077
+ const copy = join22(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
16069
16078
  mkdirSync6(dirname9(copy), { recursive: true });
16070
16079
  writeFileSync10(copy, readFileSync18(shippedLoader()));
16071
16080
  return true;
16072
16081
  }
16073
16082
  function removeLoader(projectPath) {
16074
- const copy = join21(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
16083
+ const copy = join22(projectPath, ...RUNTIME_AUTOLOAD.path.split("/"));
16075
16084
  if (!existsSync18(copy)) {
16076
16085
  return false;
16077
16086
  }
@@ -16084,14 +16093,14 @@ function removeLoader(projectPath) {
16084
16093
  return true;
16085
16094
  }
16086
16095
  function shippedListedRunner() {
16087
- return join21(dirname9(fileURLToPath2(import.meta.url)), "godot", "tests", "listed.gd");
16096
+ return join22(dirname9(fileURLToPath2(import.meta.url)), "godot", "tests", "listed.gd");
16088
16097
  }
16089
16098
  function gdUnit4Unusable(projectPath) {
16090
16099
  const marker = "addons/gdUnit4/plugin.cfg";
16091
- if (!existsSync18(join21(projectPath, ...marker.split("/")))) {
16100
+ if (!existsSync18(join22(projectPath, ...marker.split("/")))) {
16092
16101
  return { missing: true, reason: `gdUnit4 is not installed in this project: no ${marker}` };
16093
16102
  }
16094
- if (!existsSync18(join21(projectPath, ...GDUNIT4_CI_RUNNER.split("/")))) {
16103
+ if (!existsSync18(join22(projectPath, ...GDUNIT4_CI_RUNNER.split("/")))) {
16095
16104
  return {
16096
16105
  missing: false,
16097
16106
  reason: `gdUnit4 in this project is older than 6.0, which the shipped runner needs: no ${GDUNIT4_CI_RUNNER}`
@@ -16102,27 +16111,27 @@ function gdUnit4Unusable(projectPath) {
16102
16111
  function installAddons(projectPath, from = shippedAddonsDirectory()) {
16103
16112
  const installed = [];
16104
16113
  for (const name of ADDONS) {
16105
- const source = join21(from, name);
16106
- if (!existsSync18(join21(source, addonMarking(name)))) {
16114
+ const source = join22(from, name);
16115
+ if (!existsSync18(join22(source, addonMarking(name)))) {
16107
16116
  throw new Error(`The package holds no ${name} addon at ${source}.`);
16108
16117
  }
16109
- const target = join21(projectPath, "addons", name);
16118
+ const target = join22(projectPath, "addons", name);
16110
16119
  const replaced = existsSync18(target);
16111
16120
  rmSync9(target, { recursive: true, force: true });
16112
16121
  mkdirSync6(dirname9(target), { recursive: true });
16113
16122
  cpSync(source, target, { recursive: true });
16114
- writeFileSync10(join21(target, VERSION_MARKER), `${SERVER_VERSION}
16123
+ writeFileSync10(join22(target, VERSION_MARKER), `${SERVER_VERSION}
16115
16124
  `);
16116
16125
  installed.push({ name, path: target, replaced });
16117
16126
  }
16118
- writeFileSync10(join21(projectPath, "addons", ADDONS[0], DIGEST_MARKER), `${editorAddonDigest(from)}
16127
+ writeFileSync10(join22(projectPath, "addons", ADDONS[0], DIGEST_MARKER), `${editorAddonDigest(from)}
16119
16128
  `);
16120
- writeFileSync10(join21(projectPath, "addons", RUNTIME_ADDON, DIGEST_MARKER), `${runtimeAddonDigest(from)}
16129
+ writeFileSync10(join22(projectPath, "addons", RUNTIME_ADDON, DIGEST_MARKER), `${runtimeAddonDigest(from)}
16121
16130
  `);
16122
16131
  return installed;
16123
16132
  }
16124
16133
  function installedAddonVersion(projectPath) {
16125
- const marker = join21(projectPath, "addons", ADDONS[0], VERSION_MARKER);
16134
+ const marker = join22(projectPath, "addons", ADDONS[0], VERSION_MARKER);
16126
16135
  if (!existsSync18(marker)) {
16127
16136
  return null;
16128
16137
  }
@@ -16132,13 +16141,13 @@ function installedAddonVersion(projectPath) {
16132
16141
  function removeAddons(projectPath) {
16133
16142
  const removed = [];
16134
16143
  for (const name of ADDONS) {
16135
- const target = join21(projectPath, "addons", name);
16144
+ const target = join22(projectPath, "addons", name);
16136
16145
  if (existsSync18(target)) {
16137
16146
  rmSync9(target, { recursive: true, force: true });
16138
16147
  removed.push(target);
16139
16148
  }
16140
16149
  }
16141
- const addons = join21(projectPath, "addons");
16150
+ const addons = join22(projectPath, "addons");
16142
16151
  if (removed.length > 0 && existsSync18(addons) && readdirSync11(addons).length === 0) {
16143
16152
  rmdirSync(addons);
16144
16153
  removed.push(addons);
@@ -16181,7 +16190,7 @@ function loaderAmong(projectPath, named) {
16181
16190
  }
16182
16191
  let source = null;
16183
16192
  try {
16184
- source = readFileSync18(join21(projectPath, path), "utf8");
16193
+ source = readFileSync18(join22(projectPath, path), "utf8");
16185
16194
  } catch {}
16186
16195
  if (source?.includes(RUNTIME_SCRIPT)) {
16187
16196
  return { name: entry, path, exists: true };
@@ -16237,8 +16246,8 @@ function enabledPlugins(settings) {
16237
16246
  function inspectProject(projectPath) {
16238
16247
  const problems = [];
16239
16248
  const addons = ADDONS.map((name) => {
16240
- const directory = join21(projectPath, "addons", name);
16241
- const marker = join21(directory, VERSION_MARKER);
16249
+ const directory = join22(projectPath, "addons", name);
16250
+ const marker = join22(directory, VERSION_MARKER);
16242
16251
  const installed = existsSync18(directory);
16243
16252
  const version = existsSync18(marker) ? readFileSync18(marker, "utf8").trim() : null;
16244
16253
  const current = version === SERVER_VERSION;
@@ -16249,7 +16258,7 @@ function inspectProject(projectPath) {
16249
16258
  }
16250
16259
  return { name, installed, version, current };
16251
16260
  });
16252
- const settings = parseProjectGodot(readFileSync18(join21(projectPath, "project.godot"), "utf8"));
16261
+ const settings = parseProjectGodot(readFileSync18(join22(projectPath, "project.godot"), "utf8"));
16253
16262
  const pluginsEnabled = enabledPlugins(settings);
16254
16263
  for (const name of EDITOR_PLUGINS) {
16255
16264
  if (!pluginsEnabled.includes(name)) {
@@ -16273,7 +16282,7 @@ function inspectProject(projectPath) {
16273
16282
  const ignoredAutoloads = [];
16274
16283
  const addonMissing = (path) => addons.some((addon) => !addon.installed && path.startsWith(`addons/${addon.name}/`));
16275
16284
  for (const [name, path] of named) {
16276
- if (!existsSync18(join21(projectPath, path))) {
16285
+ if (!existsSync18(join22(projectPath, path))) {
16277
16286
  if (!addonMissing(path)) {
16278
16287
  problems.push(`the ${name} autoload names res://${path}, which is not in this project, so it boots with a missing script; restore that file, or point the autoload at one that is here`);
16279
16288
  }
@@ -16642,7 +16651,7 @@ var init_tool_definitions = __esm(() => {
16642
16651
  include: {
16643
16652
  type: "array",
16644
16653
  items: { type: "string", enum: [...PROJECT_INFO_SECTIONS] },
16645
- description: "Extra sections: registered autoloads, the classes the project's scripts declare with class_name, each with its script, read from the files, the input actions project.godot holds with their events (an engine ui_ action only when the project rebinds it, as engineAction), addons and whether each is enabled, export presets, the audio bus layout, a health report, or export validation. health and validation compile every script of the project in headless engines and name each that fails with its first error, each file a scene, resource or script refers to that does not exist, each input action a script reads by a name written in the call that neither the project nor the engine defines, with every line reading it, and each signal connection in a scene whose method or signal the node at its end does not have, judged from the node's type and scripts as their files are written."
16654
+ description: "Extra sections: registered autoloads, the classes the project's scripts declare with class_name, each with its script, read from the files, the input actions project.godot holds with their events (an engine ui_ action only when the project rebinds it, as engineAction), addons and whether each is enabled, export presets (runnable marks the one preset of its platform the editor's one-click deploy uses), the audio bus layout, a health report, or export validation. health and validation compile every script of the project in headless engines and name each that fails with its first error, each file a scene, resource or script refers to that does not exist, each input action a script reads by a name written in the call that neither the project nor the engine defines, with every line reading it, and each signal connection in a scene whose method or signal the node at its end does not have, judged from the node's type and scripts as their files are written."
16646
16655
  },
16647
16656
  preset: { type: "string", description: "For validation: the export preset to validate against." },
16648
16657
  detail: {
@@ -16673,7 +16682,7 @@ var init_tool_definitions = __esm(() => {
16673
16682
  prefix: {
16674
16683
  type: "string",
16675
16684
  ops: ["get"],
16676
- description: 'get: answer with every setting whose name starts with this, and the type the engine registers for each, instead of one setting by name. "debug/gdscript/warnings/" answers the whole family. The type matters: a family of levels can hold a setting that is a bool, and writing a level over it looks like it worked.'
16685
+ description: 'get: answer with every setting whose name starts with this, and the type the engine registers for each, a typed array or dictionary with what it holds as project.godot writes it (Dictionary[String, bool]), instead of one setting by name. "debug/gdscript/warnings/" answers the whole family. The type matters: a family of levels can hold a setting that is a bool, and writing a level over it looks like it worked.'
16677
16686
  },
16678
16687
  value: {
16679
16688
  blank: true,
@@ -16854,12 +16863,12 @@ var init_tool_definitions = __esm(() => {
16854
16863
  direction: {
16855
16864
  type: "string",
16856
16865
  enum: ["forward", "reverse"],
16857
- description: "forward: what this resource loads, with each reference closing a cycle marked circular and the cycle under circular_references, a script's dependencies including every script whose class_name it uses, marked by_class with the name, and the script of every autoload it names, marked by_autoload with the autoload's name. An ext_resource whose uid names another file than its path is followed to that file, as the engine loads it, with the path written under stale_path; one whose uid names no file the project has is followed by its path, as the engine does after warning, with the uid under unknown_uid; and a load or preload of a uid the project does not know is listed under that uid as missing. A shader's #include is followed as the preprocessor reads it, relative to the shader. A file the depth stops at carries beyond_depth, how many files it names that were not walked. summary.total_resources is the file asked about, so 1; total_dependencies counts each file reached, directly or through another, once however many places load it; total_references counts the entries in the tree, and missing names every file referenced that does not exist, with the files referring to it. reverse: every file that refers to it and how, for a file that is gone as well while anything still refers to it, answered with exists: false (a missing file nothing refers to is refused, naming the nearest files), a scene instancing it, a script extending, preloading or loading it, and for a script with a class_name every use of that name, and for an autoload's script every use of the autoload's name, with autoload naming it. Each reference carries a kind: ext_resource, extends, preload, load, include or path for a reference by path, with stale_path when an ext_resource reaches it by its uid under another path, and unknown_uid when one names it by path beside a uid naming no file; setting, plugin, export_preset and import for one in project.godot, a plugin.cfg, export_presets.cfg or an import sidecar; class_name for a use of the declared name, the declaration itself being the script asked about; autoload for code naming the autoload. Three kinds are not uses: doc is a name inside a ## documentation comment, which renaming would break in the generated docs; comment is one in ordinary prose, which it would only make stale; and stale_path is an ext_resource naming it by a path the engine does not load, since its uid leads to the file under loads. summary.in_code is the count with those left out, which is the number to read when the question is whether anything still uses this. Default forward."
16866
+ description: "forward: what this resource loads, with each reference closing a cycle marked circular and the cycle under circular_references, a script's dependencies including every script whose class_name it uses, marked by_class with the name, and the script of every autoload it names, marked by_autoload with the autoload's name. An ext_resource whose uid names another file than its path is followed to that file, as the engine loads it, with the path written under stale_path; one whose uid names no file the project has is followed by its path, as the engine does after warning, with the uid under unknown_uid; and a load or preload of a uid the project does not know is listed under that uid as missing. A shader's #include is followed as the preprocessor reads it, relative to the shader. A file the depth stops at carries beyond_depth, how many files it names that were not walked. A file's dependencies are listed at its first entry, and again further down only where the depth cut that list short and more is left; every other entry for a file naming any carries dependencies_listed_above. summary.total_resources is the file asked about, so 1; total_dependencies counts each file reached, directly or through another, once however many places load it; total_references counts the entries in the tree, and missing names every file referenced that does not exist, with the files referring to it. reverse: every file that refers to it and how, for a file that is gone as well while anything still refers to it, answered with exists: false (a missing file nothing refers to is refused, naming the nearest files), a scene instancing it, a script extending, preloading or loading it, and for a script with a class_name every use of that name, and for an autoload's script every use of the autoload's name, with autoload naming it. Each reference carries a kind: ext_resource, extends, preload, load, include or path for a reference by path, with stale_path when an ext_resource reaches it by its uid under another path, and unknown_uid when one names it by path beside a uid naming no file; setting, plugin, export_preset and import for one in project.godot, a plugin.cfg, export_presets.cfg or an import sidecar; class_name for a use of the declared name, the declaration itself being the script asked about; autoload for code naming the autoload. Three kinds are not uses: doc is a name inside a ## documentation comment, which renaming would break in the generated docs; comment is one in ordinary prose, which it would only make stale; and stale_path is an ext_resource naming it by a path the engine does not load, since its uid leads to the file under loads. summary.in_code is the count with those left out, which is the number to read when the question is whether anything still uses this. Default forward."
16858
16867
  },
16859
16868
  depth: {
16860
16869
  type: "integer",
16861
16870
  minimum: 1,
16862
- description: "forward: how many levels to follow, 1 being what the file loads itself. Default unlimited."
16871
+ description: "forward: how many levels to follow, 1 being what the file loads itself. Default unlimited, which follows every class_name use too and in a project whose scripts name each other's classes reaches most of it: a game of a hundred scripts with large addons answered 488 files in about a megabyte from its main scene. A depth of 2 or 3 keeps the answer to what is near."
16863
16872
  },
16864
16873
  includeBuiltin: {
16865
16874
  type: "boolean",
@@ -17545,7 +17554,7 @@ var init_tool_definitions = __esm(() => {
17545
17554
  operations: {
17546
17555
  structure: {
17547
17556
  effect: "read",
17548
- summary: `functions (each parameter's default the source text after its =, so = null reads "null", and null for a parameter with none), variables (static ones marked is_static; one written with := has the type of a literal or built-in constructor it is given, marked inferred, as a constant always does), signals, constants, enums, inner_classes (each with its name, line and extends, and its own members in these same fields), class_name, extends and line_count, read from the file, and dependencies: the paths it loads or preloads as written, then the scripts declaring each project class_name its code uses, which classes_used names with the class; autoloads_used names each autoload the code uses by its global name, with the autoload's script, which the project loads rather than this script, so it is not under dependencies. A member or inner class with a ## documentation comment directly above it carries the comment's text as doc, and the script's own, the ## block above class_name or extends or one followed by a blank line before any member, comes back as class_doc`,
17557
+ summary: `functions (each parameter's default the source text after its =, so = null reads "null", and null for a parameter with none), variables (static ones marked is_static; one written with := has the type of a literal or built-in constructor it is given, marked inferred, as a constant always does), signals, constants, enums, inner_classes (each with its name, line and extends, and its own members in these same fields), class_name, extends and line_count, read from the file, and dependencies: the paths it loads or preloads as written, by a constant it declares too, and the paths it or an inner class extends by, then the scripts declaring each project class_name its code uses, which classes_used names with the class; autoloads_used names each autoload the code uses by its global name, with the autoload's script, which the project loads rather than this script, so it is not under dependencies. A member or inner class with a ## documentation comment directly above it carries the comment's text as doc, and the script's own, the ## block above class_name or extends or one followed by a blank line before any member, comes back as class_doc`,
17549
17558
  requires: []
17550
17559
  },
17551
17560
  symbols: {
@@ -18814,7 +18823,7 @@ var init_tool_reference = __esm(() => {
18814
18823
 
18815
18824
  // src/suite-plan.ts
18816
18825
  import { existsSync as existsSync22, mkdirSync as mkdirSync9, readFileSync as readFileSync21 } from "node:fs";
18817
- import { dirname as dirname11, join as join25, posix as posix3 } from "node:path";
18826
+ import { dirname as dirname11, join as join26, posix as posix3 } from "node:path";
18818
18827
  function within(path, folder) {
18819
18828
  return path === folder || path.startsWith(`${folder}/`);
18820
18829
  }
@@ -18830,7 +18839,7 @@ class ProjectScripts {
18830
18839
  this.projectPath = projectPath;
18831
18840
  let settings = {};
18832
18841
  try {
18833
- settings = parseProjectGodot(readFileSync21(join25(projectPath, "project.godot"), "utf8"))["gdharness"] ?? {};
18842
+ settings = parseProjectGodot(readFileSync21(join26(projectPath, "project.godot"), "utf8"))["gdharness"] ?? {};
18834
18843
  } catch {}
18835
18844
  const [section, key] = [NOT_SEARCHED_SETTING, GUESS_WINDOW_SETTING].map((setting) => setting.slice("gdharness/".length));
18836
18845
  const listed = settings[section ?? ""];
@@ -40848,12 +40857,12 @@ var init_stdio = __esm(() => {
40848
40857
 
40849
40858
  // src/autoload-failure.ts
40850
40859
  import { existsSync as existsSync24, readFileSync as readFileSync24 } from "node:fs";
40851
- import { join as join28 } from "node:path";
40860
+ import { join as join29 } from "node:path";
40852
40861
  function scriptsAutoloaded(projectPath) {
40853
40862
  const scripts = new Map;
40854
40863
  let settings;
40855
40864
  try {
40856
- settings = parseProjectGodot(readFileSync24(join28(projectPath, "project.godot"), "utf8"));
40865
+ settings = parseProjectGodot(readFileSync24(join29(projectPath, "project.godot"), "utf8"));
40857
40866
  } catch {
40858
40867
  return scripts;
40859
40868
  }
@@ -40862,7 +40871,7 @@ function scriptsAutoloaded(projectPath) {
40862
40871
  scripts.set(`res://${path}`, name);
40863
40872
  continue;
40864
40873
  }
40865
- const scene = join28(projectPath, path);
40874
+ const scene = join29(projectPath, path);
40866
40875
  if (!existsSync24(scene)) {
40867
40876
  continue;
40868
40877
  }
@@ -40889,7 +40898,7 @@ var init_autoload_failure = __esm(() => {
40889
40898
  import { existsSync as existsSync25, readdirSync as readdirSync15, readFileSync as readFileSync25, statSync as statSync15, unlinkSync as unlinkSync3 } from "node:fs";
40890
40899
  import { createConnection as createConnection2 } from "node:net";
40891
40900
  import { tmpdir as tmpdir5 } from "node:os";
40892
- import { dirname as dirname14, join as join29, resolve as resolve11 } from "node:path";
40901
+ import { dirname as dirname14, join as join30, resolve as resolve11 } from "node:path";
40893
40902
  import { setTimeout as delay5 } from "node:timers/promises";
40894
40903
  function runtimeDirectory(variables = process.env) {
40895
40904
  const explicit = envValue("GDHARNESS_RUNTIME_DIR", variables);
@@ -40897,19 +40906,19 @@ function runtimeDirectory(variables = process.env) {
40897
40906
  return explicit;
40898
40907
  }
40899
40908
  const perUser = envValue("XDG_RUNTIME_DIR", variables);
40900
- return join29(perUser ?? tmpdir5(), "gdharness");
40909
+ return join30(perUser ?? tmpdir5(), "gdharness");
40901
40910
  }
40902
40911
  function runtimeDirectories(variables = process.env) {
40903
40912
  const candidates = [runtimeDirectory(variables)];
40904
40913
  const fallbacks = process.platform === "win32" ? [envValue("SystemRoot", variables) ?? envValue("windir", variables) ?? "C:\\Windows"] : ["/tmp", "/var/tmp"];
40905
40914
  for (const base of fallbacks) {
40906
- candidates.push(join29(base, process.platform === "win32" ? "Temp" : "", "gdharness"));
40915
+ candidates.push(join30(base, process.platform === "win32" ? "Temp" : "", "gdharness"));
40907
40916
  }
40908
40917
  return [...new Set(candidates.map((path) => resolve11(path)))];
40909
40918
  }
40910
40919
  function errorReportOf(pid, directories = runtimeDirectories()) {
40911
40920
  for (const directory of directories) {
40912
- const path = join29(directory, `runtime-${pid}.log`);
40921
+ const path = join30(directory, `runtime-${pid}.log`);
40913
40922
  if (existsSync25(path)) {
40914
40923
  return path;
40915
40924
  }
@@ -41065,14 +41074,14 @@ function announcedIn(directory) {
41065
41074
  for (const entry of readdirSync15(directory)) {
41066
41075
  const report = ERROR_REPORT_PATTERN.exec(entry);
41067
41076
  if (report) {
41068
- sweepErrorReport(join29(directory, entry), Number.parseInt(report[1] ?? "", 10));
41077
+ sweepErrorReport(join30(directory, entry), Number.parseInt(report[1] ?? "", 10));
41069
41078
  continue;
41070
41079
  }
41071
41080
  const match = ANNOUNCEMENT_PATTERN.exec(entry);
41072
41081
  if (!match) {
41073
41082
  continue;
41074
41083
  }
41075
- const file = join29(directory, entry);
41084
+ const file = join30(directory, entry);
41076
41085
  const pid = Number.parseInt(match[1] ?? "", 10);
41077
41086
  const running = alive(pid);
41078
41087
  entries.push({ file, pid, running });
@@ -41100,7 +41109,7 @@ function announcedIn(directory) {
41100
41109
  found.push(announced);
41101
41110
  }
41102
41111
  const held = new Set(entries.map((one) => one.file));
41103
- const here = join29(directory, ".");
41112
+ const here = join30(directory, ".");
41104
41113
  for (const file of verdicts.keys()) {
41105
41114
  if (dirname14(file) === here && !held.has(file)) {
41106
41115
  verdicts.delete(file);
@@ -41109,7 +41118,7 @@ function announcedIn(directory) {
41109
41118
  return found;
41110
41119
  }
41111
41120
  async function announcementEnded(pid, directories = runtimeDirectories()) {
41112
- const files = directories.map((directory) => join29(directory, `runtime-${pid}.json`)).filter((file) => existsSync25(file));
41121
+ const files = directories.map((directory) => join30(directory, `runtime-${pid}.json`)).filter((file) => existsSync25(file));
41113
41122
  const first = files[0];
41114
41123
  if (first === undefined) {
41115
41124
  return;
@@ -41529,9 +41538,9 @@ var init_runtime_client = __esm(() => {
41529
41538
 
41530
41539
  // src/boot-note.ts
41531
41540
  import { mkdirSync as mkdirSync11, readFileSync as readFileSync26, writeFileSync as writeFileSync13 } from "node:fs";
41532
- import { dirname as dirname15, join as join30 } from "node:path";
41541
+ import { dirname as dirname15, join as join31 } from "node:path";
41533
41542
  function bootNotePath(projectPath) {
41534
- return join30(projectPath, ".godot", "gdharness-boot.json");
41543
+ return join31(projectPath, ".godot", "gdharness-boot.json");
41535
41544
  }
41536
41545
  function readScenes(projectPath) {
41537
41546
  try {
@@ -41578,9 +41587,9 @@ var init_boot_note = __esm(() => {
41578
41587
 
41579
41588
  // src/breakpoint-note.ts
41580
41589
  import { mkdirSync as mkdirSync12, readFileSync as readFileSync27, rmSync as rmSync13, writeFileSync as writeFileSync14 } from "node:fs";
41581
- import { dirname as dirname16, isAbsolute as isAbsolute7, join as join31, relative as relative6 } from "node:path";
41590
+ import { dirname as dirname16, isAbsolute as isAbsolute7, join as join32, relative as relative6 } from "node:path";
41582
41591
  function breakpointNotePath(projectPath) {
41583
- return join31(projectPath, ".godot", "gdharness-breakpoints.json");
41592
+ return join32(projectPath, ".godot", "gdharness-breakpoints.json");
41584
41593
  }
41585
41594
  function writeBreakpointNote(projectPath, held) {
41586
41595
  const path = breakpointNotePath(projectPath);
@@ -41621,7 +41630,7 @@ function readBreakpointNote(projectPath) {
41621
41630
  }
41622
41631
  const lines = Array.isArray(listed) ? listed.filter((line) => Number.isInteger(line) && line > 0) : [];
41623
41632
  if (lines.length > 0) {
41624
- held.push({ scriptPath: realAsFarAsItExists(join31(projectPath, script)), lines });
41633
+ held.push({ scriptPath: realAsFarAsItExists(join32(projectPath, script)), lines });
41625
41634
  }
41626
41635
  }
41627
41636
  return held;
@@ -41640,9 +41649,9 @@ var init_breakpoint_note = __esm(() => {
41640
41649
 
41641
41650
  // src/class-note.ts
41642
41651
  import { mkdirSync as mkdirSync13, readFileSync as readFileSync28 } from "node:fs";
41643
- import { dirname as dirname17, join as join32 } from "node:path";
41652
+ import { dirname as dirname17, join as join33 } from "node:path";
41644
41653
  function classNotePath(projectPath) {
41645
- return join32(projectPath, ".godot", "gdharness-classes.json");
41654
+ return join33(projectPath, ".godot", "gdharness-classes.json");
41646
41655
  }
41647
41656
  function readClassNote(projectPath) {
41648
41657
  try {
@@ -41689,9 +41698,9 @@ var init_class_note = __esm(() => {
41689
41698
 
41690
41699
  // src/config-pin.ts
41691
41700
  import { existsSync as existsSync26, readFileSync as readFileSync29 } from "node:fs";
41692
- import { join as join33 } from "node:path";
41701
+ import { join as join34 } from "node:path";
41693
41702
  function versionsNamedInConfig(projectPath) {
41694
- const config = join33(projectPath, ".mcp.json");
41703
+ const config = join34(projectPath, ".mcp.json");
41695
41704
  if (!existsSync26(config)) {
41696
41705
  return [];
41697
41706
  }
@@ -41719,9 +41728,9 @@ var init_config_pin = __esm(() => {
41719
41728
 
41720
41729
  // src/cut-test-run.ts
41721
41730
  import { existsSync as existsSync27, mkdirSync as mkdirSync14, readFileSync as readFileSync30, rmSync as rmSync14, writeFileSync as writeFileSync15 } from "node:fs";
41722
- import { dirname as dirname18, join as join34 } from "node:path";
41731
+ import { dirname as dirname18, join as join35 } from "node:path";
41723
41732
  function keptAt(projectPath) {
41724
- return join34(projectPath, ".godot", "gdharness-reports", "cut-run.json");
41733
+ return join35(projectPath, ".godot", "gdharness-reports", "cut-run.json");
41725
41734
  }
41726
41735
  function keepCutTestRun(projectPath, run) {
41727
41736
  const path = keptAt(projectPath);
@@ -42479,12 +42488,12 @@ import {
42479
42488
  statSync as statSync16,
42480
42489
  writeFileSync as writeFileSync16
42481
42490
  } from "node:fs";
42482
- import { dirname as dirname19, join as join35 } from "node:path";
42491
+ import { dirname as dirname19, join as join36 } from "node:path";
42483
42492
  function editorLogPath(projectPath) {
42484
- return join35(projectPath, ".godot", "gdharness-editor.log");
42493
+ return join36(projectPath, ".godot", "gdharness-editor.log");
42485
42494
  }
42486
42495
  function editorLogNotePath(projectPath) {
42487
- return join35(projectPath, ".godot", "gdharness-editor.json");
42496
+ return join36(projectPath, ".godot", "gdharness-editor.json");
42488
42497
  }
42489
42498
  function readEditorLogNote(projectPath) {
42490
42499
  try {
@@ -43523,7 +43532,7 @@ var init_rename = __esm(() => {
43523
43532
 
43524
43533
  // src/rename-symbol.ts
43525
43534
  import { existsSync as existsSync30, mkdirSync as mkdirSync17, readdirSync as readdirSync16, realpathSync as realpathSync4, rmSync as rmSync16, writeFileSync as writeFileSync18 } from "node:fs";
43526
- import { basename as basename9, dirname as dirname21, join as join36, relative as relative7, resolve as resolve12 } from "node:path";
43535
+ import { basename as basename9, dirname as dirname21, join as join37, relative as relative7, resolve as resolve12 } from "node:path";
43527
43536
  function resourcePathOf(projectPath, absolute) {
43528
43537
  const inside = relative7(onDiskSpelling(projectPath), onDiskSpelling(absolute));
43529
43538
  if (inside === "" || inside.startsWith("..") || /^[A-Za-z]:/.test(inside)) {
@@ -43536,7 +43545,7 @@ function onDiskSpelling(path) {
43536
43545
  let at = resolve12(path);
43537
43546
  for (;; ) {
43538
43547
  try {
43539
- return join36(realpathSync4.native(at), ...missing.reverse());
43548
+ return join37(realpathSync4.native(at), ...missing.reverse());
43540
43549
  } catch {
43541
43550
  const parent = dirname21(at);
43542
43551
  if (parent === at) {
@@ -43974,15 +43983,15 @@ ${mention.kind}`;
43974
43983
  };
43975
43984
  }
43976
43985
  function writeLeftAloneDetail(projectPath, symbol, detail) {
43977
- const directory = join36(projectPath, ".godot", "gdharness-renames");
43986
+ const directory = join37(projectPath, ".godot", "gdharness-renames");
43978
43987
  mkdirSync17(directory, { recursive: true });
43979
43988
  detailWrites += 1;
43980
- const path = join36(directory, `${String(Date.now())}-${String(detailWrites).padStart(6, "0")}-${String(process.pid)}-${symbol}.json`);
43989
+ const path = join37(directory, `${String(Date.now())}-${String(detailWrites).padStart(6, "0")}-${String(process.pid)}-${symbol}.json`);
43981
43990
  writeFileSync18(path, `${JSON.stringify(detail, null, 2)}
43982
43991
  `, "utf8");
43983
43992
  const kept = readdirSync16(directory).filter((name) => name.endsWith(".json")).sort().reverse();
43984
43993
  for (const old of kept.slice(10)) {
43985
- rmSync16(join36(directory, old), { force: true });
43994
+ rmSync16(join37(directory, old), { force: true });
43986
43995
  }
43987
43996
  return path;
43988
43997
  }
@@ -44031,10 +44040,10 @@ import {
44031
44040
  statSync as statSync17,
44032
44041
  writeFileSync as writeFileSync19
44033
44042
  } from "node:fs";
44034
- import { basename as basename10, dirname as dirname22, extname as extname3, join as join37, relative as relative8 } from "node:path";
44043
+ import { basename as basename10, dirname as dirname22, extname as extname3, join as join38, relative as relative8 } from "node:path";
44035
44044
  function filesUnder(directory) {
44036
44045
  return readdirSync17(directory, { withFileTypes: true }).flatMap((entry) => {
44037
- const path = join37(directory, entry.name);
44046
+ const path = join38(directory, entry.name);
44038
44047
  return entry.isDirectory() ? filesUnder(path) : [path];
44039
44048
  });
44040
44049
  }
@@ -44055,8 +44064,8 @@ function unseenByTheEngine(projectPath, path) {
44055
44064
  return `${path} is under ${step}, and the engine passes over every directory whose name starts with a dot`;
44056
44065
  }
44057
44066
  if (at < steps.length - 1) {
44058
- directory = join37(directory, step);
44059
- if (existsSync31(join37(directory, ".gdignore"))) {
44067
+ directory = join38(directory, step);
44068
+ if (existsSync31(join38(directory, ".gdignore"))) {
44060
44069
  return `${path} is under a directory holding a .gdignore, which the engine does not load`;
44061
44070
  }
44062
44071
  }
@@ -44068,12 +44077,12 @@ function installedAddonOf(projectPath, path) {
44068
44077
  if (steps[0] !== "addons" || steps[1] === undefined) {
44069
44078
  return null;
44070
44079
  }
44071
- return existsSync31(join37(projectPath, "addons", steps[1], VERSION_MARKER)) ? `res://addons/${steps[1]}` : null;
44080
+ return existsSync31(join38(projectPath, "addons", steps[1], VERSION_MARKER)) ? `res://addons/${steps[1]}` : null;
44072
44081
  }
44073
44082
  function binaryResources(projectPath) {
44074
44083
  const found = [];
44075
44084
  const visit = (directory, prefix) => {
44076
- if (existsSync31(join37(directory, ".gdignore"))) {
44085
+ if (existsSync31(join38(directory, ".gdignore"))) {
44077
44086
  return;
44078
44087
  }
44079
44088
  for (const entry of readdirSync17(directory, { withFileTypes: true })) {
@@ -44082,7 +44091,7 @@ function binaryResources(projectPath) {
44082
44091
  }
44083
44092
  const path = `${prefix}${entry.name}`;
44084
44093
  if (entry.isDirectory()) {
44085
- visit(join37(directory, entry.name), `${path}/`);
44094
+ visit(join38(directory, entry.name), `${path}/`);
44086
44095
  } else if (/\.(scn|res)$/i.test(entry.name)) {
44087
44096
  found.push(path);
44088
44097
  }
@@ -44092,7 +44101,7 @@ function binaryResources(projectPath) {
44092
44101
  return found;
44093
44102
  }
44094
44103
  function targetPathOf(projectPath, absolute) {
44095
- const inside = relative8(onDiskSpelling(projectPath), join37(onDiskSpelling(dirname22(absolute)), basename10(absolute)));
44104
+ const inside = relative8(onDiskSpelling(projectPath), join38(onDiskSpelling(dirname22(absolute)), basename10(absolute)));
44096
44105
  if (inside === "" || inside.startsWith("..") || /^[A-Za-z]:/.test(inside)) {
44097
44106
  return null;
44098
44107
  }
@@ -44147,7 +44156,7 @@ function planFileMove(projectPath, absoluteFrom, absoluteTo) {
44147
44156
  return { ok: false, reason: `${unseen}, so nothing there could load what was moved.` };
44148
44157
  }
44149
44158
  if (!isDirectory) {
44150
- const owner = SIDECARS.map((sidecar) => from.endsWith(sidecar) ? from.slice(0, -sidecar.length) : null).find((path) => path !== null && existsSync31(join37(projectPath, path.slice("res://".length))));
44159
+ const owner = SIDECARS.map((sidecar) => from.endsWith(sidecar) ? from.slice(0, -sidecar.length) : null).find((path) => path !== null && existsSync31(join38(projectPath, path.slice("res://".length))));
44151
44160
  if (owner !== undefined && owner !== null) {
44152
44161
  return { ok: false, reason: `${from} belongs to ${owner} and moves with it: move ${owner} instead.` };
44153
44162
  }
@@ -44181,12 +44190,12 @@ function planFileMove(projectPath, absoluteFrom, absoluteTo) {
44181
44190
  scripts,
44182
44191
  moves,
44183
44192
  named: [from],
44184
- exists: (path) => existsSync31(join37(projectPath, path.slice("res://".length)))
44193
+ exists: (path) => existsSync31(join38(projectPath, path.slice("res://".length)))
44185
44194
  }, { edits: [], mentions: [] });
44186
44195
  plan = mentionIgnored(plan, ignoredTexts(projectPath), null, [from]);
44187
44196
  const binaries = [];
44188
44197
  for (const path of binaryResources(projectPath)) {
44189
- const bytes = readFileSync33(join37(projectPath, path.slice("res://".length)));
44198
+ const bytes = readFileSync33(join38(projectPath, path.slice("res://".length)));
44190
44199
  const names = [...moves.keys()].find((moving) => bytes.includes(moving));
44191
44200
  if (names !== undefined) {
44192
44201
  binaries.push({
@@ -44205,7 +44214,7 @@ function planFileMove(projectPath, absoluteFrom, absoluteTo) {
44205
44214
  file: afterwards(mention.file)
44206
44215
  }));
44207
44216
  const left = leftAloneReport(mentions);
44208
- const absoluteOf = (path) => join37(projectPath, path.slice("res://".length));
44217
+ const absoluteOf = (path) => join38(projectPath, path.slice("res://".length));
44209
44218
  const rewritten = new Map(rewrites.map((rewrite) => [rewrite.path, rewrite]));
44210
44219
  const moved = [...moves].map(([source, target]) => {
44211
44220
  const rewrite = rewritten.get(source);
@@ -47996,10 +48005,10 @@ var init_keeper_channel = () => {};
47996
48005
 
47997
48006
  // src/lifecycle-log.ts
47998
48007
  import { appendFileSync, mkdirSync as mkdirSync19, renameSync as renameSync5, statSync as statSync18 } from "node:fs";
47999
- import { dirname as dirname23, join as join38 } from "node:path";
48008
+ import { dirname as dirname23, join as join39 } from "node:path";
48000
48009
  import process16 from "node:process";
48001
48010
  function lifecycleLogPath() {
48002
- return join38(runtimeDirectory(), "servers.log");
48011
+ return join39(runtimeDirectory(), "servers.log");
48003
48012
  }
48004
48013
  function writeLifecycle(event, fields = {}) {
48005
48014
  const path = lifecycleLogPath();
@@ -48370,9 +48379,9 @@ var init_prompts = __esm(() => {
48370
48379
 
48371
48380
  // src/restart-note.ts
48372
48381
  import { mkdirSync as mkdirSync20, readFileSync as readFileSync34, rmSync as rmSync17, writeFileSync as writeFileSync20 } from "node:fs";
48373
- import { dirname as dirname24, join as join39 } from "node:path";
48382
+ import { dirname as dirname24, join as join40 } from "node:path";
48374
48383
  function restartNotePath(projectPath) {
48375
- return join39(projectPath, ".godot", "gdharness-restart.json");
48384
+ return join40(projectPath, ".godot", "gdharness-restart.json");
48376
48385
  }
48377
48386
  function noteRestartBegun(note) {
48378
48387
  const path = restartNotePath(note.projectPath);
@@ -48413,9 +48422,9 @@ var init_restart_note = __esm(() => {
48413
48422
  // src/run-record.ts
48414
48423
  import { createHash as createHash7 } from "node:crypto";
48415
48424
  import { mkdirSync as mkdirSync21, openSync as openSync5, readdirSync as readdirSync18, readFileSync as readFileSync35, rmSync as rmSync18, statSync as statSync19 } from "node:fs";
48416
- import { basename as basename11, join as join40, resolve as resolve13 } from "node:path";
48425
+ import { basename as basename11, join as join41, resolve as resolve13 } from "node:path";
48417
48426
  function runsDirectory() {
48418
- return join40(runtimeDirectory(), "runs");
48427
+ return join41(runtimeDirectory(), "runs");
48419
48428
  }
48420
48429
  function projectKey(projectPath) {
48421
48430
  const real = realAsFarAsItExists(resolve13(projectPath)).replace(/[\\/]+$/, "");
@@ -48423,10 +48432,10 @@ function projectKey(projectPath) {
48423
48432
  return createHash7("sha256").update(folded.replaceAll("\\", "/")).digest("hex").slice(0, 16);
48424
48433
  }
48425
48434
  function runRecordPath(projectPath, directory = runtimeDirectory()) {
48426
- return join40(directory, "runs", `note-${projectKey(projectPath)}.json`);
48435
+ return join41(directory, "runs", `note-${projectKey(projectPath)}.json`);
48427
48436
  }
48428
48437
  function latestRunPath(servedBy, directory = runtimeDirectory()) {
48429
- return join40(directory, "runs", `latest-${projectKey(servedBy)}.json`);
48438
+ return join41(directory, "runs", `latest-${projectKey(servedBy)}.json`);
48430
48439
  }
48431
48440
  function writeLatestRun(servedBy, latest) {
48432
48441
  try {
@@ -48451,20 +48460,20 @@ function readLatestRun(servedBy, directory = runtimeDirectory()) {
48451
48460
  }
48452
48461
  function openTranscript(startedAt) {
48453
48462
  mkdirSync21(runsDirectory(), { recursive: true });
48454
- const path = join40(runsDirectory(), `run-${startedAt}.log`);
48463
+ const path = join41(runsDirectory(), `run-${startedAt}.log`);
48455
48464
  return { path, fd: openSync5(path, "a") };
48456
48465
  }
48457
48466
  function profilePath(startedAt) {
48458
- return join40(runsDirectory(), `run-${startedAt}.profile.json`);
48467
+ return join41(runsDirectory(), `run-${startedAt}.profile.json`);
48459
48468
  }
48460
48469
  function profileMarkPath(startedAt) {
48461
- return join40(runsDirectory(), `run-${startedAt}.profile-mark.json`);
48470
+ return join41(runsDirectory(), `run-${startedAt}.profile-mark.json`);
48462
48471
  }
48463
48472
  function noteIsAbout(note, playing) {
48464
48473
  return note.play !== undefined && playing !== null && note.play.play === playing.play && note.play.editorPid === playing.editorPid;
48465
48474
  }
48466
48475
  function editorNotePath(projectPath, directory = runtimeDirectory()) {
48467
- return join40(directory, "runs", `editor-${projectKey(projectPath)}.json`);
48476
+ return join41(directory, "runs", `editor-${projectKey(projectPath)}.json`);
48468
48477
  }
48469
48478
  function writeEditorRunNote(note) {
48470
48479
  mkdirSync21(runsDirectory(), { recursive: true });
@@ -48517,13 +48526,13 @@ function everyRunRecord() {
48517
48526
  for (const directory of runtimeDirectories()) {
48518
48527
  let entries;
48519
48528
  try {
48520
- entries = readdirSync18(join40(directory, "runs"));
48529
+ entries = readdirSync18(join41(directory, "runs"));
48521
48530
  } catch {
48522
48531
  continue;
48523
48532
  }
48524
48533
  for (const entry of entries) {
48525
48534
  if (entry.startsWith("note-") && entry.endsWith(".json")) {
48526
- const record = recordAt(join40(directory, "runs", entry));
48535
+ const record = recordAt(join41(directory, "runs", entry));
48527
48536
  if (record !== null) {
48528
48537
  found.push(record);
48529
48538
  }
@@ -48791,7 +48800,7 @@ function sweepTranscripts(keepMs = 24 * 60 * 60 * 1000, now = Date.now()) {
48791
48800
  if (!transcript && !entry.endsWith(".partial")) {
48792
48801
  continue;
48793
48802
  }
48794
- const path = join40(directory, entry);
48803
+ const path = join41(directory, entry);
48795
48804
  if (kept.has(path) || ageMs(path, now) < keepMs) {
48796
48805
  continue;
48797
48806
  }
@@ -49047,16 +49056,16 @@ var init_server_instructions = __esm(() => {
49047
49056
 
49048
49057
  // src/suites-scene.ts
49049
49058
  import { existsSync as existsSync32, mkdirSync as mkdirSync22, writeFileSync as writeFileSync21 } from "node:fs";
49050
- import { join as join41, relative as relative9, sep as sep5 } from "node:path";
49059
+ import { join as join42, relative as relative9, sep as sep5 } from "node:path";
49051
49060
  function hasSuitesScene(projectPath) {
49052
- return existsSync32(join41(projectPath, SUITES_SCENE));
49061
+ return existsSync32(join42(projectPath, SUITES_SCENE));
49053
49062
  }
49054
49063
  function suitesSceneArgs(projectPath, suites) {
49055
- const runs = join41(projectPath, ".godot", "gdharness", "suite-scenes");
49064
+ const runs = join42(projectPath, ".godot", "gdharness", "suite-scenes");
49056
49065
  sweepRunDirectories(runs);
49057
- const directory = join41(runs, `${String(STARTED_AT)}-${String(process.pid)}`);
49066
+ const directory = join42(runs, `${String(STARTED_AT)}-${String(process.pid)}`);
49058
49067
  mkdirSync22(directory, { recursive: true });
49059
- const suitesFile = join41(directory, "suites.txt");
49068
+ const suitesFile = join42(directory, "suites.txt");
49060
49069
  writeFileSync21(suitesFile, `${suites.join(`
49061
49070
  `)}
49062
49071
  `);
@@ -49071,7 +49080,7 @@ function suitesSceneArgs(projectPath, suites) {
49071
49080
  "-c",
49072
49081
  "--ignoreHeadlessMode",
49073
49082
  "-rd",
49074
- `res://${relative9(projectPath, join41(directory, "reports")).split(sep5).join("/")}`,
49083
+ `res://${relative9(projectPath, join42(directory, "reports")).split(sep5).join("/")}`,
49075
49084
  "-rc",
49076
49085
  "1"
49077
49086
  ];
@@ -49085,7 +49094,7 @@ var init_suites_scene = __esm(() => {
49085
49094
 
49086
49095
  // src/test-selection.ts
49087
49096
  import { existsSync as existsSync33 } from "node:fs";
49088
- import { basename as basename12, join as join42 } from "node:path";
49097
+ import { basename as basename12, join as join43 } from "node:path";
49089
49098
  function casesOutOfPath(projectPath, given, tests) {
49090
49099
  const entries = Array.isArray(given) ? given : [given];
49091
49100
  const cases = [];
@@ -49129,12 +49138,12 @@ function casesIn(scripts, suite) {
49129
49138
  }
49130
49139
  function scriptsWithoutCases(projectPath, asked) {
49131
49140
  const scripts = new ProjectScripts(projectPath);
49132
- return asked.filter((path) => path.endsWith(".gd") && existsSync33(join42(projectPath, path.slice("res://".length))) && casesIn(scripts, path).length === 0);
49141
+ return asked.filter((path) => path.endsWith(".gd") && existsSync33(join43(projectPath, path.slice("res://".length))) && casesIn(scripts, path).length === 0);
49133
49142
  }
49134
49143
  function suitesUnder(projectPath, asked) {
49135
49144
  const scripts = projectFiles(projectPath, [".gd"]).map((path) => `res://${path}`);
49136
49145
  return [
49137
- ...new Set(asked.flatMap((path) => path.endsWith(".gd") ? existsSync33(join42(projectPath, path.slice("res://".length))) ? [path] : [] : scripts.filter((script) => script.startsWith(`${path}/`))))
49146
+ ...new Set(asked.flatMap((path) => path.endsWith(".gd") ? existsSync33(join43(projectPath, path.slice("res://".length))) ? [path] : [] : scripts.filter((script) => script.startsWith(`${path}/`))))
49138
49147
  ];
49139
49148
  }
49140
49149
  function selectTests(projectPath, asked, given) {
@@ -49212,7 +49221,7 @@ import {
49212
49221
  statSync as statSync20,
49213
49222
  writeFileSync as writeFileSync22
49214
49223
  } from "node:fs";
49215
- import { basename as basename13, dirname as dirname25, extname as extname4, isAbsolute as isAbsolute8, join as join43, normalize as normalize2, relative as relative10 } from "node:path";
49224
+ import { basename as basename13, dirname as dirname25, extname as extname4, isAbsolute as isAbsolute8, join as join44, normalize as normalize2, relative as relative10 } from "node:path";
49216
49225
  import { setTimeout as delay7 } from "node:timers/promises";
49217
49226
  import { fileURLToPath as fileURLToPath5 } from "node:url";
49218
49227
  function editorRestartTimeoutMs() {
@@ -49271,7 +49280,7 @@ function writtenFileRefusal(path, rule) {
49271
49280
  if (!existsSync34(directory)) {
49272
49281
  return `${named}'s directory ${dirname25(path)} does not exist; ${what} creates no directories.`;
49273
49282
  }
49274
- const where = join43(directory, basename13(path));
49283
+ const where = join44(directory, basename13(path));
49275
49284
  const inside = rule.projects.find((project) => project !== "" && isWithinRoot(realAsFarAsItExists(project), where));
49276
49285
  if (inside !== undefined) {
49277
49286
  return `${named} ${path} is inside the project at ${inside}; ${what} is saved outside it, so it never becomes part of the game.`;
@@ -49918,7 +49927,7 @@ function notRunNote(notRun, failFast) {
49918
49927
  function presetsIn(projectPath) {
49919
49928
  let text;
49920
49929
  try {
49921
- text = readFileSync37(join43(projectPath, "export_presets.cfg"), "utf8");
49930
+ text = readFileSync37(join44(projectPath, "export_presets.cfg"), "utf8");
49922
49931
  } catch {
49923
49932
  return null;
49924
49933
  }
@@ -49999,7 +50008,7 @@ function filesIn(folder) {
49999
50008
  try {
50000
50009
  for (const entry of readdirSync19(folder, { withFileTypes: true })) {
50001
50010
  if (entry.isFile()) {
50002
- found.set(entry.name, statSync20(join43(folder, entry.name)).mtimeMs);
50011
+ found.set(entry.name, statSync20(join44(folder, entry.name)).mtimeMs);
50003
50012
  }
50004
50013
  }
50005
50014
  } catch {}
@@ -50039,7 +50048,7 @@ function unsavedInEditorNote(scripts) {
50039
50048
  return `${named} ${one ? "is" : "are"} open in the editor's script ${one ? "tab" : "tabs"} with unsaved edits, and saving ${one ? "that tab" : "them"} there writes ${one ? "its" : "their"} text over what was written here: close ${one ? "it" : "them"} without saving, or save first and edit again.`;
50040
50049
  }
50041
50050
  function editorAddonMissing(projectPath) {
50042
- if (!existsSync34(join43(projectPath, "project.godot"))) {
50051
+ if (!existsSync34(join44(projectPath, "project.godot"))) {
50043
50052
  return null;
50044
50053
  }
50045
50054
  const report = inspectProject(projectPath);
@@ -50067,7 +50076,7 @@ function rewriteBusNamed(projectPath, from, to) {
50067
50076
  const giving = [`bus = &"${quoted(from)}"`, `bus = "${quoted(from)}"`];
50068
50077
  const rewritten = [];
50069
50078
  for (const file of projectFiles(projectPath, [".tscn", ".tres"])) {
50070
- const absolute = join43(projectPath, file);
50079
+ const absolute = join44(projectPath, file);
50071
50080
  const lines = readFileSync37(absolute, "utf8").split(`
50072
50081
  `);
50073
50082
  const at = [];
@@ -50087,7 +50096,7 @@ function rewriteBusNamed(projectPath, from, to) {
50087
50096
  }
50088
50097
  const namedInScripts = [];
50089
50098
  for (const file of projectFiles(projectPath, [".gd"])) {
50090
- readFileSync37(join43(projectPath, file), "utf8").split(`
50099
+ readFileSync37(join44(projectPath, file), "utf8").split(`
50091
50100
  `).forEach((line, index) => {
50092
50101
  if (line.includes(`"${from}"`)) {
50093
50102
  namedInScripts.push({ file: `res://${file}`, line: index + 1, text: line.trim() });
@@ -50372,7 +50381,7 @@ function profileFrameFunctions(projectPath) {
50372
50381
  let projectGodot = null;
50373
50382
  if (projectPath !== null) {
50374
50383
  try {
50375
- projectGodot = readFileSync37(join43(projectPath, "project.godot"), "utf8");
50384
+ projectGodot = readFileSync37(join44(projectPath, "project.godot"), "utf8");
50376
50385
  } catch {}
50377
50386
  }
50378
50387
  return frameFunctionsFor(queuedMessagesOf(projectGodot));
@@ -50568,7 +50577,7 @@ function foldedEntriesAnswer(log, floor = "warning") {
50568
50577
  }
50569
50578
  function gdUnitFailsOnScriptErrors(projectPath) {
50570
50579
  try {
50571
- return settingKeys(readFileSync37(join43(projectPath, "project.godot"), "utf8")).get("gdunit4/report/godot/script_error") !== false;
50580
+ return settingKeys(readFileSync37(join44(projectPath, "project.godot"), "utf8")).get("gdunit4/report/godot/script_error") !== false;
50572
50581
  } catch {
50573
50582
  return true;
50574
50583
  }
@@ -50583,7 +50592,7 @@ function uncaughtNote(uncaught) {
50583
50592
  }
50584
50593
  function elsewhereIn(projectPath, asked) {
50585
50594
  const wanted = asked.replace(/^res:\/\//, "").replace(/\/+$/, "");
50586
- if (wanted === "" || existsSync34(join43(projectPath, wanted))) {
50595
+ if (wanted === "" || existsSync34(join44(projectPath, wanted))) {
50587
50596
  return "";
50588
50597
  }
50589
50598
  const root = (wanted.split("/")[0] ?? "").toLowerCase();
@@ -50606,7 +50615,7 @@ function windowNoteFor(needing, sharing) {
50606
50615
  return `${named(needing)} ${one ? "needs" : "need"} a window, as gdharness test reads ${one ? "it" : "them"}, so the run had one: the engine ran without --headless, at the size project.godot gives its viewport, with no sound${process.platform === "win32" ? ", on a desktop of its own, where its window neither shows nor takes the keyboard" : ""}. ${why}${shared}`;
50607
50616
  }
50608
50617
  function testPathsIn(projectPath, given, named = "path") {
50609
- const defaults = TEST_DIRECTORIES.filter((directory) => existsSync34(join43(projectPath, directory)));
50618
+ const defaults = TEST_DIRECTORIES.filter((directory) => existsSync34(join44(projectPath, directory)));
50610
50619
  const entries = given === undefined || given === null || given === "" ? defaults.length > 0 ? defaults : TEST_DIRECTORIES : given;
50611
50620
  const listed = Array.isArray(entries) ? entries : [entries];
50612
50621
  if (listed.length === 0) {
@@ -50737,7 +50746,7 @@ function needsItsOwnProcess(asked) {
50737
50746
  class GodotServer {
50738
50747
  stdio = null;
50739
50748
  locator = new GodotLocator;
50740
- operationsScript = join43(__dirname2, "godot", "operations", "godot_operations.gd");
50749
+ operationsScript = join44(__dirname2, "godot", "operations", "godot_operations.gd");
50741
50750
  exportOptionsRead = new Map;
50742
50751
  heldWhilePending = new Set;
50743
50752
  evaluatedWhilePending = new Set;
@@ -51009,7 +51018,7 @@ class GodotServer {
51009
51018
  }
51010
51019
  noteTheStart() {
51011
51020
  const cwd = process.cwd();
51012
- const mcpJson = join43(cwd, ".mcp.json");
51021
+ const mcpJson = join44(cwd, ".mcp.json");
51013
51022
  const announced = this.ownProject === null ? null : readAnnouncement(announcementPath(this.ownProject));
51014
51023
  const predecessor = announced !== null && announced.pid !== process.pid && alive(announced.pid) ? announced.pid : null;
51015
51024
  writeLifecycle("started", {
@@ -51157,7 +51166,7 @@ class GodotServer {
51157
51166
  return checked.response;
51158
51167
  }
51159
51168
  const named = args["projectPath"];
51160
- if (typeof named === "string" && existsSync34(join43(named, "project.godot"))) {
51169
+ if (typeof named === "string" && existsSync34(join44(named, "project.godot"))) {
51161
51170
  this.lastProjectPath = named;
51162
51171
  }
51163
51172
  this.updates.refresh();
@@ -51200,7 +51209,7 @@ class GodotServer {
51200
51209
  let notSaved;
51201
51210
  try {
51202
51211
  savedAt = answer.content.map((item, index) => {
51203
- const file = join43(directory, item.type === "text" ? `${stem}-${index}.txt` : `${stem}-${index}.${item.mimeType.split("/")[1] ?? "bin"}`);
51212
+ const file = join44(directory, item.type === "text" ? `${stem}-${index}.txt` : `${stem}-${index}.${item.mimeType.split("/")[1] ?? "bin"}`);
51204
51213
  writeFileSync22(file, item.type === "text" ? item.text : Buffer.from(item.data, "base64"));
51205
51214
  return file;
51206
51215
  });
@@ -51897,7 +51906,7 @@ class GodotServer {
51897
51906
  if (path === undefined) {
51898
51907
  return { ok: false, response: this.createErrorResponse("projectPath is required.") };
51899
51908
  }
51900
- const file = join43(path, "project.godot");
51909
+ const file = join44(path, "project.godot");
51901
51910
  if (!existsSync34(file)) {
51902
51911
  return {
51903
51912
  ok: false,
@@ -52779,7 +52788,7 @@ class GodotServer {
52779
52788
  const platform = presetPlatform(project.value.path, preset);
52780
52789
  if (platform !== null) {
52781
52790
  const known = await this.exportOptions(platform, {
52782
- presetsFile: join43(project.value.path, "export_presets.cfg"),
52791
+ presetsFile: join44(project.value.path, "export_presets.cfg"),
52783
52792
  preset,
52784
52793
  asked: options
52785
52794
  });
@@ -52830,7 +52839,7 @@ ${platform}`;
52830
52839
  }
52831
52840
  const empty = scratchDirectory("export");
52832
52841
  try {
52833
- writeFileSync22(join43(empty, "project.godot"), `config_version=5
52842
+ writeFileSync22(join44(empty, "project.godot"), `config_version=5
52834
52843
  `);
52835
52844
  const outcome = await runOperation({ godotPath: engine.value, script: this.operationsScript, debug: DEBUG_MODE, editor: true }, "export_options", { platform, ...standing }, empty);
52836
52845
  const options = outcome.ok ? outcome.payload["options"] : undefined;
@@ -52886,7 +52895,7 @@ ${platform}`;
52886
52895
  const exportArgs = [
52887
52896
  "--headless",
52888
52897
  "--log-file",
52889
- join43(exportLogs, "engine.log"),
52898
+ join44(exportLogs, "engine.log"),
52890
52899
  "--path",
52891
52900
  project.value.path,
52892
52901
  pack ? "--export-pack" : debug ? "--export-debug" : "--export-release",
@@ -52985,7 +52994,7 @@ ${platform}`;
52985
52994
  if (movie !== null) {
52986
52995
  return this.createErrorResponse(movie);
52987
52996
  }
52988
- const missing = paths.value.filter((path) => !existsSync34(join43(project.value.path, path.slice("res://".length))));
52997
+ const missing = paths.value.filter((path) => !existsSync34(join44(project.value.path, path.slice("res://".length))));
52989
52998
  const projectScripts = new ProjectScripts(project.value.path);
52990
52999
  const present = paths.value.filter((path) => !missing.includes(path));
52991
53000
  const asked = projectScripts.searchedAsTold(present);
@@ -53077,10 +53086,10 @@ ${platform}`;
53077
53086
  const ignored = readStringArray(args, "ignore") ?? [];
53078
53087
  const declaredUnder = ignored.length === 0 ? [] : asked.flatMap((path) => path.endsWith(".gd") ? projectScripts.suite(path) ?? [] : projectScripts.suitesUnder([path]));
53079
53088
  const userData = scratchDirectory("tests");
53080
- const suitesFile = join43(userData, "suites.txt");
53081
- const skippingFile = join43(userData, "skipping.txt");
53082
- const engineLog = join43(userData, "engine.log");
53083
- const expectedFile = join43(userData, "expected.json");
53089
+ const suitesFile = join44(userData, "suites.txt");
53090
+ const skippingFile = join44(userData, "skipping.txt");
53091
+ const engineLog = join44(userData, "engine.log");
53092
+ const expectedFile = join44(userData, "expected.json");
53084
53093
  writeFileSync22(suitesFile, `${(selection.value?.suites ?? asked).join(`
53085
53094
  `)}
53086
53095
  `);
@@ -53121,11 +53130,11 @@ ${platform}`;
53121
53130
  const timeoutMs = readPositiveNumber(args, "timeoutMs") ?? TEST_TIMEOUT_MS;
53122
53131
  this.logDebug(`Running tests: ${engine.value} ${cmdArgs.join(" ")}`);
53123
53132
  const helperFiles = {
53124
- spec: join43(userData, "spec"),
53125
- pid: join43(userData, "pid"),
53126
- error: join43(userData, "error"),
53127
- stop: join43(userData, "stop"),
53128
- step: join43(userData, "step")
53133
+ spec: join44(userData, "spec"),
53134
+ pid: join44(userData, "pid"),
53135
+ error: join44(userData, "error"),
53136
+ stop: join44(userData, "stop"),
53137
+ step: join44(userData, "step")
53129
53138
  };
53130
53139
  const onDesktop = windowed && process.platform === "win32";
53131
53140
  const run = await this.spawnGame(engine.value, cmdArgs, userDataIn(userData), onDesktop ? { directory: project.value.path, files: helperFiles } : undefined);
@@ -53179,7 +53188,7 @@ ${platform}`;
53179
53188
  await run.settled;
53180
53189
  const helperFailed = onDesktop ? helperFailure(helperFiles.error) ?? (existsSync34(helperFiles.pid) ? null : `it never started, and ${helperStep(helperFiles.step)}`) : null;
53181
53190
  if (helperFailed !== null) {
53182
- discard(join43(project.value.path, ".godot", ...ours.split("/")), userData);
53191
+ discard(join44(project.value.path, ".godot", ...ours.split("/")), userData);
53183
53192
  return this.createErrorResponse(`No tests ran: ${named(needing)} ${needing.length === 1 ? "needs" : "need"} a window, and the engine could not be started on a desktop of its own: ${helperFailed}`);
53184
53193
  }
53185
53194
  const endedAt = Date.now();
@@ -53190,7 +53199,7 @@ ${platform}`;
53190
53199
  engine: endedAt - importedAt
53191
53200
  };
53192
53201
  const notCompiled = stopped.for ?? run.log.all.map((entry) => autoloadNotCompiled(entry, autoloaded)).find((found) => found !== null) ?? null;
53193
- const reportsDir = join43(project.value.path, ".godot", ...ours.split("/"));
53202
+ const reportsDir = join44(project.value.path, ".godot", ...ours.split("/"));
53194
53203
  let report = null;
53195
53204
  let reportProblem = null;
53196
53205
  const casePrinted = withNestedErrors(readRun(existsSync34(engineLog) ? readFileSync37(engineLog, "utf8") : ""), run.log.all);
@@ -53199,7 +53208,7 @@ ${platform}`;
53199
53208
  const written = existsSync34(reportsDir) && notCompiled === null ? readdirSync19(reportsDir).filter((name) => name.startsWith("report_")).sort((a, b) => Number(a.slice("report_".length)) - Number(b.slice("report_".length))) : [];
53200
53209
  const newest = written.at(-1);
53201
53210
  if (newest !== undefined) {
53202
- report = parseJUnit(readFileSync37(join43(reportsDir, newest, "results.xml"), "utf8"));
53211
+ report = parseJUnit(readFileSync37(join44(reportsDir, newest, "results.xml"), "utf8"));
53203
53212
  }
53204
53213
  } catch (error) {
53205
53214
  reportProblem = errorMessage(error);
@@ -53604,7 +53613,7 @@ ${error.text}`;
53604
53613
  const scripts = projectFiles(projectPath, [".gd"]).map((script) => `res://${script}`);
53605
53614
  const wanted = `res://${relativePath}`;
53606
53615
  const folder = dirname25(relativePath.replaceAll("\\", "/"));
53607
- const inFolder = join43(projectPath, folder);
53616
+ const inFolder = join44(projectPath, folder);
53608
53617
  const beside = existsSync34(inFolder) ? readdirSync19(inFolder, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => `res://${folder === "." ? "" : `${folder}/`}${entry.name}`) : [];
53609
53618
  return this.createErrorResponse(withNearestFiles(`Script file does not exist: ${wanted}`, wanted, scripts, beside));
53610
53619
  }
@@ -54005,7 +54014,7 @@ ${error.text}`;
54005
54014
  ...Array.isArray(stack) ? {
54006
54015
  stack: stack.map((frame) => ({
54007
54016
  ...frame,
54008
- ...projectPath !== "" && typeof frame["script"] === "string" && frame["script"].startsWith("res://") ? { path: join43(projectPath, frame["script"].slice("res://".length)) } : {}
54017
+ ...projectPath !== "" && typeof frame["script"] === "string" && frame["script"].startsWith("res://") ? { path: join44(projectPath, frame["script"].slice("res://".length)) } : {}
54009
54018
  }))
54010
54019
  } : {}
54011
54020
  });
@@ -54350,7 +54359,7 @@ ${error.text}`;
54350
54359
  return null;
54351
54360
  }
54352
54361
  try {
54353
- return settingKeys(readFileSync37(join43(projectPath, "project.godot"), "utf8"));
54362
+ return settingKeys(readFileSync37(join44(projectPath, "project.godot"), "utf8"));
54354
54363
  } catch {
54355
54364
  return null;
54356
54365
  }
@@ -54695,7 +54704,7 @@ ${error.text}`;
54695
54704
  if (!paths.ok) {
54696
54705
  return refused(paths.reason, PATH_SOLUTIONS);
54697
54706
  }
54698
- const missing = paths.value.filter((path) => !existsSync34(join43(projectPath, path.slice("res://".length))));
54707
+ const missing = paths.value.filter((path) => !existsSync34(join44(projectPath, path.slice("res://".length))));
54699
54708
  if (missing.length > 0) {
54700
54709
  return refused(`Nothing at ${missing.join(" and ")} in the project at ${projectPath}.`, PATH_SOLUTIONS);
54701
54710
  }
@@ -54866,7 +54875,7 @@ ${error.text}`;
54866
54875
  }
54867
54876
  async runtimeUp(projectPath, before, budget, withArgs) {
54868
54877
  const budgetMs = budget.ms;
54869
- if (!existsSync34(join43(projectPath, RUNTIME_SCRIPT))) {
54878
+ if (!existsSync34(join44(projectPath, RUNTIME_SCRIPT))) {
54870
54879
  return runtimeVerdict(null, {
54871
54880
  addon: false,
54872
54881
  budgetMs,
@@ -55908,7 +55917,7 @@ ${error.text}`;
55908
55917
  };
55909
55918
  const going = await this.runStillGoing(run);
55910
55919
  const projectPath = run.projectPath;
55911
- const projectGone = projectPath !== null && !existsSync34(join43(projectPath, "project.godot"));
55920
+ const projectGone = projectPath !== null && !existsSync34(join44(projectPath, "project.godot"));
55912
55921
  if (projectGone && callersName !== undefined) {
55913
55922
  return this.createErrorResponse(`callersOf reads the project's scripts, and the run's project at ${projectPath} has no project.godot any more.`, ["editor_run profile without callersOf answers with the profile itself"]);
55914
55923
  }
@@ -56293,7 +56302,7 @@ ${error.text}`;
56293
56302
  notes.push(endedWithoutACode({
56294
56303
  throughEditor: run.throughEditor,
56295
56304
  announced: announced !== undefined || run.announcedPid !== undefined,
56296
- couldAnnounce: run.projectPath !== null && existsSync34(join43(run.projectPath, RUNTIME_SCRIPT)),
56305
+ couldAnnounce: run.projectPath !== null && existsSync34(join44(run.projectPath, RUNTIME_SCRIPT)),
56297
56306
  endedHere: typeof run.endedHere === "string",
56298
56307
  pickedUp: run.pickedUp === true
56299
56308
  }));
@@ -57779,7 +57788,7 @@ ${error.text}`;
57779
57788
  async ownRunOnItsWay(projectPath, budgetMs) {
57780
57789
  const run = await this.currentRun();
57781
57790
  const project = projectPath ?? run?.projectPath ?? null;
57782
- if (run === null || project === null || run.announcedPid !== undefined || run.projectPath !== null && !isSameDirectory(run.projectPath, project) || !existsSync34(join43(project, RUNTIME_SCRIPT)) || !await this.runStillGoing(run)) {
57791
+ if (run === null || project === null || run.announcedPid !== undefined || run.projectPath !== null && !isSameDirectory(run.projectPath, project) || !existsSync34(join44(project, RUNTIME_SCRIPT)) || !await this.runStillGoing(run)) {
57783
57792
  return null;
57784
57793
  }
57785
57794
  const already = runtimesAnnounced().running;
@@ -57889,7 +57898,7 @@ ${error.text}`;
57889
57898
  return this.createErrorResponse(staleNote);
57890
57899
  }
57891
57900
  const screenshotDir = expectsScreenshot ? scratchDirectory("runtime-screenshot") : null;
57892
- const screenshotPath = screenshotDir ? join43(screenshotDir, "capture.png") : null;
57901
+ const screenshotPath = screenshotDir ? join44(screenshotDir, "capture.png") : null;
57893
57902
  const refused = (message) => this.createErrorResponse(message);
57894
57903
  const onGame = {
57895
57904
  pid: choice.endpoint.pid,
@@ -58228,7 +58237,7 @@ init_bridge_announce();
58228
58237
  init_engine_launch();
58229
58238
  init_engine_slots();
58230
58239
  import { existsSync as existsSync35 } from "node:fs";
58231
- import { dirname as dirname26, join as join44, resolve as resolve14 } from "node:path";
58240
+ import { dirname as dirname26, join as join45, resolve as resolve14 } from "node:path";
58232
58241
 
58233
58242
  // src/error-mode.ts
58234
58243
  import process8 from "node:process";
@@ -58268,13 +58277,13 @@ init_lsp_client();
58268
58277
  init_process_children();
58269
58278
  import { existsSync as existsSync17, readdirSync as readdirSync10, readFileSync as readFileSync16, unlinkSync as unlinkSync2 } from "node:fs";
58270
58279
  import { connect as connect2 } from "node:net";
58271
- import { join as join20, resolve as resolve7 } from "node:path";
58280
+ import { join as join21, resolve as resolve7 } from "node:path";
58272
58281
  var EDITOR_RECORD_PROTOCOL = 1;
58273
58282
  var LSP_WAIT_SECONDS = 20;
58274
58283
  var HOST = "127.0.0.1";
58275
58284
  var LOOK_AGAIN_MS = 500;
58276
58285
  function editorRecordsIn(projectPath) {
58277
- const directory = join20(projectPath, ".godot", "gdharness-editors");
58286
+ const directory = join21(projectPath, ".godot", "gdharness-editors");
58278
58287
  let names;
58279
58288
  try {
58280
58289
  names = readdirSync10(directory).filter((name) => /^\d+\.json$/.test(name));
@@ -58283,7 +58292,7 @@ function editorRecordsIn(projectPath) {
58283
58292
  }
58284
58293
  const records = [];
58285
58294
  for (const name of names) {
58286
- const file = join20(directory, name);
58295
+ const file = join21(directory, name);
58287
58296
  try {
58288
58297
  const said = JSON.parse(readFileSync16(file, "utf8"));
58289
58298
  const { protocol, pid, lsp_port: lspPort, written_at_ms: writtenAtMs } = said;
@@ -58378,7 +58387,7 @@ function lspOptionsOf(args, cwd) {
58378
58387
  }
58379
58388
  }
58380
58389
  const projectPath = resolve7(cwd, named ?? ".");
58381
- if (!existsSync17(join20(projectPath, "project.godot"))) {
58390
+ if (!existsSync17(join21(projectPath, "project.godot"))) {
58382
58391
  throw new EngineUsageError(`Not a Godot project: ${projectPath} holds no project.godot.`);
58383
58392
  }
58384
58393
  return { projectPath, port, waitSeconds };
@@ -58485,9 +58494,9 @@ init_setup();
58485
58494
  init_tool_definitions();
58486
58495
  init_tool_reference();
58487
58496
  import { existsSync as existsSync19, mkdirSync as mkdirSync7, readdirSync as readdirSync12, rmSync as rmSync10, writeFileSync as writeFileSync11 } from "node:fs";
58488
- import { basename as basename8, dirname as dirname10, join as join22 } from "node:path";
58497
+ import { basename as basename8, dirname as dirname10, join as join23 } from "node:path";
58489
58498
  var SKILL_NAME = "gdharness";
58490
- var SHARED_SKILLS = join22(".agents", "skills");
58499
+ var SHARED_SKILLS = join23(".agents", "skills");
58491
58500
  function skillMarkdown(version) {
58492
58501
  return `---
58493
58502
  name: ${SKILL_NAME}
@@ -58728,27 +58737,27 @@ what they report while starting comes back under \`engine_messages_before_operat
58728
58737
  function skillFiles(version) {
58729
58738
  return new Map([
58730
58739
  ["SKILL.md", skillMarkdown(version)],
58731
- [join22("references", "tools.md"), renderToolsMarkdown()]
58740
+ [join23("references", "tools.md"), renderToolsMarkdown()]
58732
58741
  ]);
58733
58742
  }
58734
58743
  function skillDirectories(harnesses, projectPath, exists) {
58735
- const directories = [join22(projectPath, SHARED_SKILLS, SKILL_NAME)];
58744
+ const directories = [join23(projectPath, SHARED_SKILLS, SKILL_NAME)];
58736
58745
  for (const harness of harnesses) {
58737
58746
  if (harness.skills === undefined) {
58738
58747
  continue;
58739
58748
  }
58740
- const own = join22(projectPath, harness.skills.dir);
58741
- if ((!harness.skills.shared || exists(own)) && !directories.includes(join22(own, SKILL_NAME))) {
58742
- directories.push(join22(own, SKILL_NAME));
58749
+ const own = join23(projectPath, harness.skills.dir);
58750
+ if ((!harness.skills.shared || exists(own)) && !directories.includes(join23(own, SKILL_NAME))) {
58751
+ directories.push(join23(own, SKILL_NAME));
58743
58752
  }
58744
58753
  }
58745
58754
  return directories;
58746
58755
  }
58747
58756
  function everySkillDirectory(projectPath, harnesses) {
58748
- const directories = new Set([join22(projectPath, SHARED_SKILLS, SKILL_NAME)]);
58757
+ const directories = new Set([join23(projectPath, SHARED_SKILLS, SKILL_NAME)]);
58749
58758
  for (const harness of harnesses) {
58750
58759
  if (harness.skills !== undefined) {
58751
- directories.add(join22(projectPath, harness.skills.dir, SKILL_NAME));
58760
+ directories.add(join23(projectPath, harness.skills.dir, SKILL_NAME));
58752
58761
  }
58753
58762
  }
58754
58763
  return [...directories];
@@ -58765,7 +58774,7 @@ function removeSkill(directories, projectPath) {
58765
58774
  return removed;
58766
58775
  }
58767
58776
  function pruneEmpty(directory, projectPath) {
58768
- const shared = join22(projectPath, ".agents");
58777
+ const shared = join23(projectPath, ".agents");
58769
58778
  let path = directory;
58770
58779
  while (path !== projectPath && (basename8(path) === "skills" || path === shared)) {
58771
58780
  if (readdirSync12(path).length > 0) {
@@ -58781,7 +58790,7 @@ function writeSkill(directories, version) {
58781
58790
  const replaced = existsSync19(directory);
58782
58791
  rmSync10(directory, { recursive: true, force: true });
58783
58792
  for (const [name, contents] of files) {
58784
- const path = join22(directory, name);
58793
+ const path = join23(directory, name);
58785
58794
  mkdirSync7(dirname10(path), { recursive: true });
58786
58795
  writeFileSync11(path, contents, "utf8");
58787
58796
  }
@@ -58796,7 +58805,7 @@ init_setup();
58796
58805
  init_suite_judge();
58797
58806
  import { existsSync as existsSync20, mkdirSync as mkdirSync8, readFileSync as readFileSync19, rmSync as rmSync11 } from "node:fs";
58798
58807
  import { availableParallelism as availableParallelism3 } from "node:os";
58799
- import { join as join23, resolve as resolve9 } from "node:path";
58808
+ import { join as join24, resolve as resolve9 } from "node:path";
58800
58809
  import process13 from "node:process";
58801
58810
  var SHARE = "--gdh-share=";
58802
58811
  var GATHER = "--gdh-share-gather=";
@@ -58836,9 +58845,9 @@ function spreadOptionsOf(args, cwd) {
58836
58845
  }
58837
58846
  const first = positional[0];
58838
58847
  const named = first === undefined ? null : resolve9(cwd, first);
58839
- const projectNamed = named !== null && existsSync20(join23(named, "project.godot"));
58848
+ const projectNamed = named !== null && existsSync20(join24(named, "project.godot"));
58840
58849
  const projectPath = projectNamed ? named : resolve9(cwd);
58841
- if (!existsSync20(join23(projectPath, "project.godot"))) {
58850
+ if (!existsSync20(join24(projectPath, "project.godot"))) {
58842
58851
  throw new EngineUsageError(`Not a Godot project: ${projectPath} holds no project.godot.`);
58843
58852
  }
58844
58853
  const scenes = positional.slice(projectNamed ? 1 : 0);
@@ -58846,7 +58855,7 @@ function spreadOptionsOf(args, cwd) {
58846
58855
  throw new EngineUsageError(scenes.length === 0 ? "gdharness spread needs the scene of the bench to play." : `gdharness spread plays one scene, and was given ${String(scenes.length)}: ${scenes.join(", ")}.`);
58847
58856
  }
58848
58857
  const scene = resPathOf(scenes[0] ?? "", projectPath, cwd);
58849
- if (!existsSync20(join23(projectPath, scene.slice("res://".length)))) {
58858
+ if (!existsSync20(join24(projectPath, scene.slice("res://".length)))) {
58850
58859
  throw new EngineUsageError(`Nothing at ${scene} in the project at ${projectPath}.`);
58851
58860
  }
58852
58861
  const benchArguments = dashes === -1 ? [] : args.slice(dashes + 1);
@@ -58917,14 +58926,14 @@ function shareFaults(played) {
58917
58926
  return faults;
58918
58927
  }
58919
58928
  async function runSpreadCommand(options, godotPath) {
58920
- if (!existsSync20(join23(options.projectPath, SHARE_SCRIPT))) {
58929
+ if (!existsSync20(join24(options.projectPath, SHARE_SCRIPT))) {
58921
58930
  throw new EngineUsageError(`res://${SHARE_SCRIPT} is not in the project, so its bench cannot ask GdhShare for outcomes. Run gdharness setup.`);
58922
58931
  }
58923
58932
  const startedAt = Date.now();
58924
- const spreadRuns = join23(options.projectPath, ".godot", "gdharness", "spread-runs");
58933
+ const spreadRuns = join24(options.projectPath, ".godot", "gdharness", "spread-runs");
58925
58934
  sweepRunDirectories(spreadRuns);
58926
- const runDirectory = join23(spreadRuns, `${String(startedAt)}-${String(process13.pid)}`);
58927
- const shareDirectory = join23(runDirectory, "share");
58935
+ const runDirectory = join24(spreadRuns, `${String(startedAt)}-${String(process13.pid)}`);
58936
+ const shareDirectory = join24(runDirectory, "share");
58928
58937
  mkdirSync8(shareDirectory, { recursive: true });
58929
58938
  const chosen = machineSlots({ directory: options.slotsDirectory, count: options.slotCount });
58930
58939
  const slotCount = chosen.count;
@@ -58963,7 +58972,7 @@ async function runSpreadCommand(options, godotPath) {
58963
58972
  share,
58964
58973
  `${INTO}${shareDirectory}`
58965
58974
  ]);
58966
- const logs = Array.from({ length: workers }, (_, index) => join23(runDirectory, `worker-${String(index)}`, "engine.log"));
58975
+ const logs = Array.from({ length: workers }, (_, index) => join24(runDirectory, `worker-${String(index)}`, "engine.log"));
58967
58976
  let done = 0;
58968
58977
  const heartbeat = setInterval(() => {
58969
58978
  console.log(`[spread] ${progressOf(logs)}`);
@@ -58981,7 +58990,7 @@ async function runSpreadCommand(options, godotPath) {
58981
58990
  }
58982
58991
  const faults = left.flatMap((worker) => engineFaults(worker, options.godotVersion));
58983
58992
  const arms = left.map((_, index) => {
58984
- const file = join23(shareDirectory, `worker-${String(index)}.arms`);
58993
+ const file = join24(shareDirectory, `worker-${String(index)}.arms`);
58985
58994
  return existsSync20(file) ? armsPlayed(readFileSync19(file, "utf8")) : [];
58986
58995
  });
58987
58996
  faults.push(...shareFaults(arms));
@@ -58991,7 +59000,7 @@ async function runSpreadCommand(options, godotPath) {
58991
59000
  const gather = await engine("gather", `${GATHER}${String(workers)}`);
58992
59001
  console.log(readFileSync19(gather.log, "utf8").replace(CONTROL_SEQUENCE, "").trimEnd());
58993
59002
  const gatherFaults = engineFaults(gather, options.godotVersion);
58994
- const gatheredFile = join23(shareDirectory, "gathered.arms");
59003
+ const gatheredFile = join24(shareDirectory, "gathered.arms");
58995
59004
  const gathered = new Set((existsSync20(gatheredFile) ? armsPlayed(readFileSync19(gatheredFile, "utf8")) ?? [] : []).map((arm) => arm.arm));
58996
59005
  const ungathered = (arms[0] ?? []).filter((arm) => !gathered.has(arm.arm)).map((arm) => arm.arm);
58997
59006
  if (ungathered.length > 0) {
@@ -59012,9 +59021,9 @@ async function runSpreadCommand(options, godotPath) {
59012
59021
  }
59013
59022
  }
59014
59023
  async function played(launch, slots, options, runDirectory, name, benchArguments) {
59015
- const directory = join23(runDirectory, name);
59016
- mkdirSync8(join23(directory, "user"), { recursive: true });
59017
- const log = join23(directory, "engine.log");
59024
+ const directory = join24(runDirectory, name);
59025
+ mkdirSync8(join24(directory, "user"), { recursive: true });
59026
+ const log = join24(directory, "engine.log");
59018
59027
  const args = [
59019
59028
  "--headless",
59020
59029
  "--audio-driver",
@@ -59097,14 +59106,14 @@ import {
59097
59106
  writeFileSync as writeFileSync12
59098
59107
  } from "node:fs";
59099
59108
  import { availableParallelism as availableParallelism4 } from "node:os";
59100
- import { dirname as dirname13, join as join27, relative as relative5, resolve as resolve10, sep as sep4 } from "node:path";
59109
+ import { dirname as dirname13, join as join28, relative as relative5, resolve as resolve10, sep as sep4 } from "node:path";
59101
59110
  import process14 from "node:process";
59102
59111
 
59103
59112
  // src/suite-fingerprint.ts
59104
59113
  init_class_cache();
59105
59114
  import { createHash as createHash6 } from "node:crypto";
59106
59115
  import { existsSync as existsSync21, readdirSync as readdirSync13, readFileSync as readFileSync20, statSync as statSync13 } from "node:fs";
59107
- import { join as join24, posix as posix2 } from "node:path";
59116
+ import { join as join25, posix as posix2 } from "node:path";
59108
59117
  var RES_LITERAL = /res:\/\/[^"'\s)\]<>]*/g;
59109
59118
  var RELATIVE_LOAD = /\b(?:pre)?load\(\s*["']((?!res:\/\/|uid:\/\/)[^"']+)["']/g;
59110
59119
  var REACHES_AT_RUN_TIME = [
@@ -59163,7 +59172,7 @@ ${this.read(path).digest}
59163
59172
  const hash = createHash6("sha256");
59164
59173
  const walk = (directory, under) => {
59165
59174
  for (const entry of readdirSync13(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
59166
- const file = join24(directory, entry.name);
59175
+ const file = join25(directory, entry.name);
59167
59176
  if (entry.isDirectory()) {
59168
59177
  walk(file, `${under}${entry.name}/`);
59169
59178
  } else if (entry.isFile()) {
@@ -59172,7 +59181,7 @@ ${this.read(path).digest}
59172
59181
  }
59173
59182
  }
59174
59183
  };
59175
- const directory = join24(this.scripts.projectPath, root.slice("res://".length));
59184
+ const directory = join25(this.scripts.projectPath, root.slice("res://".length));
59176
59185
  if (existsSync21(directory)) {
59177
59186
  walk(directory, "");
59178
59187
  }
@@ -59182,7 +59191,7 @@ ${this.read(path).digest}
59182
59191
  if (PLACEHOLDER.test(path)) {
59183
59192
  return { digest: "", reaches: [], unreadable: `${path} is filled in at run time` };
59184
59193
  }
59185
- const file = join24(this.scripts.projectPath, path.slice("res://".length));
59194
+ const file = join25(this.scripts.projectPath, path.slice("res://".length));
59186
59195
  if (!existsSync21(file)) {
59187
59196
  return { digest: "missing", reaches: [], unreadable: null };
59188
59197
  }
@@ -59231,7 +59240,7 @@ ${this.read(path).digest}
59231
59240
  }
59232
59241
  }
59233
59242
  function extensionsOf(projectPath) {
59234
- const list = join24(projectPath, ".godot", "extension_list.cfg");
59243
+ const list = join25(projectPath, ".godot", "extension_list.cfg");
59235
59244
  return existsSync21(list) ? readFileSync20(list, "utf8").split(`
59236
59245
  `).map((line) => line.trim()).filter((line) => line.startsWith("res://")) : [];
59237
59246
  }
@@ -59242,13 +59251,13 @@ init_suite_plan();
59242
59251
 
59243
59252
  // src/version.ts
59244
59253
  import { readFileSync as readFileSync22 } from "node:fs";
59245
- import { dirname as dirname12, join as join26 } from "node:path";
59254
+ import { dirname as dirname12, join as join27 } from "node:path";
59246
59255
  import { fileURLToPath as fileURLToPath3 } from "node:url";
59247
59256
  function getLocalVersion() {
59248
59257
  const currentDirectory = dirname12(fileURLToPath3(import.meta.url));
59249
59258
  const packageCandidates = [
59250
- join26(currentDirectory, "..", "package.json"),
59251
- join26(currentDirectory, "..", "..", "package.json")
59259
+ join27(currentDirectory, "..", "package.json"),
59260
+ join27(currentDirectory, "..", "..", "package.json")
59252
59261
  ];
59253
59262
  for (const packagePath of packageCandidates) {
59254
59263
  try {
@@ -59319,9 +59328,9 @@ function testOptionsOf(args, cwd) {
59319
59328
  }
59320
59329
  const first = positional[0];
59321
59330
  const named = first === undefined ? null : resolve10(cwd, first);
59322
- const projectNamed = named !== null && existsSync23(join27(named, "project.godot"));
59331
+ const projectNamed = named !== null && existsSync23(join28(named, "project.godot"));
59323
59332
  const projectPath = projectNamed ? named : resolve10(cwd);
59324
- if (!existsSync23(join27(projectPath, "project.godot"))) {
59333
+ if (!existsSync23(join28(projectPath, "project.godot"))) {
59325
59334
  throw new EngineUsageError(`Not a Godot project: ${projectPath} holds no project.godot.`);
59326
59335
  }
59327
59336
  const last = (flag) => valued.get(flag)?.at(-1);
@@ -59355,11 +59364,11 @@ function seedOf(value) {
59355
59364
  return seed;
59356
59365
  }
59357
59366
  function rootsOf(options) {
59358
- return options.roots.length > 0 ? options.roots : TEST_DIRECTORIES.filter((root) => existsSync23(join27(options.projectPath, root))).map((root) => `res://${root}`);
59367
+ return options.roots.length > 0 ? options.roots : TEST_DIRECTORIES.filter((root) => existsSync23(join28(options.projectPath, root))).map((root) => `res://${root}`);
59359
59368
  }
59360
59369
  function searchedRoots(options) {
59361
59370
  return options.selected.length === 0 ? rootsOf(options) : options.selected.filter((entry) => {
59362
- const directory = join27(options.projectPath, entry.slice("res://".length));
59371
+ const directory = join28(options.projectPath, entry.slice("res://".length));
59363
59372
  return existsSync23(directory) && statSync14(directory).isDirectory();
59364
59373
  });
59365
59374
  }
@@ -59376,7 +59385,7 @@ function selectedSuites(scripts, options) {
59376
59385
  for (const entry of options.selected) {
59377
59386
  const caseAt = /^(res:\/\/.*\.gd):(\w+)$/.exec(entry);
59378
59387
  const path = caseAt?.[1] ?? entry;
59379
- const directory = join27(options.projectPath, path.slice(6));
59388
+ const directory = join28(options.projectPath, path.slice(6));
59380
59389
  const suites = existsSync23(directory) && statSync14(directory).isDirectory() ? scripts.suitesUnder([path.replace(/\/$/, "")]) : [scripts.suite(path)].filter((suite) => suite !== null);
59381
59390
  if (suites.length === 0) {
59382
59391
  throw new EngineUsageError(existsSync23(directory) ? `${path} holds no gdUnit4 suite: nothing there extends GdUnitTestSuite and declares a test_ function.` : `Nothing at ${path} in the project at ${options.projectPath}.`);
@@ -59433,7 +59442,7 @@ class RunLogs {
59433
59442
  return this.kept ?? this.directory;
59434
59443
  }
59435
59444
  named(path) {
59436
- return this.kept === null ? path : join27(this.kept, relative5(this.directory, path));
59445
+ return this.kept === null ? path : join28(this.kept, relative5(this.directory, path));
59437
59446
  }
59438
59447
  keep() {
59439
59448
  if (this.kept === null) {
@@ -59441,8 +59450,8 @@ class RunLogs {
59441
59450
  }
59442
59451
  for (const file of readdirSync14(this.directory, { recursive: true, encoding: "utf8" })) {
59443
59452
  if (file.endsWith(".log") && file.split(sep4).length === 2) {
59444
- mkdirSync10(dirname13(join27(this.kept, file)), { recursive: true });
59445
- copyFileSync(join27(this.directory, file), join27(this.kept, file));
59453
+ mkdirSync10(dirname13(join28(this.kept, file)), { recursive: true });
59454
+ copyFileSync(join28(this.directory, file), join28(this.kept, file));
59446
59455
  }
59447
59456
  }
59448
59457
  }
@@ -59455,24 +59464,24 @@ async function runTestCommand(options, godotPath) {
59455
59464
  const startedAt = Date.now();
59456
59465
  const scripts = new ProjectScripts(options.projectPath);
59457
59466
  const home = homeOf(options.projectPath);
59458
- const state = join27(home, ".godot", "gdharness");
59459
- const timesFile = join27(state, "suite-times.json");
59460
- const passedFile = join27(state, "suite-passed.json");
59461
- const lastRunFile = join27(state, LAST_RUN_FILE);
59467
+ const state = join28(home, ".godot", "gdharness");
59468
+ const timesFile = join28(state, "suite-times.json");
59469
+ const passedFile = join28(state, "suite-passed.json");
59470
+ const lastRunFile = join28(state, LAST_RUN_FILE);
59462
59471
  let suites = selectedSuites(scripts, options);
59463
59472
  const uncollected = uncollectedSaid(scripts.uncollectedUnder(searchedRoots(options)));
59464
59473
  const wholeSuites = suites.map((suite) => scripts.suite(suite.path) ?? suite);
59465
59474
  const declared = new Map(wholeSuites.map((suite) => [suite.path, suite.cases]));
59466
- const testRuns = join27(options.projectPath, ".godot", "gdharness", "test-runs");
59467
- const keptRuns = join27(state, "test-runs");
59475
+ const testRuns = join28(options.projectPath, ".godot", "gdharness", "test-runs");
59476
+ const keptRuns = join28(state, "test-runs");
59468
59477
  sweepRunDirectories(testRuns);
59469
59478
  if (keptRuns !== testRuns) {
59470
59479
  sweepRunDirectories(keptRuns);
59471
59480
  }
59472
59481
  const runName = `${String(startedAt)}-${String(process14.pid)}`;
59473
- const runDirectory = join27(testRuns, runName);
59482
+ const runDirectory = join28(testRuns, runName);
59474
59483
  mkdirSync10(runDirectory, { recursive: true });
59475
- const logs = new RunLogs(runDirectory, keptRuns === testRuns ? null : join27(keptRuns, runName));
59484
+ const logs = new RunLogs(runDirectory, keptRuns === testRuns ? null : join28(keptRuns, runName));
59476
59485
  const chosen = machineSlots({ directory: options.slotsDirectory, count: options.slotCount });
59477
59486
  const slots = new EngineSlots(chosen.directory, chosen.count, { pid: process14.pid, started: await ownStart(), by: `gdharness test of ${options.projectPath}` }, (line) => {
59478
59487
  console.log(line);
@@ -59680,9 +59689,9 @@ async function importProject(launch) {
59680
59689
  console.log("The import was skipped: every imported file and the class cache are current.");
59681
59690
  return null;
59682
59691
  }
59683
- const directory = join27(launch.runDirectory, "import");
59684
- mkdirSync10(join27(directory, "user"), { recursive: true });
59685
- const log = join27(directory, "import.log");
59692
+ const directory = join28(launch.runDirectory, "import");
59693
+ mkdirSync10(join28(directory, "user"), { recursive: true });
59694
+ const log = join28(directory, "import.log");
59686
59695
  const lock = await launch.slots.take();
59687
59696
  try {
59688
59697
  freeLibraryCopies(launch.projectPath);
@@ -59747,12 +59756,12 @@ async function runShares(launch, units, declared, lanes, taken, times) {
59747
59756
  return (await Promise.all(Array.from({ length: lanes }, (_, at) => lane(at)))).flat().sort((a, b) => a.index - b.index);
59748
59757
  }
59749
59758
  async function runEngine2(launch, plan, index, times, again = "", slot = null) {
59750
- const directory = join27(launch.runDirectory, `engine-${String(index)}${again === "" ? "" : `-${again}`}`);
59751
- mkdirSync10(join27(directory, "user"), { recursive: true });
59752
- const suitesFile = join27(directory, "suites.txt");
59753
- const skippingFile = join27(directory, "skipping.txt");
59754
- const rowsFile = join27(directory, "rows.txt");
59755
- const expectedFile = join27(directory, "expected.json");
59759
+ const directory = join28(launch.runDirectory, `engine-${String(index)}${again === "" ? "" : `-${again}`}`);
59760
+ mkdirSync10(join28(directory, "user"), { recursive: true });
59761
+ const suitesFile = join28(directory, "suites.txt");
59762
+ const skippingFile = join28(directory, "skipping.txt");
59763
+ const rowsFile = join28(directory, "rows.txt");
59764
+ const expectedFile = join28(directory, "expected.json");
59756
59765
  writeFileSync12(suitesFile, `${plan.suites.map((suite) => suite.path).join(`
59757
59766
  `)}
59758
59767
  `);
@@ -59779,7 +59788,7 @@ async function runEngine2(launch, plan, index, times, again = "", slot = null) {
59779
59788
  ...plan.windowed ? [] : ["--ignoreHeadlessMode"],
59780
59789
  "-c",
59781
59790
  "-rd",
59782
- `res://${relative5(launch.projectPath, join27(directory, "reports")).split(sep4).join("/")}`,
59791
+ `res://${relative5(launch.projectPath, join28(directory, "reports")).split(sep4).join("/")}`,
59783
59792
  "-rc",
59784
59793
  "1",
59785
59794
  "--",
@@ -59795,7 +59804,7 @@ async function runEngine2(launch, plan, index, times, again = "", slot = null) {
59795
59804
  "--expected-out",
59796
59805
  expectedFile
59797
59806
  ];
59798
- const log = join27(directory, "engine.log");
59807
+ const log = join28(directory, "engine.log");
59799
59808
  const lock = slot ?? await launch.slots.take();
59800
59809
  const began = Date.now();
59801
59810
  let end;
@@ -59814,7 +59823,7 @@ async function runEngine2(launch, plan, index, times, again = "", slot = null) {
59814
59823
  godotVersion: launch.godotVersion
59815
59824
  };
59816
59825
  const judged = judgeEngine(printed, assignment, end);
59817
- const written = reportsFault(join27(directory, "reports"));
59826
+ const written = reportsFault(join28(directory, "reports"));
59818
59827
  return {
59819
59828
  index,
59820
59829
  plan,
@@ -59828,7 +59837,7 @@ async function runEngine2(launch, plan, index, times, again = "", slot = null) {
59828
59837
  }
59829
59838
  var REPORT_FILES_NAMED = 3;
59830
59839
  function reportsFault(reports) {
59831
- const files = existsSync23(reports) ? readdirSync14(reports, { recursive: true, encoding: "utf8" }).filter((file) => statSync14(join27(reports, file)).isFile()).sort() : [];
59840
+ const files = existsSync23(reports) ? readdirSync14(reports, { recursive: true, encoding: "utf8" }).filter((file) => statSync14(join28(reports, file)).isFile()).sort() : [];
59832
59841
  if (files.length === 0) {
59833
59842
  return null;
59834
59843
  }
@@ -59986,7 +59995,7 @@ class UsageError extends Refusal {
59986
59995
  function projectArgument(at) {
59987
59996
  const named = args.slice(at).find((value) => !value.startsWith("--"));
59988
59997
  const projectPath = resolve14(named ?? ".");
59989
- if (!existsSync35(join44(projectPath, "project.godot"))) {
59998
+ if (!existsSync35(join45(projectPath, "project.godot"))) {
59990
59999
  throw new UsageError(`Not a Godot project: ${projectPath} holds no project.godot.`);
59991
60000
  }
59992
60001
  return projectPath;
@@ -60050,7 +60059,7 @@ async function registerRuntime(godot, projectPath) {
60050
60059
  }
60051
60060
  const path = (named ?? "").replace(/^res:\/\//, "");
60052
60061
  console.log(`${RUNTIME_AUTOLOAD.name} autoload left at ${named}, which this project registers itself`);
60053
- if (!existsSync35(join44(projectPath, path))) {
60062
+ if (!existsSync35(join45(projectPath, path))) {
60054
60063
  console.log(" that file is not in this project, so it boots with a missing script");
60055
60064
  }
60056
60065
  console.log(` ${useTheShippedLoader(RUNTIME_AUTOLOAD.name, path)}`);