Skip to content

Add selected-text voice editing on macOS - #137

Merged
IchenDEV merged 2 commits into
mainfrom
extract/selected-text-voice-editing
Oct 27, 2026
Merged

IchenDEV merged 2 commits into
mainfrom
extract/selected-text-voice-editing

Conversation

@IchenDEV

Copy link
Copy Markdown
Owner

Change

Desktop selected-text voice editing, extracted from #124 so it lands on main without the iOS keyboard stack (#121).

A selected-text voice edit replaces the frozen selection automatically after generation and capture drain, through the existing Session / target lease / output transaction. The dark HUD shows only progress, cancellation and a confirmed one-use Restore. There is no candidate preview and no Apply. Ordinary dictation and the original recording controls are unchanged.

  • Esc cancels a shown selected session before delivery.
  • Command-Option-Z restores the current confirmed original once; host Command-Z is untouched. Registrations are scoped to the shown eligible session/receipt and fail closed on conflict.
  • Remote-model disclosure is required before selected text is sent. Selected content stays out of generic history/follow-up, including when generation fails before delivery.
  • Selection, document, focus, Unicode, clipboard-ownership and uncertain-write guards remain.

Source commits: de895347, 72dc402f, 1eae6726, 27ffc8c1, da43ec84 on research/voicecursor-voice-editing-20261008, rebased onto current main. de895347 was a merge of main into the iOS branch plus the feature, so the feature delta was computed against the pure merge result.

Not included (stays in #124 / #121)

  • UtterMobile, UtterKeyboardBridge, iOS/ and the mobile selection scripts.
  • Offline-sandbox build and evidence tooling: the build-app.sh options, guarded-offline-build.py, capture-candidate.py.
  • All ios.* strings.

Decisions to review

  1. Secure input refuses every write, including the clipboard-only copy. This is the rule Add selected-text voice editing on macOS and iOS #124 introduced (testSecureTargetRefusalCannotAutomaticallyCopyEvenWhenPasteIsEnabled). main's Chromium web-editor path (69cb79a) still copied to the clipboard under secure input. The web-editor path now follows the same rule, and testWebEditorUnderSecureInputOnlyCopiesWithoutPostingKeys became testWebEditorUnderSecureInputCommitsNothingAndDoesNotCopy. Reverting to the old behavior is a one-place change in TextDeliveryTransaction.
  2. Test doubles on main (UpdateFakeExecution) gained the new SessionExecutionService requirements.
  3. Conflicts in TextDeliveryTransaction, NativeDeliveryTarget, ScopedOutputService, NativeDesktopHost and Localizable.strings were merged as unions of both sides; SessionJobControl keeps finalizeCapture(reason:).

Verification (local, on ac0ad14)

Check Result
swift build --build-tests passed
swift test (full) passed, no failing target
bash scripts/sdlc-checks.sh passed
bash scripts/ci-basic-checks.sh passed
Feature-focused cases (HUD appearance/interaction, shortcuts, Session/restore/receipt retention, privacy, remote disclosure, prompts, delivery transaction) 100 passed, 0 failed, 2 skipped by design (they only apply while secure input is on)

The native tests render the real HUD and, with UTTER_NATIVE_EVIDENCE set, wrote 42 PNGs covering recording, automatic processing, restorable, restore failure and remote disclosure in English/Chinese. The HUD is always dark, so the Aqua and DarkAqua captures are identical. Those captures are content-view renders, not WindowServer composites.

Open gates

  • Not verified on a real desktop: global shortcut registration and physical key dispatch (tests use an injected registrar plus real owned Carbon event decoding), real microphone / speech recognition / model generation, replacing and restoring a selection in an external host (Chromium and Electron especially), VoiceOver, live backdrop translucency.
  • The SDLC bundle docs/sdlc/changes/2026-10-08-voice-editing-research/ still describes desktop + iOS. platform-evidence.md, rule-context-r11.md and swiftpm-result-r7.md are pending approval; offline-unit-r9.md and sandbox-registration-r8.md are blocked. Approvals are the owner's; none were changed here.
  • Dead surface from the removed review flow remains: selection_edit.review/apply/original/revised/... strings and applySelectionEdit.
  • Valid but misrecognized speech can still cause an unintended rewrite; the guarded one-use Restore is the mitigation, not a semantic guarantee.
  • Human/protected merge approval and distribution signing/notarization remain open. This PR stays Draft.

Rollback is a normal revert of the commit; no data migration or user-data reset is involved.

Extract the desktop selected-text voice editing from #124 so it no longer
depends on the iOS keyboard stack (#121) and lands directly on main.

Selected-text voice edits replace the frozen selection automatically after
generation and capture drain, through the existing Session / target lease /
output transaction. The HUD shows only progress, cancellation and a confirmed
one-use Restore. Esc cancels before delivery; Command-Option-Z restores the
confirmed original once. Remote-model disclosure is required before selected
text is sent, and selected content stays out of generic history.

Source: de89534, 72dc402, 1eae672, 27ffc8c, da43ec8 on
research/voicecursor-voice-editing-20261008, rebased onto origin/main.

Left out on purpose (still in #124 / #121): UtterMobile, UtterKeyboardBridge,
iOS/ targets and the mobile selection scripts; the offline-sandbox build and
evidence tooling (build-app.sh options, guarded-offline-build.py,
capture-candidate.py).

Merge decisions against main:
- Secure input now refuses every write, including the clipboard-only copy,
  on the Chromium web-editor path too. The main-side test that expected a
  clipboard copy under secure input is updated to match.
- Test doubles on main (UpdateFakeExecution) gained the new
  SessionExecutionService requirements.

Co-authored-by: Cursor <cursoragent@cursor.com>
@IchenDEV
IchenDEV marked this pull request as ready for review October 26, 2026 07:30
@IchenDEV
IchenDEV merged commit 0e0f3c1 into main Oct 27, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant