Repository navigation
Migrate the CLI from argh to cw - #42
Merged
Merged
Conversation
argh is LGPL-3.0-or-later; cw is MIT with no runtime dependencies and reproduces argh's grammar by default, so the command line does not move. - `coact/__main__.py`: `import argh` -> `import cw`. The three `@argh.arg` declarations become a `CONFIG` dict keyed like `COMMANDS` (command name -> parameter name -> `add_argument` kwargs), so the verbs are now plain annotated functions with nothing CLI-specific on them. - `main()` is `raise SystemExit(cw.dispatch(COMMANDS, config=CONFIG))`. `cw.dispatch` returns an exit code rather than exiting, so the re-raise is load-bearing: without it a usage error would exit 0. - `prog` is deliberately left to argparse, preserving `python -m coact`'s current `usage: __main__.py` line. - pyproject: `argh` -> `cw`. Tests: `test_main_wires_every_verb` monkeypatched `cli.argh.dispatch_commands` because argh could not be observed any other way (output file bound at import, return value discarded). cw builds a plain `argparse.ArgumentParser`, so that is replaced by real assertions: the subcommand set, the four positional nargs shapes (`?`/`+`/`+`/`*`), two end-to-end dispatches, and an exit-code test that runs `main()` itself. Verified with `cw.testing`: 19 characterized cases (top-level help, all eleven subcommand helps, six error/edge cases) recorded from the argh console script and replayed against cw with `strict_help=True` -- 19/19 identical, help bodies included. Docs: named cw as the house CLI adapter in the ai-assistant-command-mcp skill, retiring its `argh-migration stage 2` marker.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #39.
arghis LGPL-3.0-or-later.cwis MIT, has no runtime dependencies, and reproduces argh's grammar by default — so this changes nothing a user sees.The CLI surface: no diff
Recorded from the argh console script before any edit, replayed against cw after, with
cw.testing:strict_help=Trueasserts the full--helpbody, not just theusage:line — so a moved help column or a reflowed description would have failed. Nothing moved.The 19 cases: no-args, top-level
--help,--helpfor all eleven subcommands, and six error/edge vectors (estimatewith no args,inventory --nosuchflag,scaffold,publish,plan,nosuchcommand).python -m coact --helpwas checked separately and still printsusage: __main__.py— see "prog" below.What changed
The three
@argh.argdeclarations became aconfigdict. This was the modern form, not the compat shim:The eleven verbs are now plain annotated functions with nothing CLI-specific attached — the CLI's particulars live in one table next to the command list instead of being scattered across three decorators.
estimate(*agents: str)needed no entry:VAR_POSITIONALinfersnargs='*'on its own, and the replay confirms the help is byte-identical.progis deliberately not passed. Hardcodingprog='coact'would have been an improvement topython -m coact --help(which currently reportsusage: __main__.py) — and therefore a change to the surface this PR promised not to touch. Left to argparse.raise SystemExit(...)is load-bearing.argh.dispatch_commandscalledsys.exititself;cw.dispatchreturns the code. Dropping the re-raise would silently turn every usage error into exit 0. There is now a test that runsmain()and assertsSystemExit(2), so it cannot be dropped by accident.The test that had to be rewritten
test_main_wires_every_verbmonkeypatchedcli.argh.dispatch_commands. That monkeypatch existed because argh genuinely could not be observed any other way — its output file is bound at import and its return value is discarded, so the only way to see what got registered was to replace the dispatcher.cw builds a plain
argparse.ArgumentParser, so the wiring is inspectable directly. The monkeypatch is gone, replaced by five real tests:nargsshapes (?withdefault='.',+,+,*) asserted on the real actions, parametrized;cw.dispatch(..., out=buf)— includinginventorywith no positional, which is whatnargs='?'is for;Net: the CLI is better covered after the migration than before, and none of the new coverage depends on the dispatcher's identity.
Also
pyproject.toml:argh->cw.ai-assistant-command-mcpskill carried an explicitargh-migration stage 2marker — "a house CLI adapter is being built ... this section will name it and show its idiom once it ships." It has shipped, so the marker is retired and Emitter C now shows thecwdispatch-table idiom.arghmentions updated inCOACT_SPEC.md,REUSE.md, and thecoact-devskill.CHANGELOG.mdleft alone — it is history.Tests
417 passed, 4 skipped.