# xCreen — full documentation > Concatenated from the xCreen repository (https://github.com/Al-ex-W/xCreen) by scripts/build-llms.py. Relative links inside each document are relative to its path in the repository. --- # xCreen: screen memory for Hermes **xCreen reads your screen with local OCR and has your [Hermes Agent](https://github.com/NousResearch/hermes-agent) write short takeaways into your Obsidian daily notes. Hermes can run on the same Mac or on a home server.** An open source alternative to Rewind and Microsoft Recall, for Macs running Hermes. [Website](https://al-ex-w.github.io/xCreen/) · [FAQ](https://al-ex-w.github.io/xCreen/faq/) · [Alternatives compared](https://al-ex-w.github.io/xCreen/alternatives/) [![Verify](https://github.com/Al-ex-W/xCreen/actions/workflows/verify.yml/badge.svg)](https://github.com/Al-ex-W/xCreen/actions/workflows/verify.yml) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![Platform: macOS 14+](https://img.shields.io/badge/platform-macOS%2014%2B-lightgrey.svg)](INSTALL.md) ![xCreen menu-bar tray](docs/assets/tray.png) ## What it does - **Menu-bar tray, Spotlight and CLI.** Ask questions about what you've seen from the tray, the macOS 26+ "Ask xCreen" Spotlight action or the "Search xCreen" row Spotlight offers under "Search in Apps" for any typed text (both fill the question in, you submit), or `xcreen ask` in a terminal. - **Local capture with dedup.** Screenshots the display you're working on (the one with the focused window, minus the menu bar, the Dock and any excluded app) and runs Apple Vision OCR on it at most once per second and drops text that is ≥90% similar to the last snapshot. Saves a screenshot every 10 active seconds, losslessly until its batch is digested, then as a mozjpeg JPEG at about 1/8 the size. - **Hermes on your Mac or on a server.** The Mac app only captures and uploads. `xcreen-server` runs next to Hermes, on the same Mac or on a Linux/macOS machine you reach over Tailscale, and owns the evidence, the Hermes session and the vault. Both setups run the same code ([client and server](docs/client-server.md)). - **Batches into one Hermes session.** Every 30 screenshots (5 active minutes), the server sends a batch to a single persistent xCreen session in your Hermes Agent. It does not start a new chat each time, and it never digests on a model other than the xCreen default you chose. - **Notes that read like yours.** The model first reads your vault's own conventions (e.g. `Agent/Vault Conventions.md`), then adds only what's worth remembering — decisions, deadlines, milestones, people, ideas — as plain bullets with `[[wikilinks]]` in that day's Daily note, and a dated line in a related existing project/person/organisation note when relevant. No page-by-page activity log and no ids or HTML comments in your notes; provenance (evidence ids, exact text, hashes) stays in xCreen's private journal. A batch with nothing worth noting writes nothing. - **Integrity switch.** One switch, controlled only by you, stops all new screenshots and OCR. It is ON at first launch and keeps your choice across restarts. - **7-day local retention, any model.** Raw evidence is deleted after seven days. You can pick any model your Hermes setup has configured. The default for the xCreen session is Claude Haiku 5.5 on your Anthropic account. ## xCreen vs alternatives Checked October 2026 against each project's own pages ([sources](#sources)). | | xCreen | Rewind | screenpipe | Retrace | Goldfish | Microsoft Recall | |---|---|---|---|---|---|---| | Platform | Capture on macOS 14+; server on macOS or Linux | macOS[^rw1] | macOS, Windows, Linux[^sp1] | macOS 13+, Apple Silicon[^rt1] | macOS, Windows[^gf1] | Windows 11 Copilot+ PCs[^ms1] | | License / source | Apache-2.0, open source | — | Source-available Screenpipe Commercial License; personal non-commercial use free, commercial use needs a license[^sp2] | MIT, open source[^rt2] | Not covered here | Windows feature | | Capture method | Focused-display screenshots + local Vision OCR | Screen and audio recording[^rw1] | Accessibility tree, OCR fallback, audio transcription[^sp1] | Screenshots every 2 s + Vision OCR, SQLite FTS5[^rt1] | Foreground-window text via Accessibility, no screenshots[^gf2] | Periodic snapshots[^ms1] | | Where AI runs | Whichever provider your Hermes route uses (OCR is local, inference usually isn't) | — | Local models (e.g. Ollama) or cloud AI, as you configure[^sp1] | No model inference listed as active[^rt1] | Cloud: Azure OpenAI via Cloudflare; memory stored locally[^gf2] | Processed locally on the PC[^ms2] | | Writes to your notes | Yes, short takeaways in Obsidian daily notes | — | — | — | Keeps its own local memory, exposed over MCP[^gf2] | — | | Status | 2.0.0 | Shut down: capture disabled Dec 19, 2025 after Meta acquired Limitless[^rw1][^rw2] | Actively developed[^sp1] | "Very early development"[^rt1] | Free beta[^gf1] | Available on supported PCs[^ms1] | "—" and "Not covered here" mean we did not check a primary source for that cell. Rewind's AI features are left out because the app has been discontinued. Also compared, with sources: [ActivityWatch](https://al-ex-w.github.io/xCreen/alternatives/#activitywatch), [Dayflow](https://al-ex-w.github.io/xCreen/alternatives/#dayflow), [OpenRecall](https://al-ex-w.github.io/xCreen/alternatives/#openrecall), [Pensieve](https://al-ex-w.github.io/xCreen/alternatives/#pensieve), [LUCI](https://al-ex-w.github.io/xCreen/alternatives/#luci) and [Limitless](https://al-ex-w.github.io/xCreen/alternatives/#limitless) on the [alternatives page](https://al-ex-w.github.io/xCreen/alternatives/). ## Requirements and who it's for For Mac users who run Hermes Agent (on the Mac or on a server) and keep notes in Obsidian. - **A working [Hermes Agent](https://github.com/NousResearch/hermes-agent) install is required.** xCreen does not include a model or keep API keys. It uses your Hermes profile read-only. - **Local OCR does not mean local inference.** Batches and questions go to the provider behind your chosen route, and that provider's retention rules apply. For on-device inference, configure a local model in Hermes. - The Mac app needs macOS 14 or later; building it needs Xcode/Swift. The server needs Hermes's own Python (3.10+) on macOS or Linux; it compresses digested screenshots with mozjpeg, Pillow or Debian's `netpbm` + `libjpeg-turbo-progs`, whichever is installed. The Spotlight action needs macOS 26 or later and full Xcode (its App Intents metadata tool); launch xCreen once after installing so Spotlight can index it, which may take a minute. ## Quick start Hermes on the same Mac: ```sh git clone https://github.com/Al-ex-W/xCreen.git && cd xCreen bash scripts/install.sh # app + local xcreen-server, settings imported from 1.x xcreen status # Integrity should report ON (capture paused) ``` Hermes on a server (for example a Linux VM on your tailnet): ```sh # on the server, next to Hermes git clone https://github.com/Al-ex-W/xCreen.git && cd xCreen bash scripts/install-server.sh --tailscale # on the Mac bash scripts/install.sh --client --server http://SERVER-TAILSCALE-IP:8765 ssh SERVER '~/.local/bin/xcreen-server token' | xcreen server set http://SERVER-TAILSCALE-IP:8765 --token-stdin ``` Or download the app from [release 2.0.0](https://github.com/Al-ex-W/xCreen/releases/tag/v2.0.0). Turn Integrity OFF from the tray to start capture. See [INSTALL.md](INSTALL.md) for vault setup, moving an existing install to a server, verification and uninstalling. ## Privacy and safety - **What's captured** (only while Integrity is OFF and the Mac is unlocked and awake): screenshots and OCR text of the display holding the focused window: every visible window on it, except excluded apps, the menu bar and the Dock. Apps that block screen capture (some password managers, DRM video, and some apps such as Claude) appear blank. - **Where it's stored:** on the machine that runs `xcreen-server`, in private files outside your vault and outside this repository (`~/Library/Application Support/xCreen/Evidence` on a Mac, `~/.local/share/xcreen/evidence` on Linux). The Mac keeps captures in a private outbox only until the server has them. This storage is not encrypted, so use FileVault or disk encryption on the server. Only short distilled bullets go into your vault; their evidence links live in the private receipt journal under `~/.hermes/xcreen-receipts`, not in notes. - **Between Mac and server:** a bearer token (Keychain on the Mac, `0600` file on the server) authenticates every request. Plain HTTP is accepted only on loopback, private networks and Tailscale; anything else needs HTTPS. - **Retention:** raw evidence expires after 7 days. Screenshots are recompressed to JPEG once their batch is digested, so later questions see a lossy copy; the digest itself always uses the lossless capture. Anything already sent to your model provider or saved in Hermes history follows their retention rules. Deletion does not guarantee forensic erasure. - **Excluded:** known password managers (1Password, Bitwarden, LastPass, Dashlane, KeePass, Apple Passwords, Keychain), System Settings, lock and login screens, and xCreen itself. Their windows are removed from every capture, and capture pauses entirely while one of them is in front. - **NOT protected:** browser password fields, password-manager browser extensions and popovers, incognito/private windows, notifications, and anything else visible on that display are **not detected or redacted**, even in a background window. Turn Integrity ON before sensitive browsing. - **Vault writes are confined:** Markdown only, inside existing vault folders; never `Agent/`, `Archive/`, templates or hidden folders (`.obsidian`), never outside the vault, bounded size, and xCreen never deletes or rewrites your text (it only adds lines or revises lines it wrote itself). - **Integrity is user-only:** only your tray or CLI action changes it. The Mac reports it to the server, which sends no automatic batches while it is ON. The model and screen content cannot turn capture on. Screen text is treated as untrusted evidence, never as instructions. Full rules and limits: [SECURITY.md](SECURITY.md) · [How it works](docs/how-it-works.md). ## CLI ```sh xcreen status xcreen ask "What was the error I saw in the build log this morning?" xcreen integrity on xcreen models list xcreen batches xcreen server # which server, reachable?, upload queue ``` Full command list and semantics: [docs/cli.md](docs/cli.md). Local CLI (JSON) today; MCP server planned. See the [CLI page](https://al-ex-w.github.io/xCreen/cli/) and the [roadmap](docs/roadmap.md). ## Documentation - [Install](INSTALL.md) · [CLI reference](docs/cli.md) · [How it works](docs/how-it-works.md) · [Roadmap](docs/roadmap.md) - [Client and server](docs/client-server.md) · [Protocol v1](docs/protocol.md) - [Architecture](docs/architecture.md) · [CLI/tray parity](docs/cli-parity.md) · [Native durability](docs/durable-native-processing.md) - [Implementation progress and limits](docs/implementation-progress.md) · [Working specification](docs/working-spec.md) · [Toolkit contract](docs/toolkit-contract.md) - [Platform research](docs/platform-research.md) · [macOS session research](docs/macos-session-research.md) · [License research](docs/licensing-research.md) ## Contributing Issues and pull requests are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md) and the [Code of Conduct](CODE_OF_CONDUCT.md). Don't put screenshots, OCR text or vault contents in issues. Report vulnerabilities privately as described in [SECURITY.md](SECURITY.md). ## License [Apache-2.0](LICENSE) with [NOTICE](NOTICE), © Alexander Wahlström. Free for personal and commercial use. Redistributed forks must keep the Apache notices, but no advertising credit is required. Goldfish and Retrace were used as research references only. They are not dependencies, and no code was copied from them. ## Sources [^rw1]: 9to5Mac, "Rewind Mac app shutting down following Meta acquisition", 2025-12-05 — https://9to5mac.com/2025/12/05/rewind-limitless-meta-acquisition/ [^rw2]: "What happened to Rewind" (the rewind.ai domain now belongs to an unaffiliated site) — https://rewind.ai/what-happened-to-rewind/ [^sp1]: screenpipe README — https://github.com/screenpipe/screenpipe [^sp2]: screenpipe LICENSE.md — https://github.com/screenpipe/screenpipe/blob/main/LICENSE.md [^rt1]: Retrace README — https://github.com/haseab/retrace [^rt2]: Retrace LICENSE — https://github.com/haseab/retrace/blob/main/LICENSE [^gf1]: Goldfish website — https://goldfish.sh [^gf2]: Goldfish privacy documentation — https://docs.goldfish.sh/privacy.md [^ms1]: Microsoft Support, "Retrace your steps with Recall" — https://support.microsoft.com/en-us/windows/retrace-your-steps-with-recall-aa03f8a0-a78b-4b3e-b0a1-2eb8ac48701c [^ms2]: Microsoft Support, "Privacy and control over your Recall experience" — https://support.microsoft.com/en-us/windows/privacy-and-control-over-your-recall-experience-d404f672-7647-41e5-886c-a3c59680af15 --- # Installing xCreen xCreen 2.0 is two programs: the **Mac app** (capture, OCR, tray, CLI) and **`xcreen-server`** (evidence, batching, the Hermes session, notes), which runs next to your [Hermes Agent](https://github.com/NousResearch/hermes-agent). Pick a layout: | Layout | Hermes runs on | Install | |---|---|---| | Complete | the same Mac | `bash scripts/install.sh` | | Split | another machine (Linux or macOS), reached over Tailscale or a private network | `scripts/install-server.sh` on the server, `scripts/install.sh --client` on the Mac | Both run the same code; see [client and server](docs/client-server.md). Requirements: - **Mac app:** macOS 14+, Xcode/Swift to build. - **Server:** an installed Hermes Agent (check with `hermes --print-runtime-command`); the server runs on Hermes's own Python, 3.10 or newer. To recompress digested screenshots it uses mozjpeg (Homebrew `mozjpeg`), Pillow, or on Debian/Ubuntu `sudo apt install netpbm libjpeg-turbo-progs`. Without any of them screenshots simply stay PNG. xCreen uses your Hermes profile read-only and sends inference to whichever provider the xCreen session's route uses; local OCR does not make inference local. If you're an agent installing this: do not edit Hermes auth/config, grant screen permissions, turn Integrity OFF, inspect vault contents or run inference to verify the installation. ## Complete install (Hermes on this Mac) ```sh git clone https://github.com/Al-ex-W/xCreen.git cd xCreen bash scripts/install.sh --no-launch ``` This installs `xcreen-server` (code in `~/.local/share/xcreen/app`, command in `~/.local/bin/xcreen-server`) as the LaunchAgent `dev.xcreen.server` on `127.0.0.1:8765`, finds Hermes and your Obsidian vault (`--vault "/absolute/path"` overrides), builds the app into `~/Applications` and copies the `xcreen` CLI to `~/.local/bin`. Add that directory to PATH. Upgrading from 1.x keeps everything: the server opens the existing evidence store and imports the Hermes paths, vault, session, visibility and model default from the 1.x app's preferences. Omit `--no-launch` and the installer also starts the app and stores the server token in your Keychain. Otherwise do that once the app runs: ```sh xcreen-server token | xcreen server set http://127.0.0.1:8765 --token-stdin ``` ## Split install (Hermes on a server) On the server, as the user that runs Hermes: ```sh git clone https://github.com/Al-ex-W/xCreen.git cd xCreen bash scripts/install-server.sh --tailscale --vault "/absolute/path/to/vault/on/the/server" ``` - `--tailscale` binds the server to the machine's Tailscale IPv4 address, so only devices on your tailnet can reach it and WireGuard encrypts the traffic. `--bind ADDR` picks another address; the server refuses `0.0.0.0`. - On Linux it runs as the systemd user service `xcreen-server` (`systemctl --user status xcreen-server`). For it to start at boot without a login session: `sudo loginctl enable-linger $USER`. On macOS it's the LaunchAgent `dev.xcreen.server`. - The server owns the vault: notes are written to the vault folder on the server. Keeping that folder in sync with the Obsidian vault on your other devices (Obsidian Sync, Syncthing, …) is up to you. - The script ends with `xcreen-server doctor`, which checks config, token, Hermes, runtime, vault and the compression encoder. On the Mac: ```sh git clone https://github.com/Al-ex-W/xCreen.git cd xCreen bash scripts/install.sh --client --server http://SERVER-TAILSCALE-IP:8765 ssh SERVER '~/.local/bin/xcreen-server token' | xcreen server set http://SERVER-TAILSCALE-IP:8765 --token-stdin xcreen server ``` `xcreen server` should report the server as reachable. The MagicDNS name (`http://hermes.your-tailnet.ts.net:8765`) works as well. Plain HTTP is accepted only for loopback, private networks, Tailscale and `*.ts.net`/`*.local` names; use HTTPS (for example `tailscale serve`) for anything else. If the server is unreachable, the app keeps capturing into its local outbox (private, seven-day retention) and uploads it once the server is back. `xcreen flush` uploads immediately. ## Moving an existing install to a server Your 1.x Mac or a complete install already has an evidence store, a receipts journal and a Hermes session. To carry them over: 1. Stop capture and the old server: `xcreen quit` (and on a complete install `launchctl bootout gui/$(id -u)/dev.xcreen.server`). 2. Install the server (above) with `--no-start`, then copy the evidence store and the receipts journal: ```sh rsync -a --exclude capture-checkpoint.json "$HOME/Library/Application Support/xCreen/Evidence/" SERVER:.local/share/xcreen/evidence/ rsync -a ~/.hermes/xcreen-receipts/ SERVER:.hermes/xcreen-receipts/ ``` 3. On the Mac, print the xCreen session id and the vault path the 1.x app used: ```sh python3 -c 'import json,plistlib,subprocess; p=plistlib.loads(subprocess.run(["defaults","export","dev.xcreen.app","-"],capture_output=True).stdout); print(json.loads(p["xcreen.hermes.session.record"])["storedSessionID"]); print(p.get("xcreen.vault.path",""))' ``` On the server, resume that Hermes session and carry the receipts journal over to the server's vault path (the journal is keyed by the vault's path, which differs between machines): ```sh xcreen-server init --session-id SESSION_ID xcreen-server migrate-journal --from-vault "MAC_VAULT_PATH" systemctl --user start xcreen-server ``` Hermes resumes the session only if the server's Hermes has it (for example because you migrated `~/.hermes` too); otherwise skip `--session-id` and the server starts a new xCreen session. 4. Install the Mac client and give it the token (above). On connect the server verifies every batch receipt: batches whose notes were written stay completed, nothing is resent. The store can be copied as is: image paths are re-anchored by file name, so a store written on the Mac opens on Linux. ## Install from the release Download `xCreen-2.0.0-macos.zip` from [release 2.0.0](https://github.com/Al-ex-W/xCreen/releases/tag/v2.0.0), unzip it and move `xCreen.app` to `~/Applications`. The app isn't notarized, so on first open go to System Settings → Privacy & Security and click Open Anyway. The server installs from a checkout (`scripts/install-server.sh`). ## Verify without capture or inference ```sh xcreen status xcreen server xcreen integrity get xcreen session visibility get xcreen settings show xcreen models list xcreen logs --no-follow ``` Status comes from the running app and the server, not a stale file. It must report Integrity true and capture paused. Connecting and listing models resume only the dedicated xCreen session and run no model. If the default model isn't in Hermes's inventory, status says so and automatic batches wait; nothing falls back to another model. Avoid publishing settings or log output: it can contain personal paths or identifiers. On the server: `xcreen-server doctor`, and logs with `journalctl --user -u xcreen-server` (Linux) or `xcreen logs --server` (a server on the same Mac). ## Settings ```sh xcreen settings set python /absolute/python3 # paths on the server xcreen settings set root /absolute/hermes-agent xcreen settings set vault "/absolute/vault" xcreen settings set vault "" # disables note writing xcreen settings set timezone Europe/Stockholm # capture-date Daily notes use this zone xcreen settings autodetect # finds Hermes and the vault on the server xcreen connection reconnect xcreen model default # show the xCreen session default xcreen model select PROVIDER EXACT_MODEL_ID # also saves it as the xCreen default ``` Settings are stored by the server, which reconnects Hermes after a change; the session identity is kept. The xCreen session default is Claude Haiku 5.5 on your Anthropic account (`anthropic` / `claude-haiku-5-5`) until you pick another configured route in the tray or with `xcreen model default PROVIDER MODEL`. It applies only to the xCreen session, never Hermes's global default. An unavailable model is reported rather than replaced, and automatic batches wait until it's available; the server re-checks every five minutes. Bind address, port, data directory and token are changed on the server only: `xcreen-server config KEY=VALUE`, `xcreen-server token --rotate` (then `xcreen server set … --token-stdin` again on the Mac). ## Updating ```sh git pull && bash scripts/install-server.sh --tailscale # on the server: copies the new code and restarts it git pull && bash scripts/install.sh --client --server URL # on the Mac ``` Client and server check each other's protocol version and refuse to talk across incompatible versions. ## User-only deliberate actions The **Show session in Hermes** tray toggle defaults OFF (hidden). `xcreen session visibility on|off` changes the same persisted preference on the server. `xcreen --json status` separates the desired `sessionVisible`, the last Hermes-confirmed `actualSessionVisible` and `sessionVisibilityPending`. - Integrity OFF in the tray or `xcreen integrity off` explicitly consents to capture. The same capture service runs the permission, lock-state and exclusion gates for both. Permission denial leaves your desired switch unchanged and reports capture blocked; an explicit OFF action may show macOS's permission UI. No development test should run this against a real capture service. - `xcreen ask "QUESTION"` explicitly sends that question to the xCreen session. Captured evidence can reach a model provider, and Hermes/provider history may outlive the seven-day retention. - Configuring a vault enables the scoped note writer; don't configure it without understanding that boundary. - On macOS 26+, Spotlight offers "Ask xCreen" (fills the question in; you submit) and "Open xCreen". Spotlight picks them up after the installed app has launched once. ## Uninstall Mac app: ```sh xcreen stop rm -rf ~/Applications/xCreen.app ~/.local/bin/xcreen defaults delete dev.xcreen.app ``` Server on macOS: `launchctl bootout gui/$(id -u)/dev.xcreen.server && rm ~/Library/LaunchAgents/dev.xcreen.server.plist`. Server on Linux: `systemctl --user disable --now xcreen-server && rm ~/.config/systemd/user/xcreen-server.service`. Then remove `~/.local/bin/xcreen-server` and `~/.local/share/xcreen/app`. Optionally remove the data after stopping: `~/Library/Application Support/xCreen` (evidence and outbox), `~/.local/share/xcreen/evidence` (Linux server), `~/.config/xcreen` (server config and token), `~/Library/Logs/xCreen` and `~/.xcreen-control`. This does not delete Hermes history, vault notes, backups or provider retention. See the [CLI reference](docs/cli.md), [protocol](docs/protocol.md) and [implementation limits](docs/implementation-progress.md). --- # How xCreen works This page holds the pipeline and boundary details. For the design, see [client and server](client-server.md) and [architecture](architecture.md); for the commands, see the [CLI reference](cli.md). ## Capture pipeline When Integrity is explicitly turned OFF and every safety gate permits it: 1. The display holding the focused window is captured at most once per eligible second: every window on it, without the menu bar and the Dock, scaled to at most 2560 px wide. Excluded apps (and xCreen) are removed from the frame; if one of them is in front, nothing is captured. Local Apple Vision OCR reads the frame. 2. OCR that is ≥90% similar to the last saved snapshot is discarded. 3. Independent screenshots are saved every ten active seconds. 4. Each OCR snapshot and screenshot goes into the Mac's private outbox and is uploaded to `xcreen-server` in capture order (OCR ahead of the screenshot that follows it). It leaves the outbox once the server acknowledges it; while the server is unreachable the outbox keeps it, retrying with backoff, for at most seven days. 5. On the server, every 30 screenshots (five active minutes) and the OCR captured up to the last of them form a durable batch, sent with timestamp/ID binding to the same dedicated xCreen Hermes session, but only while Integrity is OFF and the xCreen default model is applied. 6. Evidence stays outside the vault (on the server: `~/Library/Application Support/xCreen/Evidence` on a Mac, `~/.local/share/xcreen/evidence` on Linux) and expires after seven days. Screenshots are recompressed to JPEG once their batch has a verified completed digest. No forensic-erasure or database-encryption claim is made; use FileVault or disk encryption. Integrity defaults ON and the user's explicitly chosen value is preserved across restart. Only explicit tray/CLI actions change it. Lock, sleep, exclusions, missing permissions and errors suspend capture without rewriting that choice. ## Hermes runtime and tools `xcreen-server` starts the Hermes runtime shipped with it (`runtime/xcreen_gateway.py`, on Hermes's own Python), which registers only the scoped xCreen tools: - latest/range OCR listing and timestamped coverage status - OCR search and nearby image lookup - native image loading - read-only vault access (`xcreen_vault_read`, `xcreen_vault_list`) so the model can follow the vault's own conventions note and link existing notes - a note writer (`xcreen_note_write`) when a vault is configured The model writes like the user: short plain bullets with `[[wikilinks]]`, only for valuable items (decisions, commitments, milestones, things learned, people, ideas), never a log of apps or pages. A batch with nothing worth noting writes nothing and is recorded as skipped. Besides the capture-date Daily note it may add a dated bullet under a section of an existing note (e.g. `Projects/X.md`) or, sparingly, create a note in an existing folder. Write safety: vault-relative `.md` paths only, inside existing non-hidden folders; `Agent/`, `Archive/`, `Sources/`, templates, attachments, `.obsidian` and the vault root are refused; Daily writes go only to the capture-date note; bounded size per write; no-follow directory walk, hardlink/symlink rejection, atomic replace with a concurrent-change check. xCreen never deletes or rewrites user text: it inserts lines, or replaces a line it wrote itself (`revises`). Text with HTML comments, evidence ids or long hashes is rejected. Provenance lives outside the vault in xCreen's private receipt journal (`$HERMES_HOME/xcreen-receipts/`): batch id, note path, exact inserted text, its hash, the note's pre-write hash and evidence ids. Retries check the journal and whether the exact text is already present, so they never duplicate; edited or removed bullets become `uncertain` and are never re-added. `scripts/migrate-vault-notes.py --vault … [--dry-run]` moves the markup of older xCreen versions (``) out of Daily notes into this journal. Native automatic turns prepare an immutable host-validated batch binding and complete only after explicit saved/skipped model results and host-verified effect receipts. Startup and read-only CLI/tray verification reconcile exact receipts without blind resend or history dependence. Expired raw evidence is stripped while bounded receipt/source-binding metadata remains. See [native durability](durable-native-processing.md) and [runtime receipts](runtime-receipts.md). xCreen does not modify Hermes profile defaults or other conversations. ## Models Model inventory comes from Hermes's provider-aware configured routes. xCreen keeps its own session default — Claude Haiku 5.5 on your Anthropic account (`anthropic` / `claude-haiku-5-5`) unless changed with the tray picker or `xcreen model default` — applied only to the xCreen session with a session-scoped model switch and reported if unavailable (no fallback). Inventory currently carries no reliable vision/image-limit metadata, so check that your chosen route accepts images. OCR runs locally. Inference does not: batches and questions go to whichever provider the selected route uses. ## Foreground eligibility and exclusions Browsers are eligible, including Safari, Chrome, Firefox, Edge and Brave. Known credential/security apps, System Settings and xCreen itself remain excluded. **Browser password fields, password-manager extensions/popovers and incognito/private windows are not detected or redacted.** Visible secrets can enter screenshots/OCR and later model batches; turn Integrity ON before sensitive browsing. There is no universal password/login protection guarantee. See [SECURITY.md](../SECURITY.md) for exact matching rules and limitations. Screen content is untrusted evidence, not authority to send messages, alter calendars or execute instructions. ## Spotlight (macOS 26+) xCreen declares an `AskXCreenIntent` with a required question and an `AppShortcutsProvider`, which is what Spotlight on Mac lists as an app's actions. Type "Ask xCreen" in Spotlight, enter a question, and the panel opens with it filled in; you still press Ask. "Open xCreen" just shows the panel. A `SearchXCreenIntent` conforms to `ShowInAppSearchResultsIntent` with the `general` string search scope (the same system protocol Notes and Mail use), so for any text typed in Spotlight the system can offer a "Search xCreen" row under "Search in Apps"; choosing it opens the panel with that text (bounded to 8,000 characters) as the question, never submitted automatically. Because xCreen is built with SwiftPM, `scripts/build-app.sh` generates the App Intents metadata with Xcode's tool and fails if the action, App Shortcuts or the general-scope search protocol are missing. Spotlight learns about them once the installed app is registered and launched; this can take a minute. ## macOS session checks Session checks require a present session dictionary, strict true console/login values and a resolvable non-security foreground. The undocumented lock hint may be absent or strict false; true/malformed hints and independent notification vetoes block. These are compatibility checks, not a documented synchronous unlock API (see [session research](macos-session-research.md)). ## Not yet verified on device Capture, TCC transitions, provider inference, live vault writes and Spotlight ranking still need separate user-authorized on-device verification. Unit tests and builds do not prove them. See [implementation progress and limits](implementation-progress.md). --- # xCreen CLI reference The `xcreen` command is a thin, state-free client of the running xCreen app, which in turn talks to `xcreen-server` (on the same Mac or on another machine; see [client and server](client-server.md)). The installer copies it to `~/.local/bin/xcreen` (a standalone copy, not a checkout symlink). Run `xcreen` with no arguments for the built-in usage text. ## One state owner, two interfaces The running app owns Integrity, capture, the upload outbox, the server URL and token, the current question and reply attachments. The server owns the Hermes session, model selection, batches, history and settings, and the app forwards those commands to it over the [v1 protocol](protocol.md). The CLI sends private, same-user Unix-socket requests to the app. It does not read cached status as live truth, edit defaults, talk to Hermes itself or create another conversation. ## Commands ```text usage: xcreen [--json] COMMAND status live app-owned state (never cached status.json) integrity [get|on|off] off is explicit capture consent, subject to macOS gates session visibility [get|on|off] show/hide the same Hermes session (default off) connection connect|disconnect|reconnect (also accepted as top-level commands) models [list] | model select PROVIDER MODEL (select also saves the xCreen default) model default [get] | model default PROVIDER MODEL xCreen-session default only server [show] xCreen server URL, reachability and upload queue server set URL [--token-stdin | --token-file PATH] token is stored in the Keychain flush upload everything still queued now settings [show] | settings set python|root|vault|timezone VALUE (paths on the server) settings autodetect | autodetect find Hermes and the vault on the server ask QUESTION [--wait-ms 0..30000] explicit submission to the existing xCreen session history [--after CURSOR] bounded sanitized history pages batches [--after BATCH_ID] up to 20 durable batch metadata records batches retry verify, then re-queue only receipt-proven zero-effect batches verify read-only receipt reconciliation; no inference/note writes cancel images [list|open ID] reply attachment metadata/open through the app panel [show|hide] start | stop | restart | quit logs [-n N] [--no-follow] [--gateway | --server] (server logs only for a local server) ``` Examples: ```sh xcreen status xcreen --json status xcreen integrity get xcreen integrity on xcreen session visibility get xcreen connection reconnect xcreen models list xcreen model default xcreen model select PROVIDER EXACT_MODEL_ID xcreen server xcreen server set http://100.64.0.10:8765 --token-stdin < token.txt xcreen flush xcreen settings show xcreen settings set vault "" # disables Daily-note writing xcreen settings autodetect xcreen ask "Summarize my recent context" --wait-ms 30000 xcreen history xcreen batches xcreen verify xcreen cancel xcreen images list xcreen images open IMAGE_ID xcreen panel show xcreen logs --no-follow xcreen start xcreen stop xcreen restart ``` ## Semantics **Integrity.** `xcreen integrity off` is an explicit user capture-consent action, equivalent to the tray switch. A denied safety gate leaves the requested switch OFF but capture suspended/blocked with its reason. Lock, sleep and errors never change the user's switch. Startup does not request permissions. Never run OFF as an automated installation/test step. Integrity ON does not erase history or block deliberate historical questions. **server.** `server` shows the configured URL, whether the server answered, its version, the upload queue and batch counts. `server set URL` saves the URL and, with `--token-stdin` or `--token-file PATH`, stores the token in the login Keychain; the token is never accepted as an argument and never shown. HTTP is allowed only for loopback, private networks, Tailscale and `*.ts.net`/`*.local` names. **flush.** Uploads everything still queued in the outbox now (it otherwise uploads within seconds of capture, and retries with backoff while the server is unreachable). **ask.** Submits once to the existing xCreen session. Waiting is bounded to 30 seconds; expiry does **not** cancel an admitted turn. Use `history` or `cancel`. Ask, history and model inventory may reconnect the dedicated session; connection failures are explicit. **cancel.** Targets the admitted manual question, including a question queued behind automatic work, not an unrelated automatic turn. **history.** Comes from the server, which reads the host's `xcreen.history.page` for the exact resumed runtime session, not a second transcript database. `history [--after CURSOR]` returns sanitized stable snapshot pages bounded before gateway stdout, flags oversized messages and removes image pixels. Evicted/restarted host cursors fail explicitly. **batches / verify.** `batches [--after BATCH_ID]` lists up to 20 byte-bounded processing-state and actual receipt metadata records, also visible in the tray; continue from the last ID until an empty page. `xcreen verify` and the tray's Verify receipts action reconcile exact host receipts without inference or note writes. `batches retry` verifies first and re-queues only batches whose host receipt proves zero effects; it does not send inference itself. See [native durability](durable-native-processing.md). **images.** `images list|open` covers the current answer's resolved attachment IDs, not arbitrary paths or a general filesystem browser. **model.** `models list` shows Hermes's provider-aware configured routes. `model select` and `model default PROVIDER MODEL` set the xCreen session default only (built-in default: `anthropic` / `claude-haiku-5-5`); Hermes's global default is unchanged. An unavailable model is reported; there is no silent fallback. **settings.** `python`, `root`, `vault` and `timezone` are paths and values **on the server**; the server saves them and reconnects Hermes. `settings autodetect` looks for Hermes and the Obsidian vault on the server. Bind address, port and token change only on the server (`xcreen-server config`, `xcreen-server token --rotate`). **session visibility.** The tray's **Show session in Hermes** switch and `xcreen session visibility [get|on|off]` share one server-owned persisted preference, default **OFF (hidden)**. They update the existing active session, never create another conversation or change profile defaults. Connect/resume reapplies the saved preference. Offline changes are saved and reported **pending**, separately from gateway-confirmed visibility; they do not connect automatically. `xcreen --json status` separates desired `sessionVisible`, last gateway-confirmed `actualSessionVisible` (absent when unknown), and `sessionVisibilityPending`. This switch does not affect Integrity or capture. **Argument handling.** Global `--json` goes before the command; option-shaped question/setting values stay literal. **start / stop.** Start launches the installed app without enabling capture; stop/quit request graceful app-owned teardown (the app first tries to upload what's queued). They don't stop the server. No process-name kill is used by the CLI. **logs.** `logs` tails the app log; `--gateway` and `--server` tail the Hermes gateway and server logs of a server on the same Mac. For a Linux server use `journalctl --user -u xcreen-server` there. ## Server commands `xcreen-server` runs on the server machine: ```text xcreen-server init [--bind ADDR] [--port N] [--vault PATH] [--data-dir PATH] [--timezone TZ] [--import-mac-app] [--session-id ID] [--no-detect] xcreen-server serve [-v] xcreen-server token [--rotate] xcreen-server doctor xcreen-server config [KEY=VALUE ...] xcreen-server migrate-journal (--from-vault OLD_PATH | --from-key KEY) ``` `scripts/install-server.sh` runs `init`, installs the service and finishes with `doctor`. **URL scheme and Spotlight.** `xcreen://ask?query=...`, `xcreen://open` and the macOS 26+ "Ask xCreen"/"Open xCreen" App Shortcuts only open/fill the panel, never submit automatically. They work whether xCreen is already running or is launched by the URL. Arbitrary-query Spotlight interception is not claimed. See [CLI/tray parity](cli-parity.md) for acknowledgment, lineage and security limits. --- # Security and privacy Not security-audited or notarized. Integrity defaults ON only when no explicit preference exists and preserves the user's chosen preference. Only explicit user actions change it. Permission/session/app gates can suspend capture without changing that preference. Integrity ON blocks new screenshots/OCR and automatic transmission; it does not erase retained evidence or provider history, or block deliberate historical questions. ## What a capture contains Each capture is the display holding the focused window (`DisplayCapturePlan`): every visible window on it, without the menu bar and the Dock, scaled to at most 2560 px wide. ScreenCaptureKit removes the windows of every excluded app (below) and of xCreen itself from the frame. If an excluded app is the focused app, nothing is captured. Windows whose app blocks screen capture appear blank. Everything else visible on that display, including background windows and notifications, is captured. Other displays are not. ## Foreground exclusions and their limits Browsers are eligible, including Safari, Chrome, Firefox, Edge, Brave, Arc and Orion. **Browser password fields, password-manager extensions/popovers and incognito/private windows are not detected or redacted, whether they are in the focused window or in a background window on the captured display.** There is no page/URL, Accessibility secure-field, private-mode or secret-content detector in the native capture path. Vision recognizes text; it does not sanitize secrets. Masked password dots are not a protection supplied by xCreen. Visible credentials, recovery codes, autofill menus and login pages can enter screenshots/OCR and later automatic model batches. Turn Integrity ON before sensitive activity. There is no universal password/login protection guarantee. `ForegroundCapturePolicy` compares lowercase bundle IDs: - Exact exclusions: `dev.xcreen.app`, `com.apple.passwords`, `com.apple.systemsettings`, `com.apple.systempreferences`, `com.agilebits.onepassword7`. - Conservative substring exclusions: `1password`, `bitwarden`, `lastpass`, `dashlane`, `keepass`, `keychain`, `loginwindow`, `screenlock`, `securityagent`, `screensaver`, `lockscreen`. These cover variants but can also block unrelated apps whose IDs contain these strings. Exact exclusions do not extend to arbitrary IDs that merely contain the full exact ID. - Missing/empty foreground identity or invalid PID prevents capture. This is an identifier policy, not signature verification or exhaustive knowledge of all credential apps. Embedded extensions/overlays are not independently classified; an excluded app must be the observed foreground app for this gate to apply. Excluded foreground observations produce transition-only activity-log metadata: the bundle ID, ASCII-sanitized and limited to 256 scalars. No title, URL, OCR, pixels or field values are included. Consecutive observations of the same excluded app are suppressed; observing an eligible/unknown foreground resets suppression. Lifecycle/permission vetoes may stop evaluation before this diagnostic is reached. ## Session and stale-work defenses The session gate requires a present session dictionary with strict Boolean true console/login-complete values and a resolvable non-security foreground. The undocumented lock hint may be absent or strict false; true/malformed values block. Independent lock, screensaver, inactive-session and sleep notifications veto capture; restore clears only its own veto and requires fresh evaluation. These are practical compatibility checks, not universal synchronous unlock proof. See [session research](docs/macos-session-research.md). Foreground bundle/PID, permission, session and capture-generation checks remain before screenshot acquisition, after awaited acquisition/OCR, and before ingestion. Pauses revoke persistence epochs so late work is rejected. Foreground checks cannot prove that every displayed overlay or password/login surface is safe, nor remove all timing races in OS observations. ## Client and server Since 2.0 the Mac app uploads captures to `xcreen-server`, which may run on another machine ([design](docs/client-server.md), [protocol](docs/protocol.md)). - **Authentication.** Every request except `GET /v1/health` needs a bearer token: 256 random bits, created by `xcreen-server init`, stored `0600` on the server and in the macOS login Keychain on the client (accessible after first unlock, this device only), compared in constant time. The CLI accepts it only on stdin or from a file, never as an argument. Rotate with `xcreen-server token --rotate`. - **Transport.** The server refuses to bind `0.0.0.0`/`::`; the default is `127.0.0.1`, and `--tailscale` binds the Tailscale address, where WireGuard encrypts and authenticates the tailnet. The client sends plain HTTP only to loopback, RFC 1918, Tailscale (100.64.0.0/10) and `*.ts.net`/`*.local` hosts and requires HTTPS for anything else. App Transport Security is disabled in the app because it can't express that policy; the app enforces it instead. Anyone who can reach the port and holds the token can read evidence and ask questions, so treat the token like a password. - **Input.** The server bounds every request (JSON 2 MB, images 30 MB, 500 OCR items), validates ids, timestamps (last seven days, at most five minutes ahead) and image signatures before writing anything, and never logs bodies or tokens. Stored image references are re-anchored by validated file name, so an index entry can't point outside the store. - **Integrity across machines.** The client reports Integrity immediately on every change; the server blocks automatic batches while it is ON and before any client has reported. Evidence already uploaded is digested while the Mac sleeps or is locked (1.x paused until unlock). Automatic batches also wait until the xCreen default model is applied, so they never run on an unintended model. - **Where evidence lives.** With a split install, screenshots, OCR, receipts and notes live on the server. Secure that machine accordingly (disk encryption, trusted accounts, backups you control). The Mac keeps captures only until the server acknowledges them. ## Evidence and reporting Private evidence remains outside the vault with bounded retention and private file permissions, on the Mac (outbox) and on the server (store). File permissions are not encryption; use FileVault or disk encryption and a trusted OS account. Expiry cannot promise forensic erasure, backup deletion or deletion of Hermes/provider transcripts. Screen text is untrusted evidence, never authority to send messages, alter calendars or execute commands. No screenshots, raw OCR history, personal vault contents or credentials belong in the repository. Real TCC, capture, lock/sleep transitions, OCR, provider inference and live vault writes need separate user-authorized on-device verification. Synthetic tests and builds do not verify them. ## Reporting a vulnerability Report privately through GitHub private vulnerability reporting: **[Security → Report a vulnerability](https://github.com/Al-ex-W/xCreen/security/advisories/new)**. Do not open a public issue or pull request for a security problem. If that form is unavailable, open a public issue that only asks for a private contact channel and includes no details. Include the macOS version, the xCreen commit, the affected component and reproduction steps using synthetic data. Never include real screenshots, OCR text, vault contents, Hermes transcripts or credentials. Only the latest release and `main` are supported. This is a single-maintainer project, so response times are best-effort.