diff --git a/concepts/categories.mdx b/concepts/categories.mdx index 9a17145..a3ca5dd 100644 --- a/concepts/categories.mdx +++ b/concepts/categories.mdx @@ -86,7 +86,7 @@ You can filter sessions by confidence score when querying `meridian.db` directly ## Categories in the dashboard -The dashboard at **http://localhost:3000** uses categories in three places: +The dashboard at **http://localhost:3939** uses categories in three places: - **Day timeline** — each session segment on the timeline bar is colored by its category, giving you an instant visual breakdown of how your day was split across activity types. - **Session badges** — every session card shows a color-coded pill badge with the category label and emoji, plus the confidence score when it's below 0.85. diff --git a/concepts/how-it-works.mdx b/concepts/how-it-works.mdx index 92d919e..4d8bcc1 100644 --- a/concepts/how-it-works.mdx +++ b/concepts/how-it-works.mdx @@ -73,7 +73,7 @@ The MCP server provides tools for querying sessions, timelines, stats, active ta ## The local dashboard -The dashboard at **http://localhost:3000** gives you a visual view of everything Meridian has recorded: a color-coded day timeline, per-category breakdowns, session cards with window titles and OCR excerpts, and an always-visible active session indicator. It runs as a local Next.js process managed by launchd — no cloud, no login. +The dashboard at **http://localhost:3939** gives you a visual view of everything Meridian has recorded: a color-coded day timeline, per-category breakdowns, session cards with window titles and OCR excerpts, and an always-visible active session indicator. It runs as a local Next.js process managed by launchd — no cloud, no login. diff --git a/concepts/sessions.mdx b/concepts/sessions.mdx index e44dfdd..2dd9d37 100644 --- a/concepts/sessions.mdx +++ b/concepts/sessions.mdx @@ -75,5 +75,5 @@ sqlite3 ~/.meridian/meridian.db \ ``` - The Meridian dashboard at **http://localhost:3000** and the MCP server both read from this same database. Any SQL query you run against `~/.meridian/meridian.db` reflects exactly what the dashboard shows. + The Meridian dashboard at **http://localhost:3939** and the MCP server both read from this same database. Any SQL query you run against `~/.meridian/meridian.db` reflects exactly what the dashboard shows. diff --git a/configuration.mdx b/configuration.mdx index 9a81ab1..50d8234 100644 --- a/configuration.mdx +++ b/configuration.mdx @@ -50,6 +50,7 @@ These variables control how the Rust daemon reads screenpipe data and classifies | `POLL_INTERVAL_SECS` | `60` | How often (in seconds) the daemon checks screenpipe for new frames. | | `CLASSIFICATION_ENABLED` | `true` | Set to `false` to run activity tracking and categorisation only, with no MLX server needed. | | `MLX_SERVER_PORT` | `7823` | The port the persistent MLX inference server listens on. | +| `MERIDIAN_UI_PORT` | `3939` | The port the local dashboard listens on. Change this if 3939 conflicts with another local service, then run `meridian restart` (or re-run `meridian setup`) to apply the new value to the UI launchd agent. | | `CLASSIFICATION_TIMEOUT_S` | `120` | Per-session inference timeout in seconds. Increase this if you see timeout errors on long sessions. | | `CLASSIFIER_BACKEND` | `mlx` | Classification backend. Set to `mlx` when using the MLX inference server (recommended for Apple Silicon). | diff --git a/guides/dashboard.mdx b/guides/dashboard.mdx index 67630c8..4b401f4 100644 --- a/guides/dashboard.mdx +++ b/guides/dashboard.mdx @@ -8,14 +8,18 @@ Meridian includes a Next.js dashboard that gives you a live, browser-based view ## Opening the dashboard -The dashboard starts automatically when you run `meridian start` and listens on port 3000. To open it, navigate to: +The dashboard starts automatically when you run `meridian start` and listens on port 3939 by default. To open it, navigate to: ``` -http://localhost:3000 +http://localhost:3939 ``` Any browser works. You can keep it open as a background tab while you work. + + To run the dashboard on a different port — for example, if 3939 conflicts with another process — set `MERIDIAN_UI_PORT` in `~/.meridian/.env` and run `meridian restart`. The installer bakes the value into the UI launchd agent on the next setup. See the [Configuration](/configuration#core-daemon-settings) reference for details. + + ## Dashboard views The dashboard has three main views accessible from the navigation bar. @@ -91,7 +95,7 @@ meridian restart ## Troubleshooting - + Check that the UI service is running: ```bash diff --git a/index.mdx b/index.mdx index 556dd85..a3f5a7c 100644 --- a/index.mdx +++ b/index.mdx @@ -57,7 +57,7 @@ Meridian is a local-first ambient automation daemon that reads your screen activ ```bash meridian start - # Dashboard → http://localhost:3000 + # Dashboard → http://localhost:3939 ``` diff --git a/introduction.mdx b/introduction.mdx index d8e6be9..1fab13e 100644 --- a/introduction.mdx +++ b/introduction.mdx @@ -12,7 +12,7 @@ Every minute you spend on PM overhead is a minute not spent building. The mismat ## How Meridian works -Meridian runs as a lightweight background daemon alongside [screenpipe](https://screenpi.pe), which continuously records your screen activity as raw frames — OCR text, accessibility tree events, audio transcriptions — stored locally in a SQLite database. Every 60 seconds (configurable), Meridian reads those frames, detects app-switch boundaries, and closes each completed work block as a structured **app session** in its own database. +Meridian runs as a lightweight background daemon alongside [screenpipe](https://screenpi.pe), which continuously records your screen activity as raw frames — OCR text and accessibility tree events — stored locally in a SQLite database. Audio capture is disabled by default, so screenpipe does not record or transcribe audio. Every 60 seconds (configurable), Meridian reads those frames, detects app-switch boundaries, and closes each completed work block as a structured **app session** in its own database. Each session captures the app you were using, how long you used it, the window titles and OCR text it observed, and the clipboard and app-switch signals it detected. From that structured data, Meridian's classification layer links the session to the specific Jira, GitHub, or Linear ticket you were working on, then automatically updates that ticket. @@ -26,7 +26,7 @@ Each session captures the app you were using, how long you used it, the window t **MCP server** — Meridian ships a TypeScript MCP server that exposes your structured session data to any MCP-compatible AI tool, including Claude Code, Claude Desktop, and Cursor. Query your activity history in plain language, ask for summaries, or feed live context into your AI assistant. -**Local dashboard** — A Next.js UI at `http://localhost:3000` gives you a real-time timeline of your sessions, daily category breakdowns, and session detail views. It reads directly from the local database and requires no account or login. +**Local dashboard** — A Next.js UI at `http://localhost:3939` (override via `MERIDIAN_UI_PORT`) gives you a real-time timeline of your sessions, daily category breakdowns, and session detail views. It reads directly from the local database and requires no account or login. ## System requirements diff --git a/quickstart.mdx b/quickstart.mdx index 01272c7..21a9631 100644 --- a/quickstart.mdx +++ b/quickstart.mdx @@ -33,20 +33,23 @@ This guide walks you through getting Meridian running on your machine for the fi - screenpipe needs three macOS privacy permissions to record your screen activity. The installer walks you through each one interactively. If you skipped that step or need to re-grant permissions later, run: + screenpipe needs two macOS privacy permissions to record your screen activity. The installer walks you through each one interactively. If you skipped that step or need to re-grant permissions later, run: ```bash meridian permissions ``` - The three permissions screenpipe requires are: + The two permissions screenpipe requires are: - **Screen Recording** — to capture frames and OCR text - **Accessibility** — to read window titles and accessibility tree events - - **Microphone** — to transcribe audio (optional but recommended for meeting context) - For Screen Recording and Accessibility, click the **+** button in the System Settings pane, navigate to the screenpipe binary, and toggle it on. The Microphone pane works differently — screenpipe will appear there automatically after it first requests mic access. If it isn't listed yet, grant Screen Recording first, then check back. + For each pane, click the **+** button in System Settings, navigate to the screenpipe binary, and toggle it on. Audio capture is disabled by default (screenpipe runs with `--disable-audio`), so no Microphone permission is required. + + + + **Add `meridian-a11y-helper` to Accessibility too.** Meridian installs a small helper agent (`com.meridiona.a11y-helper`) that needs its own Accessibility grant so Chromium- and Electron-based apps (Slack, Claude Desktop, VS Code, Cursor, Codex, …) become visible to screenpipe. The installer opens the Accessibility pane a second time for this binary — add it the same way you added screenpipe. Without it, those apps' activity is silently misattributed to whichever native app was focused beforehand. @@ -80,7 +83,7 @@ This guide walks you through getting Meridian running on your machine for the fi meridian status ``` - You should see all services — `com.meridiona.screenpipe`, `com.meridiona.daemon`, `com.meridiona.jira-updater`, `com.meridiona.ui`, `com.meridiona.mlx-server`, and `com.meridiona.coding-agent-indexer` — reported as running with their process IDs. + You should see all services — `com.meridiona.screenpipe`, `com.meridiona.daemon`, `com.meridiona.jira-updater`, `com.meridiona.ui`, `com.meridiona.mlx-server`, `com.meridiona.a11y-helper`, and `com.meridiona.coding-agent-indexer` — reported as running with their process IDs. **MLX inference server for task classification.** If you installed with `--mlx`, Meridian uses a persistent MLX inference server (Qwen3.5-9B, running on-device via Metal) for session-to-ticket classification. On first start, the model downloads to your local cache (~6.6 GB) — this can take a few minutes depending on your connection speed. Subsequent starts load from cache in around 5 seconds. Watch the server come up with `meridian logs mlx-server`. If you haven't set up the MLX server, set `CLASSIFICATION_ENABLED=false` in `~/.meridian/.env` to run in activity-tracking mode without ticket classification. @@ -90,10 +93,14 @@ This guide walks you through getting Meridian running on your machine for the fi Once the daemons are running, open your browser to: ``` - http://localhost:3000 + http://localhost:3939 ``` The dashboard shows a real-time timeline of your app sessions, coloured by activity category, with a daily breakdown chart and session detail views. New sessions appear every 60 seconds as the daemon processes the latest screenpipe frames. + + + Port 3939 is the default. To run the dashboard on a different port, set `MERIDIAN_UI_PORT` in `~/.meridian/.env` and run `meridian restart`. See [Configuration](/configuration) for details. + @@ -136,7 +143,7 @@ meridian restart Run `meridian doctor` to identify the specific failure. Common causes are a missing `~/.meridian/.env` file (run `./install.sh` to create it), or a missing screenpipe database (start screenpipe first, then run `meridian start`). - + Check the UI log: `meridian logs ui`. If the build is missing, the installer may have been run with `--no-ui`. Rebuild by running `cd ui && npm ci && npm run build`, then restart with `meridian restart`. diff --git a/reference/cli.mdx b/reference/cli.mdx index db9553e..e6a3703 100644 --- a/reference/cli.mdx +++ b/reference/cli.mdx @@ -23,8 +23,9 @@ Enables and bootstraps every Meridian LaunchAgent, then prints a live status sum | `com.meridiona.screenpipe` | screenpipe ambient recorder | | `com.meridiona.daemon` | Meridian Rust ETL daemon | | `com.meridiona.jira-updater` | Jira / GitHub / Linear sync | -| `com.meridiona.ui` | Next.js dashboard at http://localhost:3000 | +| `com.meridiona.ui` | Next.js dashboard at http://localhost:3939 (override via `MERIDIAN_UI_PORT`) | | `com.meridiona.mlx-server` | MLX inference server | +| `com.meridiona.a11y-helper` | Accessibility helper that makes Chromium/Electron apps visible to screenpipe | | `com.meridiona.coding-agent-indexer` | Coding-agent context indexer | If any `.plist` file is missing, `meridian start` prints an error for that service and exits with a non-zero code. Run `./install.sh` to reinstall missing plists. @@ -133,6 +134,8 @@ Runs a full suite of environment health checks and prints a pass/fail result for - screenpipe binary is in `$PATH` - screenpipe database exists at `~/.screenpipe/db.sqlite` - screenpipe process is running +- screenpipe capture coverage — flags apps that appear in focus events but produce no frames (the signature of an unenabled Electron app) +- `meridian-a11y-helper` is running and has been granted Accessibility (required for Chromium/Electron apps to surface their accessibility tree) - Python venv is set up and `run_agent` is importable - MCP server has been built (`packages/meridian-mcp/dist/index.js` exists) - Next.js UI has been built (`ui/.next` directory exists) @@ -173,13 +176,17 @@ EDITOR=code meridian config edit meridian permissions ``` -Walks you interactively through the three macOS privacy panes that screenpipe requires: +Walks you interactively through the macOS privacy panes Meridian requires: -1. **Screen Recording** — opens the System Settings pane; click `+`, navigate to the screenpipe binary, add it, and toggle it on. -2. **Accessibility** — same steps. -3. **Microphone** — screenpipe appears here only after it first requests mic access. Grant Screen Recording first if screenpipe is not listed yet. +1. **Screen Recording** (screenpipe) — opens the System Settings pane; click `+`, navigate to the screenpipe binary, add it, and toggle it on. +2. **Accessibility** (screenpipe) — same steps for the screenpipe binary. +3. **Accessibility** (meridian-a11y-helper) — the pane re-opens for the bundled `meridian-a11y-helper` binary. Add it the same way so Chromium/Electron apps (Slack, Claude Desktop, VS Code, Cursor, …) become visible to screenpipe. -After each step the script waits for you to press Enter. Run `meridian restart` afterwards so screenpipe picks up the newly granted permissions. +After each step the script waits for you to press Enter. Run `meridian restart` afterwards so screenpipe and the helper pick up the newly granted permissions. + + + Audio capture is disabled (screenpipe runs with `--disable-audio`), so no Microphone permission is required. + Without Screen Recording permission, screenpipe cannot capture frames and Meridian will have no data to process. diff --git a/reference/troubleshooting.mdx b/reference/troubleshooting.mdx index e7a0a64..58b5ac1 100644 --- a/reference/troubleshooting.mdx +++ b/reference/troubleshooting.mdx @@ -277,7 +277,7 @@ Run the guided permissions walkthrough: meridian permissions ``` -The command opens the Screen Recording, Accessibility, and Microphone System Settings panes in sequence and waits for you to confirm each one. After granting access, restart the stack: +The command opens the Screen Recording and Accessibility System Settings panes in sequence (Accessibility runs twice — once for the screenpipe binary, once for `meridian-a11y-helper`) and waits for you to confirm each one. After granting access, restart the stack: ```bash meridian restart @@ -291,16 +291,36 @@ You must restart screenpipe after granting Screen Recording permission. The perm -Audio transcription requires the Microphone permission. screenpipe appears in the Microphone pane only after it has first tried to access the microphone — this happens automatically once Screen Recording is granted and screenpipe is running. +Meridian ships with audio capture disabled — screenpipe is launched with `--disable-audio`, so no Microphone permission is requested and no audio is recorded or transcribed. Existing sessions will have an empty `audio_snippets` array, which is expected. -If screenpipe is not listed in the Microphone pane yet: + + + + +Chromium- and Electron-based apps ship with their macOS accessibility tree disabled. Without the tree, screenpipe's focus tracker never sees the app and its activity gets attributed to whichever native app was focused beforehand — or silently dropped. + +Meridian fixes this with the `com.meridiona.a11y-helper` agent, which enables the accessibility tree on each Electron app as it comes into focus. If sessions for these apps are missing, the helper is most likely not running or not trusted: + +1. Confirm it's running and trusted: + + ```bash + meridian doctor # look for the a11y_helper check + meridian status # com.meridiona.a11y-helper should be listed as running + ``` + +2. If the doctor check reports the helper is not trusted, re-run the permissions walkthrough and add the `meridian-a11y-helper` binary in the Accessibility pane (it's a separate entry from screenpipe): + + ```bash + meridian permissions + ``` + +3. Restart the stack so the helper picks up the new grant and screenpipe re-attaches to the now-enabled apps: -1. Ensure Screen Recording is already granted. -2. Start screenpipe: `meridian start`. -3. Wait a few seconds, then open System Settings → Privacy & Security → Microphone. -4. Toggle screenpipe on. + ```bash + meridian restart + ``` -Alternatively, run `meridian permissions` to open all three panes in the correct order. +Newly enabled apps materialise their accessibility tree within a few seconds of first focus; frames recorded before that window may still be attributed to the previous app. @@ -308,7 +328,7 @@ Alternatively, run `meridian permissions` to open all three panes in the correct ## Dashboard - + 1. Check whether the UI service is running: