Skip to content

Cross-platform rule

This page mirrors implementation notes maintained in CLAUDE.md. The CLAUDE.md form is the canonical source for the contributor checklist; this page is the public-facing version.

Cue runs on macOS and Windows. Every feature, fix, or behavioral change MUST be applied to BOTH platforms. This is the single rule that prevents a year of platform drift.

PR checklist

For every change touching platform code:

  • [ ] If you add a function to src/cue/platform/macos.py, add the equivalent to src/cue/platform/windows.py (and vice versa).
  • [ ] If you export something new from a platform module, add it to src/cue/platform/__init__.py for BOTH platforms.
  • [ ] If you add a menu item to CueApp (macOS), add it to _run_windows() tray menu too.
  • [ ] If you add a --hidden-import to scripts/build_macos.sh, add it to scripts/build_windows.bat AND scripts/build_installer.py.
  • [ ] If you add a dependency to pyproject.toml, decide if it's shared or platform-specific.
  • [ ] If you add to BLOCKED_APPS in store.py, include BOTH macOS app names AND Windows process names (case-insensitive).
  • [ ] For file/directory permissions, use cue.fs.secure_dir() / secure_file() — never raw os.chmod().
  • [ ] Test popup UI changes on both platforms (font vars FONT_UI / FONT_MONO handle platform fonts).
  • [ ] Streaming recorder runs the vendored ocap-{platform} CLI as subprocess — any new CLI option must be supported by both ocap repos. Submodules must stay in sync; run git submodule update --init --recursive after pulling.

Project layout

src/ layout — all package code lives in src/cue/. Entry point: python -m cue or run.py (for frozen builds).

Data directory

Single source of truth: cue.config.CONFIG_DIR. Never define platform paths elsewhere — import CONFIG_DIR.

Why this discipline matters

The cost of one missed item is high — a one-line forgotten import in cue/platform/__init__.py shows up as a runtime AttributeError on the other platform that didn't ship the counterpart. Multiplied across a year, the codebase silently becomes "macOS-only" or "Windows-only" while everyone thinks it still ships both.

PR review enforces the checklist.

Modules that are explicitly cross-platform

These import without a sys.platform guard and are the same on both platforms:

  • cue.capturemss + Pillow screenshots.
  • cue.fssecure_dir / secure_file / mark_not_indexed.
  • cue.configCONFIG_DIR, streaming_config, privacy_config, get_api_key.
  • cue.recorder — wraps the per-platform ocap CLI.
  • cue.pruner — MKV reader runs as its own subprocess.
  • cue.digest, cue.llm, cue.frame_select, cue.image_preprocess, cue.llama_server, cue.local_models — all platform-agnostic.
  • cue.privacy — high-level monitor + controller. Per-platform watchers live behind a small interface in cue.platform.
  • cue.overlay — dispatches to per-platform overlay_macos / overlay_windows.
  • cue.settings_model, cue.settings_window, cue.popup_window — customtkinter UI is shared.
  • cue.pii, cue.pii_recognizers, cue.store, cue.prompts, cue.memory, cue.suggest — pure logic.

Modules that DO branch on platform

src/cue/platform/__init__.py exports a stable surface; the implementation under it differs:

  • cue.platform.macos — rumps tray, CGEventTap, AppleScript, Carbon, AX, NSWorkspace.
  • cue.platform.windows — pystray tray, pynput, UIA, SetWinEventHook, win32clipboard.
  • cue.platform.overlay_macos — pyobjc NSWindow per NSScreen.
  • cue.platform.overlay_windows — Tk Toplevel per monitor with WS_EX_LAYERED|TRANSPARENT|NOACTIVATE|TOOLWINDOW.

The full table of behavioral differences is on the Platform abstraction page.

See also