gdharness 1.3.46 → 1.3.48
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 +186 -49
- package/build/godot/addons/gdharness_editor/animation_reads.gd +20 -0
- package/build/godot/addons/gdharness_editor/file_reads.gd +6 -0
- package/build/godot/addons/gdharness_editor/scene_uids.gd +25 -13
- package/build/godot/addons/gdharness_editor/tools/animation_states.gd +20 -6
- package/build/godot/addons/gdharness_editor/tools/animation_tracks.gd +19 -0
- package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +23 -4
- package/build/godot/addons/gdharness_runtime/runtime_hover.gd +9 -7
- package/build/godot/addons/gdharness_runtime/runtime_queries.gd +7 -0
- package/build/godot/addons/gdharness_runtime/runtime_waits.gd +90 -30
- package/build/godot/addons/gdharness_runtime/runtime_words.gd +1 -1
- package/build/godot/operations/animation_reads.gd +20 -0
- package/build/godot/operations/dependencies.gd +65 -9
- package/build/godot/operations/export_presets.gd +32 -5
- package/build/godot/operations/file_reads.gd +6 -0
- package/build/godot/operations/import_pipeline.gd +10 -2
- package/build/godot/operations/project_config.gd +35 -0
- package/build/godot/operations/resource_files.gd +1 -2
- package/build/godot/tests/listed.gd +25 -0
- package/build/keeper.js +1308 -1026
- package/package.json +1 -1
package/build/keeper.js
CHANGED
|
@@ -6946,8 +6946,8 @@ var require_public_api = __commonJS(function(exports) {
|
|
|
6946
6946
|
});
|
|
6947
6947
|
|
|
6948
6948
|
// src/keeper.ts
|
|
6949
|
-
import { closeSync as
|
|
6950
|
-
import { tmpdir as
|
|
6949
|
+
import { closeSync as closeSync3, existsSync as existsSync3, mkdtempSync as mkdtempSync4, openSync as openSync4, readFileSync as readFileSync8, rmSync as rmSync7, writeFileSync as writeFileSync3 } from "node:fs";
|
|
6950
|
+
import { tmpdir as tmpdir6 } from "node:os";
|
|
6951
6951
|
import { join as join10 } from "node:path";
|
|
6952
6952
|
import { setTimeout as delay3 } from "node:timers/promises";
|
|
6953
6953
|
|
|
@@ -7407,344 +7407,541 @@ function throughHelper(how, command, args, files, assembly = helperAssembly()) {
|
|
|
7407
7407
|
};
|
|
7408
7408
|
}
|
|
7409
7409
|
|
|
7410
|
-
// src/
|
|
7411
|
-
import
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
SetErrorMode: { args: [FFIType.u32], returns: FFIType.u32 }
|
|
7423
|
-
});
|
|
7424
|
-
try {
|
|
7425
|
-
const mode = kernel32.symbols.GetErrorMode();
|
|
7426
|
-
kernel32.symbols.SetErrorMode(mode & ~NO_FAULT_ERROR_BOX);
|
|
7427
|
-
cleared = true;
|
|
7428
|
-
} finally {
|
|
7429
|
-
kernel32.close();
|
|
7430
|
-
}
|
|
7431
|
-
} catch {}
|
|
7432
|
-
}
|
|
7433
|
-
function crashesReported() {
|
|
7434
|
-
return cleared;
|
|
7435
|
-
}
|
|
7410
|
+
// src/engine-slots.ts
|
|
7411
|
+
import {
|
|
7412
|
+
closeSync as closeSync2,
|
|
7413
|
+
mkdirSync,
|
|
7414
|
+
openSync as openSync2,
|
|
7415
|
+
readFileSync as readFileSync4,
|
|
7416
|
+
rmSync as rmSync3,
|
|
7417
|
+
statSync as statSync3,
|
|
7418
|
+
watch,
|
|
7419
|
+
writeSync as writeSync2
|
|
7420
|
+
} from "node:fs";
|
|
7421
|
+
import process4 from "node:process";
|
|
7436
7422
|
|
|
7437
|
-
// src/
|
|
7438
|
-
import {
|
|
7439
|
-
|
|
7440
|
-
import { join as join6 } from "node:path";
|
|
7423
|
+
// src/call-signal.ts
|
|
7424
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7425
|
+
var current = new AsyncLocalStorage;
|
|
7441
7426
|
|
|
7442
|
-
// src/
|
|
7443
|
-
|
|
7444
|
-
var BOOL = 1;
|
|
7445
|
-
var INT = 2;
|
|
7446
|
-
var FLOAT = 3;
|
|
7447
|
-
var STRING = 4;
|
|
7448
|
-
var ARRAY = 28;
|
|
7449
|
-
var FLAG_64 = 1 << 16;
|
|
7450
|
-
var MATH = {
|
|
7451
|
-
5: { name: "Vector2", count: 2 },
|
|
7452
|
-
6: { name: "Vector2i", count: 2, ints: true },
|
|
7453
|
-
7: { name: "Rect2", count: 4 },
|
|
7454
|
-
8: { name: "Rect2i", count: 4, ints: true },
|
|
7455
|
-
9: { name: "Vector3", count: 3 },
|
|
7456
|
-
10: { name: "Vector3i", count: 3, ints: true },
|
|
7457
|
-
11: { name: "Transform2D", count: 6 },
|
|
7458
|
-
12: { name: "Vector4", count: 4 },
|
|
7459
|
-
13: { name: "Vector4i", count: 4, ints: true },
|
|
7460
|
-
14: { name: "Plane", count: 4 },
|
|
7461
|
-
15: { name: "Quaternion", count: 4 },
|
|
7462
|
-
16: { name: "AABB", count: 6 },
|
|
7463
|
-
17: { name: "Basis", count: 9 },
|
|
7464
|
-
18: { name: "Transform3D", count: 12 },
|
|
7465
|
-
19: { name: "Projection", count: 16 }
|
|
7466
|
-
};
|
|
7467
|
-
var PACKED_VECTORS = { 35: 2, 36: 3, 38: 4 };
|
|
7427
|
+
// src/harnesses.ts
|
|
7428
|
+
import { basename as basename2, dirname as dirname2, isAbsolute as isAbsolute2, join as join3, relative as relative2, resolve as resolve2 } from "node:path";
|
|
7468
7429
|
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
7430
|
+
// node_modules/yaml/dist/index.js
|
|
7431
|
+
var composer = require_composer();
|
|
7432
|
+
var Document = require_Document();
|
|
7433
|
+
var Schema = require_Schema();
|
|
7434
|
+
var errors = require_errors();
|
|
7435
|
+
var Alias = require_Alias();
|
|
7436
|
+
var identity = require_identity();
|
|
7437
|
+
var Pair = require_Pair();
|
|
7438
|
+
var Scalar = require_Scalar();
|
|
7439
|
+
var YAMLMap = require_YAMLMap();
|
|
7440
|
+
var YAMLSeq = require_YAMLSeq();
|
|
7441
|
+
var cst = require_cst();
|
|
7442
|
+
var lexer = require_lexer();
|
|
7443
|
+
var lineCounter = require_line_counter();
|
|
7444
|
+
var parser = require_parser();
|
|
7445
|
+
var publicApi = require_public_api();
|
|
7446
|
+
var visit = require_visit();
|
|
7447
|
+
var $Composer = composer.Composer;
|
|
7448
|
+
var $Document = Document.Document;
|
|
7449
|
+
var $Schema = Schema.Schema;
|
|
7450
|
+
var $YAMLError = errors.YAMLError;
|
|
7451
|
+
var $YAMLParseError = errors.YAMLParseError;
|
|
7452
|
+
var $YAMLWarning = errors.YAMLWarning;
|
|
7453
|
+
var $Alias = Alias.Alias;
|
|
7454
|
+
var $isAlias = identity.isAlias;
|
|
7455
|
+
var $isCollection = identity.isCollection;
|
|
7456
|
+
var $isDocument = identity.isDocument;
|
|
7457
|
+
var $isMap = identity.isMap;
|
|
7458
|
+
var $isNode = identity.isNode;
|
|
7459
|
+
var $isPair = identity.isPair;
|
|
7460
|
+
var $isScalar = identity.isScalar;
|
|
7461
|
+
var $isSeq = identity.isSeq;
|
|
7462
|
+
var $Pair = Pair.Pair;
|
|
7463
|
+
var $Scalar = Scalar.Scalar;
|
|
7464
|
+
var $YAMLMap = YAMLMap.YAMLMap;
|
|
7465
|
+
var $YAMLSeq = YAMLSeq.YAMLSeq;
|
|
7466
|
+
var $Lexer = lexer.Lexer;
|
|
7467
|
+
var $LineCounter = lineCounter.LineCounter;
|
|
7468
|
+
var $Parser = parser.Parser;
|
|
7469
|
+
var $parse = publicApi.parse;
|
|
7470
|
+
var $parseAllDocuments = publicApi.parseAllDocuments;
|
|
7471
|
+
var $parseDocument = publicApi.parseDocument;
|
|
7472
|
+
var $stringify = publicApi.stringify;
|
|
7473
|
+
var $visit = visit.visit;
|
|
7474
|
+
var $visitAsync = visit.visitAsync;
|
|
7475
|
+
|
|
7476
|
+
// src/paths.ts
|
|
7477
|
+
import { realpathSync, statSync as statSync2 } from "node:fs";
|
|
7478
|
+
import { basename, dirname, isAbsolute, join as join2, relative, resolve, sep } from "node:path";
|
|
7479
|
+
function realAsFarAsItExists(path) {
|
|
7480
|
+
const missing = [];
|
|
7481
|
+
let at = path;
|
|
7482
|
+
for (;; ) {
|
|
7483
|
+
try {
|
|
7484
|
+
return join2(realpathSync.native(at), ...missing);
|
|
7485
|
+
} catch {
|
|
7486
|
+
const parent = dirname(at);
|
|
7487
|
+
if (parent === at) {
|
|
7488
|
+
return path;
|
|
7489
|
+
}
|
|
7490
|
+
missing.unshift(basename(at));
|
|
7491
|
+
at = parent;
|
|
7481
7492
|
}
|
|
7482
7493
|
}
|
|
7483
|
-
u32() {
|
|
7484
|
-
this.need(4);
|
|
7485
|
-
const value = this.view.getUint32(this.offset, true);
|
|
7486
|
-
this.offset += 4;
|
|
7487
|
-
return value;
|
|
7488
|
-
}
|
|
7489
|
-
i32() {
|
|
7490
|
-
this.need(4);
|
|
7491
|
-
const value = this.view.getInt32(this.offset, true);
|
|
7492
|
-
this.offset += 4;
|
|
7493
|
-
return value;
|
|
7494
|
-
}
|
|
7495
|
-
i64() {
|
|
7496
|
-
this.need(8);
|
|
7497
|
-
const value = Number(this.view.getBigInt64(this.offset, true));
|
|
7498
|
-
this.offset += 8;
|
|
7499
|
-
return value;
|
|
7500
|
-
}
|
|
7501
|
-
u64() {
|
|
7502
|
-
this.need(8);
|
|
7503
|
-
const value = Number(this.view.getBigUint64(this.offset, true));
|
|
7504
|
-
this.offset += 8;
|
|
7505
|
-
return value;
|
|
7506
|
-
}
|
|
7507
|
-
f32() {
|
|
7508
|
-
this.need(4);
|
|
7509
|
-
const value = this.view.getFloat32(this.offset, true);
|
|
7510
|
-
this.offset += 4;
|
|
7511
|
-
return value;
|
|
7512
|
-
}
|
|
7513
|
-
f64() {
|
|
7514
|
-
this.need(8);
|
|
7515
|
-
const value = this.view.getFloat64(this.offset, true);
|
|
7516
|
-
this.offset += 8;
|
|
7517
|
-
return value;
|
|
7518
|
-
}
|
|
7519
|
-
real(wide) {
|
|
7520
|
-
return wide ? this.f64() : this.f32();
|
|
7521
|
-
}
|
|
7522
|
-
bytes(count) {
|
|
7523
|
-
this.need(count);
|
|
7524
|
-
const out = new Uint8Array(this.view.buffer, this.view.byteOffset + this.offset, count);
|
|
7525
|
-
this.offset += count;
|
|
7526
|
-
return out;
|
|
7527
|
-
}
|
|
7528
|
-
string() {
|
|
7529
|
-
const length = this.u32();
|
|
7530
|
-
const text = new TextDecoder().decode(this.bytes(length));
|
|
7531
|
-
this.bytes((4 - length % 4) % 4);
|
|
7532
|
-
return text;
|
|
7533
|
-
}
|
|
7534
7494
|
}
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
reader.string();
|
|
7541
|
-
}
|
|
7495
|
+
|
|
7496
|
+
// src/harnesses.ts
|
|
7497
|
+
var SERVER_KEY = "gdharness";
|
|
7498
|
+
function tomlArray(values) {
|
|
7499
|
+
return `[${values.map((value) => `"${value}"`).join(", ")}]`;
|
|
7542
7500
|
}
|
|
7543
|
-
function
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7501
|
+
function tomlEnv(launch) {
|
|
7502
|
+
const pairs = Object.entries(launch.env).map(([name, value]) => `${name} = "${value}"`);
|
|
7503
|
+
return `env = { ${pairs.join(", ")} }`;
|
|
7504
|
+
}
|
|
7505
|
+
function jsonSnippet(launch, container, shape) {
|
|
7506
|
+
return JSON.stringify({ [container]: { [SERVER_KEY]: entryFor(shape, launch) } }, null, 2);
|
|
7507
|
+
}
|
|
7508
|
+
var HARNESSES = [
|
|
7509
|
+
{
|
|
7510
|
+
id: "claude-code",
|
|
7511
|
+
name: "Claude Code",
|
|
7512
|
+
scope: "project",
|
|
7513
|
+
file: ".mcp.json",
|
|
7514
|
+
container: "mcpServers",
|
|
7515
|
+
shape: "plain",
|
|
7516
|
+
home: ".claude",
|
|
7517
|
+
marker: ".claude",
|
|
7518
|
+
skills: { dir: join3(".claude", "skills"), shared: false }
|
|
7519
|
+
},
|
|
7520
|
+
{
|
|
7521
|
+
id: "copilot-cli",
|
|
7522
|
+
name: "Copilot CLI",
|
|
7523
|
+
scope: "project",
|
|
7524
|
+
file: ".mcp.json",
|
|
7525
|
+
container: "mcpServers",
|
|
7526
|
+
shape: "plain",
|
|
7527
|
+
home: ".copilot",
|
|
7528
|
+
skills: { dir: join3(".github", "skills"), shared: true },
|
|
7529
|
+
manual: "Trust the folder when Copilot CLI first asks, or it reads no config here."
|
|
7530
|
+
},
|
|
7531
|
+
{
|
|
7532
|
+
id: "qoder",
|
|
7533
|
+
name: "Qoder",
|
|
7534
|
+
scope: "project",
|
|
7535
|
+
file: ".mcp.json",
|
|
7536
|
+
container: "mcpServers",
|
|
7537
|
+
shape: "plain",
|
|
7538
|
+
home: ".qoder",
|
|
7539
|
+
marker: ".qoder"
|
|
7540
|
+
},
|
|
7541
|
+
{
|
|
7542
|
+
id: "command-code",
|
|
7543
|
+
name: "Command Code",
|
|
7544
|
+
scope: "project",
|
|
7545
|
+
file: ".mcp.json",
|
|
7546
|
+
container: "mcpServers",
|
|
7547
|
+
shape: "plain",
|
|
7548
|
+
home: ".commandcode"
|
|
7549
|
+
},
|
|
7550
|
+
{
|
|
7551
|
+
id: "cursor",
|
|
7552
|
+
name: "Cursor",
|
|
7553
|
+
scope: "project",
|
|
7554
|
+
file: join3(".cursor", "mcp.json"),
|
|
7555
|
+
container: "mcpServers",
|
|
7556
|
+
shape: "plain",
|
|
7557
|
+
home: ".cursor",
|
|
7558
|
+
skills: { dir: join3(".cursor", "skills"), shared: true },
|
|
7559
|
+
manual: "Cursor asks before each tool call by default, and the server can be toggled off."
|
|
7560
|
+
},
|
|
7561
|
+
{
|
|
7562
|
+
id: "vscode",
|
|
7563
|
+
name: "VS Code",
|
|
7564
|
+
scope: "project",
|
|
7565
|
+
file: join3(".vscode", "mcp.json"),
|
|
7566
|
+
container: "servers",
|
|
7567
|
+
shape: "typed",
|
|
7568
|
+
home: ".vscode",
|
|
7569
|
+
skills: { dir: join3(".github", "skills"), shared: true },
|
|
7570
|
+
manual: "VS Code asks you to trust a server the first time it starts one."
|
|
7571
|
+
},
|
|
7572
|
+
{
|
|
7573
|
+
id: "opencode",
|
|
7574
|
+
name: "opencode",
|
|
7575
|
+
scope: "project",
|
|
7576
|
+
file: "opencode.json",
|
|
7577
|
+
container: "mcp",
|
|
7578
|
+
shape: "opencode",
|
|
7579
|
+
home: join3(".config", "opencode"),
|
|
7580
|
+
marker: ".opencode",
|
|
7581
|
+
skills: { dir: join3(".opencode", "skills"), shared: true }
|
|
7582
|
+
},
|
|
7583
|
+
{
|
|
7584
|
+
id: "junie",
|
|
7585
|
+
name: "Junie",
|
|
7586
|
+
scope: "project",
|
|
7587
|
+
file: join3(".junie", "mcp", "mcp.json"),
|
|
7588
|
+
container: "mcpServers",
|
|
7589
|
+
shape: "plain",
|
|
7590
|
+
home: ".junie",
|
|
7591
|
+
skills: { dir: join3(".junie", "skills"), shared: true }
|
|
7592
|
+
},
|
|
7593
|
+
{
|
|
7594
|
+
id: "kiro",
|
|
7595
|
+
name: "Kiro",
|
|
7596
|
+
scope: "project",
|
|
7597
|
+
file: join3(".kiro", "settings", "mcp.json"),
|
|
7598
|
+
container: "mcpServers",
|
|
7599
|
+
shape: "plain",
|
|
7600
|
+
home: ".kiro",
|
|
7601
|
+
skills: { dir: join3(".kiro", "skills"), shared: false }
|
|
7602
|
+
},
|
|
7603
|
+
{
|
|
7604
|
+
id: "gemini",
|
|
7605
|
+
name: "Gemini CLI",
|
|
7606
|
+
scope: "project",
|
|
7607
|
+
file: join3(".gemini", "settings.json"),
|
|
7608
|
+
container: "mcpServers",
|
|
7609
|
+
shape: "plain",
|
|
7610
|
+
home: ".gemini",
|
|
7611
|
+
skills: { dir: join3(".gemini", "skills"), shared: true }
|
|
7612
|
+
},
|
|
7613
|
+
{
|
|
7614
|
+
id: "roo",
|
|
7615
|
+
name: "Roo Code",
|
|
7616
|
+
scope: "project",
|
|
7617
|
+
file: join3(".roo", "mcp.json"),
|
|
7618
|
+
container: "mcpServers",
|
|
7619
|
+
shape: "plain"
|
|
7620
|
+
},
|
|
7621
|
+
{
|
|
7622
|
+
id: "kilo",
|
|
7623
|
+
name: "Kilo Code",
|
|
7624
|
+
scope: "project",
|
|
7625
|
+
file: join3(".kilocode", "mcp.json"),
|
|
7626
|
+
container: "mcpServers",
|
|
7627
|
+
shape: "plain"
|
|
7628
|
+
},
|
|
7629
|
+
{
|
|
7630
|
+
id: "amazon-q",
|
|
7631
|
+
name: "Amazon Q Developer CLI",
|
|
7632
|
+
scope: "project",
|
|
7633
|
+
file: join3(".amazonq", "mcp.json"),
|
|
7634
|
+
container: "mcpServers",
|
|
7635
|
+
shape: "plain",
|
|
7636
|
+
home: join3(".aws", "amazonq")
|
|
7637
|
+
},
|
|
7638
|
+
{
|
|
7639
|
+
id: "zed",
|
|
7640
|
+
name: "Zed",
|
|
7641
|
+
scope: "project",
|
|
7642
|
+
file: join3(".zed", "settings.json"),
|
|
7643
|
+
container: "context_servers",
|
|
7644
|
+
shape: "plain"
|
|
7645
|
+
},
|
|
7646
|
+
{
|
|
7647
|
+
id: "amp",
|
|
7648
|
+
name: "Amp",
|
|
7649
|
+
scope: "project",
|
|
7650
|
+
file: join3(".amp", "settings.json"),
|
|
7651
|
+
container: "amp.mcpServers",
|
|
7652
|
+
shape: "plain",
|
|
7653
|
+
home: join3(".config", "amp")
|
|
7654
|
+
},
|
|
7655
|
+
{
|
|
7656
|
+
id: "warp",
|
|
7657
|
+
name: "Warp",
|
|
7658
|
+
scope: "project",
|
|
7659
|
+
file: join3(".warp", ".mcp.json"),
|
|
7660
|
+
container: "mcpServers",
|
|
7661
|
+
shape: "plain",
|
|
7662
|
+
home: ".warp",
|
|
7663
|
+
manual: "Warp starts a project server only once you toggle it on, on its MCP servers page."
|
|
7664
|
+
},
|
|
7665
|
+
{
|
|
7666
|
+
id: "trae",
|
|
7667
|
+
name: "Trae",
|
|
7668
|
+
scope: "project",
|
|
7669
|
+
file: join3(".trae", "mcp.json"),
|
|
7670
|
+
container: "mcpServers",
|
|
7671
|
+
shape: "plain",
|
|
7672
|
+
home: ".trae"
|
|
7673
|
+
},
|
|
7674
|
+
{
|
|
7675
|
+
id: "factory",
|
|
7676
|
+
name: "Factory Droid",
|
|
7677
|
+
scope: "project",
|
|
7678
|
+
file: join3(".factory", "mcp.json"),
|
|
7679
|
+
container: "mcpServers",
|
|
7680
|
+
shape: "typed",
|
|
7681
|
+
home: ".factory"
|
|
7682
|
+
},
|
|
7683
|
+
{
|
|
7684
|
+
id: "tabnine",
|
|
7685
|
+
name: "Tabnine",
|
|
7686
|
+
scope: "project",
|
|
7687
|
+
file: join3(".tabnine", "mcp_servers.json"),
|
|
7688
|
+
container: "mcpServers",
|
|
7689
|
+
shape: "plain",
|
|
7690
|
+
home: ".tabnine"
|
|
7691
|
+
},
|
|
7692
|
+
{
|
|
7693
|
+
id: "firebender",
|
|
7694
|
+
name: "Firebender",
|
|
7695
|
+
scope: "project",
|
|
7696
|
+
file: "firebender.json",
|
|
7697
|
+
container: "mcpServers",
|
|
7698
|
+
shape: "plain"
|
|
7699
|
+
},
|
|
7700
|
+
{
|
|
7701
|
+
id: "pi",
|
|
7702
|
+
name: "pi",
|
|
7703
|
+
scope: "project",
|
|
7704
|
+
file: join3(".pi", "mcp.json"),
|
|
7705
|
+
container: "mcpServers",
|
|
7706
|
+
shape: "plain",
|
|
7707
|
+
home: ".pi"
|
|
7708
|
+
},
|
|
7709
|
+
{
|
|
7710
|
+
id: "mistral-vibe",
|
|
7711
|
+
name: "Mistral Vibe",
|
|
7712
|
+
scope: "project",
|
|
7713
|
+
file: join3(".vibe", "config.toml"),
|
|
7714
|
+
container: "mcp_servers",
|
|
7715
|
+
shape: "plain",
|
|
7716
|
+
toml: {
|
|
7717
|
+
header: "[[mcp_servers]]",
|
|
7718
|
+
identity: `name = "${SERVER_KEY}"`,
|
|
7719
|
+
block: (launch) => [
|
|
7720
|
+
"[[mcp_servers]]",
|
|
7721
|
+
`name = "${SERVER_KEY}"`,
|
|
7722
|
+
'transport = "stdio"',
|
|
7723
|
+
`command = "${launch.command}"`,
|
|
7724
|
+
`args = ${tomlArray(launch.args)}`,
|
|
7725
|
+
tomlEnv(launch)
|
|
7726
|
+
].join(`
|
|
7727
|
+
`)
|
|
7613
7728
|
}
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7729
|
+
},
|
|
7730
|
+
{
|
|
7731
|
+
id: "vtcode",
|
|
7732
|
+
name: "VT Code",
|
|
7733
|
+
scope: "project",
|
|
7734
|
+
file: "vtcode.toml",
|
|
7735
|
+
container: "mcp.providers",
|
|
7736
|
+
shape: "plain",
|
|
7737
|
+
marker: ".vtcode",
|
|
7738
|
+
toml: {
|
|
7739
|
+
header: "[[mcp.providers]]",
|
|
7740
|
+
identity: `name = "${SERVER_KEY}"`,
|
|
7741
|
+
enable: { header: "[mcp]", line: "enabled = true" },
|
|
7742
|
+
block: (launch) => [
|
|
7743
|
+
"[[mcp.providers]]",
|
|
7744
|
+
`name = "${SERVER_KEY}"`,
|
|
7745
|
+
"enabled = true",
|
|
7746
|
+
`command = "${launch.command}"`,
|
|
7747
|
+
`args = ${tomlArray(launch.args)}`,
|
|
7748
|
+
tomlEnv(launch)
|
|
7749
|
+
].join(`
|
|
7750
|
+
`)
|
|
7618
7751
|
}
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7752
|
+
},
|
|
7753
|
+
{
|
|
7754
|
+
id: "fast-agent",
|
|
7755
|
+
name: "fast-agent",
|
|
7756
|
+
scope: "project",
|
|
7757
|
+
file: "fastagent.config.yaml",
|
|
7758
|
+
container: "mcp",
|
|
7759
|
+
shape: "plain",
|
|
7760
|
+
yaml: {
|
|
7761
|
+
path: ["mcp", "servers", SERVER_KEY],
|
|
7762
|
+
entry: (launch) => ({ command: launch.command, args: [...launch.args], env: { ...launch.env } })
|
|
7763
|
+
}
|
|
7764
|
+
},
|
|
7765
|
+
{
|
|
7766
|
+
id: "codex",
|
|
7767
|
+
name: "Codex CLI",
|
|
7768
|
+
scope: "home",
|
|
7769
|
+
file: join3(".codex", "config.toml"),
|
|
7770
|
+
container: "mcp_servers",
|
|
7771
|
+
shape: "plain",
|
|
7772
|
+
manual: "Codex reads its config at startup, so restart it.",
|
|
7773
|
+
toml: {
|
|
7774
|
+
header: `[mcp_servers.${SERVER_KEY}]`,
|
|
7775
|
+
block: (launch) => [
|
|
7776
|
+
`[mcp_servers.${SERVER_KEY}]`,
|
|
7777
|
+
`command = "${launch.command}"`,
|
|
7778
|
+
`args = ${tomlArray(launch.args)}`,
|
|
7779
|
+
tomlEnv(launch)
|
|
7780
|
+
].join(`
|
|
7781
|
+
`)
|
|
7782
|
+
}
|
|
7783
|
+
},
|
|
7784
|
+
{
|
|
7785
|
+
id: "cline",
|
|
7786
|
+
name: "Cline",
|
|
7787
|
+
scope: "home",
|
|
7788
|
+
file: join3(".cline", "data", "settings", "cline_mcp_settings.json"),
|
|
7789
|
+
container: "mcpServers",
|
|
7790
|
+
shape: "plain",
|
|
7791
|
+
marker: ".cline",
|
|
7792
|
+
skills: { dir: join3(".cline", "skills"), shared: false }
|
|
7793
|
+
},
|
|
7794
|
+
{
|
|
7795
|
+
id: "goose",
|
|
7796
|
+
name: "Goose",
|
|
7797
|
+
scope: "home",
|
|
7798
|
+
file: {
|
|
7799
|
+
win32: { appData: join3("Block", "goose", "config", "config.yaml") },
|
|
7800
|
+
darwin: join3(".config", "goose", "config.yaml"),
|
|
7801
|
+
linux: join3(".config", "goose", "config.yaml")
|
|
7802
|
+
},
|
|
7803
|
+
container: "extensions",
|
|
7804
|
+
shape: "plain",
|
|
7805
|
+
yaml: {
|
|
7806
|
+
path: ["extensions", SERVER_KEY],
|
|
7807
|
+
entry: (launch) => ({
|
|
7808
|
+
name: SERVER_KEY,
|
|
7809
|
+
type: "stdio",
|
|
7810
|
+
enabled: true,
|
|
7811
|
+
cmd: launch.command,
|
|
7812
|
+
args: [...launch.args],
|
|
7813
|
+
envs: { ...launch.env },
|
|
7814
|
+
timeout: 300
|
|
7815
|
+
})
|
|
7624
7816
|
}
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
}
|
|
7652
|
-
function pushU32(out, value) {
|
|
7653
|
-
out.push(value & 255, value >>> 8 & 255, value >>> 16 & 255, value >>> 24 & 255);
|
|
7654
|
-
}
|
|
7655
|
-
function encodeInto(out, value) {
|
|
7656
|
-
if (value === null) {
|
|
7657
|
-
pushU32(out, NIL);
|
|
7658
|
-
} else if (typeof value === "boolean") {
|
|
7659
|
-
pushU32(out, BOOL);
|
|
7660
|
-
pushU32(out, value ? 1 : 0);
|
|
7661
|
-
} else if (typeof value === "number") {
|
|
7662
|
-
const view = new DataView(new ArrayBuffer(8));
|
|
7663
|
-
if (Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) {
|
|
7664
|
-
pushU32(out, INT);
|
|
7665
|
-
view.setInt32(0, value, true);
|
|
7666
|
-
out.push(...new Uint8Array(view.buffer, 0, 4));
|
|
7667
|
-
} else if (Number.isInteger(value)) {
|
|
7668
|
-
pushU32(out, INT | FLAG_64);
|
|
7669
|
-
view.setBigInt64(0, BigInt(value), true);
|
|
7670
|
-
out.push(...new Uint8Array(view.buffer));
|
|
7671
|
-
} else {
|
|
7672
|
-
pushU32(out, FLOAT | FLAG_64);
|
|
7673
|
-
view.setFloat64(0, value, true);
|
|
7674
|
-
out.push(...new Uint8Array(view.buffer));
|
|
7817
|
+
},
|
|
7818
|
+
{
|
|
7819
|
+
id: "windsurf",
|
|
7820
|
+
name: "Windsurf",
|
|
7821
|
+
scope: "home",
|
|
7822
|
+
file: join3(".codeium", "windsurf", "mcp_config.json"),
|
|
7823
|
+
container: "mcpServers",
|
|
7824
|
+
shape: "plain",
|
|
7825
|
+
skills: { dir: join3(".windsurf", "skills"), shared: true }
|
|
7826
|
+
},
|
|
7827
|
+
{
|
|
7828
|
+
id: "hermes",
|
|
7829
|
+
name: "Hermes",
|
|
7830
|
+
scope: "home",
|
|
7831
|
+
file: join3(".hermes", "config.yaml"),
|
|
7832
|
+
container: "mcp_servers",
|
|
7833
|
+
shape: "plain",
|
|
7834
|
+
skills: { dir: join3(".hermes", "skills"), shared: true },
|
|
7835
|
+
yaml: {
|
|
7836
|
+
path: ["mcp_servers", SERVER_KEY],
|
|
7837
|
+
entry: (launch) => ({
|
|
7838
|
+
command: launch.command,
|
|
7839
|
+
args: [...launch.args],
|
|
7840
|
+
env: { ...launch.env },
|
|
7841
|
+
enabled: true
|
|
7842
|
+
})
|
|
7675
7843
|
}
|
|
7676
|
-
}
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7844
|
+
},
|
|
7845
|
+
{
|
|
7846
|
+
id: "openclaw",
|
|
7847
|
+
name: "OpenClaw",
|
|
7848
|
+
scope: "home",
|
|
7849
|
+
file: join3(".openclaw", "openclaw.json"),
|
|
7850
|
+
container: "mcpServers",
|
|
7851
|
+
shape: "plain"
|
|
7852
|
+
},
|
|
7853
|
+
{
|
|
7854
|
+
id: "claude-desktop",
|
|
7855
|
+
name: "Claude Desktop",
|
|
7856
|
+
scope: "home",
|
|
7857
|
+
file: {
|
|
7858
|
+
win32: { appData: join3("Claude", "claude_desktop_config.json") },
|
|
7859
|
+
darwin: join3("Library", "Application Support", "Claude", "claude_desktop_config.json"),
|
|
7860
|
+
linux: join3(".config", "Claude", "claude_desktop_config.json")
|
|
7861
|
+
},
|
|
7862
|
+
container: "mcpServers",
|
|
7863
|
+
shape: "plain"
|
|
7864
|
+
},
|
|
7865
|
+
{
|
|
7866
|
+
id: "zeroclaw",
|
|
7867
|
+
name: "ZeroClaw",
|
|
7868
|
+
scope: "home",
|
|
7869
|
+
file: join3(".zeroclaw", "config.toml"),
|
|
7870
|
+
container: "mcp.servers",
|
|
7871
|
+
shape: "plain",
|
|
7872
|
+
toml: {
|
|
7873
|
+
header: "[[mcp.servers]]",
|
|
7874
|
+
identity: `name = "${SERVER_KEY}"`,
|
|
7875
|
+
enable: { header: "[mcp]", line: "enabled = true" },
|
|
7876
|
+
block: (launch) => [
|
|
7877
|
+
"[[mcp.servers]]",
|
|
7878
|
+
`name = "${SERVER_KEY}"`,
|
|
7879
|
+
`command = "${launch.command}"`,
|
|
7880
|
+
`args = ${tomlArray(launch.args)}`,
|
|
7881
|
+
tomlEnv(launch)
|
|
7882
|
+
].join(`
|
|
7883
|
+
`)
|
|
7686
7884
|
}
|
|
7885
|
+
},
|
|
7886
|
+
{
|
|
7887
|
+
id: "deepcode",
|
|
7888
|
+
name: "Deep Code",
|
|
7889
|
+
scope: "home",
|
|
7890
|
+
file: join3(".deepcode", "settings.json"),
|
|
7891
|
+
container: "mcpServers",
|
|
7892
|
+
shape: "plain"
|
|
7893
|
+
},
|
|
7894
|
+
{
|
|
7895
|
+
id: "nanobot",
|
|
7896
|
+
name: "nanobot",
|
|
7897
|
+
scope: "home",
|
|
7898
|
+
file: join3(".nanobot", "config.json"),
|
|
7899
|
+
container: "mcpServers",
|
|
7900
|
+
shape: "plain",
|
|
7901
|
+
snippet: (launch) => jsonSnippet(launch, "mcpServers", "plain")
|
|
7902
|
+
},
|
|
7903
|
+
{
|
|
7904
|
+
id: "autohand",
|
|
7905
|
+
name: "Autohand",
|
|
7906
|
+
scope: "home",
|
|
7907
|
+
file: join3(".autohand", "config.json"),
|
|
7908
|
+
container: "mcpServers",
|
|
7909
|
+
shape: "plain",
|
|
7910
|
+
snippet: (launch) => jsonSnippet(launch, "mcpServers", "plain")
|
|
7687
7911
|
}
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
const body = encodeVariant([message, thread, data]);
|
|
7697
|
-
const framed = new Uint8Array(body.length + 4);
|
|
7698
|
-
new DataView(framed.buffer).setUint32(0, body.length, true);
|
|
7699
|
-
framed.set(body, 4);
|
|
7700
|
-
return framed;
|
|
7701
|
-
}
|
|
7702
|
-
var MOST_MESSAGE_BYTES = (8 << 20) + 4;
|
|
7703
|
-
|
|
7704
|
-
class DebuggerStream {
|
|
7705
|
-
pending = new Uint8Array(0);
|
|
7706
|
-
push(chunk) {
|
|
7707
|
-
const joined = new Uint8Array(this.pending.length + chunk.length);
|
|
7708
|
-
joined.set(this.pending, 0);
|
|
7709
|
-
joined.set(chunk, this.pending.length);
|
|
7710
|
-
const out = [];
|
|
7711
|
-
let at = 0;
|
|
7712
|
-
while (joined.length - at >= 4) {
|
|
7713
|
-
const length = new DataView(joined.buffer, joined.byteOffset + at, 4).getUint32(0, true);
|
|
7714
|
-
if (length > MOST_MESSAGE_BYTES) {
|
|
7715
|
-
throw new RangeError(`a message of ${length} bytes, more than the engine sends`);
|
|
7716
|
-
}
|
|
7717
|
-
if (joined.length - at - 4 < length) {
|
|
7718
|
-
break;
|
|
7912
|
+
];
|
|
7913
|
+
var OURS = ["GODOT_PATH", "GDHARNESS_PROJECT"];
|
|
7914
|
+
function environmentFor(launch, held) {
|
|
7915
|
+
const kept = {};
|
|
7916
|
+
if (typeof held === "object" && held !== null && !Array.isArray(held)) {
|
|
7917
|
+
for (const [name, value] of Object.entries(held)) {
|
|
7918
|
+
if (typeof value === "string" && !OURS.includes(name)) {
|
|
7919
|
+
kept[name] = value;
|
|
7719
7920
|
}
|
|
7720
|
-
out.push(readMessage(joined.subarray(at + 4, at + 4 + length)));
|
|
7721
|
-
at += 4 + length;
|
|
7722
7921
|
}
|
|
7723
|
-
this.pending = joined.slice(at);
|
|
7724
|
-
return out;
|
|
7725
7922
|
}
|
|
7923
|
+
return { ...kept, ...launch.env };
|
|
7726
7924
|
}
|
|
7727
|
-
function
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
const [message, thread, data] = value;
|
|
7738
|
-
if (typeof message !== "string" || typeof thread !== "number" || !Array.isArray(data)) {
|
|
7739
|
-
return { unreadable: "a message whose name, thread or data is the wrong type" };
|
|
7925
|
+
function entryFor(shape, launch, held) {
|
|
7926
|
+
const before = typeof held === "object" && held !== null && !Array.isArray(held) ? { ...held } : {};
|
|
7927
|
+
if (shape === "opencode") {
|
|
7928
|
+
return {
|
|
7929
|
+
...before,
|
|
7930
|
+
type: "local",
|
|
7931
|
+
command: [launch.command, ...launch.args],
|
|
7932
|
+
environment: environmentFor(launch, before["environment"]),
|
|
7933
|
+
enabled: true
|
|
7934
|
+
};
|
|
7740
7935
|
}
|
|
7741
|
-
return {
|
|
7936
|
+
return {
|
|
7937
|
+
...before,
|
|
7938
|
+
...shape === "typed" ? { type: "stdio" } : {},
|
|
7939
|
+
command: launch.command,
|
|
7940
|
+
args: [...launch.args],
|
|
7941
|
+
env: environmentFor(launch, before["env"])
|
|
7942
|
+
};
|
|
7742
7943
|
}
|
|
7743
7944
|
|
|
7744
|
-
// src/setup.ts
|
|
7745
|
-
import { dirname as dirname3, join as join5 } from "node:path";
|
|
7746
|
-
import { fileURLToPath } from "node:url";
|
|
7747
|
-
|
|
7748
7945
|
// src/gdscript-source.ts
|
|
7749
7946
|
var DECLARING = new Set(["var", "const", "func", "signal", "enum", "class", "for", "class_name"]);
|
|
7750
7947
|
var NAME = "[\\p{L}_][\\p{L}\\p{N}_]*";
|
|
@@ -7807,6 +8004,23 @@ import { readFileSync as readFileSync2, renameSync, rmSync as rmSync2, writeFile
|
|
|
7807
8004
|
var HELD_FILE_MS = 1000;
|
|
7808
8005
|
var HELD_FILE_RETRY_MS = 10;
|
|
7809
8006
|
var HELD_BY_A_READER = new Set(["EPERM", "EACCES", "EBUSY"]);
|
|
8007
|
+
function readWhole(path) {
|
|
8008
|
+
const until = Date.now() + HELD_FILE_MS;
|
|
8009
|
+
for (;; ) {
|
|
8010
|
+
try {
|
|
8011
|
+
return readFileSync2(path, "utf8");
|
|
8012
|
+
} catch (error) {
|
|
8013
|
+
const code = error.code ?? "";
|
|
8014
|
+
if (code === "ENOENT") {
|
|
8015
|
+
return null;
|
|
8016
|
+
}
|
|
8017
|
+
if (!HELD_BY_A_READER.has(code) || Date.now() >= until) {
|
|
8018
|
+
throw error;
|
|
8019
|
+
}
|
|
8020
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, HELD_FILE_RETRY_MS);
|
|
8021
|
+
}
|
|
8022
|
+
}
|
|
8023
|
+
}
|
|
7810
8024
|
function writeWhole(path, text) {
|
|
7811
8025
|
const partial = `${path}.${process.pid}.partial`;
|
|
7812
8026
|
try {
|
|
@@ -7831,719 +8045,757 @@ function writeWhole(path, text) {
|
|
|
7831
8045
|
}
|
|
7832
8046
|
}
|
|
7833
8047
|
}
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
8048
|
+
function removeWhole(path) {
|
|
8049
|
+
const until = Date.now() + HELD_FILE_MS;
|
|
8050
|
+
for (;; ) {
|
|
8051
|
+
try {
|
|
8052
|
+
rmSync2(path, { force: true });
|
|
8053
|
+
return true;
|
|
8054
|
+
} catch (error) {
|
|
8055
|
+
const code = error.code ?? "";
|
|
8056
|
+
if (!HELD_BY_A_READER.has(code) || Date.now() >= until) {
|
|
8057
|
+
return false;
|
|
8058
|
+
}
|
|
8059
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, HELD_FILE_RETRY_MS);
|
|
8060
|
+
}
|
|
8061
|
+
}
|
|
7838
8062
|
}
|
|
7839
8063
|
|
|
7840
|
-
// src/
|
|
7841
|
-
|
|
7842
|
-
var
|
|
8064
|
+
// src/engine-leaks.ts
|
|
8065
|
+
var REFCOUNTED_HELD = "A RefCounted alive at exit is held by a cycle of references (two holding each other, or one " + "holding a lambda that captures it) or by an Object never freed, rather than by a node left out " + "of the tree; a WeakRef on one side of the cycle, or clearing the reference once done, frees it.";
|
|
8066
|
+
var WALK_STOPPED_SENTENCE = "The engine's shutdown stopped part way through its scripts (godot#117991, fixed in 4.8 by " + "godot#120976), so it reported as leaked at exit what it never got to free, and the report is the " + "engine's rather than the run's. gdharness holds every script loaded from a file past that walk, " + "which keeps it whole, so this one stopped on a script it could not hold, such as one made in code. " + "A leak of the run's own is not told apart in such a run.";
|
|
8067
|
+
var NAME2 = "[\\p{L}_][\\p{L}\\p{N}_]*";
|
|
8068
|
+
var EXPORTED = new RegExp(`@export(?!_(?:group|subgroup|category)\\b)\\w*(?:\\([^)]*\\))?\\s+(?:@${NAME2}(?:\\([^)]*\\))?\\s+)*` + `(?:static\\s+)?var\\s+(${NAME2})\\s*:\\s*(?:Array|Dictionary)\\s*\\[([^\\]]*)\\]`, "gu");
|
|
7843
8069
|
|
|
7844
|
-
// src/
|
|
7845
|
-
|
|
8070
|
+
// src/junit.ts
|
|
8071
|
+
var ESCAPE = String.fromCharCode(27);
|
|
8072
|
+
var LOCATION = `'[^'\\n]*' in \\S+:\\d+`;
|
|
8073
|
+
var IGNORING_CASE = " \\(ignoring case\\)";
|
|
8074
|
+
var PRINTED_ACTUAL = new RegExp(` but was\\n '((?:(?!\\tat ${LOCATION})[\\s\\S])*?)'((?:${ESCAPE}\\[[0-9;]*m)*)(${IGNORING_CASE})?((?:${ESCAPE}\\[[0-9;]*m)*)\\tat (${LOCATION})`, "g");
|
|
8075
|
+
var QUOTED_EQUALITY = new RegExp(`^Expecting(?: error message)?:\\n '([\\s\\S]*)'\\n but was\\n '([\\s\\S]*)'(?:${IGNORING_CASE})?\\n\\tat `);
|
|
8076
|
+
var COLOUR = new RegExp(`${ESCAPE}\\[([0-9;]*)m`, "g");
|
|
8077
|
+
var HOOKS_LEFT = new Map([
|
|
8078
|
+
["before", "before()"],
|
|
8079
|
+
["after", "after()"],
|
|
8080
|
+
["before or after", "before() or after()"]
|
|
8081
|
+
]);
|
|
7846
8082
|
|
|
7847
|
-
//
|
|
7848
|
-
var
|
|
7849
|
-
var
|
|
7850
|
-
var
|
|
7851
|
-
var
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
var
|
|
7861
|
-
var
|
|
7862
|
-
var
|
|
7863
|
-
var
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
var
|
|
7871
|
-
var $isAlias = identity.isAlias;
|
|
7872
|
-
var $isCollection = identity.isCollection;
|
|
7873
|
-
var $isDocument = identity.isDocument;
|
|
7874
|
-
var $isMap = identity.isMap;
|
|
7875
|
-
var $isNode = identity.isNode;
|
|
7876
|
-
var $isPair = identity.isPair;
|
|
7877
|
-
var $isScalar = identity.isScalar;
|
|
7878
|
-
var $isSeq = identity.isSeq;
|
|
7879
|
-
var $Pair = Pair.Pair;
|
|
7880
|
-
var $Scalar = Scalar.Scalar;
|
|
7881
|
-
var $YAMLMap = YAMLMap.YAMLMap;
|
|
7882
|
-
var $YAMLSeq = YAMLSeq.YAMLSeq;
|
|
7883
|
-
var $Lexer = lexer.Lexer;
|
|
7884
|
-
var $LineCounter = lineCounter.LineCounter;
|
|
7885
|
-
var $Parser = parser.Parser;
|
|
7886
|
-
var $parse = publicApi.parse;
|
|
7887
|
-
var $parseAllDocuments = publicApi.parseAllDocuments;
|
|
7888
|
-
var $parseDocument = publicApi.parseDocument;
|
|
7889
|
-
var $stringify = publicApi.stringify;
|
|
7890
|
-
var $visit = visit.visit;
|
|
7891
|
-
var $visitAsync = visit.visitAsync;
|
|
8083
|
+
// src/suite-judge.ts
|
|
8084
|
+
var TIME = String.raw`(?:\d+h )?(?:\d+min )?(?:\d+s )?\d+ms`;
|
|
8085
|
+
var CASE_LINE = new RegExp(String.raw`^\s*(res://.+?\.gd) > (.+?) (STARTED|PASSED|FAILED|FLAKY|SKIPPED|WARNING)(?: \((?:retry \d+|\d+ retries)\))?(?: (${TIME}))?\s*$`);
|
|
8086
|
+
var STATISTICS = new RegExp(String.raw`^Statistics:.*\|\s*([A-Z]+)(?:\s+\(.*?\))?\s+(${TIME})\s*$`);
|
|
8087
|
+
var WINDOWS_EXITS = new Map([
|
|
8088
|
+
[3221225477, "STATUS_ACCESS_VIOLATION"],
|
|
8089
|
+
[3221225495, "STATUS_NO_MEMORY"],
|
|
8090
|
+
[3221225773, "STATUS_COMMITMENT_LIMIT"],
|
|
8091
|
+
[3221225794, "STATUS_DLL_INIT_FAILED"],
|
|
8092
|
+
[3221226505, "STATUS_STACK_BUFFER_OVERRUN"],
|
|
8093
|
+
[3228369022, "a module that could not be found (VcppException)"],
|
|
8094
|
+
[3228369023, "a procedure that could not be found (VcppException)"]
|
|
8095
|
+
]);
|
|
8096
|
+
var MEMORY_EXITS = new Set([3221225495, 3221225773]);
|
|
8097
|
+
var GDUNIT_FAILED = 100;
|
|
8098
|
+
var GDUNIT_ORPHANS = 101;
|
|
8099
|
+
var GDUNIT_EXITS = new Map([
|
|
8100
|
+
[GDUNIT_FAILED, "gdUnit4's code for a case that failed or errored"],
|
|
8101
|
+
[GDUNIT_ORPHANS, "gdUnit4's code for orphan nodes left behind"],
|
|
8102
|
+
[103, "gdUnit4's code for a suite that cannot run headless"],
|
|
8103
|
+
[104, "gdUnit4's code for a Godot version it does not support"],
|
|
8104
|
+
[105, "gdUnit4's code for scripts that did not compile"]
|
|
8105
|
+
]);
|
|
8106
|
+
var GODOT_EXITS = new Set([1, 255]);
|
|
7892
8107
|
|
|
7893
|
-
// src/
|
|
7894
|
-
import {
|
|
7895
|
-
import
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
8108
|
+
// src/windows-ask.ts
|
|
8109
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
8110
|
+
import process3 from "node:process";
|
|
8111
|
+
var SCRIPT = [
|
|
8112
|
+
"[Console]::OutputEncoding = [Text.Encoding]::UTF8",
|
|
8113
|
+
"$in = [Console]::In",
|
|
8114
|
+
"while ($null -ne ($line = $in.ReadLine())) {",
|
|
8115
|
+
' $parts = $line.Split(" ", 2)',
|
|
8116
|
+
" try {",
|
|
8117
|
+
" $asked = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($parts[1]))",
|
|
8118
|
+
" $said = (& ([ScriptBlock]::Create($asked)) | Out-String -Width 1000000)",
|
|
8119
|
+
' $tag = "OK"',
|
|
8120
|
+
" } catch {",
|
|
8121
|
+
" $said = $_.Exception.Message",
|
|
8122
|
+
' $tag = "ERR"',
|
|
8123
|
+
" }",
|
|
8124
|
+
' [Console]::Out.Write($parts[0] + " " + $tag + " " + [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($said)) + "`n")',
|
|
8125
|
+
" [Console]::Out.Flush()",
|
|
8126
|
+
"}"
|
|
8127
|
+
].join(`
|
|
8128
|
+
`);
|
|
8129
|
+
|
|
8130
|
+
class WindowsAskFailure extends Error {
|
|
8131
|
+
constructor(how) {
|
|
8132
|
+
super(`PowerShell ${how}`);
|
|
8133
|
+
}
|
|
8134
|
+
}
|
|
8135
|
+
var helper = null;
|
|
8136
|
+
var buffered = "";
|
|
8137
|
+
var next = 1;
|
|
8138
|
+
var out = null;
|
|
8139
|
+
var queued = [];
|
|
8140
|
+
var held = false;
|
|
8141
|
+
function holding(child, wanted) {
|
|
8142
|
+
if (held === wanted) {
|
|
8143
|
+
return;
|
|
8144
|
+
}
|
|
8145
|
+
held = wanted;
|
|
8146
|
+
const stdout = child.stdout;
|
|
8147
|
+
if (wanted) {
|
|
8148
|
+
stdout.ref?.();
|
|
8149
|
+
} else {
|
|
8150
|
+
stdout.unref?.();
|
|
8151
|
+
}
|
|
8152
|
+
}
|
|
8153
|
+
function running() {
|
|
8154
|
+
if (helper?.exitCode === null && helper.signalCode === null) {
|
|
8155
|
+
return helper;
|
|
8156
|
+
}
|
|
8157
|
+
const child = spawnHidden("powershell.exe", [
|
|
8158
|
+
"-NoProfile",
|
|
8159
|
+
"-NonInteractive",
|
|
8160
|
+
"-ExecutionPolicy",
|
|
8161
|
+
"Bypass",
|
|
8162
|
+
"-EncodedCommand",
|
|
8163
|
+
Buffer.from(SCRIPT, "utf16le").toString("base64")
|
|
8164
|
+
], { cwd: tmpdir2() });
|
|
8165
|
+
buffered = "";
|
|
8166
|
+
child.stdout.setEncoding("utf8");
|
|
8167
|
+
child.stdout.on("data", (chunk) => {
|
|
8168
|
+
buffered += chunk;
|
|
8169
|
+
for (let end = buffered.indexOf(`
|
|
8170
|
+
`);end !== -1; end = buffered.indexOf(`
|
|
8171
|
+
`)) {
|
|
8172
|
+
answered(buffered.slice(0, end).trim());
|
|
8173
|
+
buffered = buffered.slice(end + 1);
|
|
8174
|
+
}
|
|
8175
|
+
});
|
|
8176
|
+
child.stderr.resume();
|
|
8177
|
+
child.stdin.on("error", () => {});
|
|
8178
|
+
const gone = () => {
|
|
8179
|
+
if (helper !== child) {
|
|
8180
|
+
return;
|
|
8181
|
+
}
|
|
8182
|
+
helper = null;
|
|
8183
|
+
if (out !== null) {
|
|
8184
|
+
clearTimeout(out.timer);
|
|
8185
|
+
out.question.reject(new WindowsAskFailure("exited before it answered"));
|
|
8186
|
+
out = null;
|
|
8187
|
+
}
|
|
8188
|
+
sendNext();
|
|
8189
|
+
};
|
|
8190
|
+
child.once("exit", gone);
|
|
8191
|
+
child.once("error", gone);
|
|
8192
|
+
child.unref();
|
|
8193
|
+
child.stdin.unref?.();
|
|
8194
|
+
child.stderr.unref?.();
|
|
8195
|
+
held = true;
|
|
8196
|
+
holding(child, false);
|
|
8197
|
+
helper = child;
|
|
8198
|
+
return child;
|
|
8199
|
+
}
|
|
8200
|
+
function answered(line) {
|
|
8201
|
+
const [id, tag, body] = line.split(" ");
|
|
8202
|
+
if (out === null || out.id !== Number(id)) {
|
|
8203
|
+
return;
|
|
8204
|
+
}
|
|
8205
|
+
const { question, timer } = out;
|
|
8206
|
+
clearTimeout(timer);
|
|
8207
|
+
out = null;
|
|
8208
|
+
const said = Buffer.from(body ?? "", "base64").toString("utf8");
|
|
8209
|
+
if (tag === "OK") {
|
|
8210
|
+
question.resolve(said);
|
|
8211
|
+
} else {
|
|
8212
|
+
question.reject(new WindowsAskFailure(`refused the question: ${said.trim() || "no reason given"}`));
|
|
8213
|
+
}
|
|
8214
|
+
sendNext();
|
|
8215
|
+
}
|
|
8216
|
+
function sendNext() {
|
|
8217
|
+
const question = queued.shift();
|
|
8218
|
+
if (question === undefined) {
|
|
8219
|
+
if (helper !== null) {
|
|
8220
|
+
holding(helper, false);
|
|
8221
|
+
}
|
|
8222
|
+
return;
|
|
8223
|
+
}
|
|
8224
|
+
const child = running();
|
|
8225
|
+
holding(child, true);
|
|
8226
|
+
const id = next;
|
|
8227
|
+
next += 1;
|
|
8228
|
+
const timer = setTimeout(() => {
|
|
8229
|
+
if (out?.id !== id) {
|
|
8230
|
+
return;
|
|
8231
|
+
}
|
|
8232
|
+
out = null;
|
|
8233
|
+
question.reject(new WindowsAskFailure(`did not answer within ${question.withinMs}ms`));
|
|
8234
|
+
if (helper === child) {
|
|
8235
|
+
helper = null;
|
|
8236
|
+
}
|
|
8237
|
+
child.kill();
|
|
8238
|
+
sendNext();
|
|
8239
|
+
}, question.withinMs);
|
|
8240
|
+
out = { id, question, timer };
|
|
8241
|
+
child.stdin.write(`${id} ${Buffer.from(question.script, "utf8").toString("base64")}
|
|
8242
|
+
`);
|
|
8243
|
+
}
|
|
8244
|
+
function askWindows(script, withinMs) {
|
|
8245
|
+
if (process3.platform !== "win32") {
|
|
8246
|
+
return Promise.reject(new WindowsAskFailure("is asked only on Windows"));
|
|
8247
|
+
}
|
|
8248
|
+
return new Promise((resolve, reject) => {
|
|
8249
|
+
queued.push({ script, withinMs, resolve, reject });
|
|
8250
|
+
if (out === null) {
|
|
8251
|
+
sendNext();
|
|
8252
|
+
}
|
|
8253
|
+
});
|
|
8254
|
+
}
|
|
8255
|
+
|
|
8256
|
+
// src/engine-launch.ts
|
|
8257
|
+
var CONTROL_SEQUENCE = new RegExp(`${String.fromCharCode(27)}\\[[0-9;?]*[A-Za-z]`, "g");
|
|
8258
|
+
var MEMORY_KEPT = 4 * 1024 ** 3;
|
|
8259
|
+
var MEMORY_PER_ENGINE = 1.5 * 1024 ** 3;
|
|
8260
|
+
|
|
8261
|
+
// src/process-children.ts
|
|
8262
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
8263
|
+
import { basename as basename3 } from "node:path";
|
|
8264
|
+
async function startTimesOf(pids) {
|
|
8265
|
+
const began = new Map;
|
|
8266
|
+
if (pids.length === 0) {
|
|
8267
|
+
return began;
|
|
8268
|
+
}
|
|
8269
|
+
try {
|
|
8270
|
+
if (process.platform === "win32") {
|
|
8271
|
+
const filter = pids.map((pid) => `ProcessId=${pid}`).join(" OR ");
|
|
8272
|
+
const said = await askWindows(`Get-CimInstance Win32_Process -Filter "${filter}" | ForEach-Object { "$($_.ProcessId) $(([DateTimeOffset]$_.CreationDate).ToUnixTimeMilliseconds())" }`, ASK_TIMEOUT_MS);
|
|
8273
|
+
for (const line of said.split(`
|
|
8274
|
+
`)) {
|
|
8275
|
+
const found = /^\s*(\d+)\s+(\d+)\s*$/.exec(line);
|
|
8276
|
+
if (found?.[1] !== undefined && found[2] !== undefined) {
|
|
8277
|
+
began.set(Number(found[1]), Number(found[2]));
|
|
8278
|
+
}
|
|
8279
|
+
}
|
|
8280
|
+
return began;
|
|
8281
|
+
}
|
|
8282
|
+
if (process.platform === "linux") {
|
|
8283
|
+
return await linuxStartTimes(pids);
|
|
8284
|
+
}
|
|
8285
|
+
const said = await printedBy("ps", ["-p", pids.join(","), "-o", "pid=,lstart="], {
|
|
8286
|
+
...process.env,
|
|
8287
|
+
LC_ALL: "C"
|
|
8288
|
+
});
|
|
8289
|
+
for (const line of said.split(`
|
|
8290
|
+
`)) {
|
|
8291
|
+
const found = /^\s*(\d+)\s+(.+)$/.exec(line);
|
|
8292
|
+
const at = Date.parse(found?.[2]?.trim() ?? "");
|
|
8293
|
+
if (found?.[1] !== undefined && !Number.isNaN(at)) {
|
|
8294
|
+
began.set(Number(found[1]), at);
|
|
8295
|
+
}
|
|
8296
|
+
}
|
|
8297
|
+
} catch {}
|
|
8298
|
+
return began;
|
|
8299
|
+
}
|
|
8300
|
+
async function linuxStartTimes(pids) {
|
|
8301
|
+
const began = new Map;
|
|
8302
|
+
const hertz = await ticksPerSecond();
|
|
8303
|
+
let booted;
|
|
8304
|
+
try {
|
|
8305
|
+
booted = Number(/^btime\s+(\d+)$/m.exec(readFileSync3("/proc/stat", "utf8"))?.[1] ?? Number.NaN) * 1000;
|
|
8306
|
+
} catch {
|
|
8307
|
+
return began;
|
|
8308
|
+
}
|
|
8309
|
+
if (hertz === null || Number.isNaN(booted)) {
|
|
8310
|
+
return began;
|
|
8311
|
+
}
|
|
8312
|
+
for (const pid of pids) {
|
|
8313
|
+
let stat;
|
|
7900
8314
|
try {
|
|
7901
|
-
|
|
8315
|
+
stat = readFileSync3(`/proc/${String(pid)}/stat`, "utf8");
|
|
7902
8316
|
} catch {
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
at = parent;
|
|
8317
|
+
continue;
|
|
8318
|
+
}
|
|
8319
|
+
const ticks = Number(stat.slice(stat.lastIndexOf(")") + 2).split(" ")[19]);
|
|
8320
|
+
if (Number.isInteger(ticks) && ticks >= 0) {
|
|
8321
|
+
began.set(pid, booted + Math.round(ticks * 1000 / hertz));
|
|
7909
8322
|
}
|
|
7910
8323
|
}
|
|
8324
|
+
return began;
|
|
7911
8325
|
}
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
var SERVER_KEY = "gdharness";
|
|
7915
|
-
function tomlArray(values) {
|
|
7916
|
-
return `[${values.map((value) => `"${value}"`).join(", ")}]`;
|
|
8326
|
+
async function linuxStartEarliest() {
|
|
8327
|
+
return 1000 + Math.ceil(1000 / (await ticksPerSecond() ?? 100));
|
|
7917
8328
|
}
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
8329
|
+
var ticksAnswered;
|
|
8330
|
+
async function ticksPerSecond() {
|
|
8331
|
+
if (ticksAnswered !== undefined) {
|
|
8332
|
+
return ticksAnswered;
|
|
8333
|
+
}
|
|
8334
|
+
try {
|
|
8335
|
+
const hertz = Number((await runHidden("getconf", ["CLK_TCK"], { timeout: ASK_TIMEOUT_MS })).stdout.trim());
|
|
8336
|
+
if (Number.isInteger(hertz) && hertz > 0) {
|
|
8337
|
+
ticksAnswered = hertz;
|
|
8338
|
+
return hertz;
|
|
8339
|
+
}
|
|
8340
|
+
} catch {}
|
|
8341
|
+
return null;
|
|
7921
8342
|
}
|
|
7922
|
-
function
|
|
7923
|
-
return
|
|
8343
|
+
function printedBy(command, args, env) {
|
|
8344
|
+
return runHidden(command, args, { timeout: ASK_TIMEOUT_MS, env }).then(({ stdout }) => stdout, (error) => {
|
|
8345
|
+
const printed = error.stdout;
|
|
8346
|
+
return typeof printed === "string" ? printed : "";
|
|
8347
|
+
});
|
|
7924
8348
|
}
|
|
7925
|
-
var
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
scope: "project",
|
|
7962
|
-
file: ".mcp.json",
|
|
7963
|
-
container: "mcpServers",
|
|
7964
|
-
shape: "plain",
|
|
7965
|
-
home: ".commandcode"
|
|
7966
|
-
},
|
|
7967
|
-
{
|
|
7968
|
-
id: "cursor",
|
|
7969
|
-
name: "Cursor",
|
|
7970
|
-
scope: "project",
|
|
7971
|
-
file: join3(".cursor", "mcp.json"),
|
|
7972
|
-
container: "mcpServers",
|
|
7973
|
-
shape: "plain",
|
|
7974
|
-
home: ".cursor",
|
|
7975
|
-
skills: { dir: join3(".cursor", "skills"), shared: true },
|
|
7976
|
-
manual: "Cursor asks before each tool call by default, and the server can be toggled off."
|
|
7977
|
-
},
|
|
7978
|
-
{
|
|
7979
|
-
id: "vscode",
|
|
7980
|
-
name: "VS Code",
|
|
7981
|
-
scope: "project",
|
|
7982
|
-
file: join3(".vscode", "mcp.json"),
|
|
7983
|
-
container: "servers",
|
|
7984
|
-
shape: "typed",
|
|
7985
|
-
home: ".vscode",
|
|
7986
|
-
skills: { dir: join3(".github", "skills"), shared: true },
|
|
7987
|
-
manual: "VS Code asks you to trust a server the first time it starts one."
|
|
7988
|
-
},
|
|
7989
|
-
{
|
|
7990
|
-
id: "opencode",
|
|
7991
|
-
name: "opencode",
|
|
7992
|
-
scope: "project",
|
|
7993
|
-
file: "opencode.json",
|
|
7994
|
-
container: "mcp",
|
|
7995
|
-
shape: "opencode",
|
|
7996
|
-
home: join3(".config", "opencode"),
|
|
7997
|
-
marker: ".opencode",
|
|
7998
|
-
skills: { dir: join3(".opencode", "skills"), shared: true }
|
|
7999
|
-
},
|
|
8000
|
-
{
|
|
8001
|
-
id: "junie",
|
|
8002
|
-
name: "Junie",
|
|
8003
|
-
scope: "project",
|
|
8004
|
-
file: join3(".junie", "mcp", "mcp.json"),
|
|
8005
|
-
container: "mcpServers",
|
|
8006
|
-
shape: "plain",
|
|
8007
|
-
home: ".junie",
|
|
8008
|
-
skills: { dir: join3(".junie", "skills"), shared: true }
|
|
8009
|
-
},
|
|
8010
|
-
{
|
|
8011
|
-
id: "kiro",
|
|
8012
|
-
name: "Kiro",
|
|
8013
|
-
scope: "project",
|
|
8014
|
-
file: join3(".kiro", "settings", "mcp.json"),
|
|
8015
|
-
container: "mcpServers",
|
|
8016
|
-
shape: "plain",
|
|
8017
|
-
home: ".kiro",
|
|
8018
|
-
skills: { dir: join3(".kiro", "skills"), shared: false }
|
|
8019
|
-
},
|
|
8020
|
-
{
|
|
8021
|
-
id: "gemini",
|
|
8022
|
-
name: "Gemini CLI",
|
|
8023
|
-
scope: "project",
|
|
8024
|
-
file: join3(".gemini", "settings.json"),
|
|
8025
|
-
container: "mcpServers",
|
|
8026
|
-
shape: "plain",
|
|
8027
|
-
home: ".gemini",
|
|
8028
|
-
skills: { dir: join3(".gemini", "skills"), shared: true }
|
|
8029
|
-
},
|
|
8030
|
-
{
|
|
8031
|
-
id: "roo",
|
|
8032
|
-
name: "Roo Code",
|
|
8033
|
-
scope: "project",
|
|
8034
|
-
file: join3(".roo", "mcp.json"),
|
|
8035
|
-
container: "mcpServers",
|
|
8036
|
-
shape: "plain"
|
|
8037
|
-
},
|
|
8038
|
-
{
|
|
8039
|
-
id: "kilo",
|
|
8040
|
-
name: "Kilo Code",
|
|
8041
|
-
scope: "project",
|
|
8042
|
-
file: join3(".kilocode", "mcp.json"),
|
|
8043
|
-
container: "mcpServers",
|
|
8044
|
-
shape: "plain"
|
|
8045
|
-
},
|
|
8046
|
-
{
|
|
8047
|
-
id: "amazon-q",
|
|
8048
|
-
name: "Amazon Q Developer CLI",
|
|
8049
|
-
scope: "project",
|
|
8050
|
-
file: join3(".amazonq", "mcp.json"),
|
|
8051
|
-
container: "mcpServers",
|
|
8052
|
-
shape: "plain",
|
|
8053
|
-
home: join3(".aws", "amazonq")
|
|
8054
|
-
},
|
|
8055
|
-
{
|
|
8056
|
-
id: "zed",
|
|
8057
|
-
name: "Zed",
|
|
8058
|
-
scope: "project",
|
|
8059
|
-
file: join3(".zed", "settings.json"),
|
|
8060
|
-
container: "context_servers",
|
|
8061
|
-
shape: "plain"
|
|
8062
|
-
},
|
|
8063
|
-
{
|
|
8064
|
-
id: "amp",
|
|
8065
|
-
name: "Amp",
|
|
8066
|
-
scope: "project",
|
|
8067
|
-
file: join3(".amp", "settings.json"),
|
|
8068
|
-
container: "amp.mcpServers",
|
|
8069
|
-
shape: "plain",
|
|
8070
|
-
home: join3(".config", "amp")
|
|
8071
|
-
},
|
|
8072
|
-
{
|
|
8073
|
-
id: "warp",
|
|
8074
|
-
name: "Warp",
|
|
8075
|
-
scope: "project",
|
|
8076
|
-
file: join3(".warp", ".mcp.json"),
|
|
8077
|
-
container: "mcpServers",
|
|
8078
|
-
shape: "plain",
|
|
8079
|
-
home: ".warp",
|
|
8080
|
-
manual: "Warp starts a project server only once you toggle it on, on its MCP servers page."
|
|
8081
|
-
},
|
|
8082
|
-
{
|
|
8083
|
-
id: "trae",
|
|
8084
|
-
name: "Trae",
|
|
8085
|
-
scope: "project",
|
|
8086
|
-
file: join3(".trae", "mcp.json"),
|
|
8087
|
-
container: "mcpServers",
|
|
8088
|
-
shape: "plain",
|
|
8089
|
-
home: ".trae"
|
|
8090
|
-
},
|
|
8091
|
-
{
|
|
8092
|
-
id: "factory",
|
|
8093
|
-
name: "Factory Droid",
|
|
8094
|
-
scope: "project",
|
|
8095
|
-
file: join3(".factory", "mcp.json"),
|
|
8096
|
-
container: "mcpServers",
|
|
8097
|
-
shape: "typed",
|
|
8098
|
-
home: ".factory"
|
|
8099
|
-
},
|
|
8100
|
-
{
|
|
8101
|
-
id: "tabnine",
|
|
8102
|
-
name: "Tabnine",
|
|
8103
|
-
scope: "project",
|
|
8104
|
-
file: join3(".tabnine", "mcp_servers.json"),
|
|
8105
|
-
container: "mcpServers",
|
|
8106
|
-
shape: "plain",
|
|
8107
|
-
home: ".tabnine"
|
|
8108
|
-
},
|
|
8109
|
-
{
|
|
8110
|
-
id: "firebender",
|
|
8111
|
-
name: "Firebender",
|
|
8112
|
-
scope: "project",
|
|
8113
|
-
file: "firebender.json",
|
|
8114
|
-
container: "mcpServers",
|
|
8115
|
-
shape: "plain"
|
|
8116
|
-
},
|
|
8117
|
-
{
|
|
8118
|
-
id: "pi",
|
|
8119
|
-
name: "pi",
|
|
8120
|
-
scope: "project",
|
|
8121
|
-
file: join3(".pi", "mcp.json"),
|
|
8122
|
-
container: "mcpServers",
|
|
8123
|
-
shape: "plain",
|
|
8124
|
-
home: ".pi"
|
|
8125
|
-
},
|
|
8126
|
-
{
|
|
8127
|
-
id: "mistral-vibe",
|
|
8128
|
-
name: "Mistral Vibe",
|
|
8129
|
-
scope: "project",
|
|
8130
|
-
file: join3(".vibe", "config.toml"),
|
|
8131
|
-
container: "mcp_servers",
|
|
8132
|
-
shape: "plain",
|
|
8133
|
-
toml: {
|
|
8134
|
-
header: "[[mcp_servers]]",
|
|
8135
|
-
identity: `name = "${SERVER_KEY}"`,
|
|
8136
|
-
block: (launch) => [
|
|
8137
|
-
"[[mcp_servers]]",
|
|
8138
|
-
`name = "${SERVER_KEY}"`,
|
|
8139
|
-
'transport = "stdio"',
|
|
8140
|
-
`command = "${launch.command}"`,
|
|
8141
|
-
`args = ${tomlArray(launch.args)}`,
|
|
8142
|
-
tomlEnv(launch)
|
|
8143
|
-
].join(`
|
|
8144
|
-
`)
|
|
8145
|
-
}
|
|
8146
|
-
},
|
|
8147
|
-
{
|
|
8148
|
-
id: "vtcode",
|
|
8149
|
-
name: "VT Code",
|
|
8150
|
-
scope: "project",
|
|
8151
|
-
file: "vtcode.toml",
|
|
8152
|
-
container: "mcp.providers",
|
|
8153
|
-
shape: "plain",
|
|
8154
|
-
marker: ".vtcode",
|
|
8155
|
-
toml: {
|
|
8156
|
-
header: "[[mcp.providers]]",
|
|
8157
|
-
identity: `name = "${SERVER_KEY}"`,
|
|
8158
|
-
enable: { header: "[mcp]", line: "enabled = true" },
|
|
8159
|
-
block: (launch) => [
|
|
8160
|
-
"[[mcp.providers]]",
|
|
8161
|
-
`name = "${SERVER_KEY}"`,
|
|
8162
|
-
"enabled = true",
|
|
8163
|
-
`command = "${launch.command}"`,
|
|
8164
|
-
`args = ${tomlArray(launch.args)}`,
|
|
8165
|
-
tomlEnv(launch)
|
|
8166
|
-
].join(`
|
|
8167
|
-
`)
|
|
8349
|
+
var ASK_TIMEOUT_MS = 15000;
|
|
8350
|
+
var ONE_SHOT_OPTIONS = [
|
|
8351
|
+
"--import",
|
|
8352
|
+
"--quit",
|
|
8353
|
+
"--quit-after",
|
|
8354
|
+
"--export-release",
|
|
8355
|
+
"--export-debug",
|
|
8356
|
+
"--export-pack",
|
|
8357
|
+
"--export-patch",
|
|
8358
|
+
"--doctool",
|
|
8359
|
+
"--gdscript-docs",
|
|
8360
|
+
"--script",
|
|
8361
|
+
"-s",
|
|
8362
|
+
"--check-only",
|
|
8363
|
+
"--build-solutions",
|
|
8364
|
+
"--dump-gdextension-interface",
|
|
8365
|
+
"--dump-extension-api",
|
|
8366
|
+
"--dump-extension-api-with-docs",
|
|
8367
|
+
"--validate-extension-api",
|
|
8368
|
+
"--convert-3to4",
|
|
8369
|
+
"--validate-conversion-3to4"
|
|
8370
|
+
];
|
|
8371
|
+
function readCommandLine(command) {
|
|
8372
|
+
const all = commandWords(command);
|
|
8373
|
+
const separator = all.findIndex((word) => word === "--" || word === "++");
|
|
8374
|
+
const words = separator === -1 ? all : all.slice(0, separator);
|
|
8375
|
+
const executable = words[0] === undefined ? "" : basename3(words[0].replaceAll("\\", "/"));
|
|
8376
|
+
const at = words.indexOf("--path");
|
|
8377
|
+
let projectPath = null;
|
|
8378
|
+
if (at !== -1 && at + 1 < words.length) {
|
|
8379
|
+
const taken = [];
|
|
8380
|
+
for (const word of words.slice(at + 1)) {
|
|
8381
|
+
if (taken.length > 0 && (word.startsWith("-") || /^[a-z]+:\/\//.test(word))) {
|
|
8382
|
+
break;
|
|
8383
|
+
}
|
|
8384
|
+
taken.push(word);
|
|
8168
8385
|
}
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8386
|
+
projectPath = taken.join(" ").replaceAll("%20", " ");
|
|
8387
|
+
}
|
|
8388
|
+
return {
|
|
8389
|
+
executable,
|
|
8390
|
+
projectPath,
|
|
8391
|
+
editor: words.some((word) => word === "-e" || word === "--editor"),
|
|
8392
|
+
oneShot: words.find((word) => ONE_SHOT_OPTIONS.includes(word)) ?? null
|
|
8393
|
+
};
|
|
8394
|
+
}
|
|
8395
|
+
function commandWords(command) {
|
|
8396
|
+
const words = [];
|
|
8397
|
+
let word = "";
|
|
8398
|
+
let quoted = false;
|
|
8399
|
+
let started = false;
|
|
8400
|
+
for (const char of command) {
|
|
8401
|
+
if (char === '"') {
|
|
8402
|
+
quoted = !quoted;
|
|
8403
|
+
started = true;
|
|
8404
|
+
} else if (!quoted && /\s/.test(char)) {
|
|
8405
|
+
if (started) {
|
|
8406
|
+
words.push(word);
|
|
8407
|
+
word = "";
|
|
8408
|
+
started = false;
|
|
8409
|
+
}
|
|
8410
|
+
} else {
|
|
8411
|
+
word += char;
|
|
8412
|
+
started = true;
|
|
8180
8413
|
}
|
|
8181
|
-
}
|
|
8182
|
-
{
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
`command = "${launch.command}"`,
|
|
8195
|
-
`args = ${tomlArray(launch.args)}`,
|
|
8196
|
-
tomlEnv(launch)
|
|
8197
|
-
].join(`
|
|
8198
|
-
`)
|
|
8414
|
+
}
|
|
8415
|
+
if (started) {
|
|
8416
|
+
words.push(word);
|
|
8417
|
+
}
|
|
8418
|
+
return words;
|
|
8419
|
+
}
|
|
8420
|
+
|
|
8421
|
+
// src/engine-slots.ts
|
|
8422
|
+
function holderOf(content) {
|
|
8423
|
+
try {
|
|
8424
|
+
const parsed = JSON.parse(content);
|
|
8425
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
8426
|
+
return null;
|
|
8199
8427
|
}
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
name: "Cline",
|
|
8204
|
-
scope: "home",
|
|
8205
|
-
file: join3(".cline", "data", "settings", "cline_mcp_settings.json"),
|
|
8206
|
-
container: "mcpServers",
|
|
8207
|
-
shape: "plain",
|
|
8208
|
-
marker: ".cline",
|
|
8209
|
-
skills: { dir: join3(".cline", "skills"), shared: false }
|
|
8210
|
-
},
|
|
8211
|
-
{
|
|
8212
|
-
id: "goose",
|
|
8213
|
-
name: "Goose",
|
|
8214
|
-
scope: "home",
|
|
8215
|
-
file: {
|
|
8216
|
-
win32: { appData: join3("Block", "goose", "config", "config.yaml") },
|
|
8217
|
-
darwin: join3(".config", "goose", "config.yaml"),
|
|
8218
|
-
linux: join3(".config", "goose", "config.yaml")
|
|
8219
|
-
},
|
|
8220
|
-
container: "extensions",
|
|
8221
|
-
shape: "plain",
|
|
8222
|
-
yaml: {
|
|
8223
|
-
path: ["extensions", SERVER_KEY],
|
|
8224
|
-
entry: (launch) => ({
|
|
8225
|
-
name: SERVER_KEY,
|
|
8226
|
-
type: "stdio",
|
|
8227
|
-
enabled: true,
|
|
8228
|
-
cmd: launch.command,
|
|
8229
|
-
args: [...launch.args],
|
|
8230
|
-
envs: { ...launch.env },
|
|
8231
|
-
timeout: 300
|
|
8232
|
-
})
|
|
8428
|
+
const { pid, started, by } = parsed;
|
|
8429
|
+
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0 || typeof started !== "number") {
|
|
8430
|
+
return null;
|
|
8233
8431
|
}
|
|
8234
|
-
|
|
8235
|
-
{
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
|
|
8253
|
-
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
args: [...launch.args],
|
|
8257
|
-
env: { ...launch.env },
|
|
8258
|
-
enabled: true
|
|
8259
|
-
})
|
|
8432
|
+
return typeof by === "string" && by !== "" ? { pid, started, by } : { pid, started };
|
|
8433
|
+
} catch {
|
|
8434
|
+
return null;
|
|
8435
|
+
}
|
|
8436
|
+
}
|
|
8437
|
+
async function ownStart() {
|
|
8438
|
+
const said = (await startTimesOf([process4.pid])).get(process4.pid);
|
|
8439
|
+
return said ?? Math.round(Date.now() - process4.uptime() * 1000);
|
|
8440
|
+
}
|
|
8441
|
+
function handSlot(lock, from, to) {
|
|
8442
|
+
let content;
|
|
8443
|
+
try {
|
|
8444
|
+
content = readWhole(lock);
|
|
8445
|
+
} catch {
|
|
8446
|
+
return false;
|
|
8447
|
+
}
|
|
8448
|
+
return content !== null && holderOf(content)?.pid === from && writeWhole(lock, JSON.stringify(to));
|
|
8449
|
+
}
|
|
8450
|
+
function giveBackSlot(lock, pid) {
|
|
8451
|
+
try {
|
|
8452
|
+
if (holderOf(readFileSync4(lock, "utf8"))?.pid === pid) {
|
|
8453
|
+
removeWhole(lock);
|
|
8260
8454
|
}
|
|
8261
|
-
}
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
name: "ZeroClaw",
|
|
8285
|
-
scope: "home",
|
|
8286
|
-
file: join3(".zeroclaw", "config.toml"),
|
|
8287
|
-
container: "mcp.servers",
|
|
8288
|
-
shape: "plain",
|
|
8289
|
-
toml: {
|
|
8290
|
-
header: "[[mcp.servers]]",
|
|
8291
|
-
identity: `name = "${SERVER_KEY}"`,
|
|
8292
|
-
enable: { header: "[mcp]", line: "enabled = true" },
|
|
8293
|
-
block: (launch) => [
|
|
8294
|
-
"[[mcp.servers]]",
|
|
8295
|
-
`name = "${SERVER_KEY}"`,
|
|
8296
|
-
`command = "${launch.command}"`,
|
|
8297
|
-
`args = ${tomlArray(launch.args)}`,
|
|
8298
|
-
tomlEnv(launch)
|
|
8299
|
-
].join(`
|
|
8300
|
-
`)
|
|
8455
|
+
} catch {}
|
|
8456
|
+
}
|
|
8457
|
+
|
|
8458
|
+
// src/error-mode.ts
|
|
8459
|
+
import process5 from "node:process";
|
|
8460
|
+
var NO_FAULT_ERROR_BOX = 2;
|
|
8461
|
+
var cleared = process5.platform !== "win32";
|
|
8462
|
+
async function letWindowsReportCrashes() {
|
|
8463
|
+
if (cleared || !("bun" in process5.versions)) {
|
|
8464
|
+
return;
|
|
8465
|
+
}
|
|
8466
|
+
try {
|
|
8467
|
+
const { dlopen, FFIType } = await import("bun:ffi");
|
|
8468
|
+
const kernel32 = dlopen("kernel32.dll", {
|
|
8469
|
+
GetErrorMode: { args: [], returns: FFIType.u32 },
|
|
8470
|
+
SetErrorMode: { args: [FFIType.u32], returns: FFIType.u32 }
|
|
8471
|
+
});
|
|
8472
|
+
try {
|
|
8473
|
+
const mode = kernel32.symbols.GetErrorMode();
|
|
8474
|
+
kernel32.symbols.SetErrorMode(mode & ~NO_FAULT_ERROR_BOX);
|
|
8475
|
+
cleared = true;
|
|
8476
|
+
} finally {
|
|
8477
|
+
kernel32.close();
|
|
8301
8478
|
}
|
|
8302
|
-
}
|
|
8303
|
-
|
|
8304
|
-
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
|
|
8315
|
-
|
|
8316
|
-
|
|
8317
|
-
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
|
|
8479
|
+
} catch {}
|
|
8480
|
+
}
|
|
8481
|
+
function crashesReported() {
|
|
8482
|
+
return cleared;
|
|
8483
|
+
}
|
|
8484
|
+
|
|
8485
|
+
// src/game-debugger.ts
|
|
8486
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
8487
|
+
import { createServer } from "node:net";
|
|
8488
|
+
import { join as join6 } from "node:path";
|
|
8489
|
+
|
|
8490
|
+
// src/godot-variant.ts
|
|
8491
|
+
var NIL = 0;
|
|
8492
|
+
var BOOL = 1;
|
|
8493
|
+
var INT = 2;
|
|
8494
|
+
var FLOAT = 3;
|
|
8495
|
+
var STRING = 4;
|
|
8496
|
+
var ARRAY = 28;
|
|
8497
|
+
var FLAG_64 = 1 << 16;
|
|
8498
|
+
var MATH = {
|
|
8499
|
+
5: { name: "Vector2", count: 2 },
|
|
8500
|
+
6: { name: "Vector2i", count: 2, ints: true },
|
|
8501
|
+
7: { name: "Rect2", count: 4 },
|
|
8502
|
+
8: { name: "Rect2i", count: 4, ints: true },
|
|
8503
|
+
9: { name: "Vector3", count: 3 },
|
|
8504
|
+
10: { name: "Vector3i", count: 3, ints: true },
|
|
8505
|
+
11: { name: "Transform2D", count: 6 },
|
|
8506
|
+
12: { name: "Vector4", count: 4 },
|
|
8507
|
+
13: { name: "Vector4i", count: 4, ints: true },
|
|
8508
|
+
14: { name: "Plane", count: 4 },
|
|
8509
|
+
15: { name: "Quaternion", count: 4 },
|
|
8510
|
+
16: { name: "AABB", count: 6 },
|
|
8511
|
+
17: { name: "Basis", count: 9 },
|
|
8512
|
+
18: { name: "Transform3D", count: 12 },
|
|
8513
|
+
19: { name: "Projection", count: 16 }
|
|
8514
|
+
};
|
|
8515
|
+
var PACKED_VECTORS = { 35: 2, 36: 3, 38: 4 };
|
|
8516
|
+
|
|
8517
|
+
class Reader {
|
|
8518
|
+
offset = 0;
|
|
8519
|
+
view;
|
|
8520
|
+
constructor(view) {
|
|
8521
|
+
this.view = view;
|
|
8328
8522
|
}
|
|
8329
|
-
|
|
8330
|
-
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
if (typeof value === "string" && !OURS.includes(name)) {
|
|
8336
|
-
kept[name] = value;
|
|
8337
|
-
}
|
|
8523
|
+
get remaining() {
|
|
8524
|
+
return this.view.byteLength - this.offset;
|
|
8525
|
+
}
|
|
8526
|
+
need(bytes) {
|
|
8527
|
+
if (bytes < 0 || bytes > this.remaining) {
|
|
8528
|
+
throw new RangeError(`a value runs past the end of its message (${bytes} bytes wanted, ${this.remaining} left)`);
|
|
8338
8529
|
}
|
|
8339
8530
|
}
|
|
8340
|
-
|
|
8531
|
+
u32() {
|
|
8532
|
+
this.need(4);
|
|
8533
|
+
const value = this.view.getUint32(this.offset, true);
|
|
8534
|
+
this.offset += 4;
|
|
8535
|
+
return value;
|
|
8536
|
+
}
|
|
8537
|
+
i32() {
|
|
8538
|
+
this.need(4);
|
|
8539
|
+
const value = this.view.getInt32(this.offset, true);
|
|
8540
|
+
this.offset += 4;
|
|
8541
|
+
return value;
|
|
8542
|
+
}
|
|
8543
|
+
i64() {
|
|
8544
|
+
this.need(8);
|
|
8545
|
+
const value = Number(this.view.getBigInt64(this.offset, true));
|
|
8546
|
+
this.offset += 8;
|
|
8547
|
+
return value;
|
|
8548
|
+
}
|
|
8549
|
+
u64() {
|
|
8550
|
+
this.need(8);
|
|
8551
|
+
const value = Number(this.view.getBigUint64(this.offset, true));
|
|
8552
|
+
this.offset += 8;
|
|
8553
|
+
return value;
|
|
8554
|
+
}
|
|
8555
|
+
f32() {
|
|
8556
|
+
this.need(4);
|
|
8557
|
+
const value = this.view.getFloat32(this.offset, true);
|
|
8558
|
+
this.offset += 4;
|
|
8559
|
+
return value;
|
|
8560
|
+
}
|
|
8561
|
+
f64() {
|
|
8562
|
+
this.need(8);
|
|
8563
|
+
const value = this.view.getFloat64(this.offset, true);
|
|
8564
|
+
this.offset += 8;
|
|
8565
|
+
return value;
|
|
8566
|
+
}
|
|
8567
|
+
real(wide) {
|
|
8568
|
+
return wide ? this.f64() : this.f32();
|
|
8569
|
+
}
|
|
8570
|
+
bytes(count) {
|
|
8571
|
+
this.need(count);
|
|
8572
|
+
const out = new Uint8Array(this.view.buffer, this.view.byteOffset + this.offset, count);
|
|
8573
|
+
this.offset += count;
|
|
8574
|
+
return out;
|
|
8575
|
+
}
|
|
8576
|
+
string() {
|
|
8577
|
+
const length = this.u32();
|
|
8578
|
+
const text = new TextDecoder().decode(this.bytes(length));
|
|
8579
|
+
this.bytes((4 - length % 4) % 4);
|
|
8580
|
+
return text;
|
|
8581
|
+
}
|
|
8341
8582
|
}
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
if (
|
|
8583
|
+
var MAX_DEPTH = 1024;
|
|
8584
|
+
function containerType(reader, kind) {
|
|
8585
|
+
if (kind === 1) {
|
|
8586
|
+
reader.u32();
|
|
8587
|
+
} else if (kind === 2 || kind === 3) {
|
|
8588
|
+
reader.string();
|
|
8589
|
+
}
|
|
8590
|
+
}
|
|
8591
|
+
function decodeValue(reader, depth) {
|
|
8592
|
+
if (depth > MAX_DEPTH) {
|
|
8593
|
+
throw new RangeError("a value nests deeper than the engine allows");
|
|
8594
|
+
}
|
|
8595
|
+
const header = reader.u32();
|
|
8596
|
+
const type = header & 255;
|
|
8597
|
+
const wide = (header & FLAG_64) !== 0;
|
|
8598
|
+
const math = MATH[type];
|
|
8599
|
+
if (math !== undefined) {
|
|
8345
8600
|
return {
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
command: [launch.command, ...launch.args],
|
|
8349
|
-
environment: environmentFor(launch, before["environment"]),
|
|
8350
|
-
enabled: true
|
|
8601
|
+
kind: math.name,
|
|
8602
|
+
values: Array.from({ length: math.count }, () => math.ints === true ? reader.i32() : reader.real(wide))
|
|
8351
8603
|
};
|
|
8352
8604
|
}
|
|
8353
|
-
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
}
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
8397
|
-
|
|
8398
|
-
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
]
|
|
8404
|
-
|
|
8405
|
-
|
|
8406
|
-
|
|
8407
|
-
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
8423
|
-
|
|
8424
|
-
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
|
|
8433
|
-
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
|
|
8437
|
-
|
|
8438
|
-
try {
|
|
8439
|
-
booted = Number(/^btime\s+(\d+)$/m.exec(readFileSync3("/proc/stat", "utf8"))?.[1] ?? Number.NaN) * 1000;
|
|
8440
|
-
} catch {
|
|
8441
|
-
return began;
|
|
8605
|
+
const vectorWidth = PACKED_VECTORS[type];
|
|
8606
|
+
if (vectorWidth !== undefined) {
|
|
8607
|
+
const count = reader.u32();
|
|
8608
|
+
return Array.from({ length: count }, () => ({
|
|
8609
|
+
kind: "Vector",
|
|
8610
|
+
values: Array.from({ length: vectorWidth }, () => reader.real(wide))
|
|
8611
|
+
}));
|
|
8612
|
+
}
|
|
8613
|
+
switch (type) {
|
|
8614
|
+
case NIL:
|
|
8615
|
+
return null;
|
|
8616
|
+
case BOOL:
|
|
8617
|
+
return reader.u32() !== 0;
|
|
8618
|
+
case INT:
|
|
8619
|
+
return wide ? reader.i64() : reader.i32();
|
|
8620
|
+
case FLOAT:
|
|
8621
|
+
return wide ? reader.f64() : reader.f32();
|
|
8622
|
+
case STRING:
|
|
8623
|
+
case 21:
|
|
8624
|
+
return reader.string();
|
|
8625
|
+
case 20:
|
|
8626
|
+
return { kind: "Color", values: [reader.f32(), reader.f32(), reader.f32(), reader.f32()] };
|
|
8627
|
+
case 22: {
|
|
8628
|
+
const first = reader.u32();
|
|
8629
|
+
if ((first & 2147483648) === 0) {
|
|
8630
|
+
throw new RangeError("a node path in the format before 3.0");
|
|
8631
|
+
}
|
|
8632
|
+
const names = first & 2147483647;
|
|
8633
|
+
let subnames = reader.u32();
|
|
8634
|
+
const flags = reader.u32();
|
|
8635
|
+
if ((flags & 2) !== 0) {
|
|
8636
|
+
subnames += 1;
|
|
8637
|
+
}
|
|
8638
|
+
return { kind: "NodePath", values: Array.from({ length: names + subnames }, () => reader.string()) };
|
|
8639
|
+
}
|
|
8640
|
+
case 23:
|
|
8641
|
+
return { kind: "RID", values: [reader.u64()] };
|
|
8642
|
+
case 24:
|
|
8643
|
+
if ((header & FLAG_64) === 0) {
|
|
8644
|
+
throw new RangeError("a full object, which this reader does not take");
|
|
8645
|
+
}
|
|
8646
|
+
return { kind: "Object", values: [reader.u64()] };
|
|
8647
|
+
case 25:
|
|
8648
|
+
return { kind: "Callable", values: [] };
|
|
8649
|
+
case 26:
|
|
8650
|
+
return { kind: "Signal", values: [reader.string(), reader.u64()] };
|
|
8651
|
+
case 27: {
|
|
8652
|
+
containerType(reader, header >> 16 & 3);
|
|
8653
|
+
containerType(reader, header >> 18 & 3);
|
|
8654
|
+
const count = reader.u32() & 2147483647;
|
|
8655
|
+
const entries = [];
|
|
8656
|
+
for (let index = 0;index < count; index += 1) {
|
|
8657
|
+
const key = decodeValue(reader, depth + 1);
|
|
8658
|
+
entries.push([key, decodeValue(reader, depth + 1)]);
|
|
8659
|
+
}
|
|
8660
|
+
return { kind: "dictionary", entries };
|
|
8661
|
+
}
|
|
8662
|
+
case ARRAY: {
|
|
8663
|
+
containerType(reader, header >> 16 & 3);
|
|
8664
|
+
const count = reader.u32() & 2147483647;
|
|
8665
|
+
return Array.from({ length: count }, () => decodeValue(reader, depth + 1));
|
|
8666
|
+
}
|
|
8667
|
+
case 29: {
|
|
8668
|
+
const count = reader.u32();
|
|
8669
|
+
const bytes = [...reader.bytes(count)];
|
|
8670
|
+
reader.bytes((4 - count % 4) % 4);
|
|
8671
|
+
return bytes;
|
|
8672
|
+
}
|
|
8673
|
+
case 30:
|
|
8674
|
+
return Array.from({ length: reader.u32() }, () => reader.i32());
|
|
8675
|
+
case 31:
|
|
8676
|
+
return Array.from({ length: reader.u32() }, () => reader.i64());
|
|
8677
|
+
case 32:
|
|
8678
|
+
return Array.from({ length: reader.u32() }, () => reader.f32());
|
|
8679
|
+
case 33:
|
|
8680
|
+
return Array.from({ length: reader.u32() }, () => reader.f64());
|
|
8681
|
+
case 34:
|
|
8682
|
+
return Array.from({ length: reader.u32() }, () => reader.string().replace(/\0$/, ""));
|
|
8683
|
+
case 37:
|
|
8684
|
+
return Array.from({ length: reader.u32() }, () => ({
|
|
8685
|
+
kind: "Color",
|
|
8686
|
+
values: [reader.f32(), reader.f32(), reader.f32(), reader.f32()]
|
|
8687
|
+
}));
|
|
8688
|
+
default:
|
|
8689
|
+
throw new RangeError(`a value of type ${type}, which Godot 4.7 does not have`);
|
|
8442
8690
|
}
|
|
8443
|
-
|
|
8444
|
-
|
|
8691
|
+
}
|
|
8692
|
+
function decodeVariant(bytes) {
|
|
8693
|
+
const reader = new Reader(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength));
|
|
8694
|
+
const value = decodeValue(reader, 0);
|
|
8695
|
+
if (reader.remaining !== 0) {
|
|
8696
|
+
throw new RangeError(`${reader.remaining} bytes left over after the value`);
|
|
8445
8697
|
}
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
|
|
8451
|
-
|
|
8698
|
+
return value;
|
|
8699
|
+
}
|
|
8700
|
+
function pushU32(out, value) {
|
|
8701
|
+
out.push(value & 255, value >>> 8 & 255, value >>> 16 & 255, value >>> 24 & 255);
|
|
8702
|
+
}
|
|
8703
|
+
function encodeInto(out, value) {
|
|
8704
|
+
if (value === null) {
|
|
8705
|
+
pushU32(out, NIL);
|
|
8706
|
+
} else if (typeof value === "boolean") {
|
|
8707
|
+
pushU32(out, BOOL);
|
|
8708
|
+
pushU32(out, value ? 1 : 0);
|
|
8709
|
+
} else if (typeof value === "number") {
|
|
8710
|
+
const view = new DataView(new ArrayBuffer(8));
|
|
8711
|
+
if (Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) {
|
|
8712
|
+
pushU32(out, INT);
|
|
8713
|
+
view.setInt32(0, value, true);
|
|
8714
|
+
out.push(...new Uint8Array(view.buffer, 0, 4));
|
|
8715
|
+
} else if (Number.isInteger(value)) {
|
|
8716
|
+
pushU32(out, INT | FLAG_64);
|
|
8717
|
+
view.setBigInt64(0, BigInt(value), true);
|
|
8718
|
+
out.push(...new Uint8Array(view.buffer));
|
|
8719
|
+
} else {
|
|
8720
|
+
pushU32(out, FLOAT | FLAG_64);
|
|
8721
|
+
view.setFloat64(0, value, true);
|
|
8722
|
+
out.push(...new Uint8Array(view.buffer));
|
|
8452
8723
|
}
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8724
|
+
} else if (typeof value === "string") {
|
|
8725
|
+
const bytes = new TextEncoder().encode(value);
|
|
8726
|
+
pushU32(out, STRING);
|
|
8727
|
+
pushU32(out, bytes.length);
|
|
8728
|
+
out.push(...bytes, ...Array.from({ length: (4 - bytes.length % 4) % 4 }, () => 0));
|
|
8729
|
+
} else {
|
|
8730
|
+
pushU32(out, ARRAY);
|
|
8731
|
+
pushU32(out, value.length);
|
|
8732
|
+
for (const element of value) {
|
|
8733
|
+
encodeInto(out, element);
|
|
8456
8734
|
}
|
|
8457
8735
|
}
|
|
8458
|
-
return began;
|
|
8459
8736
|
}
|
|
8460
|
-
|
|
8461
|
-
|
|
8737
|
+
function encodeVariant(value) {
|
|
8738
|
+
const out = [];
|
|
8739
|
+
encodeInto(out, value);
|
|
8740
|
+
return Uint8Array.from(out);
|
|
8462
8741
|
}
|
|
8463
|
-
var
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
if (Number.isInteger(hertz) && hertz > 0) {
|
|
8471
|
-
ticksAnswered = hertz;
|
|
8472
|
-
return hertz;
|
|
8473
|
-
}
|
|
8474
|
-
} catch {}
|
|
8475
|
-
return null;
|
|
8742
|
+
var MAIN_THREAD = 1;
|
|
8743
|
+
function framedCommand(message, data, thread = MAIN_THREAD) {
|
|
8744
|
+
const body = encodeVariant([message, thread, data]);
|
|
8745
|
+
const framed = new Uint8Array(body.length + 4);
|
|
8746
|
+
new DataView(framed.buffer).setUint32(0, body.length, true);
|
|
8747
|
+
framed.set(body, 4);
|
|
8748
|
+
return framed;
|
|
8476
8749
|
}
|
|
8477
|
-
var
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
"--dump-extension-api",
|
|
8494
|
-
"--dump-extension-api-with-docs",
|
|
8495
|
-
"--validate-extension-api",
|
|
8496
|
-
"--convert-3to4",
|
|
8497
|
-
"--validate-conversion-3to4"
|
|
8498
|
-
];
|
|
8499
|
-
function readCommandLine(command) {
|
|
8500
|
-
const all = commandWords(command);
|
|
8501
|
-
const separator = all.findIndex((word) => word === "--" || word === "++");
|
|
8502
|
-
const words = separator === -1 ? all : all.slice(0, separator);
|
|
8503
|
-
const executable = words[0] === undefined ? "" : basename3(words[0].replaceAll("\\", "/"));
|
|
8504
|
-
const at = words.indexOf("--path");
|
|
8505
|
-
let projectPath = null;
|
|
8506
|
-
if (at !== -1 && at + 1 < words.length) {
|
|
8507
|
-
const taken = [];
|
|
8508
|
-
for (const word of words.slice(at + 1)) {
|
|
8509
|
-
if (taken.length > 0 && (word.startsWith("-") || /^[a-z]+:\/\//.test(word))) {
|
|
8750
|
+
var MOST_MESSAGE_BYTES = (8 << 20) + 4;
|
|
8751
|
+
|
|
8752
|
+
class DebuggerStream {
|
|
8753
|
+
pending = new Uint8Array(0);
|
|
8754
|
+
push(chunk) {
|
|
8755
|
+
const joined = new Uint8Array(this.pending.length + chunk.length);
|
|
8756
|
+
joined.set(this.pending, 0);
|
|
8757
|
+
joined.set(chunk, this.pending.length);
|
|
8758
|
+
const out = [];
|
|
8759
|
+
let at = 0;
|
|
8760
|
+
while (joined.length - at >= 4) {
|
|
8761
|
+
const length = new DataView(joined.buffer, joined.byteOffset + at, 4).getUint32(0, true);
|
|
8762
|
+
if (length > MOST_MESSAGE_BYTES) {
|
|
8763
|
+
throw new RangeError(`a message of ${length} bytes, more than the engine sends`);
|
|
8764
|
+
}
|
|
8765
|
+
if (joined.length - at - 4 < length) {
|
|
8510
8766
|
break;
|
|
8511
8767
|
}
|
|
8512
|
-
|
|
8768
|
+
out.push(readMessage(joined.subarray(at + 4, at + 4 + length)));
|
|
8769
|
+
at += 4 + length;
|
|
8513
8770
|
}
|
|
8514
|
-
|
|
8771
|
+
this.pending = joined.slice(at);
|
|
8772
|
+
return out;
|
|
8515
8773
|
}
|
|
8516
|
-
return {
|
|
8517
|
-
executable,
|
|
8518
|
-
projectPath,
|
|
8519
|
-
editor: words.some((word) => word === "-e" || word === "--editor"),
|
|
8520
|
-
oneShot: words.find((word) => ONE_SHOT_OPTIONS.includes(word)) ?? null
|
|
8521
|
-
};
|
|
8522
8774
|
}
|
|
8523
|
-
function
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
if (char === '"') {
|
|
8530
|
-
quoted = !quoted;
|
|
8531
|
-
started = true;
|
|
8532
|
-
} else if (!quoted && /\s/.test(char)) {
|
|
8533
|
-
if (started) {
|
|
8534
|
-
words.push(word);
|
|
8535
|
-
word = "";
|
|
8536
|
-
started = false;
|
|
8537
|
-
}
|
|
8538
|
-
} else {
|
|
8539
|
-
word += char;
|
|
8540
|
-
started = true;
|
|
8541
|
-
}
|
|
8775
|
+
function readMessage(body) {
|
|
8776
|
+
let value;
|
|
8777
|
+
try {
|
|
8778
|
+
value = decodeVariant(body);
|
|
8779
|
+
} catch (error) {
|
|
8780
|
+
return { unreadable: error instanceof Error ? error.message : String(error) };
|
|
8542
8781
|
}
|
|
8543
|
-
if (
|
|
8544
|
-
|
|
8782
|
+
if (!Array.isArray(value) || value.length !== 3) {
|
|
8783
|
+
return { unreadable: "a message that is not [message, thread, data]" };
|
|
8545
8784
|
}
|
|
8546
|
-
|
|
8785
|
+
const [message, thread, data] = value;
|
|
8786
|
+
if (typeof message !== "string" || typeof thread !== "number" || !Array.isArray(data)) {
|
|
8787
|
+
return { unreadable: "a message whose name, thread or data is the wrong type" };
|
|
8788
|
+
}
|
|
8789
|
+
return { message, thread, data };
|
|
8790
|
+
}
|
|
8791
|
+
|
|
8792
|
+
// src/setup.ts
|
|
8793
|
+
import { dirname as dirname3, join as join5 } from "node:path";
|
|
8794
|
+
import { fileURLToPath } from "node:url";
|
|
8795
|
+
|
|
8796
|
+
// src/dictionary.ts
|
|
8797
|
+
function emptyRecord() {
|
|
8798
|
+
return Object.create(null);
|
|
8547
8799
|
}
|
|
8548
8800
|
|
|
8549
8801
|
// src/game-log.ts
|
|
@@ -8653,16 +8905,16 @@ var IMPORTABLE = new Set(IMPORTABLE_EXTENSIONS);
|
|
|
8653
8905
|
var hashes = new Map;
|
|
8654
8906
|
|
|
8655
8907
|
// src/scratch.ts
|
|
8656
|
-
import { existsSync as existsSync2, mkdtempSync as mkdtempSync2, readdirSync, rmSync as
|
|
8657
|
-
import { tmpdir as
|
|
8908
|
+
import { existsSync as existsSync2, mkdtempSync as mkdtempSync2, readdirSync, rmSync as rmSync4 } from "node:fs";
|
|
8909
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
8658
8910
|
import { join as join4 } from "node:path";
|
|
8659
|
-
import
|
|
8911
|
+
import process6 from "node:process";
|
|
8660
8912
|
var SWEPT = { recursive: true, force: true };
|
|
8661
8913
|
var AGAIN_AFTER_MS = [250, 500, 1000, 2000, 4000, 8000, 16000];
|
|
8662
8914
|
var waiting = new Set;
|
|
8663
8915
|
var atExit = new Set;
|
|
8664
8916
|
function scratchDirectory(kind) {
|
|
8665
|
-
return mkdtempSync2(join4(
|
|
8917
|
+
return mkdtempSync2(join4(tmpdir3(), `gdharness-${kind}-${process6.pid}-`));
|
|
8666
8918
|
}
|
|
8667
8919
|
function discardWith(remove, paths) {
|
|
8668
8920
|
const left = [];
|
|
@@ -8686,7 +8938,7 @@ function discard(...paths) {
|
|
|
8686
8938
|
return left;
|
|
8687
8939
|
}
|
|
8688
8940
|
function remove(path) {
|
|
8689
|
-
|
|
8941
|
+
rmSync4(path, SWEPT);
|
|
8690
8942
|
}
|
|
8691
8943
|
function tryAgain(path, attempt) {
|
|
8692
8944
|
if (attempt === 0) {
|
|
@@ -8720,7 +8972,7 @@ function lastTryOnExit() {
|
|
|
8720
8972
|
return;
|
|
8721
8973
|
}
|
|
8722
8974
|
lastTryWatched = true;
|
|
8723
|
-
|
|
8975
|
+
process6.once("exit", () => {
|
|
8724
8976
|
for (const path of [...waiting, ...atExit]) {
|
|
8725
8977
|
try {
|
|
8726
8978
|
remove(path);
|
|
@@ -8847,7 +9099,7 @@ function parseIniLikeValue(value) {
|
|
|
8847
9099
|
}
|
|
8848
9100
|
|
|
8849
9101
|
// src/server-version.ts
|
|
8850
|
-
import { readFileSync as
|
|
9102
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
8851
9103
|
|
|
8852
9104
|
// src/update-check.ts
|
|
8853
9105
|
var CACHE_MS = 10 * 60 * 1000;
|
|
@@ -8858,7 +9110,7 @@ var MAX_RETRY_MS = 60 * 60 * 1000;
|
|
|
8858
9110
|
var DEBUG_MODE = process.env["GDHARNESS_DEBUG"] === "1";
|
|
8859
9111
|
var SERVER_VERSION = (() => {
|
|
8860
9112
|
try {
|
|
8861
|
-
const pkg = JSON.parse(
|
|
9113
|
+
const pkg = JSON.parse(readFileSync5(new URL("../package.json", import.meta.url), "utf8"));
|
|
8862
9114
|
return typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
8863
9115
|
} catch {
|
|
8864
9116
|
return "0.0.0";
|
|
@@ -8884,7 +9136,7 @@ var RUNTIME_AUTOLOAD2 = `${RUNTIME_ADDON}runtime_autoload.gd`;
|
|
|
8884
9136
|
var frameEnd = null;
|
|
8885
9137
|
function frameEndLine() {
|
|
8886
9138
|
if (frameEnd === null) {
|
|
8887
|
-
const lines =
|
|
9139
|
+
const lines = readFileSync6(join6(shippedAddonsDirectory(), "gdharness_runtime", "runtime_autoload.gd"), "utf8").split(`
|
|
8888
9140
|
`);
|
|
8889
9141
|
const declared = lines.findIndex((line) => line.startsWith("func _notification("));
|
|
8890
9142
|
if (declared === -1) {
|
|
@@ -9008,6 +9260,7 @@ class GameDebugger {
|
|
|
9008
9260
|
onClosed = [];
|
|
9009
9261
|
output = [];
|
|
9010
9262
|
outputDropped = 0;
|
|
9263
|
+
expressionErrors = [];
|
|
9011
9264
|
queue = Promise.resolve();
|
|
9012
9265
|
server;
|
|
9013
9266
|
port;
|
|
@@ -9132,6 +9385,14 @@ class GameDebugger {
|
|
|
9132
9385
|
this.outputDropped += over;
|
|
9133
9386
|
}
|
|
9134
9387
|
}
|
|
9388
|
+
} else if (received.message === "error") {
|
|
9389
|
+
const [, , , , file, , , error, described] = received.data;
|
|
9390
|
+
if (file === "core/math/expression.cpp" && this.expressionErrors.length < 10) {
|
|
9391
|
+
const why = typeof described === "string" && described !== "" ? described : error;
|
|
9392
|
+
if (typeof why === "string") {
|
|
9393
|
+
this.expressionErrors.push(why);
|
|
9394
|
+
}
|
|
9395
|
+
}
|
|
9135
9396
|
}
|
|
9136
9397
|
const at = this.waiters.findIndex((waiter) => waiter.wanted(received));
|
|
9137
9398
|
if (at !== -1) {
|
|
@@ -9478,6 +9739,7 @@ class GameDebugger {
|
|
|
9478
9739
|
};
|
|
9479
9740
|
}
|
|
9480
9741
|
this.forget("evaluation_return");
|
|
9742
|
+
this.expressionErrors.length = 0;
|
|
9481
9743
|
this.send("evaluate", [expression, frame], held.thread);
|
|
9482
9744
|
const answered = await this.next(GameDebugger.named("evaluation_return"), EVALUATE_MS);
|
|
9483
9745
|
if (answered === null || !("data" in answered)) {
|
|
@@ -9486,16 +9748,24 @@ class GameDebugger {
|
|
|
9486
9748
|
};
|
|
9487
9749
|
}
|
|
9488
9750
|
const [, , type, value, hint] = answered.data;
|
|
9489
|
-
|
|
9751
|
+
const answer = {
|
|
9490
9752
|
held: this.heldState(),
|
|
9491
9753
|
frame,
|
|
9492
9754
|
expression,
|
|
9493
9755
|
value: shownValue(value ?? null, typeof hint === "string" ? hint : ""),
|
|
9494
|
-
type: typeNamed(type, hint)
|
|
9495
|
-
...value === null || value === undefined ? {
|
|
9496
|
-
note: "null is also what an expression comes to when it does not parse or fails as it runs. The game prints why as an error, which editor_output reads, since its debugger hands errors over apart from the console debug_state output keeps."
|
|
9497
|
-
} : {}
|
|
9756
|
+
type: typeNamed(type, hint)
|
|
9498
9757
|
};
|
|
9758
|
+
if (value !== null && value !== undefined) {
|
|
9759
|
+
return answer;
|
|
9760
|
+
}
|
|
9761
|
+
if (!await this.taken()) {
|
|
9762
|
+
return {
|
|
9763
|
+
...answer,
|
|
9764
|
+
note: "null is also what an expression comes to when it does not parse or fails as it runs, and the game did not answer the question asked after it to say whether this one failed. editor_output has any error it printed."
|
|
9765
|
+
};
|
|
9766
|
+
}
|
|
9767
|
+
const why = this.expressionErrors.join(" ");
|
|
9768
|
+
return why === "" ? answer : { ...answer, failed: why };
|
|
9499
9769
|
}
|
|
9500
9770
|
async taken() {
|
|
9501
9771
|
this.forget("scene:inspect_object");
|
|
@@ -9518,11 +9788,11 @@ class GameDebugger {
|
|
|
9518
9788
|
|
|
9519
9789
|
// src/keeper-channel.ts
|
|
9520
9790
|
import { randomUUID } from "node:crypto";
|
|
9521
|
-
import { mkdtempSync as mkdtempSync3, rmSync as
|
|
9791
|
+
import { mkdtempSync as mkdtempSync3, rmSync as rmSync5 } from "node:fs";
|
|
9522
9792
|
import { connect, createServer as createServer2 } from "node:net";
|
|
9523
|
-
import { tmpdir as
|
|
9793
|
+
import { tmpdir as tmpdir4 } from "node:os";
|
|
9524
9794
|
import { join as join7 } from "node:path";
|
|
9525
|
-
import
|
|
9795
|
+
import process7 from "node:process";
|
|
9526
9796
|
var DEBUG_PREFIX = "debug ";
|
|
9527
9797
|
function endedOrWhyNot(end) {
|
|
9528
9798
|
try {
|
|
@@ -9549,7 +9819,7 @@ function errorText(error) {
|
|
|
9549
9819
|
async function listenForTheServer(end, debug) {
|
|
9550
9820
|
let directory = null;
|
|
9551
9821
|
try {
|
|
9552
|
-
directory =
|
|
9822
|
+
directory = process7.platform === "win32" ? null : mkdtempSync3(join7(tmpdir4(), "gdharness-keeper-"));
|
|
9553
9823
|
const address = directory === null ? `\\\\.\\pipe\\gdharness-keeper-${randomUUID()}` : join7(directory, "keeper.sock");
|
|
9554
9824
|
const server = createServer2((socket) => {
|
|
9555
9825
|
socket.setEncoding("utf8");
|
|
@@ -9586,13 +9856,13 @@ async function listenForTheServer(end, debug) {
|
|
|
9586
9856
|
close: () => {
|
|
9587
9857
|
server.close();
|
|
9588
9858
|
if (made !== null) {
|
|
9589
|
-
|
|
9859
|
+
rmSync5(made, { recursive: true, force: true });
|
|
9590
9860
|
}
|
|
9591
9861
|
}
|
|
9592
9862
|
};
|
|
9593
9863
|
} catch {
|
|
9594
9864
|
if (directory !== null) {
|
|
9595
|
-
|
|
9865
|
+
rmSync5(directory, { recursive: true, force: true });
|
|
9596
9866
|
}
|
|
9597
9867
|
return null;
|
|
9598
9868
|
}
|
|
@@ -9643,11 +9913,11 @@ function readLaunched(printed) {
|
|
|
9643
9913
|
|
|
9644
9914
|
// src/run-record.ts
|
|
9645
9915
|
import { createHash as createHash2 } from "node:crypto";
|
|
9646
|
-
import { mkdirSync, openSync as
|
|
9916
|
+
import { mkdirSync as mkdirSync2, openSync as openSync3, readdirSync as readdirSync2, readFileSync as readFileSync7, rmSync as rmSync6, statSync as statSync4 } from "node:fs";
|
|
9647
9917
|
import { basename as basename4, join as join9, resolve as resolve4 } from "node:path";
|
|
9648
9918
|
|
|
9649
9919
|
// src/runtime-client.ts
|
|
9650
|
-
import { tmpdir as
|
|
9920
|
+
import { tmpdir as tmpdir5 } from "node:os";
|
|
9651
9921
|
import { dirname as dirname4, join as join8, resolve as resolve3 } from "node:path";
|
|
9652
9922
|
|
|
9653
9923
|
// src/launch.ts
|
|
@@ -9693,7 +9963,7 @@ function runtimeDirectory(variables = process.env) {
|
|
|
9693
9963
|
return explicit;
|
|
9694
9964
|
}
|
|
9695
9965
|
const perUser = envValue("XDG_RUNTIME_DIR", variables);
|
|
9696
|
-
return join8(perUser ??
|
|
9966
|
+
return join8(perUser ?? tmpdir5(), "gdharness");
|
|
9697
9967
|
}
|
|
9698
9968
|
var ERROR_REPORT_KEEP_MS = 60 * 60 * 1000;
|
|
9699
9969
|
var verdicts = new Map;
|
|
@@ -9714,7 +9984,7 @@ function runRecordPath(projectPath, directory = runtimeDirectory()) {
|
|
|
9714
9984
|
return join9(directory, "runs", `note-${projectKey(projectPath)}.json`);
|
|
9715
9985
|
}
|
|
9716
9986
|
function writeRunRecord(record) {
|
|
9717
|
-
|
|
9987
|
+
mkdirSync2(runsDirectory(), { recursive: true });
|
|
9718
9988
|
const path = runRecordPath(record.projectPath);
|
|
9719
9989
|
if (!writeWhole(path, JSON.stringify(record, null, 2))) {
|
|
9720
9990
|
throw new Error(`the run note could not be written at ${path}`);
|
|
@@ -9739,7 +10009,7 @@ function recordRunEnded(projectPath, pid, ending) {
|
|
|
9739
10009
|
function recordAt(path) {
|
|
9740
10010
|
let parsed;
|
|
9741
10011
|
try {
|
|
9742
|
-
parsed = JSON.parse(
|
|
10012
|
+
parsed = JSON.parse(readFileSync7(path, "utf8"));
|
|
9743
10013
|
} catch {
|
|
9744
10014
|
return null;
|
|
9745
10015
|
}
|
|
@@ -10178,7 +10448,7 @@ async function startThroughHelper(spec, output, stopFile) {
|
|
|
10178
10448
|
step: stepFile
|
|
10179
10449
|
});
|
|
10180
10450
|
const envChanges = spec.desktop === undefined ? spec.envChanges : { ...spec.envChanges, [DESKTOP_VARIABLE]: spec.desktop };
|
|
10181
|
-
const started = await startDirectly({ ...spec, command: wrapper.command, args: wrapper.args, envChanges }, output, true, false, "ignore",
|
|
10451
|
+
const started = await startDirectly({ ...spec, command: wrapper.command, args: wrapper.args, envChanges }, output, true, false, "ignore", tmpdir6());
|
|
10182
10452
|
if ("error" in started) {
|
|
10183
10453
|
return started;
|
|
10184
10454
|
}
|
|
@@ -10187,7 +10457,7 @@ async function startThroughHelper(spec, output, stopFile) {
|
|
|
10187
10457
|
exited.now = true;
|
|
10188
10458
|
});
|
|
10189
10459
|
for (let waited = 0;waited < DESKTOP_START_MS; waited += 50) {
|
|
10190
|
-
const pid = existsSync3(pidFile) ? Number(
|
|
10460
|
+
const pid = existsSync3(pidFile) ? Number(readFileSync8(pidFile, "utf8").trim()) : Number.NaN;
|
|
10191
10461
|
if (Number.isInteger(pid) && pid > 0) {
|
|
10192
10462
|
return { child: started.child, pid };
|
|
10193
10463
|
}
|
|
@@ -10218,7 +10488,7 @@ function profiledBy(path, projectPath) {
|
|
|
10218
10488
|
};
|
|
10219
10489
|
let projectGodot = null;
|
|
10220
10490
|
try {
|
|
10221
|
-
projectGodot =
|
|
10491
|
+
projectGodot = readFileSync8(join10(projectPath, "project.godot"), "utf8");
|
|
10222
10492
|
} catch {}
|
|
10223
10493
|
const observer = new ProfileObserver((totals) => {
|
|
10224
10494
|
const first = latest === null;
|
|
@@ -10319,19 +10589,20 @@ async function keep() {
|
|
|
10319
10589
|
}
|
|
10320
10590
|
const profiled = run?.profile === undefined ? null : profiledBy(run.profile, run.projectPath);
|
|
10321
10591
|
const debuggerPeer = run === undefined || run.debugged === false ? null : await GameDebugger.open(run.breakpoints ?? [], profiled === null ? [] : [profiled.observer]);
|
|
10322
|
-
const exitNotes = run === undefined ? null : mkdtempSync4(join10(
|
|
10592
|
+
const exitNotes = run === undefined ? null : mkdtempSync4(join10(tmpdir6(), "gdharness-exit-"));
|
|
10323
10593
|
const noted = exitNotes === null ? spec : { ...spec, envChanges: { ...spec.envChanges, [EXIT_NOTES_VARIABLE]: exitNotes } };
|
|
10324
10594
|
const toStart = debuggerPeer === null ? noted : { ...noted, args: withEngineArguments(noted.args, debuggerPeer.engineArguments) };
|
|
10325
|
-
const transcript = run === undefined ? "ignore" :
|
|
10326
|
-
const own = run !== undefined && throughTheHelper(spec) ? mkdtempSync4(join10(
|
|
10595
|
+
const transcript = run === undefined ? "ignore" : openSync4(run.transcript, "a");
|
|
10596
|
+
const own = run !== undefined && throughTheHelper(spec) ? mkdtempSync4(join10(tmpdir6(), "gdharness-stop-")) : null;
|
|
10327
10597
|
const stopFile = own === null ? "" : join10(own, "stop");
|
|
10328
10598
|
let started;
|
|
10599
|
+
const keeperStarted = run?.slot === undefined ? undefined : ownStart();
|
|
10329
10600
|
const spawnedAt = Date.now();
|
|
10330
10601
|
try {
|
|
10331
10602
|
started = await startDetached(toStart, transcript, run === undefined, stopFile);
|
|
10332
10603
|
} finally {
|
|
10333
10604
|
if (transcript !== "ignore") {
|
|
10334
|
-
|
|
10605
|
+
closeSync3(transcript);
|
|
10335
10606
|
}
|
|
10336
10607
|
}
|
|
10337
10608
|
if ("error" in started) {
|
|
@@ -10382,6 +10653,14 @@ async function keep() {
|
|
|
10382
10653
|
process.stdout.end(`pid ${pid}
|
|
10383
10654
|
`, resolve);
|
|
10384
10655
|
});
|
|
10656
|
+
const slot = run?.slot;
|
|
10657
|
+
if (slot !== undefined && keeperStarted !== undefined) {
|
|
10658
|
+
handSlot(slot.lock, slot.from, {
|
|
10659
|
+
pid: process.pid,
|
|
10660
|
+
started: await keeperStarted,
|
|
10661
|
+
by: `${slot.by}, through the keeper process that runs it`
|
|
10662
|
+
});
|
|
10663
|
+
}
|
|
10385
10664
|
let { code, signal } = await exited;
|
|
10386
10665
|
let exitedAt = Date.now();
|
|
10387
10666
|
let note = record === null ? null : listening === null ? record : { ...record, keeper: listening.address };
|
|
@@ -10442,11 +10721,14 @@ async function keep() {
|
|
|
10442
10721
|
notTold
|
|
10443
10722
|
});
|
|
10444
10723
|
}
|
|
10724
|
+
if (slot !== undefined) {
|
|
10725
|
+
giveBackSlot(slot.lock, process.pid);
|
|
10726
|
+
}
|
|
10445
10727
|
debuggerPeer?.close();
|
|
10446
10728
|
listening?.close();
|
|
10447
10729
|
for (const made of [own, exitNotes]) {
|
|
10448
10730
|
if (made !== null) {
|
|
10449
|
-
|
|
10731
|
+
rmSync7(made, { recursive: true, force: true });
|
|
10450
10732
|
}
|
|
10451
10733
|
}
|
|
10452
10734
|
process.exit(0);
|
|
@@ -10457,7 +10739,7 @@ function restartSaid(notes, pid) {
|
|
|
10457
10739
|
return null;
|
|
10458
10740
|
}
|
|
10459
10741
|
try {
|
|
10460
|
-
const said = JSON.parse(
|
|
10742
|
+
const said = JSON.parse(readFileSync8(join10(notes, `exit-${String(pid)}.json`), "utf8"));
|
|
10461
10743
|
return typeof said === "object" && said !== null && "restart" in said && typeof said.restart === "boolean" ? said.restart : null;
|
|
10462
10744
|
} catch {
|
|
10463
10745
|
return null;
|