Repository navigation
Ship the privacycommand CLI inside the app and put it on PATH - #28
Merged
Merged
Conversation
People who install privacycommand.app could only get the auditctl CLI by cloning the repo and building it. The app now carries it. - New "Embed auditctl" run-script phase (Scripts/embed-auditctl.sh) builds the SwiftPM product for the app's architectures (universal in Release), stamps the app's version and an identifier into its __info_plist section, strips it at link time, copies it to Contents/Helpers/auditctl and signs it with the app's identity and hardened runtime, following the guest-agent phase. It uses its own SwiftPM scratch path so it doesn't ping-pong rebuilds with the host-only guest build in .build. - The cask template links it with a binary stanza, so `brew install --cask` puts auditctl on PATH. - DMG installs get an app-menu item, Install Command Line Tool…, below Check for Updates…. It symlinks the embedded binary into /usr/local/bin, or shows the equivalent sudo command (with Copy) when the folder isn't writable, and flips to Uninstall Command Line Tool…. It refuses to link from a disk image or translocated copy, recognises Homebrew's link, replaces links to other app copies, and never touches a file or link it didn't create. The filesystem logic is CommandLineTool in Core, with unit tests. - README "Get it → Command line", the in-app manual, CONTRIBUTING and the source-tree README describe the two install paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Xcode 26.6's SwiftPM (used by App CI) builds multi-arch products through its xcode build system, which hands -Xlinker values to clang unwrapped: -x became clang's language flag and the link failed. Keep only -sectcreate, which clang also understands, and run `strip -S -x` on the embedded copy instead; strip re-signs a linker-signed arm64 slice, so unsigned builds still run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CLI hasn't shipped to users yet, so rename it now, before a release puts it on anyone's PATH. "auditctl" is also the name of Linux's audit control tool, which made the command hard to search for and suggested it controls a service. - The SwiftPM executable product is now `privacycommand`. Targets move to privacycommandCLI / privacycommandCLIKit (+ Tests), since a target named privacycommand would collide with the app's module and source folder. - The app embeds it at Contents/Helpers/privacycommand with identifier org.privacykey.privacycommand.cli; the build phase is now "Embed command-line tool" (Scripts/embed-cli.sh). The cask's binary stanza and the Install Command Line Tool… item link the new path, and the alerts say "the command-line tool". - Usage text, --version, the TUI title, CI's smoke test, the issue template and every doc use the new name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 8, 2026
adamXbot
added a commit
that referenced
this pull request
Oct 9, 2026
This work was finished on 2026-10-08 against the old `Sources/auditctl` layout and never landed before the CLI was renamed to `privacycommand` (#28). Same change, re-homed under `Sources/privacycommandCLI` with the new name in help and docs: - `privacycommand upgrade` = `preview --fetch`, with its own help. - `--greedy` includes casks only `brew upgrade --greedy` touches. - `HomebrewCaskInventory.outdatedScan(greedy:)` replaces `outdatedCaskTargets()` and also reports what preview can't analyze: casks that install no app (with the reason), outdated formulae, and greedy-only casks, so the preview never silently covers less than the upgrade does. - `.pkg` casks: the installed app is found through the `uninstall pkgutil:` receipts, the incoming one through `pkgutil --expand-full` (also for a .pkg inside a dmg/zip, located by the cask's `pkg` stanza). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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>
adamXbot
added a commit
to privacykey/website-privacycommand
that referenced
this pull request
Oct 9, 2026
* copy: add the privacycommand command-line tool The app now carries a command-line tool of the same name, with tab completion (privacykey/privacycommand#28, #29). The site still called it auditctl in one place and said nothing else about it. - New "Command line" section between Features and FAQ, with a terminal mock built from real output, linked from the header and footer nav. - Homebrew and DMG install cards say how each puts the tool on PATH; the source card uses the new name and its "Build guide" link points at CONTRIBUTING.md (the README has no #build-from-source anchor). - New FAQ entry "Can I use it from Terminal or in CI?", mirrored in the FAQPage JSON-LD, plus a featureList entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep the nav on one line with the Command line link; mention upgrade - The extra "Command line" nav link made index.html scroll sideways between 761 and 797px (found while fixing #13). The links now collapse below 841px instead of 761px, and nav labels no longer wrap ("Command line" broke onto two lines at 841px). Measured: no horizontal overflow at any of 33 widths from 320 to 1440px, and the links stay on one line from 841px up. - The CLI section said the tool never runs the upgrade itself; `privacycommand upgrade --max-risk` now can, so the copy describes it, and the featureList entry mentions risk-gated upgrades. 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
Someone who installs privacycommand.app has no way to get the CLI without cloning the repo and running
swift build. This PR ships the CLI inside the app and gives both install paths a way to put it onPATH.It also renames the CLI from
auditctltoprivacycommand, matching the app and the cask, while nobody has it onPATHyet. "auditctl" is also the name of Linux's audit control tool, which made the command hard to search for.What changes
Rename.
privacycommand.privacycommandCLIandprivacycommandCLIKit(+privacycommandCLIKitTests). A target namedprivacycommandwould collide with the app's module and itsSources/privacycommandfolder.--version, the TUI title, CI's smoke test, the issue template and every doc use the new name.Embedding (Xcode app target). A new Embed command-line tool run-script phase calls
privacycommand/Scripts/embed-cli.sh, which follows the existing guest-agent phase:ARCHS(universal for Release/Archive, the active arch for Debug), using its own scratch path under DerivedData. Sharing.buildwith the host-only guest build made each one rebuild the whole package every time.org.privacykey.privacycommand.cliinto the binary's__TEXT,__info_plist, soprivacycommand --versionprints the real version.strip -S -x), which takes the universal binary from 15.0 MB to 7.8 MB.stripre-signs a linker-signed arm64 slice, so unsigned builds still run.-Xlinker -S -xbroke on Xcode 26.6, whose SwiftPM passes-Xlinkervalues to clang unwrapped. That was this PR's first App CI failure.Contents/Helpers/privacycommandand signs it withEXPANDED_CODE_SIGN_IDENTITY,--options runtime, and--timestampwhen signing with a real identity. WhenCODE_SIGNING_ALLOWED=NO(App CI) it skips signing.Homebrew.
packaging/homebrew/privacycommand.rbgainsbinary "#{appdir}/privacycommand.app/Contents/Helpers/privacycommand".DMG installs. A new app-menu item, Install Command Line Tool…, sits below Check for Updates… and above Services. It goes in the app's own
.commands, becauseSurfaceCommandsis hash-locked shared code./usr/local/bin. If that folder isn't writable (most Macs), it shows the equivalentsudo mkdir -p … && sudo ln -sf …command with a Copy Command button./opt/homebrew/bin.The filesystem logic is in Core, in
CommandLineTool, with 12 unit tests that use temp directories.CommandLineToolInstalleris the menu and alert layer. Both files are hand-added to the pbxproj.Docs. README "Get it → Command line" describes the two install paths. The in-app manual, CONTRIBUTING (the build-from-source section stays),
privacycommand/README.md,BUILDING.mdand.github/ARCHITECTURE.mdare updated too.Verification (on this Mac, ad-hoc signed; no Developer ID cert here)
swift build, then.build/debug/privacycommand /System/Applications/Calculator.app(CI's smoke test): exits 0.swift test: 290 Core tests (4 skipped, as before) and 47 CLI-kit tests, 0 failures.xcodebuildof a fresh universal Debug bundle:Contents/Helpers/privacycommandisMach-O universal (x86_64 arm64)withflags=0x10002(adhoc,runtime)and identifierorg.privacykey.privacycommand.cli.codesign --verify --deep --strict.--versionprintsprivacycommand 0.1.5, both natively and under Rosetta.xcodebuild archiveandscripts/verify-archive.py.previewagainst the real outdated casks on this machine.swift build --build-system xcode.sudocommand for/usr/local/bin/privacycommand. Copy Command put it on the clipboard.just lintandjust docs-checkpass.Not verified here
/usr/local/binis root-owned here. Both are covered by theCommandLineToolunit tests.brew install --caskwith the new stanza. That needs a release.Note for in-flight work
Uncommitted CLI work in another worktree (
feat/privacy-cli-brew-preview-f18825:upgrade, pkg support) still editsSources/auditctl/…. Git records this PR's moves as renames, so merging main into that branch should carry its edits intoSources/privacycommandCLI/. New user-facing text there needs the new name.🤖 Generated with Claude Code