feat(macos): on-demand OpenCode rewrite shortcuts (last dictation and selection) - #63
Open
qretsar wants to merge 4 commits into
Open
feat(macos): on-demand OpenCode rewrite shortcuts (last dictation and selection)#63qretsar wants to merge 4 commits into
qretsar wants to merge 4 commits into
Conversation
qretsar
force-pushed
the
feat/rewrite-last-dictation
branch
from
September 3, 2026 07:38
1824897 to
8d594f9
Compare
Add an Option-Shift-O shortcut that re-runs the last completed dictation through OpenCode and pastes the cleaned-up result at the cursor. Unlike live mode processing, the rewrite always generates with the matching mode's configured model even when automatic processing is off; failures paste nothing, the rewritten output never becomes the new last dictation, and the job flows through the existing processor queue so ordering, bounded admission, cancellation, and history capture are inherited. The shortcut is user-configurable from Settings with conflict validation, disables itself on load when it would shadow an existing binding, and shows the processing indicator through the standard Submitted -> Stage pipeline. Also fixes keyboard.rs layout-query concurrency (previous commit) that the new tests surfaced. AGENTS.md documents the invariant.
- Serialize HIToolbox keyboard-layout queries behind a lock: concurrent TISCopyCurrentKeyboardLayoutInputSource calls abort the process, which the new tests hit deterministically under parallel execution. - Drop the stored processor sender before joining processor workers so shutdown cannot block forever on a channel that never disconnects. - Publish Paste/Send text into the shared last-transcript mirror before the paste runs and restore it on failure, so a rewrite submitted while a paste is still in flight rewrites the transcript the user just heard. - Reject a second rewrite while one is already generating instead of queueing duplicate generations of the same text. - Report cancellation before the model gate, cover edit- and meeting-conflict cases in tests, and reword the normalized-settings log message.
- Surface user cancellation of a rewrite as a clean cancel instead of a failed rewrite (error tone) in the processor error path. - Fill the keyboard layout cache on cold misses so every key_code_for caller benefits from the serialized TIS scan. - Give rewrites their own DictationPhase::Rewritten so the activity feed no longer claims the dictation was merely pasted again. - Cover RewriteLast in the Voice Action takeover test.
Add a user-configurable Option-Shift-R shortcut that captures the selected text in the focused app (Accessibility, same as Voice Action), runs it through the on-demand OpenCode rewrite pipeline, and pastes the result over the selection. Requires a non-empty selection and OpenCode; failures paste nothing and never touch the last dictation. Also upgrades RewriteLast to cancel-and-replace: a second press cancels the in-flight rewrite and starts a fresh one instead of erroring.
qretsar
force-pushed
the
feat/rewrite-last-dictation
branch
from
September 3, 2026 20:42
8d594f9 to
0f88105
Compare
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.
Closes #62
Summary
Two shortcuts built entirely on the existing OpenCode rewrite machinery, addressing the lost-flow-of-thought problem after accidental or messy captures (#62):
src/suppression.rs,src/parakeet.rs): re-submits the last completed transcript throughProfiles::rewrite_cancellable(existing processor queue: bounded admission, ordered output, Escape cancellation) and pastes the result at the cursor. Always generates with the matching mode's configured model, even when the automatic mode-processing toggle is off. Failures paste nothing. The rewritten output never becomes the new last dictation, so Option-Shift-V keeps returning the original. Duplicate presses cancel-and-replace the in-flight rewrite.src/keyboard.rs): concurrentTISCopyCurrentKeyboardLayoutInputSourcecalls abort the whole process (confirmed via a macOS crash report and reproduced by the new tests under parallel execution); TIS access is now serialized behind a lock and the cache is filled on cold misses.Both shortcuts are user-configurable in Settings with the standard capture UI, conflict validation, and load-time disable when they would shadow an existing binding. History records rewrite outputs under a new
Rewritekind; AGENTS.md gains the matching invariant bullets.Verification
cargo fmt --checkcargo test --locked --bin voice-control(one pre-existing unrelated failure:personal_commands::tests::clean_workspace_provisioning_preserves_user_config_on_refresh, fails on clean main in this environment)cargo clippy --locked --all-targets --all-features -- -D warningsgit diff --checkA note from me
I use HEX every single day and I am grateful for it, it genuinely changed how I work. I do not care about contributor credit at all; the feature is what matters to me. If you would rather design or land this yourselves, or if you would prefer I stop opening PRs on your repository, that is completely fine and there are no hard feelings. Happy to close this and keep using the app either way.