Skip to content

cue.privacy

Privacy pause — monitor + controller.

Public API

start(status_callback=None) # idempotent; status_callback fires on state change stop() # idempotent; safe from atexit toggle_manual() # flip manual-pause flag (fire-and-forget) is_paused() -> bool reasons() -> frozenset[str] reason_label() -> str # privacy-safe UI label (no app / URL leak)

Reasons

"manual" — user toggled the pause hotkey / menu item "secure_input" — a password field has system-wide secure input enabled "blocked_app" — active app matches BLOCKED_APPS / blocked_apps / title regex "browser_url" — active browser URL matches blocked_url_patterns, OR active browser is in tristate denied + fail_closed=True

See /Users/jyjung/.claude/plans/groovy-frolicking-ullman.md for the full design.

PauseController

submit

submit(reasons: frozenset[str]) -> None

Fire-and-forget. Called from monitor / hotkey / menu threads. Bounded queue; on overflow we drop (monitor's next poll re-submits).

PrivacyMonitor

request_rescan

request_rescan() -> None

Wake the polling loop so reasons get recomputed now.

request_rescan_debounced

request_rescan_debounced(min_interval_s: float = 0.1) -> None

Coalesce a burst of wake requests to one wake per interval. Used by chatty event hooks (foreground / focus / name-change).

pulse_reason

pulse_reason(reason: str, duration_s: float) -> None

Add a transient reason that expires after duration_s seconds. Wakes the loop immediately so the reason is observable on the next _compute_reasons tick rather than the next slow poll.

pulse_wake_blackout

pulse_wake_blackout() -> None

1.5 s system_transition blackout — registered with the platform watcher so OS sleep / wake events trip pause around the transition before the first detection cycle has a chance to run.

reload_browser_auth

reload_browser_auth() -> None

Drop the cached BrowserAuth singleton so the next browser_auth() call re-reads browser_auth.json from disk. Called by the main process after the Preferences subprocess exits — without it the main loop's cached dict would keep serving stale tristate values until restart.

start

start(status_callback: Optional[Callable[[], None]] = None) -> None

Idempotent. Safe to call from any thread.

toggle_manual

toggle_manual() -> None

Flip the manual-pause flag. Fire-and-forget — safe from hotkey taps.

reason_label

reason_label() -> str

UI-safe label — never exposes app / URL details.

run_browser_onboarding

run_browser_onboarding() -> dict

Walk supported browsers, prompt user per-browser. Returns the new auth states {app_lower: state}.

macOS: only prompts for installed browsers; "Ask now" fires the actual AppleEvents permission dialog. Windows: prompts for all supported browsers (no per-app permission prompt exists; the tristate is purely a Cue-side policy knob).

reset_browser_auth

reset_browser_auth() -> None

Clear tristate + attempt tccutil reset AppleEvents on macOS so the next onboarding run re-prompts. Best-effort.