Architecture overview¶
This page mirrors implementation notes maintained in CLAUDE.md.
Update both when changing this subsystem.
Project layout¶
src/ layout — all package code lives in src/cue/. Entry points:
python -m cue (dev) or run.py (frozen builds).
src/cue/
├── main.py # menu-bar app, hotkey, top-level worker spawn
├── popup_window.py # customtkinter popup subprocess
├── settings_window.py # Preferences subprocess (customtkinter)
├── settings_model.py # pure-logic layer for Preferences (stdlib only, unit-testable)
├── recorder.py # ocap subprocess wrapper + rotator/evictor/digest threads
├── pruner.py # MKV → keyframe extractor (own subprocess for GStreamer env)
├── ocap_launcher.py # ocap CLI wrapper that monkey-patches the pipeline
├── digest.py # 5 s digest tick — Haiku/Gemma 4 over keyframes + events
├── llm.py # DigestBackend Protocol + CloudVisionBackend + LocalVisionBackend
├── llama_server.py # bundled llama-server subprocess lifecycle
├── local_models.py # pinned Gemma 4 manifest + resumable download
├── frame_select.py # 10-frame selector with anchor protection + dedupe
├── image_preprocess.py # 896 px JPEG q75 + EXIF/ICC strip
├── prompts.py # single source of truth for every Claude prompt
├── memory.py # Opus rewrites memory.md from recent digests
├── suggest.py # hotkey path: Opus + memory + recent context
├── pii.py # Presidio scrub() + scrub_strict()
├── pii_recognizers.py # Cue-specific Presidio recognizers
├── privacy.py # PrivacyMonitor + PauseController
├── overlay.py # red-border overlay dispatcher
├── store.py # SQLite — sessions, digests, BLOCKED_APPS, backfill_scrub
├── config.py # CONFIG_DIR, get_api_key, streaming_config, privacy_config
├── fs.py # secure_dir / secure_file (POSIX chmod, Windows no-op) + Spotlight opt-out
├── capture.py # mss + Pillow screenshot (cross-platform)
└── platform/
├── __init__.py # facade — import from `cue.platform`, never directly
├── macos.py # rumps tray, CGEventTap, AppleScript, Carbon, AX
├── windows.py # pystray tray, pynput, UIA, SetWinEventHook
├── overlay_macos.py # NSPanel per NSScreen, NSFloatingWindowLevel
└── overlay_windows.py # Tk Toplevel per monitor, WS_EX_LAYERED|TRANSPARENT
Process model¶
graph TB
subgraph "Cue main process (menu bar / tray)"
Main[cue.main]
Hotkey[hotkey listener<br/>CGEventTap / GlobalHotKeys]
Privacy[PrivacyMonitor + PauseController]
Recorder[recorder.py rotator/evictor/digest threads]
end
subgraph "Subprocesses"
Popup[popup_window<br/>customtkinter]
Settings[settings_window<br/>customtkinter]
Ocap[ocap-macos / ocap-windows<br/>GStreamer pipeline]
Pruner[pruner worker<br/>per-chunk MKV reader]
LlamaServer[llama-server<br/>localhost only, opt-in]
end
Main --> Hotkey
Main --> Privacy
Main --> Recorder
Hotkey -- "Shift+Space" --> Popup
Main -- "Preferences..." --> Settings
Recorder -- "spawn / SIGKILL" --> Ocap
Recorder -- "per-chunk" --> Pruner
Recorder -- "5 s tick → cue.llm" --> LlamaServer
The menu bar process owns the hotkey listener, privacy monitor, recorder threads, and the popup/settings subprocess management. Heavy or risky work is in subprocesses: ocap (GStreamer), pruner (MKV decode + dhash), llama-server (multimodal inference). The menu bar is small and fast — never blocks the GUI run loop on a Cue worker.
Data directory¶
Single source of truth: cue.config.CONFIG_DIR. Never define
platform paths elsewhere — import CONFIG_DIR.
| Platform | Path |
|---|---|
| macOS | ~/Library/Application Support/Cue/ (data) + ~/Library/Caches/Cue/ (streaming, GStreamer-friendly) |
| Windows | %LOCALAPPDATA%\Cue\ |
See Data on disk for the file-by-file table.
Shared modules¶
These are the modules that both platforms import without
sys.platform guards:
| Module | What it does |
|---|---|
cue.capture |
Screen capture via mss + Pillow (thread-safe). |
cue.fs |
secure_dir() / secure_file() for permissions + mark_not_indexed() (Spotlight / Search opt-out). |
cue.config |
CONFIG_DIR, get_api_key, streaming_enabled, streaming_config, privacy_config. |
cue.recorder |
start() / stop() / is_running() / snapshot_context() / recent_mcap_paths() + stop_for_pause / resume_after_pause. |
cue.pruner |
process_chunk() (own subprocess) + recent_keyframes() + evict_older_than() / evict_newer_than(). Also runs as python -m cue.pruner worker. |
cue.digest |
read_digest() for hotkey path + evict_entries_newer_than(cutoff_ns) for the privacy purge cascade. |
cue.privacy |
start() / stop() / toggle_manual() / is_paused() / reasons() / reason_label() / reload_browser_auth(). |
cue.overlay |
show() / hide() dispatching to cue.platform.overlay_*. |
cue.settings_model |
Pure-logic layer for Preferences. stdlib-only, unit-testable. |
cue.settings_window |
Preferences subprocess entry point. |
Cross-platform discipline¶
Cue runs on macOS and Windows. Every feature, fix, or behavioral change must be applied to both. See the Cross-platform rule for the PR checklist.