Add keyword-argument description to Cmd.__init__(), and default it to help. Also, add a property .description returning it, and add it to add_parser() so that it shows up in the usage message.
Without --backtrace, the outmost try-catch block logs exceptions plainly as their text. If it catches a key error, the exception text only consists of the key itself, which can be easily mistaken for a normal program output, so prefix it with a "Failed:".
By default, argcomplete uses argcomplete.FilesCompleter as default for every argument. This mixes accessible files into the list of possible completions. For most of jw-pkg's commands, that's unwanted, so turn it off by defining a NoopCompleter class which does nothing, and by set every arguments's default completer to a NoopCompleter instance. If desired, completing files can be restored for an argument by
Every module derived from lib.Cmd implements its own parser.add_argument() logic. As a consequence, all Cmd derived modules need to be loaded to have the full argument tree available. This is avoided during normal program startup because it takes some time. It's not necessary during normal program execution, nor for showing help messages. It is, however, needed for argcomplete to do its thing, so fully parse the command line if the program runs in argcomplete mode, as determined by checking if _ARGCOMPLETE is present in the environment.
Use the AsyncRunner class introduced in the previous commit to add a call_async() method, allowing to run async functions from sync functions by spawning an extra event loop.
Don't log an Exception as {e} but as str(e) producing nicer output. Or as repr(e) if a backtrace is requested, because to people who can read backtraces, type info might be of interest. Also, remove pointless time stamps, those belong into the logging framework.
During __init__(), commands have no idea of their parent. This is not a problem as of now, but is easy to fix, and it's architecturally desirable to be prepared just in case, so add the parent argument to the ctor before more commands are added.
Add App and Cmd as generic base classes for multi-command applications. The code is taken from jw-python: The exising jw.pkg.App is very similar to the more capable jwutils.Cmds class, so, to avoid code duplication, add it here to allow for jwutils.Cmds and jw.pkg.App to derive from it at some point in the future.
Both had to be slightly modified to work within jw-pkg's less equipped context, and will need futher code cleanup.