`cligen` does not hide the main control flow, per se (which you mention 3 times) -- `dispatch` is meant here as a verb after all meaning "do something". You can even define `mergeParams` to redirect "do it to what?". CLauthors must even choose _where_ to invoke - unconditional global code, guarded by a `when isMainModule`, etc. What is hidden is code generation (which sure, internally is macro heavy & contains control flow - like any API call does) and the "binding" \- but the binding is really pretty natural. (Argh once called itself "The Natural CLI".)
There is always a spectrum/axis of explicitness & abstraction / automation. One man's useful automatic translation to assembly code is another's "hostile (over-assuming | undersmart) compiler". There is no "perfect level" of abstraction independent of background knowledge & context. To each his own. It might be helpful to post here a link to [more motivation for the skeptical](https://github.com/c-blake/cligen/tree/master/MOTIVATION.md), though which touches on "system-wide complexity/perf" \- a higher order consideration often neglected. FWIW, while it grew somewhat complex, the first public release had just 163 lines for `cligen.nim` with a 97 line `argcvt.nim` that could drive 11 test use cases. Then 178 issues were handled with many features requested (& thought of) & added. It's all public in the git log / github discussion (alluded to in the README). There are many "satisfied customers" (some of whom have piped up here -- thanks for the implicit thanks!), but sure - it's a pile of work & code "for the _union_ of many" \- almost _by definition_ making it seem like "overkill to _any one_ " user. Like Nim itself, it isn't perfect, but I like using it a lot - both as a CLauthor & CLuser. Anyway, cheers, all.