Skip to content

feat: add setting to keep transcript in clipboard after pasting#107

Open
HNKNTA wants to merge 2 commits intoamicalhq:mainfrom
HNKNTA:dev
Open

feat: add setting to keep transcript in clipboard after pasting#107
HNKNTA wants to merge 2 commits intoamicalhq:mainfrom
HNKNTA:dev

Conversation

@HNKNTA
Copy link

@HNKNTA HNKNTA commented Feb 26, 2026

Add a "Keep transcript in clipboard" toggle to Advanced Settings that skips restoring the original clipboard contents after dictation paste, leaving the transcribed text available for subsequent manual pastes.

Addresses issue #100.

image

Summary by CodeRabbit

  • New Features

    • Added "Keep Transcript in Clipboard" toggle in Advanced Preferences — when enabled, pasted transcriptions remain in the clipboard instead of restoring prior contents; applies to paste actions across platforms.
  • Localization

    • UI text and descriptions added for English, Spanish, and Japanese.

Add a "Keep transcript in clipboard" toggle to Advanced Settings that
skips restoring the original clipboard contents after dictation paste,
leaving the transcribed text available for subsequent manual pastes.

Addresses issue amicalhq#100.
@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d384b33 and 7564b79.

📒 Files selected for processing (2)
  • apps/desktop/src/renderer/main/pages/settings/advanced/index.tsx
  • packages/native-helpers/windows-helper/src/RpcHandler.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/renderer/main/pages/settings/advanced/index.tsx

📝 Walkthrough

Walkthrough

Adds a new user preference to optionally retain transcribed text in the clipboard after pasting; updates schema, default settings, migrations, UI, settings service, recording logic, type defs, and native paste implementations for macOS and Windows to respect the flag.

Changes

Cohort / File(s) Summary
Settings Data Model
apps/desktop/src/db/schema.ts, apps/desktop/src/db/app-settings.ts, apps/desktop/src/services/settings-service.ts, apps/desktop/src/trpc/routers/settings.ts
Added preferences.keepTranscriptInClipboard: boolean (optional in schema) and included default false in default settings; surfaced in service and tRPC schemas.
Settings Migration
apps/desktop/src/db/settings-migrations/index.ts
Bumped CURRENT_SETTINGS_VERSION 7→8 and wired migrateToV8.
Internationalization
apps/desktop/src/i18n/locales/en.json, apps/desktop/src/i18n/locales/es.json, apps/desktop/src/i18n/locales/ja.json
Added settings.advanced.keepTranscriptInClipboard entries (label + description) for en/es/ja.
Advanced Settings UI
apps/desktop/src/renderer/main/pages/settings/advanced/index.tsx
Query + mutation for preferences added; local state and switch control for keepTranscriptInClipboard; update handler wired to preferences API with toast/invalidation.
Recording & Paste Logic
apps/desktop/src/main/managers/recording-manager.ts
Fetches preference and passes keepInClipboard flag to native pasteText call when pasting transcriptions.
macOS Native Bridge
packages/native-helpers/swift-helper/.../AccessibilityService.swift, .../RpcHandler.swift
pasteText signature extended to accept keepInClipboard: Bool = false; when true, skip restoration of original pasteboard.
Windows Native Bridge
packages/native-helpers/windows-helper/src/RpcHandler.cs, .../Services/AccessibilityService.cs
PasteText signature extended with keepInClipboard; post-paste logic updated to conditionally restore or preserve clipboard and adjust logging/error messages.
Type Definitions
packages/types/src/schemas/methods/paste-text.ts
Added optional keepInClipboard to PasteTextParamsSchema and inferred types.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant SettingsUI as Settings UI
    participant SettingsService as Settings Service
    participant RecordingMgr as Recording Manager
    participant NativeBridge as Native Bridge (macOS/Windows)
    participant Clipboard as System Clipboard

    User->>SettingsUI: Toggle "Keep Transcript in Clipboard"
    SettingsUI->>SettingsService: updatePreferences(keepTranscriptInClipboard)
    SettingsService-->>SettingsUI: ack

    Note over RecordingMgr,SettingsService: Later: user requests paste

    RecordingMgr->>SettingsService: getPreferences()
    SettingsService-->>RecordingMgr: preferences (keepTranscriptInClipboard)
    RecordingMgr->>NativeBridge: pasteText(transcript, keepInClipboard)
    
    rect rgba(100, 150, 255, 0.5)
    Note over NativeBridge,Clipboard: keepInClipboard = true
    NativeBridge->>Clipboard: Paste transcribed text (do not restore)
    end

    rect rgba(100, 200, 150, 0.5)
    Note over NativeBridge,Clipboard: keepInClipboard = false
    NativeBridge->>Clipboard: Paste transcribed text
    NativeBridge->>NativeBridge: Schedule restore original clipboard content
    end

    Clipboard-->>User: Clipboard updated
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Add mute system audio setting and handling #62 — Similar change pattern: adds a boolean preference in AppSettingsData, bumps settings migrations, updates settings service/schema/UI, and applies preference in RecordingManager (comparable clipboard/mute preference work).

Suggested reviewers

  • haritabh-z01

Poem

