Repository navigation
feat(abgui): a console for typing abctl commands with the connection already applied - #10
Merged
Merged
Conversation
…already applied The GUI will always cover less of abctl than abctl covers, and the gap is where people go back to a terminal — re-deriving the connection by hand, and running in whatever directory the shell happened to be in. That second part is not hypothetical: resolving `gitops/` against the wrong working directory is the bug that made GUI writes land in a tree nobody was looking at. New Console screen. Type a command, press Return, read all three streams. It runs through the ORDINARY client seam, so a typed command is threaded with `--context`, runs in the chosen workspace, and is recorded and redacted by `RecordingRunner` exactly like one a button issued. It appears in the Command Log and the per-verb timing roll-up alongside everything else, because as far as the app is concerned there is no difference. `runConsole` deliberately does NOT map the exit code to an error the way every other client method does: a non-zero exit is a result to render, not a failure to swallow. `diff --exit-on-diff` returning 3 is drift, not breakage, and the console colours it accordingly. Safety, in the order it matters: - No `--yes` is ever added. What you type is what runs. - A write verb typed WITHOUT `--yes` is flagged before you press Run, because abctl will ask on stdin, the console gives it none, and the command aborts having changed nothing. Safe, but baffling if you expected it to run. - A write verb typed WITH `--yes` gets abgui's own confirmation naming the command and the context. A typed `--yes` is the only route in this app to a tenant write that no button asked about, so it does not get to be the one that skips asking. - `sync` without `--apply` is a dry run and is not treated as a write — confirming a dry run would teach people to click through the dialog. `CommandLineParser` handles quotes and backslash escapes because no shell is involved: a config named `Corp WiFi.mobileconfig` must arrive as one argument. It is deliberately not a shell — no pipes, redirection or variable expansion — since those would be promises with nothing behind them, and a `$TOKEN` that silently expanded would put a secret on argv, which this app never does. Go untouched and green. 5 new Swift tests cover tokenizing, the dropped leading `abctl`, an explicitly quoted empty argument, and both halves of write detection (including that a bare `sync` is not a write). Co-Authored-By: Claude Opus 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.
The GUI will always cover less of abctl than abctl covers, and the gap is where people go back to a terminal — re-deriving the connection by hand, and running in whatever directory the shell happened to be in.
That second part isn't hypothetical: resolving
gitops/against the wrong working directory is the bug that made GUI writes land in a tree nobody was looking at.What it does
Type a command, press Return, read all three streams. It runs through the ordinary client seam, so a typed command is threaded with
--context, runs in the chosen workspace, and is recorded and redacted byRecordingRunnerexactly like one a button issued — it shows up in the Command Log and the per-verb timing roll-up alongside everything else, because as far as the app is concerned there is no difference.runConsoledeliberately does not map the exit code to an error the way every other client method does: a non-zero exit is a result to render, not a failure to swallow.diff --exit-on-diffreturning 3 is drift, not breakage.Safety, in the order it matters
--yesis ever added. What you type is what runs.--yesis flagged before you press Run — abctl will ask on stdin, the console gives it none, and the command aborts having changed nothing. Safe, but baffling if you expected it to run.--yesgets abgui's own confirmation naming the command and the context. A typed--yesis the only route in this app to a tenant write that no button asked about, so it doesn't get to be the one that skips asking.syncwithout--applyis a dry run and is not treated as a write — confirming a dry run would teach people to click through the dialog.Parsing
CommandLineParserhandles quotes and backslash escapes because no shell is involved: a config namedCorp WiFi.mobileconfigmust arrive as one argument, or the command fails for a reason that looks nothing like the cause.It is deliberately not a shell — no pipes, redirection or variable expansion. Those would be promises with nothing behind them, and a
$TOKENthat silently expanded would put a secret on argv, which this app never does.Verification
Go untouched and green. 5 new Swift tests: tokenizing with quotes and escapes, the dropped leading
abctl(only as the first token), an explicitly quoted empty argument surviving, and both halves of write detection including that a baresyncis not a write. macOS CI is the compile gate.🤖 Generated with Claude Code