Repository navigation
Add zsh, bash and fish tab completion to the privacycommand CLI - #29
Merged
Merged
Conversation
- `privacycommand completion <zsh|bash|fish>` prints a completion script; `--help` gives the one line to add for each shell. Scripts are generated from command tables in privacycommandCLIKit/ShellCompletion, so subcommands, options, risk tiers, installed app names, directories and outdated casks complete the same way in every shell. - The app build writes the three scripts to Contents/Resources/completions, and the cask links them with bash_completion / zsh_completion / fish_completion (Homebrew 4.4.24+). They're generated with the SwiftPM build output rather than the embedded copy: macOS drops what a binary writes into its own freshly built .app on its first run, which left _privacycommand empty. The phase now fails if any script comes out empty. - ShellCompletionTests checks every table entry reaches every shell, that zsh and bash parse the scripts, and what bash completes for fixed inputs. zsh was also checked interactively through a pty, both from fpath and via eval; fish isn't installed here. - The Install Command Line Tool… alert, README, in-app manual, CONTRIBUTING and the source-tree README describe completion setup. README and CONTRIBUTING also stop saying `preview` never runs brew or always exits 0, and CONTRIBUTING's `--min-tier warn` example (which exits 2) now uses `high`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adamXbot
added a commit
to privacykey/docs-privacycommand
that referenced
this pull request
Oct 8, 2026
Documents `privacycommand completion <zsh|bash|fish>` (privacykey/privacycommand#29): what completes, that Homebrew sets it up, the one line per shell otherwise, and a zsh troubleshooting entry (compinit order, Homebrew's fpath, a stale ~/.zcompdump). llms files regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 8, 2026
adamXbot
added a commit
to privacykey/docs-privacycommand
that referenced
this pull request
Oct 9, 2026
* docs: document the privacycommand CLI and how to install it The CLI was renamed from auditctl to privacycommand and now ships inside the app (privacykey/privacycommand#28). The docs still said it had to be built from source. - auditctl.mdx becomes cli.mdx ("Command line"), with a redirect from /auditctl. It covers the Homebrew install, the app menu's Install Command Line Tool… (and its sudo fallback and safety rules), building from source for 0.1.5 and earlier, usage with the new name, and the audit exit codes. - Every page that ran `swift run -c release auditctl …` or linked /auditctl now uses `privacycommand …` and /cli. - Installation and Updating mention the tool, Troubleshooting gains "command not found" and "asks you to move the app" entries, and the Develop pages use the new target names and the embed phase. - llms.txt and llms-full.txt regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: add tab completion setup for the privacycommand CLI Documents `privacycommand completion <zsh|bash|fish>` (privacykey/privacycommand#29): what completes, that Homebrew sets it up, the one line per shell otherwise, and a zsh troubleshooting entry (compinit order, Homebrew's fpath, a stale ~/.zcompdump). llms files regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: cover privacycommand upgrade, --max-risk, --greedy and .pkg The CLI on main gained `upgrade`, a `--max-risk` gate, `--greedy` and .pkg artifact support, so cli.mdx's "`.pkg` is skipped" and "will not upgrade anything" were no longer the whole story. - cli.mdx: preview's new flags, the casks and formulae it lists but can't analyse, the brew calls it makes now, exit code 3, .pkg handling, and a new "Upgrading within a risk limit" section (cleared/held, --dry-run, --no-input, exit codes 0/1/2/3, the daily alias). - Security lists `brew upgrade` as the sixth outbound call; the Introduction and FAQ follow. - llms files regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
Why
The
privacycommandCLI (#28) had no tab completion. This adds it for zsh (macOS's default shell), bash and fish. Homebrew installs set it up automatically, and everyone else adds one line to their shell's startup file.What changes
privacycommand completion <zsh|bash|fish>prints a completion script. Its--helplists the line to add for each shell. For zsh, in~/.zshrcaftercompinit:The scripts are generated from command tables in
privacycommandCLIKit/ShellCompletion.swift, so all three complete the same things:*.appnames in/Applications,~/Applicationsand/System/Applicationsthatprivacycommand <name>matches. Names with spaces are escaped. Directories complete too.audit <app>or a bare<app>.--min-tierlevels,--apps-dirdirectories, and the outdated cask tokens frombrew outdated --cask.completion.The zsh script works both autoloaded from
fpathandeval'd from~/.zshrc. The bash script works with macOS's bash 3.2: it avoidscompoptand relies oncomplete -o filenamesfor escaping.Bundled for Homebrew. The Embed command-line tool phase writes the three scripts to
Contents/Resources/completions. The cask links them withbash_completion,zsh_completionandfish_completion. Those stanzas need Homebrew 4.4.24 (March 2025) or later. I avoided the newergenerate_completions_from_executable, which older Homebrew can't parse.brew stylereports no new offences; the two it flags were already there.A macOS quirk this hit. The first run of a binary from inside a freshly built
.appsilently loses whatever it writes into that same bundle. Swift'sprintignores the failed writes, so it still exits 0. Generating with the embedded copy left_privacycommandempty on every fresh build. The phase now generates with the identical SwiftPM build output and copies the files in, and it fails the build if any script comes out empty.This doesn't affect users: their output goes to the terminal or to files outside the app. I reproduced it outside Xcode and confirmed the same binary run from outside the bundle writes fine.
Docs.
upgrade/--greedywork.preview"never runsbrew" and "always exits 0". It runs read-onlybrewqueries and exits 2 on usage errors or missing Homebrew.--min-tier warnexample, which exits 2, now useshigh.Verification
swift test: 290 Core tests (4 skipped, as before) and 52 CLI-kit tests (5 new), 0 failures.ShellCompletionTestschecks that:zsh -nandbash -naccept the scripts (fish -ntoo, when fish is installed).fpathand viaevalaftercompinit:prev→preview,preview --f→--fetch,--min-tier→ the four tiers.completion b→bash,Calc→Calculator,Calculator --s→--short./bin/bash): subcommands plus app names with spaces (App S→App Store), preview options, tiers,--apps-dirdirectories, and audit options after a bare app name.xcodebuildbundles, signed (ad-hoc) and unsigned, universal: all three files are present and byte-identical toprivacycommand completion <shell>, and the signed bundle passescodesign --verify --deep --strict.just lintpasses.Not verified
__fish_use_subcommand,__fish_seen_subcommand_from,__fish_complete_directories), and the content test covers it, but it hasn't been run.brew install --caskwith the new stanzas needs a release.🤖 Generated with Claude Code