gdharness 1.3.14 → 1.3.15

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
@@ -18385,12 +18385,14 @@ function unitsOf(suites, times, splitPast = SPLIT_PAST_SECONDS) {
18385
18385
  return suites.flatMap((suite) => {
18386
18386
  const time = times[suite.path];
18387
18387
  const costOf = (func) => time?.cases[func] ?? caseCost;
18388
+ const timedCase = (func) => time?.cases[func] !== undefined;
18388
18389
  const around = time === undefined ? aroundCost : Math.max(0, time.seconds - Object.values(time.cases).reduce((sum, s) => sum + s, 0));
18389
18390
  const whole = around + suite.cases.reduce((sum, func) => sum + costOf(func), 0);
18390
18391
  const wholly = {
18391
18392
  suite: suite.path,
18392
18393
  cases: suite.cases,
18393
18394
  cost: whole,
18395
+ timed: suite.cases.every(timedCase),
18394
18396
  windowed: suite.windowed,
18395
18397
  headless: suite.headless
18396
18398
  };
@@ -18405,6 +18407,7 @@ function unitsOf(suites, times, splitPast = SPLIT_PAST_SECONDS) {
18405
18407
  suite: suite.path,
18406
18408
  cases: [func],
18407
18409
  cost: around + costOf(func),
18410
+ timed: timedCase(func),
18408
18411
  windowed: false,
18409
18412
  headless: suite.headless
18410
18413
  }
@@ -18415,6 +18418,7 @@ function unitsOf(suites, times, splitPast = SPLIT_PAST_SECONDS) {
18415
18418
  cases: [func],
18416
18419
  row: { index, rest: index === rows.length - 1 },
18417
18420
  cost: around + seconds,
18421
+ timed: true,
18418
18422
  windowed: false,
18419
18423
  headless: suite.headless
18420
18424
  }));
@@ -18432,7 +18436,7 @@ function dealt(units, declared, most) {
18432
18436
  const restart = windowed.length > 0 ? ENGINE_START_SECONDS : 0;
18433
18437
  const total = units.reduce((sum, unit) => sum + unit.cost, 0);
18434
18438
  const slowest = Math.max(together, headless[0]?.cost ?? 0);
18435
- const count = Math.max(1, Math.min(most, headless.length + (windowed.length > 0 ? 1 : 0), Math.ceil(total / Math.max(slowest, ENGINE_START_SECONDS))));
18439
+ const count = Math.max(1, Math.min(most, headless.length + (windowed.length > 0 ? 1 : 0), Math.ceil(total / Math.max(slowest, ENGINE_START_SECONDS)) + headless.filter((unit) => !unit.timed).length));
18436
18440
  const bins = Array.from({ length: count }, () => []);
18437
18441
  const loads = Array.from({ length: count }, (_, lane) => lane === 0 ? together + restart : 0);
18438
18442
  for (const unit of headless) {
@@ -245,6 +245,14 @@ func _wait_for_the_profiler() -> void:
245
245
  OS.delay_msec(1)
246
246
 
247
247
 
248
+ ## Whether this runtime is listening for gdharness's server. It is not in a release build, a script
249
+ ## run, a scene the project keeps quiet, an engine `gdharness spread` started, or a game that could
250
+ ## not have its port, though the node is there in all of them, so ask this rather than whether the
251
+ ## node exists.
252
+ func serving() -> bool:
253
+ return _enabled and _server != null and _server.is_listening()
254
+
255
+
248
256
  func _ready() -> void:
249
257
  name = "GdharnessRuntime"
250
258
  # The TCP control loop runs in _process. With the default PROCESS_MODE_INHERIT it stops
@@ -1,16 +1,27 @@
1
1
  extends Node
2
2
  ## Brings gdharness's runtime up in a debug build that has its addon, and does nothing elsewhere.
3
3
  ##
4
- ## `project.godot` names this file rather than the addon's script. `addons/` is often not committed
5
- ## and exports leave it out, so an entry naming the addon boots a fresh clone or an exported build
6
- ## with a missing script. `gdharness setup` writes this file, and `gdharness doctor` says when it is
7
- ## not the one that gdharness ships. The runtime refuses a `-s` script run by itself unless
8
- ## `gdharness/runtime/serve_script_runs` is on, so that is left to it.
4
+ ## `project.godot` names this file rather than the addon's script. The addons folder is often not
5
+ ## committed and exports leave it out, so an entry naming the addon boots a fresh clone or an
6
+ ## exported build with a missing script. `gdharness setup` writes this file, and `gdharness doctor`
7
+ ## says when it is not the one that gdharness ships. The runtime refuses a `-s` script run by itself
8
+ ## unless the project's serve_script_runs setting is on, so that is left to it.
9
9
 
10
10
  ## Loaded by path as it runs rather than preloaded: a preload resolves when this script is parsed,
11
11
  ## and in a build without the addon that is the missing script this file is here to avoid.
12
12
  const RUNTIME: String = "res://addons/gdharness_runtime/runtime_autoload.gd"
13
13
 
14
+ var _runtime: Node
15
+
16
+
17
+ ## Whether gdharness's runtime is listening in this engine: false in a release build, a script run
18
+ ## and an engine without the addon, though this node is in every one of them.
19
+ func serving() -> bool:
20
+ if not is_instance_valid(_runtime) or not _runtime.has_method("serving"):
21
+ return false
22
+ var answered: Variant = _runtime.call("serving")
23
+ return answered is bool and answered
24
+
14
25
 
15
26
  func _ready() -> void:
16
27
  if not OS.is_debug_build() or not ResourceLoader.exists(RUNTIME):
@@ -26,3 +37,4 @@ func _ready() -> void:
26
37
  # autoloads, and a deferred add would bring the runtime up only after the main scene's _ready.
27
38
  # Added now, it announces before the main scene runs, as it does when an entry names it.
28
39
  add_child(runtime)
40
+ _runtime = runtime
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdharness",
3
- "version": "1.3.14",
3
+ "version": "1.3.15",
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",