🐰 A tiny toggle, quiet and bright,
Keep transcripts close after paste-flight.
From schema to Swift and Windows too,
The clipboard stays put — hooray, we do! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main feature added: a new setting to keep transcribed text in the clipboard after pasting.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/main/managers/recording-manager.ts (1)

773-804: ⚠️ Potential issue | 🟠 Major

Do not block paste when preference lookup fails.

A failure reading preferences currently aborts paste. This creates a functional regression under transient settings/DB errors. Fallback to false and continue pasting.

💡 Proposed fix
   try {
     const nativeBridge = this.serviceManager.getService("nativeBridge");
-    const settingsService =
-      this.serviceManager.getService("settingsService");
-    const preferences = await settingsService.getPreferences();
-    const keepInClipboard =
-      preferences?.keepTranscriptInClipboard ?? false;
+    let keepInClipboard = false;
+    try {
+      const settingsService =
+        this.serviceManager.getService("settingsService");
+      const preferences = await settingsService.getPreferences();
+      keepInClipboard = preferences?.keepTranscriptInClipboard ?? false;
+    } catch (error) {
+      logger.main.warn(
+        "Failed to load keepTranscriptInClipboard, using default=false",
+        { error: error instanceof Error ? error.message : String(error) },
+      );
+    }

     logger.main.info("Pasting transcription to active application", {
       textLength: transcription.length,
       keepInClipboard,
     });

     if (nativeBridge) {
       void nativeBridge
         .call("pasteText", {
           transcript: transcription,
           keepInClipboard,
         })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/main/managers/recording-manager.ts` around lines 773 - 804,
The current preference lookup via settingsService.getPreferences() can throw and
abort the paste; change the flow in the paste routine in recording-manager
(around serviceManager.getService("settingsService") and getPreferences()) to
catch errors from getPreferences() separately, log a warning, and fall back to
keepInClipboard = false so the paste still proceeds; ensure you still call
nativeBridge.call("pasteText", { transcript: transcription, keepInClipboard })
and preserve the existing error handling for nativeBridge.call failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/desktop/src/renderer/main/pages/settings/advanced/index.tsx`:
- Around line 63-73: The mutation handler updatePreferencesMutation currently
logs and shows a toast on error but doesn't revert optimistic UI changes; update
the onError callback in updatePreferencesMutation (and the other mutation at
lines ~149-154) to either refetch the preference cache via
utils.settings.getPreferences.invalidate() or explicitly roll back the local
toggle state used by the settings page component (the state/handler that flips
the switch) so the switch reflects the server value after a failed update;
ensure the rollback runs before showing the error toast to keep the UI
consistent.

In `@packages/native-helpers/windows-helper/src/RpcHandler.cs`:
- Around line 309-310: The current RPC handler calls
accessibilityService.PasteText(parameters.Transcript, keepInClipboard, out var
errorMessage) and always returns the fixed string "Pasted successfully", which
discards any non-fatal warning in errorMessage; update the response creation in
the method that handles the PasteText RPC (RpcHandler.cs) to surface
errorMessage when it is non-empty even if success==true—e.g., append or include
the warning text in the success message or add an explicit warning field in the
response object—so when parameters.KeepInClipboard is false and restore fails
the client sees the warning instead of losing the errorMessage.

---

Outside diff comments:
In `@apps/desktop/src/main/managers/recording-manager.ts`:
- Around line 773-804: The current preference lookup via
settingsService.getPreferences() can throw and abort the paste; change the flow
in the paste routine in recording-manager (around
serviceManager.getService("settingsService") and getPreferences()) to catch
errors from getPreferences() separately, log a warning, and fall back to
keepInClipboard = false so the paste still proceeds; ensure you still call
nativeBridge.call("pasteText", { transcript: transcription, keepInClipboard })
and preserve the existing error handling for nativeBridge.call failures.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a2d11d and d384b33.

⛔ Files ignored due to path filters (1)
  • packages/native-helpers/windows-helper/src/Models/Generated/Models.cs is excluded by !**/generated/**
📒 Files selected for processing (15)
  • apps/desktop/src/db/app-settings.ts
  • apps/desktop/src/db/schema.ts
  • apps/desktop/src/db/settings-migrations/index.ts
  • apps/desktop/src/i18n/locales/en.json
  • apps/desktop/src/i18n/locales/es.json
  • apps/desktop/src/i18n/locales/ja.json
  • apps/desktop/src/main/managers/recording-manager.ts
  • apps/desktop/src/renderer/main/pages/settings/advanced/index.tsx
  • apps/desktop/src/services/settings-service.ts
  • apps/desktop/src/trpc/routers/settings.ts
  • packages/native-helpers/swift-helper/Sources/SwiftHelper/AccessibilityService.swift
  • packages/native-helpers/swift-helper/Sources/SwiftHelper/RpcHandler.swift
  • packages/native-helpers/windows-helper/src/RpcHandler.cs
  • packages/native-helpers/windows-helper/src/Services/AccessibilityService.cs
  • packages/types/src/schemas/methods/paste-text.ts

… paste warnings

Invalidate preferences query cache on updatePreferencesMutation error
so the toggle resyncs to the server value. Also fix Windows RPC handler
to surface clipboard restore warnings instead of discarding them when
paste succeeds with a non-fatal error.
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