ADR 0006: Adopt Subcommand Architecture¶
Status¶
Accepted
Date¶
2025-11-21
Context¶
Shtym's CLI was initially designed as a simple wrapper: stym command args. While this works for the basic pass-through functionality, future LLM integration will require additional commands for configuration and status checking.
With a simple wrapper design, commands like stym status would be ambiguous:
- Does it execute a command named "status"?
- Does it show shtym's LLM status?
This ambiguity becomes critical when planning for future features:
stym status- Check LLM connection, API key validity, usage quotastym config- View or modify configuration (API keys, default model)stym models- List available LLM models
Without a clear subcommand structure, these would either:
- Require awkward flag syntax (
stym --status,stym --config) - Use reserved word lists (fragile, prevents wrapping commands with those names)
- Be impossible to implement without breaking changes
This decision must be made before the first release because changing from stym command to stym run command later would be a breaking change for all users.
Decision¶
Adopt a subcommand architecture using argparse subparsers:
stym run <command> [args...] # Execute and filter command
stym status # (Future) Check LLM status
stym config [options] # (Future) Manage configuration
stym models # (Future) List available models
Rationale¶
Extensibility for LLM integration:
- Clear namespace for shtym operations vs wrapped commands
- No ambiguity:
stym statusalways means shtym's status, never a command named "status" - Natural place for future subcommands without breaking changes
Industry standard pattern:
git commit,docker run,kubectl get- all use subcommandsgh pr create,cargo build- modern CLIs follow this pattern- Users familiar with these tools will immediately understand shtym's structure
Prevents future breaking changes:
- Adding
stym statuslater would break users runningstym statusexpecting command execution - Changing from
stym pytesttostym run pytestwould break all existing scripts and documentation - Must decide now, before first release and user adoption
Explicit is better than implicit:
stym run pytestclearly indicates "run this command through shtym"- No magic reserved words or special parsing rules
- Easier to explain and document
Implications¶
Positive Implications¶
- Future-proof: can add
status,config,modelswithout breaking changes - Clear separation: shtym commands vs wrapped commands
- Industry-standard pattern: familiar to users
- Enables rich CLI features: help for each subcommand, subcommand-specific options
- Testable: each subcommand can be tested independently
Concerns¶
- Slightly more typing:
stym run pytestvsstym pytest(mitigation: users can create shell aliases if desired:alias sr='stym run') - Breaking change from current development version (mitigation: no released version yet, no users affected)
Alternatives¶
Simple Wrapper (No Subcommands)¶
Keep stym command args pattern, add shtym operations as flags.
- Pros: Shortest syntax for command execution
- Cons: Awkward operation syntax (
stym --status), limited extensibility, confusing help output - Reason for rejection: Cannot support rich LLM features without awkward UX
Reserved Word List¶
Use stym command but treat certain words (status, config, etc.) as special.
- Pros: Short command execution syntax
- Cons: Cannot wrap commands named "status", "config", etc.; fragile (must maintain reserved list); confusing ("why doesn't
stym statuswork?") - Reason for rejection: Too many edge cases and user confusion
Auto-Detection¶
Detect whether argument is a shtym subcommand or external command.
- Pros: "Smart" behavior
- Cons: Magic behavior, ambiguity (what if someone creates a command named "status"?), hard to predict
- Reason for rejection: Explicit is better than implicit; too much magic
Future Direction¶
This subcommand structure is foundational and should remain stable. Expected future subcommands:
Planned:
stym status- LLM connection and usage statusstym config- Configuration managementstym models- List and manage available models
Possible:
stym history- Command execution historystym explain- Explain previous command outputstym debug- Debug mode with verbose logging
Triggers for revisiting:
- If
stym runbecomes overwhelming majority of usage and other subcommands rarely used (could addrunas default, but keep subcommand structure) - If user feedback strongly prefers shorter syntax despite tradeoffs (could add shell completion to make
stym runtyping easier)
For now, explicit subcommand architecture provides the best balance of clarity, extensibility, and future-proofing.