gdharness 1.0.31 → 1.0.32
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
|
@@ -16575,7 +16575,7 @@ var init_tool_definitions = __esm(() => {
|
|
|
16575
16575
|
operations: {
|
|
16576
16576
|
tree: { summary: "the live scene tree", requires: [] },
|
|
16577
16577
|
text: {
|
|
16578
|
-
summary: "every line of text under nodePath, the values in its fields included, in the order somebody reads the screen, leaving out what is hidden and everything under it. Every line reads as drawn: rich text without its tags, text only as far as it has been typed out, a translation rather than its key, an upper-case label in capitals and a secret field as its mask. Tab titles, menu bar titles, list items, a tree's column titles and rows, and an open menu's items read a line each",
|
|
16578
|
+
summary: "every line of text under nodePath, the values in its fields included, in the order somebody reads the screen, leaving out what is hidden and everything under it. Every line reads as drawn: rich text without its tags, text only as far as it has been typed out, a translation rather than its key, an upper-case label in capitals and a secret field as its mask. Tab titles, menu bar titles, list items, a tree's column titles and rows, and an open menu's items and the titles of its separators read a line each",
|
|
16579
16579
|
requires: []
|
|
16580
16580
|
},
|
|
16581
16581
|
find: {
|
|
@@ -664,7 +664,19 @@ func choose(params: Dictionary) -> Dictionary:
|
|
|
664
664
|
"message": "%s has no such item. It holds: %s" % [node_path, ", ".join(_items_of(menu))]
|
|
665
665
|
}
|
|
666
666
|
if menu.is_item_separator(index):
|
|
667
|
-
|
|
667
|
+
var heading: String = Words.item_says(menu, index).strip_edges()
|
|
668
|
+
return {
|
|
669
|
+
"type": "error",
|
|
670
|
+
"message":
|
|
671
|
+
(
|
|
672
|
+
"%s item %d is a separator, not a choice" % [node_path, index]
|
|
673
|
+
if heading.is_empty()
|
|
674
|
+
else (
|
|
675
|
+
"%s item %d, %s, is a separator heading the items below it, not a choice"
|
|
676
|
+
% [node_path, index, heading]
|
|
677
|
+
)
|
|
678
|
+
)
|
|
679
|
+
}
|
|
668
680
|
if menu.is_item_disabled(index):
|
|
669
681
|
return {
|
|
670
682
|
"type": "error",
|
|
@@ -732,26 +744,39 @@ static func _wanted_item(menu: PopupMenu, params: Dictionary) -> int:
|
|
|
732
744
|
var wanted: String = str(params.get("text", ""))
|
|
733
745
|
if wanted.is_empty():
|
|
734
746
|
return -1
|
|
747
|
+
# The items before the separators, because a heading can carry the same words as an item under
|
|
748
|
+
# it, and finding the heading first refused the choice the caller meant. A separator is still
|
|
749
|
+
# looked for after, so a heading asked for by name is refused as one rather than as missing.
|
|
750
|
+
var order: Array[int] = []
|
|
751
|
+
for separators: bool in [false, true]:
|
|
752
|
+
for index: int in menu.get_item_count():
|
|
753
|
+
if menu.is_item_separator(index) == separators:
|
|
754
|
+
order.append(index)
|
|
735
755
|
var shown: Array[String] = []
|
|
736
756
|
var held: Array[String] = []
|
|
737
|
-
for index: int in
|
|
757
|
+
for index: int in order:
|
|
738
758
|
shown.append(Words.item_says(menu, index))
|
|
739
759
|
held.append(menu.get_item_text(index))
|
|
740
760
|
for words: Array[String] in [shown, held]:
|
|
741
|
-
for
|
|
742
|
-
if words[
|
|
743
|
-
return
|
|
744
|
-
for
|
|
745
|
-
if words[
|
|
746
|
-
return
|
|
761
|
+
for at: int in words.size():
|
|
762
|
+
if words[at] == wanted:
|
|
763
|
+
return order[at]
|
|
764
|
+
for at: int in words.size():
|
|
765
|
+
if words[at].nocasecmp_to(wanted) == 0:
|
|
766
|
+
return order[at]
|
|
747
767
|
return -1
|
|
748
768
|
|
|
749
769
|
|
|
750
|
-
## What the menu shows, for a refusal that names the choices rather than the miss
|
|
770
|
+
## What the menu shows, for a refusal that names the choices rather than the miss: a titled
|
|
771
|
+
## separator marked as the heading it is, and one with no title left out, since it shows nothing.
|
|
751
772
|
static func _items_of(menu: PopupMenu) -> Array[String]:
|
|
752
773
|
var said: Array[String] = []
|
|
753
774
|
for index: int in menu.get_item_count():
|
|
754
|
-
|
|
775
|
+
var words: String = Words.item_says(menu, index)
|
|
776
|
+
if not menu.is_item_separator(index):
|
|
777
|
+
said.append("%d: %s" % [index, words])
|
|
778
|
+
elif not words.strip_edges().is_empty():
|
|
779
|
+
said.append("%d: %s (a heading)" % [index, words])
|
|
755
780
|
return said
|
|
756
781
|
|
|
757
782
|
|
|
@@ -49,10 +49,11 @@ static func lines_said_by(node: Node) -> Array[String]:
|
|
|
49
49
|
for item: int in list.item_count:
|
|
50
50
|
_keep(_as_drawn(node, list.get_item_text(item), list.get_item_auto_translate_mode(item)), lines)
|
|
51
51
|
elif node is PopupMenu:
|
|
52
|
+
# A separator too, by its title: the popup draws a titled one as a heading over the items
|
|
53
|
+
# below it, and one without a title says nothing and is dropped as an empty line.
|
|
52
54
|
var menu: PopupMenu = node
|
|
53
55
|
for item: int in menu.item_count:
|
|
54
|
-
|
|
55
|
-
_keep(item_says(menu, item), lines)
|
|
56
|
+
_keep(item_says(menu, item), lines)
|
|
56
57
|
elif node is Tree:
|
|
57
58
|
var tree: Tree = node
|
|
58
59
|
if tree.column_titles_visible:
|
package/build/index.js
CHANGED
|
@@ -30701,7 +30701,7 @@ var TOOL_SPECS = [
|
|
|
30701
30701
|
operations: {
|
|
30702
30702
|
tree: { summary: "the live scene tree", requires: [] },
|
|
30703
30703
|
text: {
|
|
30704
|
-
summary: "every line of text under nodePath, the values in its fields included, in the order somebody reads the screen, leaving out what is hidden and everything under it. Every line reads as drawn: rich text without its tags, text only as far as it has been typed out, a translation rather than its key, an upper-case label in capitals and a secret field as its mask. Tab titles, menu bar titles, list items, a tree's column titles and rows, and an open menu's items read a line each",
|
|
30704
|
+
summary: "every line of text under nodePath, the values in its fields included, in the order somebody reads the screen, leaving out what is hidden and everything under it. Every line reads as drawn: rich text without its tags, text only as far as it has been typed out, a translation rather than its key, an upper-case label in capitals and a secret field as its mask. Tab titles, menu bar titles, list items, a tree's column titles and rows, and an open menu's items and the titles of its separators read a line each",
|
|
30705
30705
|
requires: []
|
|
30706
30706
|
},
|
|
30707
30707
|
find: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdharness",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.32",
|
|
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",
|