ShellCommandKit: vend bridged Commands as instances + redact Sandbox.Denial#16
Merged
Conversation
…mmand) `ShellCommandKit` could bridge an ArgumentParser command into a ShellKit `Command` only via `Shell.register(_:)`, which stores the bridge in a shell's in-memory `commands` map. An external installer that maintains its own registry — e.g. a filesystem-backed bin catalog that places commands at `/usr/bin/…` so they're PATH-resolvable — had no way to obtain the bridged `Command` instance to install. Add `Shell.parsableCommand(_:)`, a public static factory that builds (but does not register) a bridged `Command`, deriving its name from `configuration.commandName` exactly as `register(_:)` does. `register(_:)` now delegates to it, so there's a single bridging path. The bridge type itself stays internal. Purely additive and backward-compatible. This lets producer packages (e.g. SwiftPorts) vend ready-to-install ShellKit `Command`s built on ShellKit's own bridge — no duplicate bridge in each shell. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The bridge funnelled every non-ExitCode/non-cancellation error through ArgumentParser's `fullMessage(for:)`, which `String(describing:)`s a `Sandbox.Denial` and dumps all its fields — including the sandbox root and the requested path. For an app-as-sandbox embedder that leaks the container path into ordinary command error output. Catch `Sandbox.Denial` explicitly and print only its `reason`. Putting this in the command-building base means every bridged command is protected once, rather than each embedder re-implementing the redaction in its own bridge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This was referenced Jun 9, 2026
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.
Completes ShellKit's role as the command-building base for the Cocoanetics CLI toolchain — the layer that every shellkit-compatible CLI (sqlite3, git, jq, …) is built on, with no bridge duplicated in each consumer.
Changes
Shell.parsableCommand<P: ParsableCommand>(_:) -> Command— a public factory that builds (but doesn't register) a bridgedCommand, deriving the name exactly asregister(_:)does (which now delegates to it). Lets a producer package (SwiftPorts) vend ready-to-installCommandinstances to an installer (SwiftBash) — previously the bridge was only reachable viaregister(_:), which stores into aShell's in-memory map. The bridge type stays internal. Purely additive.Sandbox.Denialredaction in the bridge — the bridge funnelled every non-ExitCode/non-cancellation error through ArgumentParser'sfullMessage(for:), whichString(describing:)s aSandbox.Denialand dumps the sandbox root + requested path. Now caught explicitly and rendered as justreason. Putting this in the base protects every bridged command once, instead of each embedder re-implementing it.Verification
swift build+swift testgreen (incl. the existingArgumentParserBridgeTestsand a new factory test).Landing
First of a coordinated 4-repo change (ShellKit → SQLiteKit → SwiftPorts → SwiftBash). Merge this first — the others depend on the factory (and inherit the redaction). Additive + backward-compatible, so it's safe to merge ahead of the rest.
🤖 Generated with Claude Code