You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Design pass + implementation for "inverse recursion": cases where dazzlecmd is nested under another tool's CLI surface, rather than the (currently supported) downward composition where dazzlecmd or a dazzlecmd-lib aggregator imports kits.
This addresses two distinct scopes:
Library-consumer parents (immediate): MetaCommandRegistry.nest_all_under('dz') — let downstream aggregators built on dazzlecmd-lib nest all library meta-commands under a sub-parser group. Originally proposed in Root command namespace flexibility: nest, rename, selective exposure #47 as the primary feature request.
Non-library-consumer parents (design pass): mytool dz some-cmd where the parent tool is NOT built on dazzlecmd-lib. Currently architecturally unaddressed — the framework assumes downward-only composition. Solving requires either (a) AggregatorEngine.run() accepting a parent argparse subparser to attach to, or (b) the parent shelling out to dz via subprocess.
Why
The user's stated architectural vision is for dazzlecmd to be "completely recursive" — dz itself is just one configured instance of AggregatorEngine. The downward case is fully validated (wtf-windows v0.1.4-alpha). The inverse case (parents subordinating dazzlecmd) is undesigned and unimplemented.
Library API addition. A consumer constructs an aggregator and chooses to nest all library meta-commands (list, info, kit, tree, mode, setup, add, new, etc.) under a single sub-parser group:
engine=AggregatorEngine(name="my-tool", command="mt", ...)
engine.meta_commands.nest_all_under("dz")
# Now: `mt dz list` instead of `mt list`# Aggregator's own commands stay at top level
Acceptance criteria (Scope 1):
MetaCommandRegistry.nest_all_under(group_name) API works
All currently-registered meta-commands appear under the named sub-parser group
Top-level help (mt --help) shows the group as a single command with its own help
mt dz --help shows all nested meta-commands
mt list falls back to aggregator-level command if registered (precedence: top-level wins)
Companion MetaCommandRegistry.rename(old, new) for individual command renaming
Companion MetaCommandRegistry.nest_under(group, members=[...]) for partial nesting
Design problem: a third-party tool (Bash script, Go binary, Rust CLI, anything not Python) wants to expose dazzlecmd as a sub-command tree. Today the only path is subprocess shell-out (subprocess.run(["dz", cmd, ...])), which loses error context, can't share state, and is brittle.
Design questions (to resolve in /dev-workflow-process):
Is this in scope at all, or is "build a thin shell wrapper that calls dz" sufficient?
If in scope: does AggregatorEngine expose a register_with_parser(parent_subparsers) API that attaches the engine's commands to an external parser?
How does is_root=False interact? Currently it just suppresses meta-commands; this scope might need a third mode.
What's the import-time concern? A non-Python parent can't import dazzlecmd_lib at all.
Acceptance criteria (Scope 2):
Dev-workflow-process design doc covering the design space
Decision: implement, or formally close as "subprocess shell-out is the supported path"
If implementing: API design + tests + at least one example (Python parent embedding dazzlecmd as sub-namespace)
Summary
Design pass + implementation for "inverse recursion": cases where dazzlecmd is nested under another tool's CLI surface, rather than the (currently supported) downward composition where dazzlecmd or a dazzlecmd-lib aggregator imports kits.
This addresses two distinct scopes:
MetaCommandRegistry.nest_all_under('dz')— let downstream aggregators built ondazzlecmd-libnest all library meta-commands under a sub-parser group. Originally proposed in Root command namespace flexibility: nest, rename, selective exposure #47 as the primary feature request.mytool dz some-cmdwhere the parent tool is NOT built ondazzlecmd-lib. Currently architecturally unaddressed — the framework assumes downward-only composition. Solving requires either (a)AggregatorEngine.run()accepting a parent argparse subparser to attach to, or (b) the parent shelling out todzvia subprocess.Why
The user's stated architectural vision is for dazzlecmd to be "completely recursive" —
dzitself is just one configured instance ofAggregatorEngine. The downward case is fully validated (wtf-windows v0.1.4-alpha). The inverse case (parents subordinating dazzlecmd) is undesigned and unimplemented.Scope 1 —
MetaCommandRegistry.nest_all_under(group_name)Library API addition. A consumer constructs an aggregator and chooses to nest all library meta-commands (
list,info,kit,tree,mode,setup,add,new, etc.) under a single sub-parser group:Acceptance criteria (Scope 1):
MetaCommandRegistry.nest_all_under(group_name)API worksmt --help) shows the group as a single command with its own helpmt dz --helpshows all nested meta-commandsmt listfalls back to aggregator-level command if registered (precedence: top-level wins)MetaCommandRegistry.rename(old, new)for individual command renamingMetaCommandRegistry.nest_under(group, members=[...])for partial nestingScope 2 — Non-library-consumer parents (design only)
Design problem: a third-party tool (Bash script, Go binary, Rust CLI, anything not Python) wants to expose dazzlecmd as a sub-command tree. Today the only path is subprocess shell-out (
subprocess.run(["dz", cmd, ...])), which loses error context, can't share state, and is brittle.Design questions (to resolve in
/dev-workflow-process):dz" sufficient?AggregatorEngineexpose aregister_with_parser(parent_subparsers)API that attaches the engine's commands to an external parser?is_root=Falseinteract? Currently it just suppresses meta-commands; this scope might need a third mode.dazzlecmd_libat all.Acceptance criteria (Scope 2):
Phasing
nest_all_under+rename+nest_underAPI additions toMetaCommandRegistry. Tests. Closes the immediate Root command namespace flexibility: nest, rename, selective exposure #47 ask.Related issues
Analysis
See
2026-04-29__07-41-11__claude-plan__0-7-x-closeout-ultraplan.md(X-6/X-7/X-8/X-9) for placement in the closeout sequence.