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