I'm designing a CLI tool in Go that will expose roughly 100 commands. Each command has its own set of flags, and there are also several global flags. My main goals are maintainability, testability, good DX for contributors (easy to add/remove commands), and features like help generation and shell autocompletion.
I'm not asking only about which library to use (I know libraries like Cobra exist) — I want guidance on architectural patterns and best practices for handling a large command surface and many flags.
Specific concerns I’d love answers on:
Organization: Should each command live in its own package/file with init-style registration, or should I keep a declarative registry (e.g. structs or JSON/YAML definitions) and dynamically register commands? Pros/cons?
Shared flags: What’s the best pattern to share flags between commands (e.g. auth, config flags) while avoiding duplication? Composition of structs, embedding, global flag sets, or another pattern?
Parsing strategy: Centralized parser that knows about all commands vs per-command parsing. Which is simpler/safer/performant for ~100 commands?
Help & autocompletion: Practical ways to keep help text and completions in sync with the command definitions (codegen? annotations? runtime introspection?).
Reflection vs codegen: When to use struct tags + reflection vs generating command code from a schema (YAML/JSON) — trade-offs in complexity, compile-time safety, and ergonomics.
Performance / lookup: Any concerns with command lookup / memory overhead as commands grow — should I use trie/radix lookup or is a simple map fine?