Skip to content

Add auto-paste user toggle#16

Merged
maker-or merged 3 commits into
mainfrom
fix-accessibility-text-input
Mar 6, 2026
Merged

Add auto-paste user toggle#16
maker-or merged 3 commits into
mainfrom
fix-accessibility-text-input

Conversation

@maker-or

@maker-or maker-or commented Mar 6, 2026

Copy link
Copy Markdown
Owner

Agent-Id: agent-ccd5997d-22eb-4fb4-bf2f-c45d4b11c2c0

Summary by CodeRabbit

  • New Features
    • Added "Auto-paste to focused field" toggle in General settings with persistent state and reset-to-default behavior.
    • Transcriptions now only auto-paste when the toggle is enabled and accessibility permission is available.
  • Improvements
    • Safer auto-paste flow with explicit permission checks and logging for accessibility decisions.

Agent-Id: agent-ccd5997d-22eb-4fb4-bf2f-c45d4b11c2c0
@coderabbitai

coderabbitai Bot commented Mar 6, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds a persisted auto-paste toggle to AppState and Settings, threads a PermissionManager into TranscriptionService, and conditions transcription delivery to call copyAndPasteIfPossible when auto-paste is enabled and accessibility permission is available, otherwise falling back to copyToClipboard.

Changes

Cohort / File(s) Summary
App State
dhavnii/App/AppState.swift
Adds autoPasteEnabledDefaultsKey and autoPasteEnabled: Bool property initialized from and persisted to UserDefaults.
Settings UI
dhavnii/Features/Settings/SettingsView.swift
Adds an Auto-paste toggle bound to appState.autoPasteEnabled, changes binding to a Bindable, and resets/removes the setting from UserDefaults on reset.
Transcription & Wiring
dhavnii/Features/Transcription/TranscriptionService.swift, openwispher/openwispherApp.swift
Adds permissionManager dependency; updates initializer calls; when autoPasteEnabled is true uses copyAndPasteIfPossible, otherwise copyToClipboard.
Clipboard Behavior
dhavnii/Features/Clipboard/ClipboardManager.swift
Replaces unconditional AXIsProcessTrusted path with guarded accessibility-permission checks, logs decisions, and only performs delayed paste when permission is present.
Permissions API
dhavnii/Features/Permissions/PermissionManager.swift
Adds accessibilityPermissionState(for:) to expose cached accessibility state with contextual logging.

Sequence Diagram

sequenceDiagram
    actor User
    participant Settings as "Settings UI"
    participant AppState
    participant UserDefaults
    participant Transcription as "TranscriptionService"
    participant Permission as "PermissionManager"
    participant Clipboard as "ClipboardManager / System"

    User->>Settings: Toggle Auto-paste
    Settings->>AppState: set autoPasteEnabled
    AppState->>UserDefaults: persist autoPasteEnabled

    User->>Transcription: trigger transcription
    Transcription->>AppState: read autoPasteEnabled

    alt autoPasteEnabled == true
        Transcription->>Permission: accessibilityPermissionState(reason)
        Permission-->>Transcription: hasAccessibilityPermission
        alt permission granted
            Transcription->>Clipboard: copyAndPasteIfPossible(transcript)
        else permission denied
            Transcription->>Clipboard: copyToClipboard(transcript)
        end
    else autoPasteEnabled == false
        Transcription->>Clipboard: copyToClipboard(transcript)
    end
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • update #6: touches Settings UI and auto-paste related UI blocks; may conflict or overlap with toggle changes.
  • es #12: modifies the same AppState, TranscriptionService, ClipboardManager, PermissionManager, and app wiring — strongly related to these changes.

Poem

