Skip to content

Make Screen Recording permission optional#633

Merged
FuJacob merged 2 commits into
mainfrom
optional-screen-recording
Jun 7, 2026
Merged

Make Screen Recording permission optional#633
FuJacob merged 2 commits into
mainfrom
optional-screen-recording

Conversation

@FuJacob
Copy link
Copy Markdown
Owner

@FuJacob FuJacob commented Jun 7, 2026

Summary

Screen Recording was a hard requirement that blocked all autocomplete when missing, even though Fast Mode already skips the screenshot/OCR pipeline (the Permissions pane even admitted it: "Required even when Fast Mode skips capture"). This makes the permission optional: without it, Cotabby runs the text-only Fast Mode path (predictions still work), and granting it later re-enables visual context per the user's stored preference. Users without the permission are effectively forced into Fast Mode rather than left with autocomplete fully disabled.

Validation

Ran locally on macOS:

swiftlint lint --quiet
# exit 0 (one pre-existing warning on an untouched long test-class name)

xcodebuild -project Cotabby.xcodeproj -scheme Cotabby -destination 'platform=macOS' build \
  -derivedDataPath build/DerivedData
# ** BUILD SUCCEEDED **

xcodebuild -project Cotabby.xcodeproj -scheme Cotabby -destination 'platform=macOS' test \
  -derivedDataPath build/DerivedData CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO \
  -only-testing:CotabbyTests/SuggestionAvailabilityEvaluatorTests \
  -only-testing:CotabbyTests/TerminalAppDetectorTests \
  -only-testing:CotabbyTests/CotabbyPermissionKindTests
# ** TEST SUCCEEDED **  46 tests, 0 failures

Not yet verified end-to-end in a live session (needs real TCC permission toggling plus observing inline ghost text). Suggested manual check: with Screen Recording denied, autocomplete should work text-only and Fast Mode should show locked-on; granting it should resume visual context; revoking it mid-session should inject no visual context on the next suggestion (verify in ~/Library/Logs/Cotabby/llm-io.jsonl).

Linked issues

Addresses the request to make Screen Recording optional now that Fast Mode skips OCR / screen capture. No matching open issue number was located in the tracker; add Fixes #N if one exists.

Risk / rollout notes

  • Behavior change to an existing user flow: Screen Recording is no longer required. Users who already granted it are unaffected (visual context keeps working per their Fast Mode setting). Users who never granted it, or who revoke it, now keep working in text-only Fast Mode instead of being fully disabled.
  • PermissionManager.requiredPermissionsGranted no longer includes Screen Recording, so the onboarding Continue gate, the post-onboarding permission reminder, the menu-bar permission nag, and the settings attention dot stop flagging it. Onboarding still surfaces it as an optional, skippable card.
  • Privacy: on revoke, the visual-context session is cancelled in handlePermissionChange() and the excerpt read is re-gated on the live permission, so a cached screenshot excerpt cannot be injected into prompts after the user turns the permission off.
  • No schema, settings, or pbxproj migrations. The stored Fast Mode preference is left untouched; it is only force-displayed as on (locked) while the permission is off, and restored when granted.

Greptile Summary

Screen Recording is demoted from a hard requirement to an optional enhancement — its absence now routes Cotabby into the text-only Fast Mode path rather than blocking autocomplete entirely.

  • SuggestionAvailabilityEvaluator drops screenRecordingGranted from disabledReason/shouldSchedulePrediction and moves the Screen Recording gate into shouldCaptureVisualContext only. PermissionModels grows isOptionalEnhancement to encode the three-state onboarding model (required / optional / hidden), and PermissionManager.requiredPermissionsGranted is narrowed to Accessibility + Input Monitoring only.
  • handlePermissionChange explicitly cancels the visual context coordinator on revoke (since it no longer trips the prediction-disabled path), and generateFromCurrentFocus re-checks the live permission immediately before reading the cached screenshot excerpt to close the 2-second poll window.
  • UI surfaces — menu bar, General settings, Permissions pane, and onboarding — consistently show Fast Mode as forced-on and locked while Screen Recording is absent, and restore the stored preference on grant.

