Unification Decisions
This document tracks decisions where we chose unified approaches over specialized ones. The goal: avoid runaway complexity by composing from fewer primitives.
See docs/philosophy.md for the "Generalize, Don't Multiply" tenet.
Core Commands: view, edit, analyze
Decision: Three composable primitives instead of many specialized commands.
Alternatives rejected:
moss show-imports,moss show-deps,moss show-callees,moss show-symbols→ unified underviewwith flagsmoss health,moss complexity,moss security,moss hotspots→ unified underanalyzewith flagsmoss edit-function,moss rename-symbol,moss add-import→ unified undereditwith structural targeting
Why: Each new command adds cognitive load. Flags on a core command are discoverable via --help. Same path resolution, filtering, and output formatting applies everywhere.
Trade-off: Flags can be cryptic. Mitigation: --json + --jq for programmatic use, good defaults for interactive use.
Workflow Engine: Lua
Decision: One language (Lua) instead of config-for-simple + DSL-for-complex.
Alternatives rejected:
- TOML for simple sequences, custom DSL for conditionals → two syntaxes, unclear boundary
- Shell scripts → awkward composition, no structured return values
- Rhai → smaller ecosystem
- Custom YAML/JSON workflow format → reinventing a worse language
Why: The boundary between "config" and "script" is fuzzy. Once you need if is_dirty() then ..., you need a real language. Lua is minimal (~200KB LuaJIT), widely known, and handles both simple (view("foo")) and complex cases.
Trade-off: Higher initial learning curve than TOML. Mitigation: simple examples, LuaCats type definitions for IDE support.
Path Resolution: dwim.rs
Decision: Single path resolver for files, directories, symbols, and fuzzy matches.
Alternatives rejected:
- Separate resolution for
view src/vsview MyClassvsview MyClass.method - Explicit prefixes like
view file:src/vsview symbol:MyClass
Why: Users think in terms of "show me X", not "resolve X as a file path and then show it". The resolver tries interpretations in order (literal path, indexed symbol, fuzzy match) and picks the best.
Trade-off: Ambiguity when a symbol and file have the same name. Mitigation: path/symbol syntax for disambiguation.
Output Formatting: --json + --jq
Decision: JSON output with jq filtering instead of many format flags.
Alternatives rejected:
--format=json,--format=yaml,--format=csv,--format=table- Separate commands:
moss view-json,moss view-table
Why: JSON is the universal interchange format. jq is powerful enough for any transformation. Adding more formats means more code to maintain.
Trade-off: jq syntax has learning curve. Mitigation: common patterns documented, --jq implies --json for convenience.
Adding New Decisions
When making a unification decision, document:
- What was unified: The N things → 1 approach
- Alternatives rejected: What we didn't do and why
- Why this works: The composability/simplicity gain
- Trade-off: What we gave up, how we mitigate it