gdharness 1.1.19 → 1.1.21
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
|
@@ -7850,6 +7850,27 @@ var init_game_log = __esm(() => {
|
|
|
7850
7850
|
};
|
|
7851
7851
|
});
|
|
7852
7852
|
|
|
7853
|
+
// src/reimport.ts
|
|
7854
|
+
import { createHash } from "node:crypto";
|
|
7855
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, rmSync as rmSync3, statSync as statSync2, utimesSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
7856
|
+
import { basename as basename2, join as join5 } from "node:path";
|
|
7857
|
+
function forceNextImport(projectPath, resourcePath) {
|
|
7858
|
+
const relative = resourcePath.replace(/^res:\/\//, "");
|
|
7859
|
+
const sidecar = join5(projectPath, `${relative}.import`);
|
|
7860
|
+
if (!existsSync5(sidecar)) {
|
|
7861
|
+
return;
|
|
7862
|
+
}
|
|
7863
|
+
const { atime, mtimeMs } = statSync2(sidecar);
|
|
7864
|
+
writeFileSync3(sidecar, readFileSync3(sidecar, "utf8").replace(/^valid=false\r?\n/m, ""));
|
|
7865
|
+
utimesSync(sidecar, atime, new Date(mtimeMs + 2000));
|
|
7866
|
+
rmSync3(importRecord(projectPath, resourcePath), { force: true });
|
|
7867
|
+
}
|
|
7868
|
+
function importRecord(projectPath, resourcePath) {
|
|
7869
|
+
const digest = createHash("md5").update(resourcePath).digest("hex");
|
|
7870
|
+
return join5(projectPath, ".godot", "imported", `${basename2(resourcePath)}-${digest}.md5`);
|
|
7871
|
+
}
|
|
7872
|
+
var init_reimport = () => {};
|
|
7873
|
+
|
|
7853
7874
|
// src/alive.ts
|
|
7854
7875
|
import process5 from "node:process";
|
|
7855
7876
|
function alive(pid) {
|
|
@@ -7866,12 +7887,12 @@ function alive(pid) {
|
|
|
7866
7887
|
var init_alive = () => {};
|
|
7867
7888
|
|
|
7868
7889
|
// src/scratch.ts
|
|
7869
|
-
import { existsSync as
|
|
7890
|
+
import { existsSync as existsSync6, mkdtempSync, readdirSync as readdirSync2, rmSync as rmSync4 } from "node:fs";
|
|
7870
7891
|
import { tmpdir } from "node:os";
|
|
7871
|
-
import { join as
|
|
7892
|
+
import { join as join6 } from "node:path";
|
|
7872
7893
|
import process6 from "node:process";
|
|
7873
7894
|
function scratchDirectory(kind) {
|
|
7874
|
-
return mkdtempSync(
|
|
7895
|
+
return mkdtempSync(join6(tmpdir(), `gdharness-${kind}-${process6.pid}-`));
|
|
7875
7896
|
}
|
|
7876
7897
|
function sweepAbandonedScratch(directory = tmpdir()) {
|
|
7877
7898
|
let entries;
|
|
@@ -7887,7 +7908,7 @@ function sweepAbandonedScratch(directory = tmpdir()) {
|
|
|
7887
7908
|
continue;
|
|
7888
7909
|
}
|
|
7889
7910
|
try {
|
|
7890
|
-
remove(
|
|
7911
|
+
remove(join6(directory, entry));
|
|
7891
7912
|
} catch {}
|
|
7892
7913
|
}
|
|
7893
7914
|
}
|
|
@@ -7913,7 +7934,7 @@ function discard(...paths) {
|
|
|
7913
7934
|
return left;
|
|
7914
7935
|
}
|
|
7915
7936
|
function remove(path) {
|
|
7916
|
-
|
|
7937
|
+
rmSync4(path, SWEPT);
|
|
7917
7938
|
}
|
|
7918
7939
|
function tryAgain(path, attempt) {
|
|
7919
7940
|
if (attempt === 0) {
|
|
@@ -7925,7 +7946,7 @@ function tryAgain(path, attempt) {
|
|
|
7925
7946
|
lastTryOnExit();
|
|
7926
7947
|
}
|
|
7927
7948
|
const after = AGAIN_AFTER_MS[attempt];
|
|
7928
|
-
if (after === undefined || !
|
|
7949
|
+
if (after === undefined || !existsSync6(path)) {
|
|
7929
7950
|
waiting.delete(path);
|
|
7930
7951
|
if (after === undefined) {
|
|
7931
7952
|
atExit.add(path);
|
|
@@ -7973,8 +7994,8 @@ var init_scratch = __esm(() => {
|
|
|
7973
7994
|
|
|
7974
7995
|
// src/headless.ts
|
|
7975
7996
|
import { execFile as execFile3 } from "node:child_process";
|
|
7976
|
-
import { writeFileSync as
|
|
7977
|
-
import { join as
|
|
7997
|
+
import { writeFileSync as writeFileSync4 } from "node:fs";
|
|
7998
|
+
import { join as join7 } from "node:path";
|
|
7978
7999
|
import { promisify as promisify3 } from "node:util";
|
|
7979
8000
|
function snakeCased(params) {
|
|
7980
8001
|
const result = emptyRecord();
|
|
@@ -8023,21 +8044,36 @@ function librariesNotCopied(messages) {
|
|
|
8023
8044
|
}
|
|
8024
8045
|
return [...found];
|
|
8025
8046
|
}
|
|
8026
|
-
function extensionRetryNote(libraries) {
|
|
8027
|
-
|
|
8047
|
+
function extensionRetryNote(libraries, stillNotLoaded = []) {
|
|
8048
|
+
const second = stillNotLoaded.length === 0 ? "so the import was run again and loaded the extension, and the messages are from that second run." : `so the import was run again, and it still could not load ${stillNotLoaded.join(" and ")}: this answer is from an import without ${stillNotLoaded.length === 1 ? "it" : "them"}, and its messages say what the engine hit.`;
|
|
8049
|
+
return `The first import could not load ${libraries.join(" and ")}: on Windows an engine running as the editor ` + "loads a GDExtension from a ~ copy beside the library, and the editor open on this project holds its own " + "copy there, so the first engine started beside it cannot make one. That failed attempt moves the " + `editor's copy aside, ${second} The editor's copy is left beside the library as a ~RF….TMP file, which ` + "can be deleted once the editor has exited.";
|
|
8028
8050
|
}
|
|
8029
|
-
async function runImport(godotPath, projectPath,
|
|
8030
|
-
const
|
|
8051
|
+
async function runImport(godotPath, projectPath, options = {}) {
|
|
8052
|
+
const once = options.once ?? importOnce;
|
|
8053
|
+
const pass = () => {
|
|
8054
|
+
for (const target of options.forcing ?? []) {
|
|
8055
|
+
forceNextImport(projectPath, target);
|
|
8056
|
+
}
|
|
8057
|
+
return once(godotPath, projectPath);
|
|
8058
|
+
};
|
|
8059
|
+
const first = await pass();
|
|
8031
8060
|
const collided = librariesNotCopied(first.messages);
|
|
8032
8061
|
if (collided.length === 0) {
|
|
8033
8062
|
return first;
|
|
8034
8063
|
}
|
|
8035
|
-
|
|
8064
|
+
const second = await pass();
|
|
8065
|
+
const still = librariesNotCopied(second.messages);
|
|
8066
|
+
return {
|
|
8067
|
+
...second,
|
|
8068
|
+
librariesRetried: collided,
|
|
8069
|
+
...still.length === 0 ? {} : { librariesNotLoaded: still },
|
|
8070
|
+
extensionNote: extensionRetryNote(collided, still)
|
|
8071
|
+
};
|
|
8036
8072
|
}
|
|
8037
8073
|
async function importOnce(godotPath, projectPath) {
|
|
8038
8074
|
const logDir = scratchDirectory("import");
|
|
8039
8075
|
try {
|
|
8040
|
-
const { stderr } = await run3(godotPath, ["--headless", "--log-file",
|
|
8076
|
+
const { stderr } = await run3(godotPath, ["--headless", "--log-file", join7(logDir, "engine.log"), "--path", projectPath, "--import"], { signal: callSignal() });
|
|
8041
8077
|
return { ok: true, messages: problems(stderr) };
|
|
8042
8078
|
} catch (error) {
|
|
8043
8079
|
if (error instanceof Error && "stdout" in error && "stderr" in error) {
|
|
@@ -8059,12 +8095,12 @@ async function importOnce(godotPath, projectPath) {
|
|
|
8059
8095
|
}
|
|
8060
8096
|
async function runOperation(engine, operation, params, projectPath) {
|
|
8061
8097
|
const paramsDir = scratchDirectory("params");
|
|
8062
|
-
const paramsFile =
|
|
8063
|
-
|
|
8098
|
+
const paramsFile = join7(paramsDir, `${operation}.json`);
|
|
8099
|
+
writeFileSync4(paramsFile, JSON.stringify(snakeCased(params)), "utf8");
|
|
8064
8100
|
const args = [
|
|
8065
8101
|
"--headless",
|
|
8066
8102
|
"--log-file",
|
|
8067
|
-
|
|
8103
|
+
join7(paramsDir, "engine.log"),
|
|
8068
8104
|
"--path",
|
|
8069
8105
|
projectPath,
|
|
8070
8106
|
"--script",
|
|
@@ -8108,14 +8144,15 @@ var run3;
|
|
|
8108
8144
|
var init_headless = __esm(() => {
|
|
8109
8145
|
init_call_signal();
|
|
8110
8146
|
init_game_log();
|
|
8147
|
+
init_reimport();
|
|
8111
8148
|
init_scratch();
|
|
8112
8149
|
run3 = promisify3(execFile3);
|
|
8113
8150
|
});
|
|
8114
8151
|
|
|
8115
8152
|
// src/update-check.ts
|
|
8116
|
-
import { existsSync as
|
|
8153
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "node:fs";
|
|
8117
8154
|
import { homedir as homedir3, tmpdir as tmpdir2 } from "node:os";
|
|
8118
|
-
import { join as
|
|
8155
|
+
import { join as join8 } from "node:path";
|
|
8119
8156
|
function packageUrl(root) {
|
|
8120
8157
|
return `${root.replace(/\/+$/, "")}/gdharness/latest`;
|
|
8121
8158
|
}
|
|
@@ -8137,28 +8174,28 @@ function cacheDirectory(environment) {
|
|
|
8137
8174
|
};
|
|
8138
8175
|
const home = set("HOME") ?? homedir3();
|
|
8139
8176
|
if (process.platform === "win32") {
|
|
8140
|
-
return
|
|
8177
|
+
return join8(set("LOCALAPPDATA") ?? home, "gdharness");
|
|
8141
8178
|
}
|
|
8142
8179
|
if (process.platform === "darwin") {
|
|
8143
|
-
return
|
|
8180
|
+
return join8(home, "Library", "Caches", "gdharness");
|
|
8144
8181
|
}
|
|
8145
|
-
return
|
|
8182
|
+
return join8(set("XDG_CACHE_HOME") ?? join8(home, ".cache"), "gdharness");
|
|
8146
8183
|
}
|
|
8147
8184
|
function cacheFile(environment = process.env) {
|
|
8148
8185
|
try {
|
|
8149
8186
|
const directory = cacheDirectory(environment);
|
|
8150
8187
|
mkdirSync3(directory, { recursive: true, mode: 448 });
|
|
8151
|
-
return
|
|
8188
|
+
return join8(directory, "update-check.json");
|
|
8152
8189
|
} catch {
|
|
8153
|
-
return
|
|
8190
|
+
return join8(tmpdir2(), "gdharness-update-check.json");
|
|
8154
8191
|
}
|
|
8155
8192
|
}
|
|
8156
8193
|
function readCache(path) {
|
|
8157
8194
|
try {
|
|
8158
|
-
if (!
|
|
8195
|
+
if (!existsSync7(path)) {
|
|
8159
8196
|
return null;
|
|
8160
8197
|
}
|
|
8161
|
-
const parsed = JSON.parse(
|
|
8198
|
+
const parsed = JSON.parse(readFileSync4(path, "utf8"));
|
|
8162
8199
|
if (typeof parsed !== "object" || parsed === null) {
|
|
8163
8200
|
return null;
|
|
8164
8201
|
}
|
|
@@ -8175,7 +8212,7 @@ function readCache(path) {
|
|
|
8175
8212
|
}
|
|
8176
8213
|
function writeCache(path, entry) {
|
|
8177
8214
|
try {
|
|
8178
|
-
|
|
8215
|
+
writeFileSync5(path, JSON.stringify(entry), { encoding: "utf8", mode: 384 });
|
|
8179
8216
|
} catch {}
|
|
8180
8217
|
}
|
|
8181
8218
|
function parts(version) {
|
|
@@ -8306,7 +8343,7 @@ var init_update_check = __esm(() => {
|
|
|
8306
8343
|
});
|
|
8307
8344
|
|
|
8308
8345
|
// src/server-version.ts
|
|
8309
|
-
import { readFileSync as
|
|
8346
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
8310
8347
|
function editorIsStale(addonVersion, serverVersion, addonDigest, shippedDigest) {
|
|
8311
8348
|
if (addonDigest !== undefined && addonDigest !== "" && shippedDigest !== undefined) {
|
|
8312
8349
|
return addonDigest !== shippedDigest;
|
|
@@ -8348,7 +8385,7 @@ var init_server_version = __esm(() => {
|
|
|
8348
8385
|
GODOT_DEBUG_MODE_DEFAULT = process.env["GODOT_DEBUG"] === "true" || DEBUG_MODE;
|
|
8349
8386
|
SERVER_VERSION = (() => {
|
|
8350
8387
|
try {
|
|
8351
|
-
const pkg = JSON.parse(
|
|
8388
|
+
const pkg = JSON.parse(readFileSync5(new URL("../package.json", import.meta.url), "utf8"));
|
|
8352
8389
|
return typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
8353
8390
|
} catch {
|
|
8354
8391
|
return "0.0.0";
|
|
@@ -8357,7 +8394,7 @@ var init_server_version = __esm(() => {
|
|
|
8357
8394
|
});
|
|
8358
8395
|
|
|
8359
8396
|
// src/issues.ts
|
|
8360
|
-
import { createHash } from "node:crypto";
|
|
8397
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
8361
8398
|
import process7 from "node:process";
|
|
8362
8399
|
function feedbackNotice(every) {
|
|
8363
8400
|
return JSON.stringify({
|
|
@@ -8376,7 +8413,7 @@ function runtime() {
|
|
|
8376
8413
|
function defectSignature(where, message) {
|
|
8377
8414
|
const normalised = `${where}
|
|
8378
8415
|
${message}`.toLowerCase().replaceAll("\\", "/").replaceAll(/(?:[a-z]:)?(?:\/+[\w.-]+){2,}/gu, "<path>").replaceAll(/\d+/gu, "0");
|
|
8379
|
-
return
|
|
8416
|
+
return createHash2("sha256").update(normalised).digest("hex").slice(0, 8);
|
|
8380
8417
|
}
|
|
8381
8418
|
function facts(where, message, godotVersion) {
|
|
8382
8419
|
return [
|
|
@@ -8482,8 +8519,8 @@ var init_issues = __esm(() => {
|
|
|
8482
8519
|
});
|
|
8483
8520
|
|
|
8484
8521
|
// src/class-cache.ts
|
|
8485
|
-
import { existsSync as
|
|
8486
|
-
import { join as
|
|
8522
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync6, statSync as statSync3 } from "node:fs";
|
|
8523
|
+
import { join as join9 } from "node:path";
|
|
8487
8524
|
function declaredClasses(projectPath) {
|
|
8488
8525
|
const declared = new Map;
|
|
8489
8526
|
eachScript(projectPath, (script, source) => {
|
|
@@ -8496,18 +8533,18 @@ function declaredClasses(projectPath) {
|
|
|
8496
8533
|
}
|
|
8497
8534
|
function eachScript(projectPath, each) {
|
|
8498
8535
|
const visit = (directory, prefix) => {
|
|
8499
|
-
if (
|
|
8536
|
+
if (existsSync8(join9(directory, ".gdignore"))) {
|
|
8500
8537
|
return;
|
|
8501
8538
|
}
|
|
8502
8539
|
for (const entry of readdirSync3(directory, { withFileTypes: true })) {
|
|
8503
8540
|
if (entry.name.startsWith(".")) {
|
|
8504
8541
|
continue;
|
|
8505
8542
|
}
|
|
8506
|
-
const path =
|
|
8543
|
+
const path = join9(directory, entry.name);
|
|
8507
8544
|
if (entry.isDirectory()) {
|
|
8508
8545
|
visit(path, `${prefix}${entry.name}/`);
|
|
8509
8546
|
} else if (entry.isFile() && entry.name.endsWith(".gd")) {
|
|
8510
|
-
each(`res://${prefix}${entry.name}`,
|
|
8547
|
+
each(`res://${prefix}${entry.name}`, readFileSync6(path, "utf8"));
|
|
8511
8548
|
}
|
|
8512
8549
|
}
|
|
8513
8550
|
};
|
|
@@ -8556,12 +8593,12 @@ function codeOf(source) {
|
|
|
8556
8593
|
return code;
|
|
8557
8594
|
}
|
|
8558
8595
|
function cachedClasses(projectPath) {
|
|
8559
|
-
const cache =
|
|
8560
|
-
if (!
|
|
8596
|
+
const cache = join9(projectPath, ".godot", "global_script_class_cache.cfg");
|
|
8597
|
+
if (!existsSync8(cache)) {
|
|
8561
8598
|
return null;
|
|
8562
8599
|
}
|
|
8563
8600
|
const listed = new Map;
|
|
8564
|
-
const text =
|
|
8601
|
+
const text = readFileSync6(cache, "utf8");
|
|
8565
8602
|
for (const entry of text.matchAll(/"class":\s*&"([^"]+)"[\s\S]*?"path":\s*"([^"]+)"/g)) {
|
|
8566
8603
|
listed.set(entry[1] ?? "", entry[2] ?? "");
|
|
8567
8604
|
}
|
|
@@ -8604,32 +8641,33 @@ function missingMemberIn(message) {
|
|
|
8604
8641
|
if (called !== null) {
|
|
8605
8642
|
return { kind: "static method", member: called[1] ?? "", type: called[2] ?? "" };
|
|
8606
8643
|
}
|
|
8607
|
-
const inBase = /Cannot find member "([A-Za-z_]\w*)" in base "([A-Za-z_]\w*)((
|
|
8644
|
+
const inBase = /Cannot find member "([A-Za-z_]\w*)" in base "([A-Za-z_]\w*)(?:\.([A-Za-z_]\w*))?"/.exec(message);
|
|
8608
8645
|
if (inBase === null) {
|
|
8609
8646
|
return null;
|
|
8610
8647
|
}
|
|
8611
8648
|
const member = inBase[1] ?? "";
|
|
8612
8649
|
const type = inBase[2] ?? "";
|
|
8613
|
-
const
|
|
8614
|
-
const enumName = within.at(-1);
|
|
8650
|
+
const enumName = inBase[3];
|
|
8615
8651
|
return enumName === undefined ? { kind: "member", member, type } : { kind: "enum member", member, type, enum: enumName };
|
|
8616
8652
|
}
|
|
8617
8653
|
function declaresMember(source, missing) {
|
|
8618
8654
|
const name = missing.member.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8655
|
+
const top = String.raw`^(?:@\w+(?:\([^)]*\))?\s+)*`;
|
|
8656
|
+
const declared = (kinds) => new RegExp(String.raw`${top}(?:${kinds})\s+${name}\b`, "m").test(source);
|
|
8619
8657
|
if (missing.kind === "method") {
|
|
8620
|
-
return new RegExp(String.raw
|
|
8658
|
+
return new RegExp(String.raw`${top}(?:static\s+)?func\s+${name}\s*\(`, "m").test(source);
|
|
8621
8659
|
}
|
|
8622
8660
|
if (missing.kind === "static method") {
|
|
8623
|
-
return new RegExp(String.raw
|
|
8661
|
+
return new RegExp(String.raw`${top}static\s+func\s+${name}\s*\(`, "m").test(source);
|
|
8624
8662
|
}
|
|
8625
8663
|
if (missing.kind === "enum member") {
|
|
8626
8664
|
return enumValues(source, missing.enum ?? "").includes(missing.member);
|
|
8627
8665
|
}
|
|
8628
|
-
const kinds = missing.kind === "property" ?
|
|
8629
|
-
return
|
|
8666
|
+
const kinds = missing.kind === "property" ? String.raw`(?:static\s+)?(?:var|func)|const|enum|class|signal` : String.raw`static\s+(?:var|func)|const|enum|class`;
|
|
8667
|
+
return declared(kinds) || enumValues(source, null).includes(missing.member);
|
|
8630
8668
|
}
|
|
8631
8669
|
function enumValues(source, named) {
|
|
8632
|
-
const opening = named === null ?
|
|
8670
|
+
const opening = named === null ? /^enum\s*\{([^}]*)\}/gm : new RegExp(String.raw`^enum\s+${named.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\s*\{([^}]*)\}`, "gm");
|
|
8633
8671
|
const values = [];
|
|
8634
8672
|
for (const [, body] of source.matchAll(opening)) {
|
|
8635
8673
|
const uncommented = (body ?? "").split(`
|
|
@@ -8672,21 +8710,22 @@ function classesNamedIn(source, known) {
|
|
|
8672
8710
|
return [...named].sort();
|
|
8673
8711
|
}
|
|
8674
8712
|
function contradictedDiagnostics(messages, classes, sourceOf) {
|
|
8713
|
+
const keyOf = (missing) => [missing.type, missing.enum ?? "", missing.member].join(".");
|
|
8714
|
+
const denials = messages.map((message) => missingMemberIn(message)).filter((missing) => missing !== null);
|
|
8715
|
+
const calledOnTheClass = new Set(denials.filter((missing) => missing.kind === "static method").map((missing) => keyOf(missing)));
|
|
8675
8716
|
const read = new Map;
|
|
8676
8717
|
const found = new Map;
|
|
8677
|
-
for (const
|
|
8678
|
-
const
|
|
8679
|
-
const
|
|
8680
|
-
if (
|
|
8718
|
+
for (const missing of denials) {
|
|
8719
|
+
const declaredIn = classes.get(missing.type);
|
|
8720
|
+
const key = keyOf(missing);
|
|
8721
|
+
if (declaredIn === undefined || missing.kind === "method" && calledOnTheClass.has(key)) {
|
|
8681
8722
|
continue;
|
|
8682
8723
|
}
|
|
8683
8724
|
if (!read.has(declaredIn)) {
|
|
8684
8725
|
read.set(declaredIn, sourceOf(declaredIn));
|
|
8685
8726
|
}
|
|
8686
8727
|
const source = read.get(declaredIn) ?? null;
|
|
8687
|
-
|
|
8688
|
-
const already = found.get(key);
|
|
8689
|
-
if (source !== null && declaresMember(source, missing) && already?.kind !== "static method") {
|
|
8728
|
+
if (source !== null && declaresMember(source, missing)) {
|
|
8690
8729
|
found.set(key, { ...missing, declaredIn });
|
|
8691
8730
|
}
|
|
8692
8731
|
}
|
|
@@ -8725,7 +8764,8 @@ function classRemedy(entries) {
|
|
|
8725
8764
|
}
|
|
8726
8765
|
const declaring = declaringScripts(entries);
|
|
8727
8766
|
const reload = declaring.length === 1 ? `editor_rescan with reloadScript set to ${declaring[0]}` : `editor_rescan with reloadScript, a call each for ${declaring.join(" and ")} since it takes one script,`;
|
|
8728
|
-
|
|
8767
|
+
const oneAtATime = declaring.length === 1 ? "" : " Take them one at a time: a rescan that brings in a class also reloads every script naming it and lists them under dependentsReloaded, so a script listed there needs no call of its own.";
|
|
8768
|
+
return `For ${entries.map(written).join(", ")}, run ${reload} first.${oneAtATime} In the one project ` + "that has reproduced a stale enum member, three times, the reload cleared it at once each time, " + "and the one plain editor_rescan tried left the diagnostic standing.";
|
|
8729
8769
|
}
|
|
8730
8770
|
function failedReloadNote(failed) {
|
|
8731
8771
|
const missing = (before, after) => before.filter((name) => !after.includes(name));
|
|
@@ -8735,9 +8775,9 @@ function failedReloadNote(failed) {
|
|
|
8735
8775
|
];
|
|
8736
8776
|
const unchanged = lost.length === 0 && missing(failed.heldAfter, failed.heldBefore).length === 0 && missing(failed.constantsAfter, failed.constantsBefore).length === 0;
|
|
8737
8777
|
const answered = failed.codeName === "" ? `error ${failed.code}` : `error ${failed.code}, ${failed.codeName}`;
|
|
8738
|
-
const copy = unchanged ? "
|
|
8778
|
+
const copy = unchanged ? "Nothing was reloaded: the copy the editor holds is as it was, with the members under heldBeforeReload and heldConstantsBeforeReload." : `The copy the editor holds changed even so${lost.length === 0 ? "" : `, and has lost ${lost.join(", ")}`}: anything diagnosed against it now is answered from what is left, and reloading it once it compiles rebuilds it.`;
|
|
8739
8779
|
const order = failed.names.length === 0 ? "" : ` If they deny a member of ${failed.names.join(" or ")} that its file declares, the editor's copy of that class is behind: reload that class first with reloadScript and then this script, the order that cleared it in the one project that has met this.`;
|
|
8740
|
-
return `${failed.script} did not compile
|
|
8780
|
+
return `${failed.script} did not compile: Godot answered ${answered}. ${copy} ` + `script_diagnostics on it gives the errors.${order}`;
|
|
8741
8781
|
}
|
|
8742
8782
|
function uncachedClassNote(types) {
|
|
8743
8783
|
if (types.length === 0) {
|
|
@@ -8747,9 +8787,9 @@ function uncachedClassNote(types) {
|
|
|
8747
8787
|
return `${types.join(", ")} ${one ? "is declared" : "are declared"} in this project and missing from ` + `.godot/global_script_class_cache.cfg, so a game launched now would not resolve ${one ? "it" : "them"} ` + "either. Try editor_rescan first: it asks the editor already running and starts nothing, and it " + "cleared this in 314ms in a second project with a 31-worker fan-out still importing. It is not " + "always enough, because a file another engine has already imported reads as settled and the " + "walk does not look inside it. project_import refresh_classes rewrites the cache from the " + "declarations on disk and does reach that case, at the cost of a short headless engine, which " + "is worth knowing when something else is already running against this project.";
|
|
8748
8788
|
}
|
|
8749
8789
|
function cacheWrittenAt(projectPath) {
|
|
8750
|
-
const cache =
|
|
8790
|
+
const cache = join9(projectPath, ".godot", "global_script_class_cache.cfg");
|
|
8751
8791
|
try {
|
|
8752
|
-
return
|
|
8792
|
+
return statSync3(cache).mtimeMs;
|
|
8753
8793
|
} catch {
|
|
8754
8794
|
return null;
|
|
8755
8795
|
}
|
|
@@ -8761,14 +8801,14 @@ function declaredSince(projectPath, paths, names, since) {
|
|
|
8761
8801
|
return false;
|
|
8762
8802
|
}
|
|
8763
8803
|
try {
|
|
8764
|
-
return
|
|
8804
|
+
return statSync3(join9(projectPath, path.slice("res://".length))).mtimeMs > since;
|
|
8765
8805
|
} catch {
|
|
8766
8806
|
return false;
|
|
8767
8807
|
}
|
|
8768
8808
|
});
|
|
8769
8809
|
}
|
|
8770
8810
|
function cachedAtMissingPaths(cached, projectPath) {
|
|
8771
|
-
return [...cached].filter(([, path]) => path.startsWith("res://") && !
|
|
8811
|
+
return [...cached].filter(([, path]) => path.startsWith("res://") && !existsSync8(join9(projectPath, path.slice("res://".length)))).map(([name]) => name).sort();
|
|
8772
8812
|
}
|
|
8773
8813
|
function staleAgainst(cached, projectPath) {
|
|
8774
8814
|
return [...declaredClasses(projectPath)].filter(([name, path]) => cached.get(name) !== path).map(([name]) => name);
|
|
@@ -15955,7 +15995,7 @@ var init_paths = __esm(() => {
|
|
|
15955
15995
|
});
|
|
15956
15996
|
|
|
15957
15997
|
// src/resources.ts
|
|
15958
|
-
import { readFileSync as
|
|
15998
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
15959
15999
|
import { extname, resolve as resolve2 } from "node:path";
|
|
15960
16000
|
function ensureProjectPath(getProjectPath) {
|
|
15961
16001
|
const projectPath = getProjectPath();
|
|
@@ -16121,7 +16161,7 @@ function readResourceText(uri, getProjectPath) {
|
|
|
16121
16161
|
const parsedUri = parseGodotUri(uri);
|
|
16122
16162
|
if (parsedUri.kind === "project-info") {
|
|
16123
16163
|
const projectFilePath = resolveProjectFile(projectPath, "project.godot");
|
|
16124
|
-
const rawProject =
|
|
16164
|
+
const rawProject = readFileSync7(projectFilePath, "utf-8");
|
|
16125
16165
|
const parsedProject = parseProjectGodot(rawProject);
|
|
16126
16166
|
return {
|
|
16127
16167
|
mimeType: "application/json",
|
|
@@ -16130,7 +16170,7 @@ function readResourceText(uri, getProjectPath) {
|
|
|
16130
16170
|
}
|
|
16131
16171
|
const filePath = resolveProjectFile(projectPath, parsedUri.resourcePath);
|
|
16132
16172
|
ensureAllowedExtension(parsedUri.kind, filePath);
|
|
16133
|
-
const text =
|
|
16173
|
+
const text = readFileSync7(filePath, "utf-8");
|
|
16134
16174
|
return {
|
|
16135
16175
|
mimeType: parsedUri.kind === "script" ? "text/x-gdscript" : "text/plain",
|
|
16136
16176
|
text
|
|
@@ -16259,42 +16299,42 @@ function readParams(params, key) {
|
|
|
16259
16299
|
|
|
16260
16300
|
// src/setup.ts
|
|
16261
16301
|
import { spawnSync } from "node:child_process";
|
|
16262
|
-
import { createHash as
|
|
16302
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
16263
16303
|
import {
|
|
16264
16304
|
cpSync,
|
|
16265
|
-
existsSync as
|
|
16305
|
+
existsSync as existsSync9,
|
|
16266
16306
|
mkdirSync as mkdirSync4,
|
|
16267
16307
|
readdirSync as readdirSync4,
|
|
16268
|
-
readFileSync as
|
|
16308
|
+
readFileSync as readFileSync8,
|
|
16269
16309
|
rmdirSync,
|
|
16270
|
-
rmSync as
|
|
16271
|
-
statSync as
|
|
16272
|
-
writeFileSync as
|
|
16310
|
+
rmSync as rmSync5,
|
|
16311
|
+
statSync as statSync4,
|
|
16312
|
+
writeFileSync as writeFileSync6
|
|
16273
16313
|
} from "node:fs";
|
|
16274
|
-
import { dirname as dirname4, join as
|
|
16314
|
+
import { dirname as dirname4, join as join10 } from "node:path";
|
|
16275
16315
|
import { fileURLToPath } from "node:url";
|
|
16276
16316
|
function editorAddonDigest(from = shippedAddonsDirectory()) {
|
|
16277
|
-
const hash =
|
|
16317
|
+
const hash = createHash3("sha256");
|
|
16278
16318
|
const walk = (directory, relative) => {
|
|
16279
16319
|
for (const name of readdirSync4(directory).sort()) {
|
|
16280
16320
|
if (name === VERSION_MARKER || name === DIGEST_MARKER) {
|
|
16281
16321
|
continue;
|
|
16282
16322
|
}
|
|
16283
|
-
const path =
|
|
16323
|
+
const path = join10(directory, name);
|
|
16284
16324
|
const inside = `${relative}/${name}`;
|
|
16285
|
-
if (
|
|
16325
|
+
if (statSync4(path).isDirectory()) {
|
|
16286
16326
|
walk(path, inside);
|
|
16287
16327
|
} else {
|
|
16288
16328
|
hash.update(`${inside}
|
|
16289
16329
|
`);
|
|
16290
|
-
hash.update(
|
|
16330
|
+
hash.update(readFileSync8(path));
|
|
16291
16331
|
hash.update(`
|
|
16292
16332
|
`);
|
|
16293
16333
|
}
|
|
16294
16334
|
}
|
|
16295
16335
|
};
|
|
16296
16336
|
for (const name of EDITOR_PLUGINS) {
|
|
16297
|
-
walk(
|
|
16337
|
+
walk(join10(from, name), name);
|
|
16298
16338
|
}
|
|
16299
16339
|
return hash.digest("hex");
|
|
16300
16340
|
}
|
|
@@ -16309,58 +16349,58 @@ function shippedEditorDigest() {
|
|
|
16309
16349
|
return shippedDigest ?? undefined;
|
|
16310
16350
|
}
|
|
16311
16351
|
function installedEditorDigest(projectPath) {
|
|
16312
|
-
const marker =
|
|
16313
|
-
if (!
|
|
16352
|
+
const marker = join10(projectPath, "addons", ADDONS[0], DIGEST_MARKER);
|
|
16353
|
+
if (!existsSync9(marker)) {
|
|
16314
16354
|
return null;
|
|
16315
16355
|
}
|
|
16316
|
-
const said =
|
|
16356
|
+
const said = readFileSync8(marker, "utf8").trim();
|
|
16317
16357
|
return said === "" ? null : said;
|
|
16318
16358
|
}
|
|
16319
16359
|
function shippedAddonsDirectory() {
|
|
16320
|
-
return
|
|
16360
|
+
return join10(dirname4(fileURLToPath(import.meta.url)), "godot", "addons");
|
|
16321
16361
|
}
|
|
16322
16362
|
function shippedOperationsScript() {
|
|
16323
|
-
return
|
|
16363
|
+
return join10(dirname4(fileURLToPath(import.meta.url)), "godot", "operations", "godot_operations.gd");
|
|
16324
16364
|
}
|
|
16325
16365
|
function installAddons(projectPath, from = shippedAddonsDirectory()) {
|
|
16326
16366
|
const installed = [];
|
|
16327
16367
|
for (const name of ADDONS) {
|
|
16328
|
-
const source =
|
|
16329
|
-
if (!
|
|
16368
|
+
const source = join10(from, name);
|
|
16369
|
+
if (!existsSync9(join10(source, name === "gdharness_runtime" ? "runtime_autoload.gd" : "plugin.cfg"))) {
|
|
16330
16370
|
throw new Error(`The package holds no ${name} addon at ${source}.`);
|
|
16331
16371
|
}
|
|
16332
|
-
const target =
|
|
16333
|
-
const replaced =
|
|
16334
|
-
|
|
16372
|
+
const target = join10(projectPath, "addons", name);
|
|
16373
|
+
const replaced = existsSync9(target);
|
|
16374
|
+
rmSync5(target, { recursive: true, force: true });
|
|
16335
16375
|
mkdirSync4(dirname4(target), { recursive: true });
|
|
16336
16376
|
cpSync(source, target, { recursive: true });
|
|
16337
|
-
|
|
16377
|
+
writeFileSync6(join10(target, VERSION_MARKER), `${SERVER_VERSION}
|
|
16338
16378
|
`);
|
|
16339
16379
|
installed.push({ name, path: target, replaced });
|
|
16340
16380
|
}
|
|
16341
|
-
|
|
16381
|
+
writeFileSync6(join10(projectPath, "addons", ADDONS[0], DIGEST_MARKER), `${editorAddonDigest(from)}
|
|
16342
16382
|
`);
|
|
16343
16383
|
return installed;
|
|
16344
16384
|
}
|
|
16345
16385
|
function installedAddonVersion(projectPath) {
|
|
16346
|
-
const marker =
|
|
16347
|
-
if (!
|
|
16386
|
+
const marker = join10(projectPath, "addons", ADDONS[0], VERSION_MARKER);
|
|
16387
|
+
if (!existsSync9(marker)) {
|
|
16348
16388
|
return null;
|
|
16349
16389
|
}
|
|
16350
|
-
const said =
|
|
16390
|
+
const said = readFileSync8(marker, "utf8").trim();
|
|
16351
16391
|
return said === "" ? null : said;
|
|
16352
16392
|
}
|
|
16353
16393
|
function removeAddons(projectPath) {
|
|
16354
16394
|
const removed = [];
|
|
16355
16395
|
for (const name of ADDONS) {
|
|
16356
|
-
const target =
|
|
16357
|
-
if (
|
|
16358
|
-
|
|
16396
|
+
const target = join10(projectPath, "addons", name);
|
|
16397
|
+
if (existsSync9(target)) {
|
|
16398
|
+
rmSync5(target, { recursive: true, force: true });
|
|
16359
16399
|
removed.push(target);
|
|
16360
16400
|
}
|
|
16361
16401
|
}
|
|
16362
|
-
const addons =
|
|
16363
|
-
if (removed.length > 0 &&
|
|
16402
|
+
const addons = join10(projectPath, "addons");
|
|
16403
|
+
if (removed.length > 0 && existsSync9(addons) && readdirSync4(addons).length === 0) {
|
|
16364
16404
|
rmdirSync(addons);
|
|
16365
16405
|
removed.push(addons);
|
|
16366
16406
|
}
|
|
@@ -16394,7 +16434,7 @@ function loaderAmong(projectPath, named) {
|
|
|
16394
16434
|
}
|
|
16395
16435
|
let source = null;
|
|
16396
16436
|
try {
|
|
16397
|
-
source =
|
|
16437
|
+
source = readFileSync8(join10(projectPath, path), "utf8");
|
|
16398
16438
|
} catch {}
|
|
16399
16439
|
if (source?.includes(RUNTIME_AUTOLOAD.path)) {
|
|
16400
16440
|
return { name: entry, path, exists: true };
|
|
@@ -16436,10 +16476,10 @@ function enabledPlugins(settings) {
|
|
|
16436
16476
|
function inspectProject(projectPath) {
|
|
16437
16477
|
const problems = [];
|
|
16438
16478
|
const addons = ADDONS.map((name) => {
|
|
16439
|
-
const directory =
|
|
16440
|
-
const marker =
|
|
16441
|
-
const installed =
|
|
16442
|
-
const version =
|
|
16479
|
+
const directory = join10(projectPath, "addons", name);
|
|
16480
|
+
const marker = join10(directory, VERSION_MARKER);
|
|
16481
|
+
const installed = existsSync9(directory);
|
|
16482
|
+
const version = existsSync9(marker) ? readFileSync8(marker, "utf8").trim() : null;
|
|
16443
16483
|
const current = version === SERVER_VERSION;
|
|
16444
16484
|
if (!installed) {
|
|
16445
16485
|
problems.push(`addons/${name} is not installed; run gdharness setup`);
|
|
@@ -16448,7 +16488,7 @@ function inspectProject(projectPath) {
|
|
|
16448
16488
|
}
|
|
16449
16489
|
return { name, installed, version, current };
|
|
16450
16490
|
});
|
|
16451
|
-
const settings = parseProjectGodot(
|
|
16491
|
+
const settings = parseProjectGodot(readFileSync8(join10(projectPath, "project.godot"), "utf8"));
|
|
16452
16492
|
const pluginsEnabled = enabledPlugins(settings);
|
|
16453
16493
|
for (const name of EDITOR_PLUGINS) {
|
|
16454
16494
|
if (!pluginsEnabled.includes(name)) {
|
|
@@ -16464,7 +16504,7 @@ function inspectProject(projectPath) {
|
|
|
16464
16504
|
const tracked = trackedByGit(projectPath, [...named.values()]);
|
|
16465
16505
|
const addonMissing = (path) => addons.some((addon) => !addon.installed && path.startsWith(`addons/${addon.name}/`));
|
|
16466
16506
|
for (const [name, path] of named) {
|
|
16467
|
-
if (!
|
|
16507
|
+
if (!existsSync9(join10(projectPath, path))) {
|
|
16468
16508
|
if (!addonMissing(path)) {
|
|
16469
16509
|
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`);
|
|
16470
16510
|
}
|
|
@@ -17754,7 +17794,7 @@ var init_tool_definitions = __esm(() => {
|
|
|
17754
17794
|
},
|
|
17755
17795
|
value: {
|
|
17756
17796
|
ops: ["until"],
|
|
17757
|
-
description: "until: the value to wait for, fitted to the property's type. On a property declared to
|
|
17797
|
+
description: "until: the value to wait for, fitted to the property's type. On a property holding an object, whether declared to or untyped and holding one or null, the text null means null. One declared to hold an object refuses any value other than null, since it can never hold it."
|
|
17758
17798
|
},
|
|
17759
17799
|
says: {
|
|
17760
17800
|
type: "string",
|
|
@@ -32586,10 +32626,10 @@ var init_stdio2 = __esm(() => {
|
|
|
32586
32626
|
});
|
|
32587
32627
|
|
|
32588
32628
|
// src/runtime-client.ts
|
|
32589
|
-
import { existsSync as
|
|
32629
|
+
import { existsSync as existsSync11, readdirSync as readdirSync6, readFileSync as readFileSync10, statSync as statSync5, unlinkSync } from "node:fs";
|
|
32590
32630
|
import { createConnection } from "node:net";
|
|
32591
32631
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
32592
|
-
import { dirname as dirname7, join as
|
|
32632
|
+
import { dirname as dirname7, join as join13, resolve as resolve3 } from "node:path";
|
|
32593
32633
|
import { setTimeout as delay } from "node:timers/promises";
|
|
32594
32634
|
function runtimeDirectory(variables = process.env) {
|
|
32595
32635
|
const explicit = envValue("GDHARNESS_RUNTIME_DIR", variables);
|
|
@@ -32597,20 +32637,20 @@ function runtimeDirectory(variables = process.env) {
|
|
|
32597
32637
|
return explicit;
|
|
32598
32638
|
}
|
|
32599
32639
|
const perUser = envValue("XDG_RUNTIME_DIR", variables);
|
|
32600
|
-
return
|
|
32640
|
+
return join13(perUser ?? tmpdir3(), "gdharness");
|
|
32601
32641
|
}
|
|
32602
32642
|
function runtimeDirectories(variables = process.env) {
|
|
32603
32643
|
const candidates = [runtimeDirectory(variables)];
|
|
32604
32644
|
const fallbacks = process.platform === "win32" ? [envValue("SystemRoot", variables) ?? envValue("windir", variables) ?? "C:\\Windows"] : ["/tmp", "/var/tmp"];
|
|
32605
32645
|
for (const base of fallbacks) {
|
|
32606
|
-
candidates.push(
|
|
32646
|
+
candidates.push(join13(base, process.platform === "win32" ? "Temp" : "", "gdharness"));
|
|
32607
32647
|
}
|
|
32608
32648
|
return [...new Set(candidates.map((path) => resolve3(path)))];
|
|
32609
32649
|
}
|
|
32610
32650
|
function errorReportOf(pid, directories = runtimeDirectories()) {
|
|
32611
32651
|
for (const directory of directories) {
|
|
32612
|
-
const path =
|
|
32613
|
-
if (
|
|
32652
|
+
const path = join13(directory, `runtime-${pid}.log`);
|
|
32653
|
+
if (existsSync11(path)) {
|
|
32614
32654
|
return path;
|
|
32615
32655
|
}
|
|
32616
32656
|
}
|
|
@@ -32641,7 +32681,7 @@ function reportAlreadyInTranscript(transcript, report) {
|
|
|
32641
32681
|
function parseAnnouncement(file, pid) {
|
|
32642
32682
|
let fields;
|
|
32643
32683
|
try {
|
|
32644
|
-
fields = asParams(JSON.parse(
|
|
32684
|
+
fields = asParams(JSON.parse(readFileSync10(file, "utf8")));
|
|
32645
32685
|
} catch {
|
|
32646
32686
|
return { kind: "rubbish" };
|
|
32647
32687
|
}
|
|
@@ -32658,7 +32698,7 @@ function parseAnnouncement(file, pid) {
|
|
|
32658
32698
|
};
|
|
32659
32699
|
let announcedAt;
|
|
32660
32700
|
try {
|
|
32661
|
-
announcedAt =
|
|
32701
|
+
announcedAt = statSync5(file).mtimeMs;
|
|
32662
32702
|
} catch {}
|
|
32663
32703
|
const when = announcedAt === undefined ? {} : { announcedAt };
|
|
32664
32704
|
if (protocol !== RUNTIME_PROTOCOL) {
|
|
@@ -32699,7 +32739,7 @@ function discoverRuntimes(directories = runtimeDirectories()) {
|
|
|
32699
32739
|
function wentAway(file, pid) {
|
|
32700
32740
|
let project = "";
|
|
32701
32741
|
try {
|
|
32702
|
-
const fields = asParams(JSON.parse(
|
|
32742
|
+
const fields = asParams(JSON.parse(readFileSync10(file, "utf8")));
|
|
32703
32743
|
project = readString(readParams(fields, "project") ?? {}, "path") ?? "";
|
|
32704
32744
|
} catch {
|
|
32705
32745
|
return;
|
|
@@ -32742,7 +32782,7 @@ function strangersAmong(candidates, now, startTimes = startTimesOf) {
|
|
|
32742
32782
|
}).map((one) => one.file));
|
|
32743
32783
|
}
|
|
32744
32784
|
function announcedIn(directory) {
|
|
32745
|
-
if (!
|
|
32785
|
+
if (!existsSync11(directory)) {
|
|
32746
32786
|
return [];
|
|
32747
32787
|
}
|
|
32748
32788
|
const found = [];
|
|
@@ -32751,20 +32791,20 @@ function announcedIn(directory) {
|
|
|
32751
32791
|
for (const entry of readdirSync6(directory)) {
|
|
32752
32792
|
const report = ERROR_REPORT_PATTERN.exec(entry);
|
|
32753
32793
|
if (report) {
|
|
32754
|
-
sweepErrorReport(
|
|
32794
|
+
sweepErrorReport(join13(directory, entry), Number.parseInt(report[1] ?? "", 10));
|
|
32755
32795
|
continue;
|
|
32756
32796
|
}
|
|
32757
32797
|
const match = ANNOUNCEMENT_PATTERN.exec(entry);
|
|
32758
32798
|
if (!match) {
|
|
32759
32799
|
continue;
|
|
32760
32800
|
}
|
|
32761
|
-
const file =
|
|
32801
|
+
const file = join13(directory, entry);
|
|
32762
32802
|
const pid = Number.parseInt(match[1] ?? "", 10);
|
|
32763
32803
|
const running = alive(pid);
|
|
32764
32804
|
entries.push({ file, pid, running });
|
|
32765
32805
|
if (running) {
|
|
32766
32806
|
try {
|
|
32767
|
-
candidates.push({ file, pid, writtenAt:
|
|
32807
|
+
candidates.push({ file, pid, writtenAt: statSync5(file).mtimeMs });
|
|
32768
32808
|
} catch {}
|
|
32769
32809
|
}
|
|
32770
32810
|
}
|
|
@@ -32786,7 +32826,7 @@ function announcedIn(directory) {
|
|
|
32786
32826
|
found.push(announced);
|
|
32787
32827
|
}
|
|
32788
32828
|
const held = new Set(entries.map((one) => one.file));
|
|
32789
|
-
const here =
|
|
32829
|
+
const here = join13(directory, ".");
|
|
32790
32830
|
for (const file of verdicts.keys()) {
|
|
32791
32831
|
if (dirname7(file) === here && !held.has(file)) {
|
|
32792
32832
|
verdicts.delete(file);
|
|
@@ -32795,7 +32835,7 @@ function announcedIn(directory) {
|
|
|
32795
32835
|
return found;
|
|
32796
32836
|
}
|
|
32797
32837
|
async function announcementEnded(pid, directories = runtimeDirectories()) {
|
|
32798
|
-
const files = directories.map((directory) =>
|
|
32838
|
+
const files = directories.map((directory) => join13(directory, `runtime-${pid}.json`)).filter((file) => existsSync11(file));
|
|
32799
32839
|
const first = files[0];
|
|
32800
32840
|
if (first === undefined) {
|
|
32801
32841
|
return;
|
|
@@ -32821,7 +32861,7 @@ function sweepErrorReport(path, pid, now = Date.now()) {
|
|
|
32821
32861
|
return;
|
|
32822
32862
|
}
|
|
32823
32863
|
try {
|
|
32824
|
-
if (now -
|
|
32864
|
+
if (now - statSync5(path).mtimeMs >= ERROR_REPORT_KEEP_MS) {
|
|
32825
32865
|
unlinkSync(path);
|
|
32826
32866
|
}
|
|
32827
32867
|
} catch {}
|
|
@@ -33095,14 +33135,14 @@ var init_runtime_client = __esm(() => {
|
|
|
33095
33135
|
});
|
|
33096
33136
|
|
|
33097
33137
|
// src/boot-note.ts
|
|
33098
|
-
import { mkdirSync as mkdirSync6, readFileSync as
|
|
33099
|
-
import { dirname as dirname8, join as
|
|
33138
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "node:fs";
|
|
33139
|
+
import { dirname as dirname8, join as join14 } from "node:path";
|
|
33100
33140
|
function bootNotePath(projectPath) {
|
|
33101
|
-
return
|
|
33141
|
+
return join14(projectPath, ".godot", "gdharness-boot.json");
|
|
33102
33142
|
}
|
|
33103
33143
|
function readBootNote(projectPath) {
|
|
33104
33144
|
try {
|
|
33105
|
-
const noted = readNumber(asParams(JSON.parse(
|
|
33145
|
+
const noted = readNumber(asParams(JSON.parse(readFileSync11(bootNotePath(projectPath), "utf8"))), "announcedAfterMs");
|
|
33106
33146
|
return noted !== undefined && Number.isFinite(noted) && noted > 0 ? noted : null;
|
|
33107
33147
|
} catch {
|
|
33108
33148
|
return null;
|
|
@@ -33112,7 +33152,7 @@ function writeBootNote(projectPath, announcedAfterMs) {
|
|
|
33112
33152
|
try {
|
|
33113
33153
|
const path = bootNotePath(projectPath);
|
|
33114
33154
|
mkdirSync6(dirname8(path), { recursive: true });
|
|
33115
|
-
|
|
33155
|
+
writeFileSync8(path, JSON.stringify({ announcedAfterMs: Math.round(announcedAfterMs), at: new Date().toISOString() }, null, 2), "utf8");
|
|
33116
33156
|
} catch {}
|
|
33117
33157
|
}
|
|
33118
33158
|
function halfAsLongAgain(lastBootMs) {
|
|
@@ -33130,10 +33170,10 @@ var init_boot_note = __esm(() => {
|
|
|
33130
33170
|
});
|
|
33131
33171
|
|
|
33132
33172
|
// src/breakpoint-note.ts
|
|
33133
|
-
import { mkdirSync as mkdirSync7, readFileSync as
|
|
33134
|
-
import { dirname as dirname9, isAbsolute as isAbsolute2, join as
|
|
33173
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync12, rmSync as rmSync7, writeFileSync as writeFileSync9 } from "node:fs";
|
|
33174
|
+
import { dirname as dirname9, isAbsolute as isAbsolute2, join as join15, relative as relative2 } from "node:path";
|
|
33135
33175
|
function breakpointNotePath(projectPath) {
|
|
33136
|
-
return
|
|
33176
|
+
return join15(projectPath, ".godot", "gdharness-breakpoints.json");
|
|
33137
33177
|
}
|
|
33138
33178
|
function writeBreakpointNote(projectPath, held) {
|
|
33139
33179
|
const path = breakpointNotePath(projectPath);
|
|
@@ -33141,7 +33181,7 @@ function writeBreakpointNote(projectPath, held) {
|
|
|
33141
33181
|
const inside = held.map((one) => ({ scriptPath: realPathOr(one.scriptPath), lines: one.lines })).filter((one) => one.lines.length > 0 && withinProject(root, one.scriptPath));
|
|
33142
33182
|
try {
|
|
33143
33183
|
if (inside.length === 0) {
|
|
33144
|
-
|
|
33184
|
+
rmSync7(path, { force: true });
|
|
33145
33185
|
return;
|
|
33146
33186
|
}
|
|
33147
33187
|
const note = {
|
|
@@ -33151,7 +33191,7 @@ function writeBreakpointNote(projectPath, held) {
|
|
|
33151
33191
|
}))
|
|
33152
33192
|
};
|
|
33153
33193
|
mkdirSync7(dirname9(path), { recursive: true });
|
|
33154
|
-
|
|
33194
|
+
writeFileSync9(path, `${JSON.stringify(note, null, 2)}
|
|
33155
33195
|
`, "utf8");
|
|
33156
33196
|
} catch (error) {
|
|
33157
33197
|
console.error(`[SERVER] Could not record the breakpoints at ${path}: ${errorMessage(error)}`);
|
|
@@ -33159,7 +33199,7 @@ function writeBreakpointNote(projectPath, held) {
|
|
|
33159
33199
|
}
|
|
33160
33200
|
function readBreakpointNote(projectPath) {
|
|
33161
33201
|
try {
|
|
33162
|
-
const parsed = JSON.parse(
|
|
33202
|
+
const parsed = JSON.parse(readFileSync12(breakpointNotePath(projectPath), "utf8"));
|
|
33163
33203
|
if (typeof parsed !== "object" || parsed === null || !Array.isArray(parsed.breakpoints)) {
|
|
33164
33204
|
return [];
|
|
33165
33205
|
}
|
|
@@ -33174,7 +33214,7 @@ function readBreakpointNote(projectPath) {
|
|
|
33174
33214
|
}
|
|
33175
33215
|
const lines = Array.isArray(listed) ? listed.filter((line) => Number.isInteger(line) && line > 0) : [];
|
|
33176
33216
|
if (lines.length > 0) {
|
|
33177
|
-
held.push({ scriptPath: realPathOr(
|
|
33217
|
+
held.push({ scriptPath: realPathOr(join15(projectPath, script)), lines });
|
|
33178
33218
|
}
|
|
33179
33219
|
}
|
|
33180
33220
|
return held;
|
|
@@ -33192,14 +33232,14 @@ var init_breakpoint_note = __esm(() => {
|
|
|
33192
33232
|
});
|
|
33193
33233
|
|
|
33194
33234
|
// src/class-note.ts
|
|
33195
|
-
import { mkdirSync as mkdirSync8, readFileSync as
|
|
33196
|
-
import { dirname as dirname10, join as
|
|
33235
|
+
import { mkdirSync as mkdirSync8, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "node:fs";
|
|
33236
|
+
import { dirname as dirname10, join as join16 } from "node:path";
|
|
33197
33237
|
function classNotePath(projectPath) {
|
|
33198
|
-
return
|
|
33238
|
+
return join16(projectPath, ".godot", "gdharness-classes.json");
|
|
33199
33239
|
}
|
|
33200
33240
|
function readClassNote(projectPath) {
|
|
33201
33241
|
try {
|
|
33202
|
-
const fields = asParams(JSON.parse(
|
|
33242
|
+
const fields = asParams(JSON.parse(readFileSync13(classNotePath(projectPath), "utf8")));
|
|
33203
33243
|
const rebuiltWith = readArray(fields, "rebuiltWith");
|
|
33204
33244
|
if (rebuiltWith === undefined || !rebuiltWith.every((name) => typeof name === "string")) {
|
|
33205
33245
|
return null;
|
|
@@ -33217,23 +33257,23 @@ function writeClassNote(projectPath, note) {
|
|
|
33217
33257
|
try {
|
|
33218
33258
|
const path = classNotePath(projectPath);
|
|
33219
33259
|
mkdirSync8(dirname10(path), { recursive: true });
|
|
33220
|
-
|
|
33260
|
+
writeFileSync10(path, `${JSON.stringify(note, null, 2)}
|
|
33221
33261
|
`, "utf8");
|
|
33222
33262
|
} catch {}
|
|
33223
33263
|
}
|
|
33224
33264
|
var init_class_note = () => {};
|
|
33225
33265
|
|
|
33226
33266
|
// src/config-pin.ts
|
|
33227
|
-
import { existsSync as
|
|
33228
|
-
import { join as
|
|
33267
|
+
import { existsSync as existsSync12, readFileSync as readFileSync14 } from "node:fs";
|
|
33268
|
+
import { join as join17 } from "node:path";
|
|
33229
33269
|
function versionsNamedInConfig(projectPath) {
|
|
33230
|
-
const config =
|
|
33231
|
-
if (!
|
|
33270
|
+
const config = join17(projectPath, ".mcp.json");
|
|
33271
|
+
if (!existsSync12(config)) {
|
|
33232
33272
|
return [];
|
|
33233
33273
|
}
|
|
33234
33274
|
let text;
|
|
33235
33275
|
try {
|
|
33236
|
-
text =
|
|
33276
|
+
text = readFileSync14(config, "utf8");
|
|
33237
33277
|
JSON.parse(text);
|
|
33238
33278
|
} catch {
|
|
33239
33279
|
return [];
|
|
@@ -33993,25 +34033,25 @@ var init_desktop = () => {};
|
|
|
33993
34033
|
// src/editor-log.ts
|
|
33994
34034
|
import {
|
|
33995
34035
|
closeSync,
|
|
33996
|
-
existsSync as
|
|
34036
|
+
existsSync as existsSync13,
|
|
33997
34037
|
mkdirSync as mkdirSync9,
|
|
33998
34038
|
openSync,
|
|
33999
|
-
readFileSync as
|
|
34039
|
+
readFileSync as readFileSync15,
|
|
34000
34040
|
readSync,
|
|
34001
|
-
rmSync as
|
|
34002
|
-
statSync as
|
|
34003
|
-
writeFileSync as
|
|
34041
|
+
rmSync as rmSync8,
|
|
34042
|
+
statSync as statSync6,
|
|
34043
|
+
writeFileSync as writeFileSync11
|
|
34004
34044
|
} from "node:fs";
|
|
34005
|
-
import { dirname as dirname11, join as
|
|
34045
|
+
import { dirname as dirname11, join as join18 } from "node:path";
|
|
34006
34046
|
function editorLogPath(projectPath) {
|
|
34007
|
-
return
|
|
34047
|
+
return join18(projectPath, ".godot", "gdharness-editor.log");
|
|
34008
34048
|
}
|
|
34009
34049
|
function editorLogNotePath(projectPath) {
|
|
34010
|
-
return
|
|
34050
|
+
return join18(projectPath, ".godot", "gdharness-editor.json");
|
|
34011
34051
|
}
|
|
34012
34052
|
function readEditorLogNote(projectPath) {
|
|
34013
34053
|
try {
|
|
34014
|
-
const fields = asParams(JSON.parse(
|
|
34054
|
+
const fields = asParams(JSON.parse(readFileSync15(editorLogNotePath(projectPath), "utf8")));
|
|
34015
34055
|
const pid = readNumber(fields, "pid");
|
|
34016
34056
|
const startedAt = readString(fields, "startedAt");
|
|
34017
34057
|
return pid !== undefined && Number.isInteger(pid) && pid > 0 && startedAt !== undefined ? { pid, startedAt } : null;
|
|
@@ -34023,15 +34063,15 @@ function clearEditorLog(projectPath) {
|
|
|
34023
34063
|
try {
|
|
34024
34064
|
const path = editorLogPath(projectPath);
|
|
34025
34065
|
mkdirSync9(dirname11(path), { recursive: true });
|
|
34026
|
-
|
|
34027
|
-
|
|
34066
|
+
rmSync8(path, { force: true });
|
|
34067
|
+
rmSync8(editorLogNotePath(projectPath), { force: true });
|
|
34028
34068
|
} catch {}
|
|
34029
34069
|
}
|
|
34030
34070
|
function writeEditorLogNote(projectPath, pid) {
|
|
34031
34071
|
try {
|
|
34032
34072
|
const path = editorLogNotePath(projectPath);
|
|
34033
34073
|
mkdirSync9(dirname11(path), { recursive: true });
|
|
34034
|
-
|
|
34074
|
+
writeFileSync11(path, JSON.stringify({ pid, startedAt: new Date().toISOString() }, null, 2), "utf8");
|
|
34035
34075
|
} catch {}
|
|
34036
34076
|
}
|
|
34037
34077
|
function theConsoleWasNotCaptured(why, projectPath) {
|
|
@@ -34052,7 +34092,7 @@ function editorConsole(projectPath, editorPid, openedByAServer) {
|
|
|
34052
34092
|
return { kind: "older server", notedPid: noted?.pid ?? null };
|
|
34053
34093
|
}
|
|
34054
34094
|
const path = editorLogPath(projectPath);
|
|
34055
|
-
if (!
|
|
34095
|
+
if (!existsSync13(path)) {
|
|
34056
34096
|
return { kind: "not written" };
|
|
34057
34097
|
}
|
|
34058
34098
|
const log = new GameLog;
|
|
@@ -34062,9 +34102,9 @@ function editorConsole(projectPath, editorPid, openedByAServer) {
|
|
|
34062
34102
|
return { log, path, ...of === undefined ? {} : { readBytes: text.length, of } };
|
|
34063
34103
|
}
|
|
34064
34104
|
function theFirstOf(path) {
|
|
34065
|
-
const whole =
|
|
34105
|
+
const whole = statSync6(path).size;
|
|
34066
34106
|
if (whole <= MOST_CONSOLE_BYTES) {
|
|
34067
|
-
return { text:
|
|
34107
|
+
return { text: readFileSync15(path, "utf8") };
|
|
34068
34108
|
}
|
|
34069
34109
|
const handle = openSync(path, "r");
|
|
34070
34110
|
try {
|
|
@@ -38589,13 +38629,13 @@ var init_process_time = __esm(() => {
|
|
|
38589
38629
|
});
|
|
38590
38630
|
|
|
38591
38631
|
// src/project-scan.ts
|
|
38592
|
-
import { existsSync as
|
|
38593
|
-
import { join as
|
|
38632
|
+
import { existsSync as existsSync14, readdirSync as readdirSync7, readFileSync as readFileSync16 } from "node:fs";
|
|
38633
|
+
import { join as join19 } from "node:path";
|
|
38594
38634
|
function skipped(name) {
|
|
38595
38635
|
return name.startsWith(".") || SKIPPED.has(name);
|
|
38596
38636
|
}
|
|
38597
38637
|
function steppedOver(directory) {
|
|
38598
|
-
return
|
|
38638
|
+
return existsSync14(join19(directory, ".gdignore"));
|
|
38599
38639
|
}
|
|
38600
38640
|
function projectStructure(projectPath) {
|
|
38601
38641
|
const structure = { scenes: 0, scripts: 0, assets: 0, other: 0 };
|
|
@@ -38608,7 +38648,7 @@ function projectStructure(projectPath) {
|
|
|
38608
38648
|
continue;
|
|
38609
38649
|
}
|
|
38610
38650
|
if (entry.isDirectory()) {
|
|
38611
|
-
visit(
|
|
38651
|
+
visit(join19(directory, entry.name));
|
|
38612
38652
|
} else if (entry.isFile()) {
|
|
38613
38653
|
const extension = entry.name.split(".").pop()?.toLowerCase() ?? "";
|
|
38614
38654
|
if (extension === "tscn") {
|
|
@@ -38638,14 +38678,14 @@ function scriptsWithoutUid(projectPath) {
|
|
|
38638
38678
|
}
|
|
38639
38679
|
const spelled = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
|
|
38640
38680
|
if (entry.isDirectory()) {
|
|
38641
|
-
visit(
|
|
38681
|
+
visit(join19(directory, entry.name), spelled);
|
|
38642
38682
|
continue;
|
|
38643
38683
|
}
|
|
38644
38684
|
if (!entry.isFile()) {
|
|
38645
38685
|
continue;
|
|
38646
38686
|
}
|
|
38647
38687
|
const extension = entry.name.split(".").pop()?.toLowerCase() ?? "";
|
|
38648
|
-
if (CARRIES_A_UID.has(extension) && !
|
|
38688
|
+
if (CARRIES_A_UID.has(extension) && !existsSync14(join19(directory, `${entry.name}.uid`))) {
|
|
38649
38689
|
found.push(spelled);
|
|
38650
38690
|
}
|
|
38651
38691
|
}
|
|
@@ -38680,7 +38720,7 @@ function searchProject(projectPath, options) {
|
|
|
38680
38720
|
if (skipped(entry.name)) {
|
|
38681
38721
|
continue;
|
|
38682
38722
|
}
|
|
38683
|
-
const entryPath =
|
|
38723
|
+
const entryPath = join19(directory, entry.name);
|
|
38684
38724
|
if (entry.isDirectory()) {
|
|
38685
38725
|
visit(entryPath);
|
|
38686
38726
|
continue;
|
|
@@ -38691,7 +38731,7 @@ function searchProject(projectPath, options) {
|
|
|
38691
38731
|
}
|
|
38692
38732
|
result.summary.files_searched += 1;
|
|
38693
38733
|
const matches = [];
|
|
38694
|
-
for (const [index, line] of
|
|
38734
|
+
for (const [index, line] of readFileSync16(entryPath, "utf8").split(`
|
|
38695
38735
|
`).entries()) {
|
|
38696
38736
|
if (full()) {
|
|
38697
38737
|
break;
|
|
@@ -38719,27 +38759,6 @@ var init_project_scan = __esm(() => {
|
|
|
38719
38759
|
CARRIES_A_UID = new Set(["gd", "shader", "gdshader"]);
|
|
38720
38760
|
});
|
|
38721
38761
|
|
|
38722
|
-
// src/reimport.ts
|
|
38723
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
38724
|
-
import { existsSync as existsSync14, readFileSync as readFileSync16, rmSync as rmSync8, statSync as statSync6, utimesSync, writeFileSync as writeFileSync11 } from "node:fs";
|
|
38725
|
-
import { basename as basename3, join as join19 } from "node:path";
|
|
38726
|
-
function forceNextImport(projectPath, resourcePath) {
|
|
38727
|
-
const relative = resourcePath.replace(/^res:\/\//, "");
|
|
38728
|
-
const sidecar = join19(projectPath, `${relative}.import`);
|
|
38729
|
-
if (!existsSync14(sidecar)) {
|
|
38730
|
-
return;
|
|
38731
|
-
}
|
|
38732
|
-
const { atime, mtimeMs } = statSync6(sidecar);
|
|
38733
|
-
writeFileSync11(sidecar, readFileSync16(sidecar, "utf8").replace(/^valid=false\r?\n/m, ""));
|
|
38734
|
-
utimesSync(sidecar, atime, new Date(mtimeMs + 2000));
|
|
38735
|
-
rmSync8(importRecord(projectPath, resourcePath), { force: true });
|
|
38736
|
-
}
|
|
38737
|
-
function importRecord(projectPath, resourcePath) {
|
|
38738
|
-
const digest = createHash3("md5").update(resourcePath).digest("hex");
|
|
38739
|
-
return join19(projectPath, ".godot", "imported", `${basename3(resourcePath)}-${digest}.md5`);
|
|
38740
|
-
}
|
|
38741
|
-
var init_reimport = () => {};
|
|
38742
|
-
|
|
38743
38762
|
// src/restart-note.ts
|
|
38744
38763
|
import { mkdirSync as mkdirSync10, readFileSync as readFileSync17, rmSync as rmSync9, writeFileSync as writeFileSync12 } from "node:fs";
|
|
38745
38764
|
import { dirname as dirname13, join as join20 } from "node:path";
|
|
@@ -40650,7 +40669,7 @@ class GodotServer {
|
|
|
40650
40669
|
uidsCreated: given,
|
|
40651
40670
|
stillWithoutUid: after,
|
|
40652
40671
|
note: uidsLeftNote(after.length),
|
|
40653
|
-
...imported.
|
|
40672
|
+
...imported.extensionNote === undefined ? {} : { extensionNote: imported.extensionNote }
|
|
40654
40673
|
}
|
|
40655
40674
|
}, scanned));
|
|
40656
40675
|
}
|
|
@@ -40795,19 +40814,16 @@ class GodotServer {
|
|
|
40795
40814
|
if (!engine.ok) {
|
|
40796
40815
|
return { ok: false, response: engine.response };
|
|
40797
40816
|
}
|
|
40798
|
-
for (const target of targets) {
|
|
40799
|
-
forceNextImport(projectPath, target);
|
|
40800
|
-
}
|
|
40801
40817
|
const scanned = await this.untilTheEditorsScanIsWritten(projectPath);
|
|
40802
|
-
const imported = await runImport(engine.value, projectPath);
|
|
40818
|
+
const imported = await runImport(engine.value, projectPath, { forcing: targets });
|
|
40803
40819
|
if (!imported.ok) {
|
|
40804
40820
|
return { ok: false, response: this.answer(withScanWait(imported, scanned)) };
|
|
40805
40821
|
}
|
|
40806
40822
|
if (imported.messages.length > 0) {
|
|
40807
40823
|
extra["engine_messages"] = imported.messages;
|
|
40808
40824
|
}
|
|
40809
|
-
if (imported.
|
|
40810
|
-
extra["extensionNote"] =
|
|
40825
|
+
if (imported.extensionNote !== undefined) {
|
|
40826
|
+
extra["extensionNote"] = imported.extensionNote;
|
|
40811
40827
|
}
|
|
40812
40828
|
}
|
|
40813
40829
|
const after = await this.operation("get_import_status", resourcePath === undefined ? { includeUpToDate: true } : { resourcePath }, projectPath);
|
|
@@ -41298,7 +41314,7 @@ class GodotServer {
|
|
|
41298
41314
|
const notes = [];
|
|
41299
41315
|
if (contradicted.length > 0) {
|
|
41300
41316
|
const dependsOn = new Set;
|
|
41301
|
-
for (const one of contradicted) {
|
|
41317
|
+
for (const one of contradicted.filter((entry) => entry.kind === "method" || entry.kind === "property")) {
|
|
41302
41318
|
const source = cached === null ? null : this.sourceOfClass(projectPath, one.declaredIn);
|
|
41303
41319
|
if (source === null || cached === null) {
|
|
41304
41320
|
continue;
|
|
@@ -41338,9 +41354,10 @@ class GodotServer {
|
|
|
41338
41354
|
});
|
|
41339
41355
|
}
|
|
41340
41356
|
classesAScriptNames(projectPath, scriptPath) {
|
|
41341
|
-
const
|
|
41357
|
+
const resourcePath = scriptPath.startsWith("res://") ? scriptPath : `res://${scriptPath.replace(/^\/+/, "")}`;
|
|
41358
|
+
const source = this.sourceOfClass(projectPath, resourcePath);
|
|
41342
41359
|
const known = cachedClasses(projectPath) ?? declaredClasses(projectPath);
|
|
41343
|
-
return source === null ? [] : classesNamedIn(source, known).filter((name) => known.get(name) !==
|
|
41360
|
+
return source === null ? [] : classesNamedIn(source, known).filter((name) => known.get(name) !== resourcePath);
|
|
41344
41361
|
}
|
|
41345
41362
|
sourceOfClass(projectPath, resourcePath) {
|
|
41346
41363
|
const contained = resolveWithinProject(projectPath, resourcePath);
|
|
@@ -43626,7 +43643,6 @@ var init_server3 = __esm(() => {
|
|
|
43626
43643
|
init_process_children();
|
|
43627
43644
|
init_process_time();
|
|
43628
43645
|
init_project_scan();
|
|
43629
|
-
init_reimport();
|
|
43630
43646
|
init_resources();
|
|
43631
43647
|
init_restart_note();
|
|
43632
43648
|
init_run_record();
|
|
@@ -44586,8 +44602,8 @@ init_setup();
|
|
|
44586
44602
|
// src/skill.ts
|
|
44587
44603
|
init_setup();
|
|
44588
44604
|
init_tool_definitions();
|
|
44589
|
-
import { existsSync as
|
|
44590
|
-
import { basename as
|
|
44605
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync5, readdirSync as readdirSync5, rmSync as rmSync6, writeFileSync as writeFileSync7 } from "node:fs";
|
|
44606
|
+
import { basename as basename3, dirname as dirname5, join as join11 } from "node:path";
|
|
44591
44607
|
|
|
44592
44608
|
// src/tool-reference.ts
|
|
44593
44609
|
init_headless_operations();
|
|
@@ -44683,7 +44699,7 @@ function renderToolsMarkdown() {
|
|
|
44683
44699
|
|
|
44684
44700
|
// src/skill.ts
|
|
44685
44701
|
var SKILL_NAME = "gdharness";
|
|
44686
|
-
var SHARED_SKILLS =
|
|
44702
|
+
var SHARED_SKILLS = join11(".agents", "skills");
|
|
44687
44703
|
function skillMarkdown(version) {
|
|
44688
44704
|
return `---
|
|
44689
44705
|
name: ${SKILL_NAME}
|
|
@@ -44874,27 +44890,27 @@ whatever the engine said on stderr comes back under \`engine_messages\`.
|
|
|
44874
44890
|
function skillFiles(version) {
|
|
44875
44891
|
return new Map([
|
|
44876
44892
|
["SKILL.md", skillMarkdown(version)],
|
|
44877
|
-
[
|
|
44893
|
+
[join11("references", "tools.md"), renderToolsMarkdown()]
|
|
44878
44894
|
]);
|
|
44879
44895
|
}
|
|
44880
44896
|
function skillDirectories(harnesses, projectPath, exists) {
|
|
44881
|
-
const directories = [
|
|
44897
|
+
const directories = [join11(projectPath, SHARED_SKILLS, SKILL_NAME)];
|
|
44882
44898
|
for (const harness of harnesses) {
|
|
44883
44899
|
if (harness.skills === undefined) {
|
|
44884
44900
|
continue;
|
|
44885
44901
|
}
|
|
44886
|
-
const own =
|
|
44887
|
-
if ((!harness.skills.shared || exists(own)) && !directories.includes(
|
|
44888
|
-
directories.push(
|
|
44902
|
+
const own = join11(projectPath, harness.skills.dir);
|
|
44903
|
+
if ((!harness.skills.shared || exists(own)) && !directories.includes(join11(own, SKILL_NAME))) {
|
|
44904
|
+
directories.push(join11(own, SKILL_NAME));
|
|
44889
44905
|
}
|
|
44890
44906
|
}
|
|
44891
44907
|
return directories;
|
|
44892
44908
|
}
|
|
44893
44909
|
function everySkillDirectory(projectPath, harnesses) {
|
|
44894
|
-
const directories = new Set([
|
|
44910
|
+
const directories = new Set([join11(projectPath, SHARED_SKILLS, SKILL_NAME)]);
|
|
44895
44911
|
for (const harness of harnesses) {
|
|
44896
44912
|
if (harness.skills !== undefined) {
|
|
44897
|
-
directories.add(
|
|
44913
|
+
directories.add(join11(projectPath, harness.skills.dir, SKILL_NAME));
|
|
44898
44914
|
}
|
|
44899
44915
|
}
|
|
44900
44916
|
return [...directories];
|
|
@@ -44902,8 +44918,8 @@ function everySkillDirectory(projectPath, harnesses) {
|
|
|
44902
44918
|
function removeSkill(directories, projectPath) {
|
|
44903
44919
|
const removed = [];
|
|
44904
44920
|
for (const directory of directories) {
|
|
44905
|
-
if (
|
|
44906
|
-
|
|
44921
|
+
if (existsSync10(directory)) {
|
|
44922
|
+
rmSync6(directory, { recursive: true, force: true });
|
|
44907
44923
|
pruneEmpty(dirname5(directory), projectPath);
|
|
44908
44924
|
removed.push(directory);
|
|
44909
44925
|
}
|
|
@@ -44911,43 +44927,43 @@ function removeSkill(directories, projectPath) {
|
|
|
44911
44927
|
return removed;
|
|
44912
44928
|
}
|
|
44913
44929
|
function pruneEmpty(directory, projectPath) {
|
|
44914
|
-
const shared =
|
|
44930
|
+
const shared = join11(projectPath, ".agents");
|
|
44915
44931
|
let path = directory;
|
|
44916
|
-
while (path !== projectPath && (
|
|
44932
|
+
while (path !== projectPath && (basename3(path) === "skills" || path === shared)) {
|
|
44917
44933
|
if (readdirSync5(path).length > 0) {
|
|
44918
44934
|
return;
|
|
44919
44935
|
}
|
|
44920
|
-
|
|
44936
|
+
rmSync6(path, { recursive: true, force: true });
|
|
44921
44937
|
path = dirname5(path);
|
|
44922
44938
|
}
|
|
44923
44939
|
}
|
|
44924
44940
|
function writeSkill(directories, version) {
|
|
44925
44941
|
const files = skillFiles(version);
|
|
44926
44942
|
return directories.map((directory) => {
|
|
44927
|
-
const replaced =
|
|
44928
|
-
|
|
44943
|
+
const replaced = existsSync10(directory);
|
|
44944
|
+
rmSync6(directory, { recursive: true, force: true });
|
|
44929
44945
|
for (const [name, contents] of files) {
|
|
44930
|
-
const path =
|
|
44946
|
+
const path = join11(directory, name);
|
|
44931
44947
|
mkdirSync5(dirname5(path), { recursive: true });
|
|
44932
|
-
|
|
44948
|
+
writeFileSync7(path, contents, "utf8");
|
|
44933
44949
|
}
|
|
44934
44950
|
return { path: directory, replaced };
|
|
44935
44951
|
});
|
|
44936
44952
|
}
|
|
44937
44953
|
|
|
44938
44954
|
// src/version.ts
|
|
44939
|
-
import { readFileSync as
|
|
44940
|
-
import { dirname as dirname6, join as
|
|
44955
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
44956
|
+
import { dirname as dirname6, join as join12 } from "node:path";
|
|
44941
44957
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
44942
44958
|
function getLocalVersion() {
|
|
44943
44959
|
const currentDirectory = dirname6(fileURLToPath2(import.meta.url));
|
|
44944
44960
|
const packageCandidates = [
|
|
44945
|
-
|
|
44946
|
-
|
|
44961
|
+
join12(currentDirectory, "..", "package.json"),
|
|
44962
|
+
join12(currentDirectory, "..", "..", "package.json")
|
|
44947
44963
|
];
|
|
44948
44964
|
for (const packagePath of packageCandidates) {
|
|
44949
44965
|
try {
|
|
44950
|
-
const value = JSON.parse(
|
|
44966
|
+
const value = JSON.parse(readFileSync9(packagePath, "utf-8"));
|
|
44951
44967
|
if (typeof value === "object" && value !== null && "name" in value && value.name === "gdharness" && "version" in value && typeof value.version === "string") {
|
|
44952
44968
|
return value.version;
|
|
44953
44969
|
}
|