🐰
I hopped through settings, soft and neat,
Toggled paste so transcripts meet,
I checked permissions, gave a thump,
Clipboard dances with a jump,
Little rabbit cheers — paste on repeat! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% 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 'Add auto-paste user toggle' directly and accurately summarizes the main change: introducing a new user-controllable toggle for auto-paste functionality across AppState, SettingsView, and TranscriptionService.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-accessibility-text-input

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dhavnii/Features/Transcription/TranscriptionService.swift`:
- Around line 231-234: The call to ClipboardManager.copyAndPasteIfPossible in
TranscriptionService is passing a non-existent parameter
hasAccessibilityPermission; update the invocation to match the method signature
by removing the second argument so only the transcription string is passed
(i.e., call copyAndPasteIfPossible(transcription)); reference:
ClipboardManager.copyAndPasteIfPossible, transcription,
hasAccessibilityPermission.
- Around line 34-42: TranscriptionService's initializer now requires a
permissionManager parameter; update the place that constructs the service (the
let service = TranscriptionService(...) call) to pass the existing
permissionManager variable as permissionManager: permissionManager alongside
appState and selectedProvider so the call matches internal
init(appState:permissionManager:selectedProvider:) and compiles.
- Around line 227-237: The auto-paste branch is calling a non-existent
permissionManager.accessibilityPermissionState(for:) and passing an extra
parameter to clipboardManager.copyAndPasteIfPossible(_:); remove the permission
check and call clipboardManager.copyAndPasteIfPossible(transcription) directly
when appState.autoPasteEnabled is true (fall back to
clipboardManager.copyToClipboard(transcription) in the else branch), and delete
the unused permissionManager.accessibilityPermissionState(...) invocation so the
code uses the existing hasAccessibilityPermission logic inside
copyAndPasteIfPossible.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 181c3273-cc42-4c22-8a6a-bb186e28332c

📥 Commits

Reviewing files that changed from the base of the PR and between 151f0be and 3c4bccc.

📒 Files selected for processing (3)
  • dhavnii/App/AppState.swift
  • dhavnii/Features/Settings/SettingsView.swift
  • dhavnii/Features/Transcription/TranscriptionService.swift

Comment thread dhavnii/Features/Transcription/TranscriptionService.swift
Comment thread dhavnii/Features/Transcription/TranscriptionService.swift
Comment thread dhavnii/Features/Transcription/TranscriptionService.swift Outdated
maker-or added 2 commits March 6, 2026 15:44
Agent-Id: agent-9f4e06c6-7785-477e-b5ab-fa6d7af53e47
Agent-Id: agent-ccd5997d-22eb-4fb4-bf2f-c45d4b11c2c0

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
dhavnii/Features/Clipboard/ClipboardManager.swift (1)

69-80: Bypasses PermissionManager by calling AXIsProcessTrusted() directly.

PermissionManager was enhanced with accessibilityPermissionState(for:) to provide cached permission state with logging, but this code calls AXIsProcessTrusted() directly. This:

  1. Misses the debouncing/caching logic in PermissionManager
  2. Produces duplicate logging (here and in PermissionManager)
  3. Could report different state than what PermissionManager.hasAccessibilityPermission shows

Consider injecting PermissionManager into ClipboardManager and using permissionManager.accessibilityPermissionState(for: "auto-paste") instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dhavnii/Features/Clipboard/ClipboardManager.swift` around lines 69 - 80,
Replace the direct AXIsProcessTrusted() call in ClipboardManager with the
injected PermissionManager: add a PermissionManager property to
ClipboardManager, call permissionManager.accessibilityPermissionState(for:
"auto-paste") to obtain the cached state (instead of AXIsProcessTrusted()), use
that state's granted flag for the guard check, and remove the duplicate print
logging so only PermissionManager handles accessibility logging; update any uses
of the local hasAccessibilityPermission variable to use the permission state
returned by accessibilityPermissionState(for:).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dhavnii/Features/Permissions/PermissionManager.swift`:
- Around line 244-250: The method accessibilityPermissionState(for:) is
unused—either delete it or make ClipboardManager use it instead of calling
AXIsProcessTrusted() directly; to keep a single source of truth, update
ClipboardManager to call PermissionManager.accessibilityPermissionState(for:
"ClipboardManager") (or the instance method on your PermissionManager object)
and remove the direct AXIsProcessTrusted() usage, ensuring any logging/behaviour
still references hasAccessibilityPermission, lastAccessibilityState and
isMonitoring for consistency.

---

Nitpick comments:
In `@dhavnii/Features/Clipboard/ClipboardManager.swift`:
- Around line 69-80: Replace the direct AXIsProcessTrusted() call in
ClipboardManager with the injected PermissionManager: add a PermissionManager
property to ClipboardManager, call
permissionManager.accessibilityPermissionState(for: "auto-paste") to obtain the
cached state (instead of AXIsProcessTrusted()), use that state's granted flag
for the guard check, and remove the duplicate print logging so only
PermissionManager handles accessibility logging; update any uses of the local
hasAccessibilityPermission variable to use the permission state returned by
accessibilityPermissionState(for:).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a48252c8-c082-4a71-a5c0-98ac920d123c

📥 Commits

Reviewing files that changed from the base of the PR and between 3c4bccc and eb18be5.

📒 Files selected for processing (4)
  • dhavnii/Features/Clipboard/ClipboardManager.swift
  • dhavnii/Features/Permissions/PermissionManager.swift
  • dhavnii/Features/Transcription/TranscriptionService.swift
  • openwispher/openwispherApp.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • dhavnii/Features/Transcription/TranscriptionService.swift

Comment on lines +244 to +250
internal func accessibilityPermissionState(for reason: String) -> Bool {
let trusted = hasAccessibilityPermission
print(
"🔓 Accessibility permission queried for \(reason): cached=\(trusted), lastKnown=\(lastAccessibilityState), monitoring=\(isMonitoring)"
)
return trusted
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if accessibilityPermissionState is used anywhere in the codebase

echo "=== Searching for usages of accessibilityPermissionState ==="
rg -n "accessibilityPermissionState" --type swift

echo ""
echo "=== Searching for direct AXIsProcessTrusted calls outside PermissionManager ==="
rg -n "AXIsProcessTrusted" --type swift -g '!*PermissionManager*'

Repository: maker-or/openwispher

Length of output: 454


Remove unused method or update ClipboardManager to use it.

The method accessibilityPermissionState(for:) is never called anywhere in the codebase. Meanwhile, ClipboardManager.swift at line 70 calls AXIsProcessTrusted() directly instead of using this centralized method. Either remove the dead code or update ClipboardManager to use the new method for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dhavnii/Features/Permissions/PermissionManager.swift` around lines 244 - 250,
The method accessibilityPermissionState(for:) is unused—either delete it or make
ClipboardManager use it instead of calling AXIsProcessTrusted() directly; to
keep a single source of truth, update ClipboardManager to call
PermissionManager.accessibilityPermissionState(for: "ClipboardManager") (or the
instance method on your PermissionManager object) and remove the direct
AXIsProcessTrusted() usage, ensuring any logging/behaviour still references
hasAccessibilityPermission, lastAccessibilityState and isMonitoring for
consistency.

@maker-or maker-or merged commit 483ea53 into main Mar 6, 2026
2 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