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(
|
|
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
|
|
381
|
-
##
|
|
382
|
-
##
|
|
383
|
-
##
|
|
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 =
|
|
405
|
+
var parent: Node = outermost.get_parent()
|
|
396
406
|
if parent != null:
|
|
397
407
|
for sibling: Node in parent.get_children():
|
|
398
|
-
if 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
|
|
404
|
-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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.
|
|
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",
|