gdharness 0.5.6 → 0.5.7

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
@@ -34164,6 +34164,8 @@ var init_godot_bridge = __esm(() => {
34164
34164
  server.once("error", (error) => {
34165
34165
  if (!settled) {
34166
34166
  settled = true;
34167
+ server.close();
34168
+ godotWss.close();
34167
34169
  reject(error);
34168
34170
  return;
34169
34171
  }
@@ -35730,6 +35732,7 @@ class GodotServer {
35730
35732
  lspClient = null;
35731
35733
  dapClient = null;
35732
35734
  bridgeStartupError = null;
35735
+ bridgeRetry = null;
35733
35736
  lastProjectPath = null;
35734
35737
  shutdownInitiated = false;
35735
35738
  constructor() {
@@ -35786,11 +35789,43 @@ class GodotServer {
35786
35789
  const reason = errorMessage(bridgeError);
35787
35790
  this.bridgeStartupError = code && !reason.includes(code) ? `${code}: ${reason}` : reason;
35788
35791
  console.error(`[SERVER] Warning: Godot Editor Bridge failed to start: ${this.bridgeStartupError}`);
35789
- console.error("[SERVER] Continuing without bridge-backed editor tools.");
35792
+ console.error("[SERVER] Continuing without bridge-backed editor tools, and trying again.");
35793
+ this.keepTryingTheBridge();
35794
+ }
35795
+ }
35796
+ keepTryingTheBridge() {
35797
+ if (this.bridgeRetry !== null || this.shutdownInitiated) {
35798
+ return;
35799
+ }
35800
+ this.bridgeRetry = setInterval(() => {
35801
+ this.tryTheBridgeAgain();
35802
+ }, BRIDGE_RETRY_MS);
35803
+ this.bridgeRetry.unref();
35804
+ }
35805
+ async tryTheBridgeAgain() {
35806
+ if (this.shutdownInitiated) {
35807
+ this.stopTryingTheBridge();
35808
+ return;
35809
+ }
35810
+ try {
35811
+ await this.godotBridge.start();
35812
+ } catch {
35813
+ return;
35814
+ }
35815
+ this.bridgeStartupError = null;
35816
+ this.stopTryingTheBridge();
35817
+ const bridgeStatus = this.godotBridge.getStatus();
35818
+ console.error(`[SERVER] Godot Editor Bridge came up on ${bridgeStatus.host}:${bridgeStatus.port}; editor tools are live.`);
35819
+ }
35820
+ stopTryingTheBridge() {
35821
+ if (this.bridgeRetry !== null) {
35822
+ clearInterval(this.bridgeRetry);
35823
+ this.bridgeRetry = null;
35790
35824
  }
35791
35825
  }
35792
35826
  async cleanup() {
35793
35827
  this.logDebug("Cleaning up resources");
35828
+ this.stopTryingTheBridge();
35794
35829
  if (this.activeProcess) {
35795
35830
  this.activeProcess.process?.kill();
35796
35831
  this.activeProcess = null;
@@ -36612,8 +36647,9 @@ class GodotServer {
36612
36647
  bridgeAvailable: this.bridgeStartupError === null,
36613
36648
  startupError: this.bridgeStartupError,
36614
36649
  staleNote: stale ? addonMismatch(status.addonVersion, SERVER_VERSION) : undefined,
36615
- note: isPortConflict ? "Bridge port is already in use. Another gdharness instance may own the editor bridge, so this server cannot report that editor connection." : undefined,
36616
- suggestion: isPortConflict ? "Stop duplicate gdharness/MCP server instances or re-run the command from the same server process that owns the bridge port." : undefined
36650
+ retryingBridge: this.bridgeRetry === null ? undefined : true,
36651
+ note: isPortConflict ? "Bridge port is already in use. Another gdharness instance owns the editor bridge, so this server cannot reach the editor. Usually the server this one replaced, still on its way out." : undefined,
36652
+ suggestion: isPortConflict ? `This server is asking for the port again every ${BRIDGE_RETRY_MS / 1000}s and takes it the moment the other one lets go, so editor tools come back on their own. Ask again, or end the older gdharness process to have it now.` : undefined
36617
36653
  };
36618
36654
  }
36619
36655
  async editorPlayingState() {
@@ -37091,7 +37127,7 @@ async function runGodotServer() {
37091
37127
  const server = new GodotServer;
37092
37128
  await server.run();
37093
37129
  }
37094
- var UPDATE_NOTICE_EVERY = 500, FEEDBACK_NOTICE_EVERY = 250, run5, __dirname2, EDITOR_RESTART_TIMEOUT_MS = 90000, PATH_SOLUTIONS, PROJECT_FILE_ARGUMENTS, DEBUG_STATE_CALLS, HEADLESS_OPERATIONS, PROJECT_INFO_SECTIONS;
37130
+ var UPDATE_NOTICE_EVERY = 500, FEEDBACK_NOTICE_EVERY = 250, run5, __dirname2, EDITOR_RESTART_TIMEOUT_MS = 90000, BRIDGE_RETRY_MS = 2000, PATH_SOLUTIONS, PROJECT_FILE_ARGUMENTS, DEBUG_STATE_CALLS, HEADLESS_OPERATIONS, PROJECT_INFO_SECTIONS;
37095
37131
  var init_server3 = __esm(() => {
37096
37132
  init_mcp();
37097
37133
  init_stdio2();
package/build/index.js CHANGED
@@ -25468,6 +25468,8 @@ class GodotBridge extends EventEmitter {
25468
25468
  server.once("error", (error) => {
25469
25469
  if (!settled) {
25470
25470
  settled = true;
25471
+ server.close();
25472
+ godotWss.close();
25471
25473
  reject(error);
25472
25474
  return;
25473
25475
  }
@@ -28405,6 +28407,7 @@ var FEEDBACK_NOTICE_EVERY = 250;
28405
28407
  var run3 = promisify3(execFile3);
28406
28408
  var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
28407
28409
  var EDITOR_RESTART_TIMEOUT_MS = 90000;
28410
+ var BRIDGE_RETRY_MS = 2000;
28408
28411
  var PATH_SOLUTIONS = [
28409
28412
  'Give the path relative to the project, such as "scenes/main.tscn" or "res://scenes/main.tscn"',
28410
28413
  "Point projectPath at the project the file belongs to"
@@ -28511,6 +28514,7 @@ class GodotServer {
28511
28514
  lspClient = null;
28512
28515
  dapClient = null;
28513
28516
  bridgeStartupError = null;
28517
+ bridgeRetry = null;
28514
28518
  lastProjectPath = null;
28515
28519
  shutdownInitiated = false;
28516
28520
  constructor() {
@@ -28567,11 +28571,43 @@ class GodotServer {
28567
28571
  const reason = errorMessage(bridgeError);
28568
28572
  this.bridgeStartupError = code && !reason.includes(code) ? `${code}: ${reason}` : reason;
28569
28573
  console.error(`[SERVER] Warning: Godot Editor Bridge failed to start: ${this.bridgeStartupError}`);
28570
- console.error("[SERVER] Continuing without bridge-backed editor tools.");
28574
+ console.error("[SERVER] Continuing without bridge-backed editor tools, and trying again.");
28575
+ this.keepTryingTheBridge();
28576
+ }
28577
+ }
28578
+ keepTryingTheBridge() {
28579
+ if (this.bridgeRetry !== null || this.shutdownInitiated) {
28580
+ return;
28581
+ }
28582
+ this.bridgeRetry = setInterval(() => {
28583
+ this.tryTheBridgeAgain();
28584
+ }, BRIDGE_RETRY_MS);
28585
+ this.bridgeRetry.unref();
28586
+ }
28587
+ async tryTheBridgeAgain() {
28588
+ if (this.shutdownInitiated) {
28589
+ this.stopTryingTheBridge();
28590
+ return;
28591
+ }
28592
+ try {
28593
+ await this.godotBridge.start();
28594
+ } catch {
28595
+ return;
28596
+ }
28597
+ this.bridgeStartupError = null;
28598
+ this.stopTryingTheBridge();
28599
+ const bridgeStatus = this.godotBridge.getStatus();
28600
+ console.error(`[SERVER] Godot Editor Bridge came up on ${bridgeStatus.host}:${bridgeStatus.port}; editor tools are live.`);
28601
+ }
28602
+ stopTryingTheBridge() {
28603
+ if (this.bridgeRetry !== null) {
28604
+ clearInterval(this.bridgeRetry);
28605
+ this.bridgeRetry = null;
28571
28606
  }
28572
28607
  }
28573
28608
  async cleanup() {
28574
28609
  this.logDebug("Cleaning up resources");
28610
+ this.stopTryingTheBridge();
28575
28611
  if (this.activeProcess) {
28576
28612
  this.activeProcess.process?.kill();
28577
28613
  this.activeProcess = null;
@@ -29393,8 +29429,9 @@ class GodotServer {
29393
29429
  bridgeAvailable: this.bridgeStartupError === null,
29394
29430
  startupError: this.bridgeStartupError,
29395
29431
  staleNote: stale ? addonMismatch(status.addonVersion, SERVER_VERSION) : undefined,
29396
- note: isPortConflict ? "Bridge port is already in use. Another gdharness instance may own the editor bridge, so this server cannot report that editor connection." : undefined,
29397
- suggestion: isPortConflict ? "Stop duplicate gdharness/MCP server instances or re-run the command from the same server process that owns the bridge port." : undefined
29432
+ retryingBridge: this.bridgeRetry === null ? undefined : true,
29433
+ note: isPortConflict ? "Bridge port is already in use. Another gdharness instance owns the editor bridge, so this server cannot reach the editor. Usually the server this one replaced, still on its way out." : undefined,
29434
+ suggestion: isPortConflict ? `This server is asking for the port again every ${BRIDGE_RETRY_MS / 1000}s and takes it the moment the other one lets go, so editor tools come back on their own. Ask again, or end the older gdharness process to have it now.` : undefined
29398
29435
  };
29399
29436
  }
29400
29437
  async editorPlayingState() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdharness",
3
- "version": "0.5.6",
3
+ "version": "0.5.7",
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",