Confidence Score: 5/5

Safe to merge — the permission demotion is correctly threaded through every code path with no functional regressions introduced.

The core change — removing Screen Recording from the prediction-availability gate and adding it to the visual-context gate — is consistently applied across all call sites: the evaluator, all three coordinator extensions, and the lifecycle settings handler. The double-gating approach (cancel-on-revoke in handlePermissionChange plus the live re-check in generateFromCurrentFocus) correctly closes the 2-second poll window without over-cancelling on grant. UI surfaces are consistently updated and the test suite directly covers the new split behavior. No data-loss, stale-context, or auth-boundary issues were found.

No files require special attention.

Important Files Changed

Filename Overview
Cotabby/App/Coordinators/SuggestionCoordinator+Input.swift handlePermissionChange: explicit visual-context cancel on Screen Recording revoke; Screen Recording removed from shouldSchedulePrediction call. Logic is correct for both grant and revoke paths.
Cotabby/App/Coordinators/SuggestionCoordinator+Prediction.swift Adds a live permission re-check before reading the cached screenshot excerpt — belt-and-suspenders guard for the 2-second poll window. Correct; no issues.
Cotabby/Support/SuggestionAvailabilityEvaluator.swift screenRecordingGranted removed from disabledReason/shouldSchedulePrediction signatures; moved into shouldCaptureVisualContext. Clean and well-documented split of concerns.
Cotabby/Models/PermissionModels.swift Adds isOptionalEnhancement, correctly independent from isRequiredForAutocomplete, with a clear doc comment explaining the three-state onboarding model. Screen Recording returns false/true respectively.
Cotabby/UI/WelcomePermissionStepView.swift Onboarding split into required/optional card sections. Optional badge added. Button label remains "Allow" for all ungranted permissions.
CotabbyTests/SuggestionAvailabilityEvaluatorTests.swift Old screenRecording-blocks-prediction tests removed; new test_noScreenRecording_suppressesVisualContextButNotPredictions added, correctly verifying the split behavior.
CotabbyTests/PermissionAndContextModelTests.swift Tests updated to assert new isRequiredForAutocomplete and isOptionalEnhancement values per-case. Good coverage of the model change.

Comments Outside Diff (1)

  1. Cotabby/UI/WelcomePermissionStepView.swift, line 115-127 (link)

    P2 The onboarding PermissionCard always shows "Allow" for ungranted permissions regardless of isOptional, while the Permissions settings pane shows "Enable" for the same optional Screen Recording card. Users who skip Screen Recording in onboarding and later find the settings pane will see different button labels for the same action. Consider matching the settings label in the optional card path.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

    Fix in Codex Fix in Claude Code

Reviews (2): Last reviewed commit: "Document that isOptionalEnhancement and ..." | Re-trigger Greptile

Screen Recording previously blocked all autocomplete even though Fast Mode
already skips the screenshot/OCR pipeline. It is now optional: without it the
app runs the text-only Fast Mode path (predictions still work), and granting it
re-enables visual context per the user's stored preference.

- Evaluator: gate visual-context capture on the permission in
  shouldCaptureVisualContext; drop it from disabledReason/shouldSchedulePrediction
  so it no longer blocks predictions.
- PermissionModels: isRequiredForAutocomplete is false for screenRecording; add
  isOptionalEnhancement so onboarding still shows it as a skippable card.
- Coordinator: cancel the visual-context session on revoke and re-check the
  permission before injecting a cached excerpt, so screenshot-derived text can't
  leak into prompts after the user turns it off.
- UI: Permissions pane presents Screen Recording as optional; Fast Mode is locked
  on with an explanation when the permission is off (menu bar + General pane).
- Tests updated for the new gating.
Comment thread Cotabby/Models/PermissionModels.swift
… independent

Addresses Greptile review on #633: the two booleans encode three onboarding
states (required / optional / hidden), so they are intentionally not derived
from each other.
@FuJacob FuJacob merged commit 858a905 into main Jun 7, 2026
4 checks passed
@FuJacob FuJacob deleted the optional-screen-recording branch June 7, 2026 20:11
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