Command-line access to a running app GUI's live scene graph over the
netdebug ZeroMQ backend: navigate and display nodes and properties, set
typed values and exprs, create and remove Layer/VectorArt nodes, and
push shape data — all without recompiling the app.
The system SHALL provide a python -m pydrk command (runnable from
bin/app, argparse-based) whose commands talk to a running app's netdebug
REQ/REP endpoint. The endpoint SHALL default to 127.0.0.1:9484 and be
overridable with --addr/--port on every subcommand. When no app is
listening, commands SHALL print an error naming the endpoint they tried and
exit non-zero.
python -m pydrk ping runs against a running dev-mode apphello and exits 0--port 9999 and nothing is listening there127.0.0.1:9999 and exits non-zeroThe ls [path] subcommand SHALL list the contents of a scene node: first
its child nodes as one row per child showing the child name, numeric node
id, and lowercase type name (e.g. content 1234567890 layer), then its
properties as one row each showing name, type, and current value summary
(exprs as source, shapes as a placeholder). Paths that do not resolve SHALL
produce a readable node_not_found error and non-zero exit.
python -m pydrk ls /setting and window) followed by the root's propertiespython -m pydrk ls /nopenode_not_found for /nope and exits non-zeroThe tree subcommand SHALL recursively print a node's descendants with a
--depth N limit, showing for every node: its name, id, type, properties
with current values, signals with registered slots, and methods with full
signatures. Property values SHALL be rendered distinctly per status: plain
values as literals, exprs as their decompiled source (e.g. w/2), null as
null, unset-with-default as the default, and vector shapes as a
placeholder (shapes are write-only over the wire). Methods that declare a
result SHALL show the result argument types (not be silently truncated).
python -m pydrk tree / --depth 2python -m pydrk tree /plugin/drkget_default_address method line includes its result
signature (a str result), demonstrating result decodingThe props [path] subcommand SHALL list a node's properties with their
metadata: name, type, subtype, array length (marking unbounded), null/expr
allowance, ranges when bounded, enum items when present, and UI text. The
show [path] PROP subcommand SHALL print all info for one property: its
full metadata (as listed for props, plus its depends list) followed by
the current per-index values with their statuses. The get [path] PROP
[idx] subcommand SHALL print the property's per-index values (only index
idx when given), each on its own line annotated with its status
(value, expr, null, or unset). For all three, a leading path
argument is optional and defaults to the shell cwd (or / in one-shot
mode); in get, when the final argument is an integer it is taken as the
index.
python -m pydrk props /window/contentalpha property (or another bounded one) shows its [0.0, 1.0] rangepython -m pydrk show /window/content alphafloat32,
the [0.0, 1.0] range, its UI text) followed by 0: value 1.0python -m pydrk get is run for itexpr and shows the expr source stringThe set subcommand SHALL set values using the property's server-declared
type for encoding (bool, uint32, float32, str, enum, scene_node_id as
decimal). Its grammar is set [path] PROP [idx] VAL: the last argument
is always the value; when the argument before the value is an integer it
is taken as the array index (default 0); any remaining leading arguments
(joined with /) are the node path, optional and defaulting to the shell
cwd (or / in one-shot mode). The --expr flag sends the value as expr
source to be compiled server-side. After a successful set the app SHALL
redraw. Server rejections (wrong type, out-of-range, invalid enum item,
invalid expr syntax, unknown expr global) SHALL be printed readably with
the error name and exit non-zero, and a usage error SHALL be reported
when the arguments cannot be parsed into the grammar (e.g. a property
name is missing).
python -m pydrk set /window/content/chat is_visible falseget shows false, and the app window updatespython -m pydrk set /window/content rect 2 "w/2" --exprget /window/content rect 2 shows expr "w/2"5.0 when its range is [0.0, 1.0]property_out_of_range and exits non-zeropython -m pydrk set <path> rect 2 "w/2" --exprget for that index shows expr "w/2"The mknode subcommand SHALL create and attach a node in one step:
mknode <parent_path> <name> <type> where <type> is layer or
vector_art. On success it SHALL print the new node's id and full path,
and the node SHALL immediately appear in ls <parent_path> with all its
factory properties (queryable via props). Creating a node whose parent
path does not resolve SHALL fail with node_not_found; a name colliding
with an existing sibling SHALL fail with a name-conflict error; any other
type string SHALL fail with a readable unsupported node type message
without touching the tree.
python -m pydrk mknode /window/content debug_layer layer then
python -m pydrk mknode /window/content/debug_layer art1 vector_artprops /window/content/debug_layer/art1 lists the factory properties
including shapepython -m pydrk mknode /window/content debug_layer chatviewThe rmnode <path> subcommand SHALL remove any node subtree from its
parent (the node and its descendants disappear from listings) and trigger
an app redraw; GPU resources owned by removed nodes SHALL be released by
the app. This is a debugging tool with full scene-graph access: built-in
nodes are removable the same way as wire-created ones. Removing the scene
root / SHALL fail with a readable error. All removals are runtime-only
and undone by restarting the app.
mknode and python -m pydrk rmnode /window/content/debug_layer runsls /window/content no longer lists debug_layer and the app redrawspython -m pydrk rmnode <path-to-a-built-in-layer> runs against a running dev apppython -m pydrk rmnode /node_not_removable and the tree is unchangedThe set-shape <path> [--prop NAME] [--index N] subcommand SHALL build a
vector shape from repeatable primitive flags and push it as the property's
value: --box X1 Y1 X2 Y2, --gbox X1 Y1 X2 Y2 (top and bottom colors),
--vgradient X1 Y1 X2 Y2 TOPCOLOR BOTCOLOR STRIPS GAMMA, --outline X1 Y1
X2 Y2 BORDERPX, --line X1 Y1 X2 Y2 THICKNESS, and --glow CX CY W H
SEGMENTS COLOR, each taking colors as R G B A float groups. Coordinates
SHALL accept both plain numbers and expr source strings (e.g. w/2), and
primitives SHALL join into a single shape in flag order. Shape indices are
16-bit; vertex counts beyond that SHALL be rejected client-side with a
readable message. After a successful set the shape SHALL be visible in the
app window at the next frame (given a non-empty rect and is_visible).
vector_art node exists with rect set, and
python -m pydrk set-shape /window/content/debug_layer/art1 --box 0 0 w 10 --color 1 0 0 1
runs (with w passed as an expr coordinate)q/3)sexpr_global_not_found) and exits non-zeroThe methods <path> subcommand SHALL list each method with its argument
signatures and, when declared, result signatures; signals <path> SHALL
list signal names. The call <path> <method> [ARGS...] subcommand SHALL
encode positional ARGS according to the method's declared argument types
(uint32/uint64/float32/bool/str; hash as 64-char hex), print the decoded
result when the method returns one, and void when it does not.
python -m pydrk call /window/content/chat/view copy_selectvoid and exits 0str with a non-string token where coercion is impossible, or supplying the wrong number of argumentsEvery subcommand SHALL map netdebug error frames to the human-readable
error name from the netdebug error table (e.g. property_not_found)
together with command context (path, property, method as applicable), and
exit non-zero. Unknown error codes SHALL be printed with their numeric
value.
python -m pydrk get /window no_such_propproperty_not_found and the exit code is non-zeroRunning python -m pydrk with no subcommand SHALL start an interactive
shell connected to the same endpoint, maintaining a current working node
path (cwd, initially /) shown in the prompt (e.g. pydrk:/window>).
Shell commands SHALL reuse the one-shot command set with path arguments
resolved against cwd; absolute paths starting with / SHALL be honored as
absolute. pwd SHALL print the cwd; cd <path> SHALL change it, cd
with no argument SHALL go to /, .. SHALL pop one node, and cd into a
path that has children but is not itself resolvable SHALL fail with
node_not_found leaving cwd unchanged; exit (or EOF) SHALL quit the
shell. In the shell, the optional-path grammar of set, get and
show SHALL default to the cwd node, so the workflow cd into a node,
ls its contents, show foo for full property info, set foo XXX (or
set foo 2 XXX for an array index) works without repeating paths.
Server errors in the shell SHALL print the readable error name and return
to the prompt (the shell SHALL NOT exit on a failed command).
cd /window, then cd content,
then ls, then show is_visible, then set is_visible falsels lists the content node's children and properties, show
prints the is_visible metadata and current value, set reports
success, the app redraws, and a subsequent get is_visible prints
falseget no_such_prop)The interactive shell SHALL provide tab completion (stdlib readline):
completing the first word yields command names; completing a later word
that looks like a path yields child node names of the referenced parent,
fetched live from the running app (so newly created mknode nodes
complete after creation); completing the first positional argument of
get, set and show yields the cwd node's property names together
with its child node paths (both are valid leading arguments under the
optional-path grammar). Completion SHALL NOT
print duplicates, and completing a partial token SHALL offer all matches
when ambiguous. If readline is unavailable the shell SHALL still work
without completion.
cd /win and presses Tab/window/is_visible property and the user
types set is_v and presses Tabis_visiblemknode /window/content debug_layer layer was run and the user
types cd /window/content/debug and presses Tab/window/content/debug_layer/