Lead with the unquoted command form, and take -- the way every tool does - #39
Merged
Merged
Conversation
keycmd already ran a command written out as separate arguments, but the docs treated it as the exception: every example put the command in quotes, which reads as a requirement rather than as the tool for the one job it is needed for. Quotes are what you reach for when you want a shell — a pipe, an &&, a credential expanded into the command line — and almost nothing else needs one. `keycmd npm install` is the form the docs now lead with, on the landing pages, in the quick start, in the examples and in the guide, which is also what the README meant by "prefix any command with keycmd". Writing a command out that way brings `--` with it, since every tool that goes on to run another one takes it. keycmd took it as the first word of the command instead, so `keycmd -- npm install` reached the shell as `-- npm install` and failed on it. `end_of_options` removes the one that ends keycmd's own options, which also makes a command whose first word starts with a dash reachable; any further `--` is the command's own and is passed along untouched. --help gains a usage line and examples covering both forms, since that is where someone looks before the docs. The one place the unquoted form cannot keep its word boundaries is WSL, where wsl.exe strips the quotes off its own command line before the distribution sees them. That is the platform's limit rather than keycmd's, and the WSL guide now says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HFqRvGXvoDW1tiX7dJHoYb
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.
keycmd already ran a command written out as separate arguments —
join_cmdhas handled a multi-argument command all along, quoting each one so that the shell hands it on as the word it was. What was missing was the framing: every example on every page put the command in quotes, so quoting read as a requirement rather than as the tool for the one job it is needed for.Quotes are what you reach for when you want a shell — a pipe, an
&&, a credential expanded into the command line — and almost nothing else needs one.keycmd npm installis what the README already meant by "prefix any command withkeycmd", and it is the form the docs now lead with.The bug behind it
Writing a command out unquoted brings
--with it, since every tool that goes on to run another one takes it (uv run --,npx --,env --). keycmd took it as the first word of the command instead:end_of_optionsnow removes the--that ends keycmd's own options, which argparse leaves sitting in theREMAINDER. Only the leading one —keycmd npm install -- --flagkeeps its own. It also makes a command whose first word starts with a dash reachable, which argparse otherwise rejects as an unrecognized option.Changes
keycmd/cli.py—end_of_options, plus ausageline and an examples block in--help, since that is where someone looks before the docs:Docs — the unquoted form leads on the landing pages, in the quick start, in both examples and in the guide, which is rewritten around prefix your command →
--→ a quoted command line. Quoting is kept where it is genuinely needed and explained as such: printing a secret is the one thing in the quick start that needs it, and it now says so instead of implying that is how keycmd is used. Troubleshooting gains entries for the stale--failure and for thekeycmd --verbose pytestvskeycmd pytest --verbosedistinction.Two caveats documented rather than papered over
wsl.exestrips the quotes off its own command line before the distribution sees them, which the suite already asserts intests/test_wsl.py. It is the platform's limit and not fixable from the Windows side, so the WSL guide says so.keycmd npm installis unaffected; only an argument containing spaces is.cmdand Windows PowerShell have argv limits that no amount of quoting lifts (a newline,%VAR%, an embedded", an empty argument). These were documented inquote's docstring but never surfaced to users.Testing
13 new cases in
tests/test_cli.py:--across the parse table,--end to end throughmain, and a credential reaching a command in the unquoted form across every installed shell.Full suite (182 passed, 3 skipped),
ruff check,ruff format --check,ty check --error-on-warningandmkdocs build --strictall clean. Both forms were also smoke tested end to end against a real keyring backend, including thatkeycmd python --versionreaches python rather than keycmd.The version is not bumped; that happens in its own commit.
Generated by Claude Code