Settings: Context pane splits Claude/SSH context out of Text Processing - #223
Settings: Context pane splits Claude/SSH context out of Text Processing#223T0mSIlver wants to merge 9 commits into
Conversation
Text Processing's Polishing group had grown to seven consent-grade context toggles plus the Claude Code plugin row plus the whole remote-SSH enrollment UI, under a heading that promised transcript formatting. The toggles whose help text IS the consent — what may be read from your terminal, your repo, your clipboard, and where it may be sent — were being scrolled past as if they were siblings of "Exact match". They move to a Context pane of their own (raw value `context`, sidebar tile terminal.fill on systemIndigo), in three static groups: Polish context (the four sources plus the non-local-endpoint relaxation), Claude Code (title fallback + plugin install), Remote hosts (SSH enrollment). Same bindings, same help text, same behavior — nothing here changes what the app sends. The availability gating moves with the rows it gated: the Polish context group carries the same "No Overlay Buffer shortcut" card and the same disabled/opacity treatment, because context is only ever harvested for an Overlay Buffer dictation. The plugin and remote-host rows stay ALWAYS enabled, for the reason they always were — revoking a host is the security off switch for an already-bound listener, and it must work whatever the hotkey configuration is. Text Processing keeps Replacements, a Polishing group reduced to the three rows that really are about the transcript (Enable, agent prompt profile, spoken clipboard paste), and Configuration. Contracts updated in step, since the raw value is a literal in two scripts: SettingsTabTests pins `context` and its settings.tab/settings.pane ids, ui-smoke.sh drills the pane and asserts content unique to it, and capture-readme-assets.sh captures assets/settings-context.png for the README table.
…ontract test read the scripts The README referenced assets/settings-context.png before it existed; the capture-assets run on this branch generated it, so it ships with the PR. The script-contract test asserted only the Swift-side identifier scheme, so a divergent literal in ui-smoke.sh or capture-readme-assets.sh kept every test green while the AX drills broke at runtime. It now reads both scripts from the repo and compares their drilled tab ids against the enum.
… new pane The opencode pass found the real gap was documentation, not code: five user-facing paths still sent people to Settings -> Text Processing for rows that now live on Context — the README install one-liner, the pane feature list (which also gains a Context bullet), and three paths in the integration README that nothing in the move had touched. Also pins the capture script's TAB_NAMES/TAB_IDS/TAB_FILES lockstep (the loop indexes them under set -u, so a missing sibling entry previously only failed at README-regen time on the Mac) and gives the one-line-array parser an actionable failure message.
# Conflicts: # Sources/localvoxtral/SettingsView.swift # scripts/capture-readme-assets.sh
|
Merged the updated #201 ( Conflicts (2 files)
Where main's new Claude/remote UI landed — Context pane, three groups unchanged:
Proof: |
…e main merge surfaced Main's cmux additions were written against the old Text Processing layout, so the merge brought two more Settings paths pointing at rows that now live on Context. And the terminal-screen row's help still claimed Ghostty only — stale on main itself since the allowlist grew to iTerm2, Terminal.app, and cmux; the row lives here now, so the copy gets corrected here.
The coverage tests compare Sets, so an accidental reorder passed every test while moving rows users have muscle memory for. Pinned here at the stack top, where the final five-pane order lives.
… and the row-idiom polish since the first capture
…depends on (delta-review nit)
|
Final scoped review (opencode/GLM-5.2) of everything since the first full review (merge from main, copy fixes, row-idiom merge-up, order pin): clean — no resolution damage. Verified: all 13 of main's Polishing-group rows accounted for exactly once across the three Context groups; exactly the five consent toggles inside the availability gate, both join arms and the remote plumbing outside it; no stale navigation path remains anywhere; footer-slot usage consistent; order-pin test byte-identical to the sidebar arrays. One low-severity copy nuance adopted in the follow-up commit: the terminal-screen row now cross-references the cmux join it depends on. |
Stacked on #201 (
settings-row-idiom) — base is that branch, not main. Merge #201 first.What
Text Processing's "Polishing" group had grown into three unrelated things: the transcript-formatting toggles it is named for, seven consent-grade context toggles whose help text is the consent, and the whole Claude Code plugin + remote-SSH enrollment UI. This splits the last two out into a Context pane of its own.
New
SettingsTabcase, raw valuecontext(existing raw values untouched — the scripts key off them). Sidebar tileterminal.fillon systemIndigo; subtitle "What the polisher and Claude Code integration may see."Moved from Text Processing → Context, with identical bindings, help text and behavior:
The three groups are static — a toggle switches a group's content, never the number or identity of the groups (owner rule, 2026-07-04).
Gating moves with the rows it gated: the Polish context group carries the same
SettingsAvailabilityCard("No Overlay Buffer shortcut") and the same.disabled(!isLLMPolishingReachable).opacity(...)treatment. The plugin and remote-host rows stay always enabled, with the existing comment explaining why — revoking a host is the security off switch for an already-bound listener and cannot depend on the current hotkey configuration.Text Processing keeps: Replacements; Polishing reduced to Enable / Agent prompt profile in terminals / Spoken clipboard paste (still carded and gated as before); Configuration unchanged.
Nothing about what the app collects or sends changes — this is presentation and consent legibility only.
Contracts updated in the same PR
The raw value is a literal in two scripts, so all three move together:
Tests/localvoxtralTests/SettingsTabTests.swift—contextadded to the frozen raw-value set (existing pins untouched), plus a new test spelling outsettings.tab.context/settings.pane.context.scripts/ui-smoke.sh— drills the pane by AX id and asserts, scoped tosettings.pane.context, both the group heading ("Polish context") and "Remote Claude Code over SSH", which exists on no other pane.scripts/capture-readme-assets.sh—TAB_NAMES/TAB_IDS/TAB_FILESgain "Context" /context/settings-context.png.README.md— settings screenshot table gains the Context row.Proof
./scripts/remote-build.sh(build + full suite)./scripts/remote-build.sh test --filter SettingsTabTeststestRawValuesAreStable(existing, unweakened) is what fails on any raw-value drift;testSidebarArraysCoverEveryTabExactlyOnceis what fails if the new tab were declared but never reachable in the sidebar; the newtestContextTabUsesTheDrillIdentifiersTheScriptsHardcodepins the two literals the drills press and scope by. No test was weakened, no assertion removed, no skip added; the only warnings in the build are the pre-existing ones inClaudePluginInstallService.swiftandClaudeHookPublisherTests.swift.ui-smoke.shdrill and eyes-on-pane checks (sidebar tile/order, the availability card gating the Polish context group, the enrollment sheet still opening from its new group) have not been run against a packaged build in this PR. Pane screenshots come from the capture-assets workflow (capture-assets.yml/scripts/capture-readme-assets.sh), not from this branch —assets/settings-context.pngis referenced by the README but not yet generated. The orchestrator will attach screenshots and the hand-test result.LLM lanes: not run and not required — no prompt, model pin, sampling, request-shape, or context-attachment path is touched. This is Settings presentation plus two AX drill scripts; the bindings the toggles write are byte-identical.
Update — review round 1 (codex, 2026-08-04)
An independent codex review of the diff found no behavior drift in the move (bindings, consent copy, gating, sheet/alert/onAppear wiring all verified) and two minors, both fixed in
7eac743:assets/settings-context.pngbefore it existed → the capture-assets workflow was dispatched on this branch (run 30941718903) and the generated screenshot is now committed. Preview:testContextTabUsesTheDrillIdentifiersTheScriptsHardcodeonly repeated the Swift-side identifier scheme, so a divergent literal inui-smoke.sh/capture-readme-assets.shkept tests green while the AX drills broke at runtime. Replaced bytestAutomationScriptsDrillExactlyTheTabsTheEnumDefines, which reads both scripts and compares their drilled tab ids against the enum. Red/green proof:Red (with
assert_tab "context"seeded toassert_tab "kontext"in ui-smoke.sh):Green (real scripts):
Executed 7 tests, with 0 failures(SettingsTabTests, 2026-08-04 21:07).Update — review round 2 (opencode final review, 2026-08-04)
The pane split itself was verified clean (bindings, gating, consent copy byte-identical, AX derivation, Swift 6 isolation). Findings, all addressed in
a2bcba4:Settings → Text Processing …for rows that now live on Context (README install one-liner + pane list, and three paths inintegrations/claude-code/README.md, a file the PR had not touched). All now point atSettings → Context → …, and the README pane list gains a Context bullet.set -u).if letaround the Remote hosts group) judged intentional and left, with rationale in code comments.SettingsTabTests after both rounds:
Executed 7 tests, with 0 failures.