gdharness 1.2.2 → 1.2.3

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
@@ -42866,6 +42866,9 @@ function runIsUp(run, editorSays, editorPlay = null, now = Date.now()) {
42866
42866
  function noCodeWillCome(run) {
42867
42867
  return !exited(run);
42868
42868
  }
42869
+ function transcriptNote(transcript, going) {
42870
+ return going ? `Everything this run has printed is in ${transcript}, uncapped and still being written. Read it for output, not for whether the run is alive: a transcript that stops growing is a run between prints. running above is asked of the operating system while there is a process to ask about, and for an editor-played run that announced no runtime it is the editor's answer instead, which can lag after the game has gone.` : `Everything this run printed is in ${transcript}, uncapped and complete, since the run is over.`;
42871
+ }
42869
42872
  function stopWaitMs() {
42870
42873
  return waitFromEnv("GDHARNESS_STOP_WAIT_MS", 1e4);
42871
42874
  }
@@ -47601,7 +47604,7 @@ class GodotServer {
47601
47604
  notes.push(`The debug adapter this run's console arrives over went away while the run was going, so what is below has a hole in it and the counts are of what was heard rather than of what was printed. ${back ? "It is connected again, and the line marking where is in the log." : "It is still gone, so nothing further will arrive here."} The project's own user://logs/godot.log has the rest, and "no entries" here means "not heard" rather than a quiet run.`);
47602
47605
  }
47603
47606
  if (run.transcript !== null && selected.omitted > 0) {
47604
- notes.push(`Everything this run has printed is in ${run.transcript}, uncapped and still being written. Read it for output, not for whether the run is alive: a transcript that stops growing is a run between prints. running above is asked of the operating system while there is a process to ask about, and for an editor-played run that announced no runtime it is the editor's answer instead, which can lag after the game has gone.`);
47607
+ notes.push(transcriptNote(run.transcript, going));
47605
47608
  }
47606
47609
  return this.jsonTextResponse({
47607
47610
  running: going,
@@ -377,10 +377,15 @@ static func drawn_over(target: Control) -> Node:
377
377
 
378
378
 
379
379
  ## Why [param node], which is not visible in the tree, is not, as a parenthesis to follow its path:
380
- ## which nodes hide it, nearest first, and what is shown beside the nearest. Reading visible off
381
- ## the node itself says true when only an ancestor is hidden, so without this a caller had nothing
382
- ## to unhide; every hidden one is named because unhiding only the nearest leaves the rest hiding it.
383
- ## "" when nothing on the way up says so.
380
+ ## which nodes hide it, nearest first, and what has taken its place. Reading visible off the node
381
+ ## itself says true when only an ancestor is hidden, so without this a caller had nothing to unhide;
382
+ ## every hidden one is named because unhiding only the nearest leaves the rest hiding it.
383
+ ##
384
+ ## What has taken its place is what a click at its centre reaches now, which is the screen a game
385
+ ## shows instead. Without a control there, as for a 3D node, it is what is shown beside the
386
+ ## outermost hidden node: a game hides a screen by hiding the screen's root, and the nearest hidden
387
+ ## node can be a panel deep inside it whose siblings are hidden with it. "" when nothing on the way
388
+ ## up says the node is hidden.
384
389
  static func why_hidden(node: Node) -> String:
385
390
  var hiding: Array[Node] = _hiding(node)
386
391
  if hiding.is_empty():
@@ -391,27 +396,71 @@ static func why_hidden(node: Node) -> String:
391
396
  named.append("its own visible is false")
392
397
  else:
393
398
  named.append("%s is hidden%s" % [one.get_path(), "" if named.is_empty() else " too"])
399
+ var control: Control = node as Control
400
+ var instead: Node = null if control == null else drawn_at(control)
401
+ if instead != null:
402
+ return " (%s; %s is drawn where it would be)" % [", and ".join(named), instead.get_path()]
403
+ var outermost: Node = hiding.back()
394
404
  var beside: Array[String] = []
395
- var parent: Node = hiding[0].get_parent()
405
+ var parent: Node = outermost.get_parent()
396
406
  if parent != null:
397
407
  for sibling: Node in parent.get_children():
398
- if sibling != hiding[0] and _shown(sibling):
408
+ if sibling != outermost and _shown(sibling):
399
409
  beside.append(str(sibling.get_path()))
400
- return " (%s%s)" % [", and ".join(named), _shown_beside(beside)]
410
+ return " (%s%s)" % [", and ".join(named), _shown_beside(beside, outermost)]
411
+
412
+
413
+ ## What a click at the centre of [param target], which is hidden, would reach instead, or null.
414
+ ##
415
+ ## The topmost thing there that takes the pointer, whatever order it is drawn in relative to the
416
+ ## target, since the target is not drawn at all; and never a node holding the target, which covers
417
+ ## its place by containing it and is not what took it.
418
+ static func drawn_at(target: Control) -> Node:
419
+ var drawn: Array[Node] = _pointer_takers(target.get_tree().root)
420
+ var point: Vector2 = _centre_of(target)
421
+ var none: Dictionary[ScrollContainer, Vector2] = {}
422
+ var viewport: Viewport = target.get_viewport()
423
+ var best: Control = null
424
+ for each: Node in drawn:
425
+ var window: Window = each as Window
426
+ if window != null:
427
+ if _window_over(target, point, window):
428
+ return window
429
+ continue
430
+ var control: Control = each
431
+ if control.is_ancestor_of(target) or target.is_ancestor_of(control):
432
+ continue
433
+ if control.get_viewport() != viewport or not _holds(control, point):
434
+ continue
435
+ if _clipped_away(control, point, none):
436
+ continue
437
+ if best == null or _drawn_above(control, best):
438
+ best = control
439
+ return best
440
+
441
+
442
+ ## Whether [param control] is drawn above [param other]: on a higher canvas layer, or later on the
443
+ ## same one.
444
+ static func _drawn_above(control: Control, other: Control) -> bool:
445
+ var layer: int = _layer_of(control)
446
+ var other_layer: int = _layer_of(other)
447
+ return layer > other_layer or (layer == other_layer and control.is_greater_than(other))
401
448
 
402
449
 
403
- ## "; A, B and C beside it are shown" for [param beside], naming three at most and counting the rest.
404
- static func _shown_beside(beside: Array[String]) -> String:
450
+ ## "; A, B and C are shown beside N" for [param beside] and the hidden node [param hidden], naming
451
+ ## three at most and counting the rest.
452
+ static func _shown_beside(beside: Array[String], hidden: Node) -> String:
405
453
  if beside.is_empty():
406
454
  return ""
455
+ var at: String = str(hidden.get_path())
407
456
  if beside.size() == 1:
408
- return "; %s beside it is shown" % beside[0]
457
+ return "; %s is shown beside %s" % [beside[0], at]
409
458
  var listed: Array[String] = beside.slice(0, 3)
410
459
  var rest: int = beside.size() - listed.size()
411
460
  if rest > 0:
412
- return "; %s and %d more beside it are shown" % [", ".join(listed), rest]
461
+ return "; %s and %d more are shown beside %s" % [", ".join(listed), rest, at]
413
462
  var last: String = listed.pop_back()
414
- return "; %s and %s beside it are shown" % [", ".join(listed), last]
463
+ return "; %s and %s are shown beside %s" % [", ".join(listed), last, at]
415
464
 
416
465
 
417
466
  ## The nodes whose visible is false and keeps [param node] from being drawn, nearest first. Walked
package/build/index.js CHANGED
@@ -35294,6 +35294,9 @@ function runIsUp(run, editorSays, editorPlay = null, now = Date.now()) {
35294
35294
  function noCodeWillCome(run) {
35295
35295
  return !exited(run);
35296
35296
  }
35297
+ function transcriptNote(transcript, going) {
35298
+ return going ? `Everything this run has printed is in ${transcript}, uncapped and still being written. Read it for output, not for whether the run is alive: a transcript that stops growing is a run between prints. running above is asked of the operating system while there is a process to ask about, and for an editor-played run that announced no runtime it is the editor's answer instead, which can lag after the game has gone.` : `Everything this run printed is in ${transcript}, uncapped and complete, since the run is over.`;
35299
+ }
35297
35300
  function stopWaitMs() {
35298
35301
  return waitFromEnv("GDHARNESS_STOP_WAIT_MS", 1e4);
35299
35302
  }
@@ -40098,7 +40101,7 @@ class GodotServer {
40098
40101
  notes.push(`The debug adapter this run's console arrives over went away while the run was going, so what is below has a hole in it and the counts are of what was heard rather than of what was printed. ${back ? "It is connected again, and the line marking where is in the log." : "It is still gone, so nothing further will arrive here."} The project's own user://logs/godot.log has the rest, and "no entries" here means "not heard" rather than a quiet run.`);
40099
40102
  }
40100
40103
  if (run.transcript !== null && selected.omitted > 0) {
40101
- notes.push(`Everything this run has printed is in ${run.transcript}, uncapped and still being written. Read it for output, not for whether the run is alive: a transcript that stops growing is a run between prints. running above is asked of the operating system while there is a process to ask about, and for an editor-played run that announced no runtime it is the editor's answer instead, which can lag after the game has gone.`);
40104
+ notes.push(transcriptNote(run.transcript, going));
40102
40105
  }
40103
40106
  return this.jsonTextResponse({
40104
40107
  running: going,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdharness",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
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",