gdharness 1.0.15 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/cli.js CHANGED
@@ -7187,6 +7187,19 @@ function alongside(execPath, name) {
7187
7187
  }
7188
7188
  var init_runner = () => {};
7189
7189
 
7190
+ // src/call-signal.ts
7191
+ import { AsyncLocalStorage } from "node:async_hooks";
7192
+ function withCallSignal(signal, answer) {
7193
+ return signal === undefined ? answer() : current.run(signal, answer);
7194
+ }
7195
+ function callSignal() {
7196
+ return current.getStore();
7197
+ }
7198
+ var current;
7199
+ var init_call_signal = __esm(() => {
7200
+ current = new AsyncLocalStorage;
7201
+ });
7202
+
7190
7203
  // src/dictionary.ts
7191
7204
  function emptyRecord() {
7192
7205
  return Object.create(null);
@@ -7781,14 +7794,7 @@ function reason2(stdout, stderr) {
7781
7794
  async function runImport(godotPath, projectPath) {
7782
7795
  const logDir = mkdtempSync2(join7(tmpdir3(), "gdharness-import-"));
7783
7796
  try {
7784
- const { stderr } = await run3(godotPath, [
7785
- "--headless",
7786
- "--log-file",
7787
- join7(logDir, "engine.log"),
7788
- "--path",
7789
- projectPath,
7790
- "--import"
7791
- ]);
7797
+ const { stderr } = await run3(godotPath, ["--headless", "--log-file", join7(logDir, "engine.log"), "--path", projectPath, "--import"], { signal: callSignal() });
7792
7798
  return { ok: true, messages: problems2(stderr) };
7793
7799
  } catch (error) {
7794
7800
  if (error instanceof Error && "stdout" in error && "stderr" in error) {
@@ -7827,7 +7833,7 @@ async function runOperation2(engine, operation, params, projectPath) {
7827
7833
  let stdout;
7828
7834
  let stderr;
7829
7835
  try {
7830
- ({ stdout, stderr } = await run3(engine.godotPath, args));
7836
+ ({ stdout, stderr } = await run3(engine.godotPath, args, { signal: callSignal() }));
7831
7837
  } catch (error) {
7832
7838
  if (error instanceof Error && "stdout" in error && "stderr" in error) {
7833
7839
  const failed = error;
@@ -7857,6 +7863,7 @@ async function runOperation2(engine, operation, params, projectPath) {
7857
7863
  }
7858
7864
  var run3;
7859
7865
  var init_headless = __esm(() => {
7866
+ init_call_signal();
7860
7867
  init_game_log();
7861
7868
  init_scratch();
7862
7869
  run3 = promisify3(execFile3);
@@ -38591,7 +38598,7 @@ class GodotServer {
38591
38598
  }
38592
38599
  setupToolHandlers() {
38593
38600
  this.mcp.server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: this.tools }));
38594
- this.mcp.server.setRequestHandler(CallToolRequestSchema, async (request) => {
38601
+ this.mcp.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
38595
38602
  this.logDebug(`Handling tool request: ${request.params.name}`);
38596
38603
  const spec = toolSpec(request.params.name);
38597
38604
  if (!spec) {
@@ -38606,7 +38613,7 @@ class GodotServer {
38606
38613
  this.lastProjectPath = args["projectPath"];
38607
38614
  }
38608
38615
  this.updates.refresh();
38609
- const answer = await this.answered(spec.name, checked.op ?? "", args);
38616
+ const answer = await withCallSignal(extra.signal, () => this.answered(spec.name, checked.op ?? "", args));
38610
38617
  return this.withFeedbackNotice(this.withUpdateNotice(answer));
38611
38618
  });
38612
38619
  }
@@ -39377,7 +39384,10 @@ class GodotServer {
39377
39384
  const log = new GameLog;
39378
39385
  let exitCode = 0;
39379
39386
  try {
39380
- const { stdout, stderr } = await run7(engine.value, exportArgs, { timeout: 300000 });
39387
+ const { stdout, stderr } = await run7(engine.value, exportArgs, {
39388
+ timeout: 300000,
39389
+ signal: callSignal()
39390
+ });
39381
39391
  log.append("stdout", stdout);
39382
39392
  log.append("stderr", stderr);
39383
39393
  } catch (error) {
@@ -40393,6 +40403,23 @@ class GodotServer {
40393
40403
  }
40394
40404
  spawnGame(godotPath, cmdArgs, env) {
40395
40405
  const child = spawn(godotPath, cmdArgs, { stdio: ["ignore", "pipe", "pipe"], ...env ? { env } : {} });
40406
+ const cancelled = callSignal();
40407
+ if (cancelled !== undefined) {
40408
+ const end = () => {
40409
+ if (child.exitCode === null && child.signalCode === null) {
40410
+ this.logDebug(`The call waiting on pid ${child.pid ?? "unknown"} was cancelled; ending it.`);
40411
+ child.kill();
40412
+ }
40413
+ };
40414
+ if (cancelled.aborted) {
40415
+ end();
40416
+ } else {
40417
+ cancelled.addEventListener("abort", end, { once: true });
40418
+ child.once("exit", () => {
40419
+ cancelled.removeEventListener("abort", end);
40420
+ });
40421
+ }
40422
+ }
40396
40423
  const log = new GameLog;
40397
40424
  const started = {
40398
40425
  process: child,
@@ -41515,6 +41542,7 @@ var init_server3 = __esm(() => {
41515
41542
  init_boot_note();
41516
41543
  init_breakpoint_note();
41517
41544
  init_bridge_announce();
41545
+ init_call_signal();
41518
41546
  init_class_cache();
41519
41547
  init_class_note();
41520
41548
  init_config_pin();
@@ -42523,6 +42551,7 @@ function taken(harness, path, held, stripped) {
42523
42551
  }
42524
42552
 
42525
42553
  // src/headless.ts
42554
+ init_call_signal();
42526
42555
  init_game_log();
42527
42556
  init_scratch();
42528
42557
  import { execFile as execFile2 } from "node:child_process";
@@ -42587,7 +42616,7 @@ async function runOperation(engine, operation, params, projectPath) {
42587
42616
  let stdout;
42588
42617
  let stderr;
42589
42618
  try {
42590
- ({ stdout, stderr } = await run2(engine.godotPath, args));
42619
+ ({ stdout, stderr } = await run2(engine.godotPath, args, { signal: callSignal() }));
42591
42620
  } catch (error) {
42592
42621
  if (error instanceof Error && "stdout" in error && "stderr" in error) {
42593
42622
  const failed = error;
package/build/index.js CHANGED
@@ -25730,6 +25730,16 @@ function withdrawBridge(path) {
25730
25730
  }
25731
25731
  }
25732
25732
 
25733
+ // src/call-signal.ts
25734
+ import { AsyncLocalStorage } from "node:async_hooks";
25735
+ var current = new AsyncLocalStorage;
25736
+ function withCallSignal(signal, answer) {
25737
+ return signal === undefined ? answer() : current.run(signal, answer);
25738
+ }
25739
+ function callSignal() {
25740
+ return current.getStore();
25741
+ }
25742
+
25733
25743
  // src/class-cache.ts
25734
25744
  import { existsSync as existsSync3, readdirSync as readdirSync2, readFileSync as readFileSync7, statSync as statSync2 } from "node:fs";
25735
25745
  import { join as join6 } from "node:path";
@@ -27754,14 +27764,7 @@ function reason(stdout, stderr) {
27754
27764
  async function runImport(godotPath, projectPath) {
27755
27765
  const logDir = mkdtempSync(join11(tmpdir3(), "gdharness-import-"));
27756
27766
  try {
27757
- const { stderr } = await run3(godotPath, [
27758
- "--headless",
27759
- "--log-file",
27760
- join11(logDir, "engine.log"),
27761
- "--path",
27762
- projectPath,
27763
- "--import"
27764
- ]);
27767
+ const { stderr } = await run3(godotPath, ["--headless", "--log-file", join11(logDir, "engine.log"), "--path", projectPath, "--import"], { signal: callSignal() });
27765
27768
  return { ok: true, messages: problems(stderr) };
27766
27769
  } catch (error) {
27767
27770
  if (error instanceof Error && "stdout" in error && "stderr" in error) {
@@ -27800,7 +27803,7 @@ async function runOperation(engine, operation, params, projectPath) {
27800
27803
  let stdout;
27801
27804
  let stderr;
27802
27805
  try {
27803
- ({ stdout, stderr } = await run3(engine.godotPath, args));
27806
+ ({ stdout, stderr } = await run3(engine.godotPath, args, { signal: callSignal() }));
27804
27807
  } catch (error) {
27805
27808
  if (error instanceof Error && "stdout" in error && "stderr" in error) {
27806
27809
  const failed = error;
@@ -31329,7 +31332,7 @@ class GodotServer {
31329
31332
  }
31330
31333
  setupToolHandlers() {
31331
31334
  this.mcp.server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: this.tools }));
31332
- this.mcp.server.setRequestHandler(CallToolRequestSchema, async (request) => {
31335
+ this.mcp.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
31333
31336
  this.logDebug(`Handling tool request: ${request.params.name}`);
31334
31337
  const spec = toolSpec(request.params.name);
31335
31338
  if (!spec) {
@@ -31344,7 +31347,7 @@ class GodotServer {
31344
31347
  this.lastProjectPath = args["projectPath"];
31345
31348
  }
31346
31349
  this.updates.refresh();
31347
- const answer = await this.answered(spec.name, checked.op ?? "", args);
31350
+ const answer = await withCallSignal(extra.signal, () => this.answered(spec.name, checked.op ?? "", args));
31348
31351
  return this.withFeedbackNotice(this.withUpdateNotice(answer));
31349
31352
  });
31350
31353
  }
@@ -32115,7 +32118,10 @@ class GodotServer {
32115
32118
  const log = new GameLog;
32116
32119
  let exitCode = 0;
32117
32120
  try {
32118
- const { stdout, stderr } = await run5(engine.value, exportArgs, { timeout: 300000 });
32121
+ const { stdout, stderr } = await run5(engine.value, exportArgs, {
32122
+ timeout: 300000,
32123
+ signal: callSignal()
32124
+ });
32119
32125
  log.append("stdout", stdout);
32120
32126
  log.append("stderr", stderr);
32121
32127
  } catch (error) {
@@ -33131,6 +33137,23 @@ class GodotServer {
33131
33137
  }
33132
33138
  spawnGame(godotPath, cmdArgs, env) {
33133
33139
  const child = spawn(godotPath, cmdArgs, { stdio: ["ignore", "pipe", "pipe"], ...env ? { env } : {} });
33140
+ const cancelled = callSignal();
33141
+ if (cancelled !== undefined) {
33142
+ const end = () => {
33143
+ if (child.exitCode === null && child.signalCode === null) {
33144
+ this.logDebug(`The call waiting on pid ${child.pid ?? "unknown"} was cancelled; ending it.`);
33145
+ child.kill();
33146
+ }
33147
+ };
33148
+ if (cancelled.aborted) {
33149
+ end();
33150
+ } else {
33151
+ cancelled.addEventListener("abort", end, { once: true });
33152
+ child.once("exit", () => {
33153
+ cancelled.removeEventListener("abort", end);
33154
+ });
33155
+ }
33156
+ }
33134
33157
  const log = new GameLog;
33135
33158
  const started = {
33136
33159
  process: child,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdharness",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "mcpName": "io.github.Aureliolo/gdharness",
5
5
  "description": "A harness for driving a Godot 4 project from an agent: editor addons, a runtime bridge into the running game, an MCP server in front of them, and a CLI that installs and diagnoses the Godot side.",
6
6
  "type": "module",