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/concepts/task-classification.mdx b/concepts/task-classification.mdx index b60c830..629cac2 100644 --- a/concepts/task-classification.mdx +++ b/concepts/task-classification.mdx @@ -83,7 +83,7 @@ Task classification runs entirely on your machine using a persistent MLX inferen If you don't need ticket linking — or if you're running on a machine without Apple Silicon — you can disable classification entirely: ```bash -# In ~/.meridian/.env +# In ~/.meridian/app/.env CLASSIFICATION_ENABLED=false ``` diff --git a/configuration.mdx b/configuration.mdx index 9a81ab1..44b1aaf 100644 --- a/configuration.mdx +++ b/configuration.mdx @@ -4,34 +4,30 @@ sidebarTitle: "Configuration" description: "Learn where Meridian's config files live, how to edit them, and what every environment variable does — from polling intervals to PM credentials." --- -Meridian is configured entirely through environment variables. There are no config files with special formats or UI settings to hunt down — every option is a key-value pair in a `.env` file. The installer creates these files and populates them during the credential walkthrough, but you can edit them at any time. +Meridian is configured entirely through environment variables. There are no config files with special formats or UI settings to hunt down — every option is a key-value pair in a single `.env` file. `meridian setup` creates the file and you can edit it at any time. ## Where configuration lives -Meridian uses two env files, one per process boundary: +The npm install lays out the runtime under `~/.meridian/`: -| File | Used by | +| Path | Purpose | |---|---| -| `~/.meridian/.env` | The Rust daemon — core settings and PM credentials | -| `services/.env` | The Python agents — LLM endpoint and Jira credentials | +| `~/.meridian/app/.env` | The one backend config — read by the daemon, classifier, and worklog stage. | +| `~/.meridian/meridian.db` | The session database. | +| `~/.meridian/logs/` | Per-service logs (daemon, MLX server, screenpipe, UI). | +| `~/Library/LaunchAgents/com.meridiona.*.plist` | The launchd agents registered by `meridian setup`. | -A third internal env file is managed automatically by the installer and holds the `OPENROUTER_API_KEY` for cloud LLM fallback. In practice you never need to touch it directly — the installer keeps it in sync with the values you provide during setup. +Contributors building from source share the same on-disk layout, except their config lives at the **repo-root `.env`** instead of `~/.meridian/app/.env` (the source checkout is what `meridian dev` runs against). ## Editing configuration -To open the daemon config in your `$EDITOR`, run: +To open the config in your `$EDITOR`, run: ```bash meridian config edit ``` -This opens `~/.meridian/.env`. To edit the Python agents config, open `services/.env` directly: - -```bash -$EDITOR services/.env -``` - -After saving, restart the relevant daemon for the change to take effect: +This opens `~/.meridian/app/.env` (or the repo-root `.env` for source builds). After saving, restart for the change to take effect: ```bash meridian restart @@ -91,7 +87,7 @@ The API key is required to enable the Linear connector. `LINEAR_TEAM_IDS` is opt The smallest configuration that enables activity tracking, session categorisation, and Jira ticket sync is: -```bash title="~/.meridian/.env" +```bash title="~/.meridian/app/.env" # Required for task classification and Jira sync JIRA_BASE_URL=https://your-org.atlassian.net JIRA_EMAIL=you@your-org.com @@ -103,24 +99,17 @@ CLASSIFICATION_ENABLED=true Everything else defaults to safe values and can be added incrementally. -## Re-running credential prompts +## Editing credentials later -The installer skips any variable that already has a value in the relevant `.env` file. To re-prompt for a specific credential, delete that line from the file and re-run the installer: +The npm install does not include an interactive credential prompt — edit the file directly: ```bash -# 1. Remove the line you want to re-set (e.g. JIRA_API_TOKEN) meridian config edit - -# 2. Re-run the installer — it will prompt only for missing values -./install.sh --skip-permissions +meridian restart ``` -If you want to bypass the credential prompts entirely and manage the files yourself, pass `--skip-env`: - -```bash -./install.sh --skip-env -``` +Contributors who built from source can re-run `./install.sh --skip-permissions` to be re-prompted for any variable that isn't already set; `./install.sh --skip-env` bypasses the prompt flow entirely. - You can also edit `~/.meridian/.env` directly with any text editor and then run `meridian restart`. The installer's prompt flow is a convenience, not a requirement. + You can edit the `.env` with any text editor and then run `meridian restart`. The daemon reads the file once at startup and does not hot-reload changes. diff --git a/guides/dashboard.mdx b/guides/dashboard.mdx index 67630c8..41a5a28 100644 --- a/guides/dashboard.mdx +++ b/guides/dashboard.mdx @@ -8,12 +8,14 @@ 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. To open it, navigate to: ``` -http://localhost:3000 +http://localhost:3939 ``` +Override the port by setting `MERIDIAN_UI_PORT` in `~/.meridian/app/.env`, then `meridian restart`. + Any browser works. You can keep it open as a background tab while you work. ## Dashboard views @@ -72,17 +74,13 @@ To tail the dashboard's log output: meridian logs ui ``` -If you've pulled an update to the repository and want to rebuild the dashboard with the latest changes: +To pull a newer release of the dashboard along with the rest of Meridian: ```bash -cd ui && npm run build +meridian update ``` -Then restart Meridian to pick up the new build: - -```bash -meridian restart -``` +`meridian update` runs `npm install -g @meridiona/meridian@latest` under the hood and re-runs `meridian setup`. Source-built contributors rebuild manually with `cd ui && npm run build && meridian restart`. The dashboard reads directly from `~/.meridian/meridian.db`. It does not make any network requests and does not send your activity data anywhere. All rendering happens locally in your browser. @@ -91,7 +89,7 @@ meridian restart ## Troubleshooting - + Check that the UI service is running: ```bash @@ -113,12 +111,14 @@ meridian restart The daemon writes new data every 60 seconds (configurable via `POLL_INTERVAL_SECS`). If the card hasn't updated in longer than a minute or two, check that the daemon is running with `meridian status` and review the daemon log with `meridian logs`. - - If you ran `./install.sh --no-ui`, the dashboard was not built. Build and register it now: + + If you built from source with `./install.sh --no-ui`, the dashboard was skipped. Build and register it now: ```bash cd ui && npm run build meridian restart ``` + + The npm distribution always includes a prebuilt dashboard, so this only applies to source-built contributors. diff --git a/guides/github-linear.mdx b/guides/github-linear.mdx index f93d1c6..1bd1ede 100644 --- a/guides/github-linear.mdx +++ b/guides/github-linear.mdx @@ -44,10 +44,10 @@ Meridian supports two additional issue trackers alongside Jira: GitHub Issues an meridian config edit ``` - Add the GitHub block to `~/.meridian/.env`: + Add the GitHub block to `~/.meridian/app/.env`: ```bash - # ~/.meridian/.env + # ~/.meridian/app/.env GITHUB_TOKEN=ghp_your_personal_access_token GITHUB_ORG=your-org-name @@ -140,10 +140,10 @@ Meridian supports two additional issue trackers alongside Jira: GitHub Issues an meridian config edit ``` - Add the Linear block to `~/.meridian/.env`: + Add the Linear block to `~/.meridian/app/.env`: ```bash - # ~/.meridian/.env + # ~/.meridian/app/.env LINEAR_API_KEY=lin_api_your_key_here diff --git a/guides/jira.mdx b/guides/jira.mdx index 8b82fb1..9fdc88e 100644 --- a/guides/jira.mdx +++ b/guides/jira.mdx @@ -37,10 +37,10 @@ Set the following environment variables. The cleanest way is to open the Meridia meridian config edit ``` -This opens `~/.meridian/.env` in your `$EDITOR`. Add or update the Jira block: +This opens `~/.meridian/app/.env` in your `$EDITOR`. Add or update the Jira block: ```bash -# ~/.meridian/.env +# ~/.meridian/app/.env JIRA_BASE_URL=https://your-org.atlassian.net JIRA_EMAIL=you@your-org.com @@ -54,12 +54,6 @@ JIRA_API_TOKEN=your-api-token-here Meridian only reads your Jira tickets for classification. It never creates, modifies, closes, or deletes tickets on your behalf. -Alternatively, re-run the installer's credential walkthrough to be prompted interactively: - -```bash -./install.sh --skip-permissions -``` - ## Apply and verify @@ -67,7 +61,7 @@ Alternatively, re-run the installer's credential walkthrough to be prompted inte ```bash meridian restart ``` - The daemon re-reads `~/.meridian/.env` on startup and refreshes the `pm_tasks` cache from Jira within the first poll cycle. + The daemon re-reads `~/.meridian/app/.env` on startup and refreshes the `pm_tasks` cache from Jira within the first poll cycle. ```bash @@ -117,7 +111,7 @@ python3 scripts/refresh_pm_tasks.py \ --db ~/.meridian/meridian.db ``` -The script reads your credentials from `~/.meridian/.env` automatically — no extra configuration needed. +The script reads your credentials from `~/.meridian/app/.env` automatically — no extra configuration needed. (The script ships in the source repo; it's a contributor utility, not part of the npm distribution.) ## Troubleshooting diff --git a/guides/mcp-setup.mdx b/guides/mcp-setup.mdx index 1dd5b13..0fc323a 100644 --- a/guides/mcp-setup.mdx +++ b/guides/mcp-setup.mdx @@ -8,15 +8,17 @@ Meridian ships a TypeScript MCP (Model Context Protocol) server that gives any c The MCP server opens `~/.meridian/meridian.db` in read-only mode on each tool call, so the AI always sees up-to-date session data without any manual syncing. -## How the MCP server is built +## Where the MCP server lives -`./install.sh` builds the MCP server automatically into `packages/meridian-mcp/dist/index.js`. If you need to rebuild it manually — for example after updating the repository — run: +The npm install (`npm install -g @meridiona/meridian` + `meridian setup`) places the prebuilt MCP server inside the app bundle at `~/.meridian/app/packages/meridian-mcp/dist/index.js` — point your MCP client at that path. + +Source-built contributors run `./install.sh`, which builds the MCP server into `packages/meridian-mcp/dist/index.js` in the checkout. To rebuild manually after editing the source: ```bash cd packages/meridian-mcp && npm run build ``` -The server uses [sql.js](https://github.com/sql-js/sql.js) (pure WebAssembly SQLite) so it works with any Node.js version without native module compilation. +The server uses [sql.js](https://github.com/sql-js/sql.js) (pure WebAssembly SQLite) so it works with any modern Node.js version without native module compilation. ## Add Meridian to your AI tool @@ -28,14 +30,14 @@ The server uses [sql.js](https://github.com/sql-js/sql.js) (pure WebAssembly SQL ~/Library/Application Support/Claude/claude_desktop_config.json ``` - Add the `meridian` entry inside `mcpServers`. Replace `/path/to/meridian` with the absolute path to your cloned repository: + Add the `meridian` entry inside `mcpServers`. If you installed via npm, point at the bundle inside `~/.meridian/app`; if you built from source, use the path to your repo checkout instead. ```json { "mcpServers": { "meridian": { "command": "node", - "args": ["/path/to/meridian/packages/meridian-mcp/dist/index.js"] + "args": ["/Users/you/.meridian/app/packages/meridian-mcp/dist/index.js"] } } } @@ -44,7 +46,7 @@ The server uses [sql.js](https://github.com/sql-js/sql.js) (pure WebAssembly SQL Save the file, then quit and relaunch Claude Desktop. The Meridian tools will appear automatically in the tool picker. - You can find your repo path by running `pwd` inside the `meridian` directory. + Use an absolute path — `~` is not expanded by all MCP hosts. Replace `/Users/you` with your real home directory (`echo $HOME`). @@ -60,7 +62,7 @@ The server uses [sql.js](https://github.com/sql-js/sql.js) (pure WebAssembly SQL "mcpServers": { "meridian": { "command": "node", - "args": ["/path/to/meridian/packages/meridian-mcp/dist/index.js"] + "args": ["/Users/you/.meridian/app/packages/meridian-mcp/dist/index.js"] } } } @@ -69,10 +71,10 @@ The server uses [sql.js](https://github.com/sql-js/sql.js) (pure WebAssembly SQL **Option B — Claude Code CLI (global):** ```bash - claude mcp add meridian node /path/to/meridian/packages/meridian-mcp/dist/index.js + claude mcp add meridian node ~/.meridian/app/packages/meridian-mcp/dist/index.js ``` - Replace `/path/to/meridian` with the absolute path to your cloned repository. Run `claude mcp list` to confirm Meridian appears in the registered servers. + Use an absolute path with your real home directory. Run `claude mcp list` to confirm Meridian appears in the registered servers. @@ -80,7 +82,7 @@ The server uses [sql.js](https://github.com/sql-js/sql.js) (pure WebAssembly SQL - **Name:** `meridian` - **Command:** `node` - - **Args:** `/path/to/meridian/packages/meridian-mcp/dist/index.js` + - **Args:** `/Users/you/.meridian/app/packages/meridian-mcp/dist/index.js` Alternatively, edit your Cursor MCP config file directly (usually `~/.cursor/mcp.json`): @@ -89,7 +91,7 @@ The server uses [sql.js](https://github.com/sql-js/sql.js) (pure WebAssembly SQL "mcpServers": { "meridian": { "command": "node", - "args": ["/path/to/meridian/packages/meridian-mcp/dist/index.js"] + "args": ["/Users/you/.meridian/app/packages/meridian-mcp/dist/index.js"] } } } @@ -108,7 +110,7 @@ By default the MCP server reads `~/.meridian/meridian.db`. To point it at a diff "mcpServers": { "meridian": { "command": "node", - "args": ["/path/to/meridian/packages/meridian-mcp/dist/index.js"], + "args": ["/Users/you/.meridian/app/packages/meridian-mcp/dist/index.js"], "env": { "MERIDIAN_DB": "/custom/path/to/meridian.db" } @@ -168,7 +170,7 @@ For the complete input schema and parameter reference for each tool, see [MCP To Check two things: - 1. **The daemon is running.** Run `meridian status` — all four services (screenpipe, daemon, jira-updater, ui) should show as running. + 1. **The daemon is running.** Run `meridian status` — all four services (screenpipe, daemon, mlx-server, ui) should show as running. 2. **The database exists.** Run `ls -lh ~/.meridian/meridian.db`. If the file is missing, the daemon hasn't written any sessions yet. Wait for the first 60-second poll cycle to complete. If the path is correct and the daemon is running, confirm the `args` path in your MCP config points to the actual `dist/index.js` file with no typos. @@ -180,6 +182,6 @@ For the complete input schema and parameter reference for each tool, see [MCP To The MCP server uses sql.js (pure WebAssembly) instead of native SQLite bindings, so it is compatible with any modern Node.js version. If you see unexpected errors, rebuild the server with `cd packages/meridian-mcp && npm run build` and ensure you're on Node 18 or later. - Tools like `get-task-sessions`, `get-task-breakdown`, and `get-active-task` require the AI classifier to have linked sessions to tickets. Confirm that `CLASSIFICATION_ENABLED=true` in `~/.meridian/.env` and that at least one Jira, GitHub, or Linear integration is configured. Check `meridian doctor` for the classifier status. + Tools like `get-task-sessions`, `get-task-breakdown`, and `get-active-task` require the AI classifier to have linked sessions to tickets. Confirm that `CLASSIFICATION_ENABLED=true` in `~/.meridian/app/.env` and that at least one Jira, GitHub, or Linear integration is configured. Check `meridian doctor` for the classifier status. diff --git a/index.mdx b/index.mdx index 556dd85..fd0cd0c 100644 --- a/index.mdx +++ b/index.mdx @@ -19,7 +19,7 @@ Meridian is a local-first ambient automation daemon that reads your screen activ icon="rocket" href="/quickstart" > - Clone, install, and have Meridian running and syncing tickets in under 15 minutes. + Install from npm and have Meridian running and drafting worklogs in under 10 minutes. - Clone the repository and run the installer. It handles every dependency — Homebrew, Rust, Node, Python, screenpipe — and registers Meridian's background daemons automatically. + Install the Meridian CLI from npm and run the one-time setup. The bundle ships a prebuilt binary — no clone, no compiler — and `meridian setup` installs any missing prerequisites (Homebrew packages, Python, screenpipe, ffmpeg) and registers the background services. ```bash - git clone https://github.com/meridiona/meridian - cd meridian - ./install.sh + npm install -g @meridiona/meridian + meridian setup ``` - The installer walks you through an interactive credential prompt. Enter your OpenRouter API key plus credentials for any PM tools you use (Jira, GitHub, Linear). Skip any service you don't need by pressing Enter. + Open the config in your `$EDITOR` and add credentials for the tracker you use (Jira, Linear, or GitHub): + + ```bash + meridian config edit + ``` - Bring all daemons up with a single command, then open the dashboard to see your first sessions appear. + The setup command registers launchd agents that start automatically. Confirm everything is up and open the dashboard: ```bash - meridian start - # Dashboard → http://localhost:3000 + meridian status + # Dashboard → http://localhost:3939 ``` diff --git a/introduction.mdx b/introduction.mdx index d8e6be9..bfcf707 100644 --- a/introduction.mdx +++ b/introduction.mdx @@ -26,21 +26,23 @@ 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` 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 -Before installing, confirm your machine meets the following requirements: +Meridian is distributed as an npm package that ships a **prebuilt binary** — there is no source checkout and no Rust or Python build step on your machine. You only need: | Requirement | Version / Notes | |---|---| -| **macOS** | 13 or later, Apple Silicon (the MLX inference server requires Metal) | -| **screenpipe** | Must be installed and running before Meridian starts | -| **Rust** | 1.93.1 — the installer picks up `rust-toolchain.toml` automatically | -| **Python** | 3.13 — install via `brew install python@3.13` or `pyenv install 3.13` | -| **Node.js** | 18 or later — required for the MCP server and dashboard | +| **macOS** | Apple Silicon (M1 or later). The on-device model requires Metal; Intel Macs are not supported. | +| **Node.js** | Any modern version — needed only for `npm install -g`. Install with `brew install node` if you don't have it. | +| **screenpipe** | Installed automatically by `meridian setup` if it's missing. | -The installer detects any missing prerequisites and offers to install them via Homebrew before proceeding. +`meridian setup` installs the remaining prerequisites (Homebrew packages, Python 3.11, ffmpeg, screenpipe) and downloads the on-device model on first run. Contributors who want to build from source need Rust 1.93.1 and Python 3.11 instead — see the [Quickstart](/quickstart#build-from-source-contributors-only). + + + **Unsigned v1 builds.** The current release ships an unsigned binary, so macOS Gatekeeper may block it on first launch. Clear the quarantine attribute with `xattr -dr com.apple.quarantine ~/.meridian/app` and run `meridian restart`. + **Local-first by design.** Meridian never sends your screen recordings, OCR text, or session data to any remote server. All inference runs on-device via the MLX server. The only outbound network calls are the ticket updates you explicitly configure — to your own Jira instance, GitHub org, or Linear workspace. @@ -54,7 +56,7 @@ The installer detects any missing prerequisites and offers to install them via H icon="rocket" href="/quickstart" > - Install Meridian, grant permissions, and see your first sessions in the dashboard. + Install Meridian from npm, grant permissions, and see your first sessions in the dashboard. - Run `./install.sh --dry-run` to preview every action the installer would take without actually executing anything. This is a good way to understand the installation before committing to it. - + + **Platform:** macOS on **Apple Silicon** (M1 or later). The on-device model requires Metal; Intel Macs are not supported. You also need Node.js (any modern version) for `npm` — `brew install node` if you don't already have it. + - - Clone Meridian and run `install.sh` from the repository root. The installer detects missing prerequisites (Homebrew, Rust, Node 18+, Python 3.13, screenpipe) and offers to install each one before proceeding. It then builds the Rust daemon, the MCP server, the Next.js dashboard, and the Python services, and registers background launchd agents for each service. + + The recommended path is the bootstrap one-liner. It handles the most common stock-macOS gotcha (a root-owned npm prefix that makes `npm install -g` fail with `EACCES`) before installing Meridian and running setup: ```bash - git clone https://github.com/meridiona/meridian - cd meridian - ./install.sh + curl -fsSL https://raw.githubusercontent.com/Meridiona/meridian/main/scripts/bootstrap.sh | bash ``` - The following flags are available if you want to customise the installation: + The script verifies you're on Apple Silicon, confirms Homebrew and Node are present, redirects the npm global prefix to `~/.npm-global` (user-owned) if it's currently root-owned, patches your shell profile so the change persists, installs `@meridiona/meridian` from npm, and then hands off to `meridian setup`. Re-running is safe — every step is idempotent, and **`sudo` is never required**. - | Flag | Effect | + + Prefer to inspect the script first? Download it, read it, then run it locally: + + ```bash + curl -fsSL -o bootstrap.sh \ + https://raw.githubusercontent.com/Meridiona/meridian/main/scripts/bootstrap.sh + less bootstrap.sh + bash bootstrap.sh + ``` + + + If your npm global prefix is already user-writable (typical with Homebrew Node at `/opt/homebrew`), you can skip the bootstrap and install directly: + + ```bash + npm install -g @meridiona/meridian + meridian setup + ``` + + Either way, `meridian setup` copies the prebuilt app bundle into `~/.meridian/app`, installs any missing prerequisites (Homebrew packages, Python 3.11, ffmpeg, screenpipe), prepares the on-device model environment, and registers four launchd agents that start automatically: + + | Service | Role | |---|---| - | `--no-ui` | Skip building the Next.js dashboard | - | `--dry-run` | Preview all actions without executing any of them | - | `--no-daemon` | Build everything but do not register launchd agents | - | `--skip-permissions` | Skip the macOS permissions walkthrough | - | `--skip-env` | Skip the interactive credential prompts entirely | - | `--mlx` | Set up the persistent MLX inference server for task classification | + | **screenpipe** | Captures your screen activity (the data source; audio capture is disabled) | + | **Meridian daemon** | The pipeline — ETL, classification, coding-agent ingest, worklog drafting | + | **MLX server** | The on-device model used for classification and worklog synthesis | + | **Dashboard** | The web UI at `http://localhost:3939` | + + + **Piped install (`curl | bash`)** has no TTY for interactive prompts, so the bootstrap runs `meridian setup --skip-permissions` and reminds you to open a new terminal and run `meridian setup` to grant macOS permissions and collect tracker credentials. Running the script directly with `bash bootstrap.sh` hands off to the full interactive setup in the same terminal. + + + + Pin a specific version with `npm install -g @meridiona/meridian@`. To update later, run `meridian update`. + + + **Gatekeeper bypass (unsigned v1 builds).** The current release ships an unsigned binary. If macOS blocks it on first run, clear the quarantine attribute and restart: + + ```bash + xattr -dr com.apple.quarantine ~/.meridian/app + meridian restart + ``` + - 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 that only **you** can grant. `meridian setup` opens each pane interactively; if you skipped that step or need to re-grant 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, so no Microphone permission is required. - - - Immediately after the build, the installer prompts you for credentials grouped by service. Press **Enter** on any prompt to skip that variable — you can always add it later. - The installer collects: + After granting access, run `meridian restart` so screenpipe picks up the permissions. + + + Meridian drafts worklogs against tickets assigned to you. It supports Jira, Linear, and GitHub — pick whichever you use (you can configure more than one). Open the config in your `$EDITOR`: - - **OpenRouter API key** (`OPENROUTER_API_KEY`) — for cloud LLM inference. Skip this if you're running entirely local with MLX. - - **Jira** — your Atlassian base URL, email address, API token, and optionally a comma-separated list of project keys to scope ticket lookups. - - **GitHub** — a personal access token, your org name, and optionally a comma-separated list of repos. - - **Linear** — an API key and optionally a comma-separated list of team IDs. + ```bash + meridian config edit + ``` - Values you've already entered are preserved on re-runs; the installer never overwrites an existing value. To update a credential after installation, run: + This opens `~/.meridian/app/.env`. Add the block for your tracker. For Jira, that's: ```bash - meridian config edit + JIRA_BASE_URL=https://your-org.atlassian.net + JIRA_EMAIL=you@your-org.com + JIRA_API_TOKEN=your-api-token + # JIRA_PROJECT_KEYS=KAN,ENG # optional filter; empty = all projects + + CLASSIFICATION_ENABLED=true ``` - This opens `~/.meridian/.env` in your `$EDITOR`. See the [Configuration](/configuration) page for the full variable reference. - - - Bring all daemons up with a single command: + Save, then restart: ```bash - meridian start + meridian restart ``` - Then confirm everything is running: + See the [Jira](/guides/jira) and [GitHub & Linear](/guides/github-linear) guides for the equivalent setup for each tracker, and the [Configuration](/configuration) page for the full variable reference. + + + Confirm all four services are up: ```bash 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 `com.meridiona.screenpipe`, `com.meridiona.daemon`, `com.meridiona.mlx-server`, and `com.meridiona.ui` reported as running with their process IDs. If anything is off, run `meridian doctor` for a full health check. - **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. + **First-run model download.** On the first `meridian start` after install, the MLX server downloads the on-device model (~6 GB) into your local cache. Subsequent starts load from cache in around 5 seconds. Tail the progress with `meridian logs mlx-server -f` — you'll see `MLX model ready` once it's loaded. - Once the daemons are running, open your browser to: + With the services 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. + The dashboard shows a real-time timeline of your app sessions coloured by activity category, a daily breakdown chart, and your draft worklogs. New sessions appear every 60 seconds as the daemon processes the latest screenpipe frames. + + + Change the port by setting `MERIDIAN_UI_PORT` in `~/.meridian/app/.env`, then `meridian restart`. + ## Useful commands after starting -Once Meridian is running, the following commands are the ones you'll reach for most often: +Once Meridian is running, these are the commands you'll reach for most often: ```bash -# Tail the daemon log (last 100 lines) -meridian logs - -# Stream the daemon log live +# Watch the daemon pipeline live meridian logs -f # Tail a specific service log meridian logs daemon-error -meridian logs jira-updater +meridian logs mlx-server meridian logs screenpipe -meridian logs screenpipe-error meridian logs ui -meridian logs ui-error -meridian logs mlx-server -meridian logs coding-agent-indexer -# Run environment health checks +# Today's worklog drafts (done / pending / per-ticket comments) +meridian worklog-status + +# Diagnose missing config, services, or permissions meridian doctor -# Stop all daemons +# Stop / restart everything meridian stop - -# Restart all daemons meridian restart + +# Update to the latest release +meridian update ``` -`meridian doctor` checks that all plists are installed and valid, that screenpipe is running and has a database, that your Python virtualenv is set up, that the MCP server is built, and that the dashboard has been compiled. Run it any time something looks wrong. +`meridian doctor` checks that all launchd plists are installed, screenpipe is running and has a database, the MLX server is reachable, and the dashboard has been built. Run it any time something looks wrong. + + + **Nothing posts to your tracker automatically.** The daemon only *drafts* worklogs; you review and approve each one in the dashboard's **Worklogs** view, and the daemon posts approved worklogs within ~60s. Approval is the only gate. + ## Troubleshooting - - 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`). + + Your npm global prefix is root-owned — typical with the stock macOS Node install at `/usr/local`. The bootstrap one-liner at the top of this page fixes this automatically by redirecting the prefix to `~/.npm-global` and patching your shell profile. Run it instead of `npm install -g` directly: + + ```bash + curl -fsSL https://raw.githubusercontent.com/Meridiona/meridian/main/scripts/bootstrap.sh | bash + ``` + + Never run npm with `sudo` — that creates root-owned files in your home and breaks future installs. - - 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`. + + Run `meridian doctor` to identify the specific failure. The most common causes are a missing config file (re-run `meridian setup`), screenpipe permissions not yet granted (`meridian permissions`), or a Gatekeeper block on the unsigned binary — see the warning at the top of step 1. - - Confirm your PM credentials are set: `meridian config edit`. Ensure `CLASSIFICATION_ENABLED=true` and that the MLX server is running (`meridian logs mlx-server`). Run `meridian doctor` to verify the jira-updater is installed and check `meridian logs jira-updater` for any API errors. + + Unsigned v1 builds are quarantined by Gatekeeper. Clear the attribute and restart: + + ```bash + xattr -dr com.apple.quarantine ~/.meridian/app + meridian restart + ``` + + + Give it ~15 seconds after `meridian start` for the Next.js server to boot, then check `meridian logs ui-error -n 50`. If the port is in use, set `MERIDIAN_UI_PORT` in `~/.meridian/app/.env` and `meridian restart`. + + + + Confirm your tracker credentials with `meridian config edit`, that `CLASSIFICATION_ENABLED=true`, and that the MLX server is up (`meridian logs mlx-server -f` should show `MLX model ready`). Inspect the day's drafts with `meridian worklog-status`. + + +## Build from source (contributors only) + +If you're contributing to Meridian itself rather than just using it, clone the repository and run the source installer instead of the bootstrap one-liner. This builds the daemon and dashboard from source and registers the same launchd services: + +```bash +git clone https://github.com/Meridiona/meridian +cd meridian +./install.sh +``` + +The source path is intended for development — use `meridian dev` to rebuild and restart after edits. Everyone else should stick with the bootstrap install above. diff --git a/reference/cli.mdx b/reference/cli.mdx index db9553e..61172d8 100644 --- a/reference/cli.mdx +++ b/reference/cli.mdx @@ -1,15 +1,46 @@ --- title: "Meridian CLI Reference: Commands, Flags, and Usage" sidebarTitle: "CLI Reference" -description: "Complete reference for every meridian CLI command and install.sh flag, including start, stop, logs, doctor, config, permissions, and uninstall." +description: "Complete reference for every meridian CLI command — setup, start, stop, logs, doctor, config, permissions, update, and uninstall — plus the install.sh flags for source builds." --- -The `meridian` CLI is a bash script that wraps macOS launchd, letting you manage all Meridian daemons without touching `launchctl` directly. After installation, the script is symlinked into `/usr/local/bin/meridian` (or `~/.local/bin/meridian`) so you can call it from any directory. +The `meridian` CLI is a bash script that wraps macOS launchd, letting you manage all Meridian services without touching `launchctl` directly. When you install via npm (`npm install -g @meridiona/meridian`), the CLI is placed on your `PATH` automatically. Source-built contributors get the same binary symlinked into `/usr/local/bin/meridian` (or `~/.local/bin/meridian`) by `./install.sh`. --- ## Commands + + +```bash +meridian setup +``` + +The one-time installer run after `npm install -g @meridiona/meridian`. Copies the prebuilt app bundle to `~/.meridian/app`, installs any missing prerequisites (Homebrew packages, Python 3.11, ffmpeg, screenpipe), prepares the on-device model environment, and registers four launchd agents that start automatically: + +- `com.meridiona.screenpipe` — capture +- `com.meridiona.daemon` — pipeline (ETL, classification, worklog drafting) +- `com.meridiona.mlx-server` — on-device model +- `com.meridiona.ui` — dashboard at http://localhost:3939 + +After setup completes, `meridian setup` walks you through the macOS permissions panes (Screen Recording, Accessibility). Run it again at any time to re-register services or top up missing prerequisites; it's idempotent. + + +Source-built contributors run `./install.sh` from the repo root instead. The on-disk layout under `~/.meridian/` is the same. + + + + + + +```bash +meridian update +``` + +Pulls the latest release of `@meridiona/meridian` from npm and re-runs `meridian setup` so the registered launchd agents pick up the new binary. Your config in `~/.meridian/app/.env` and database at `~/.meridian/meridian.db` are preserved. + + + ```bash @@ -22,12 +53,10 @@ 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.mlx-server` | MLX inference server | -| `com.meridiona.coding-agent-indexer` | Coding-agent context indexer | +| `com.meridiona.ui` | Next.js dashboard at http://localhost:3939 | -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. +If any `.plist` file is missing, `meridian start` prints an error for that service and exits with a non-zero code. Re-run `meridian setup` (or `./install.sh` for source builds) to reinstall missing plists. The Rust daemon TCP-connects to the MLX server at startup to verify it is reachable. If the MLX server is not running, the daemon exits immediately. Start all services together with `meridian start` rather than launching them individually. @@ -43,7 +72,7 @@ meridian stop Disables and boots out every LaunchAgent, then kills any orphaned `mlx_lm.server` processes that launchd does not track. The `.plist` files in `~/Library/LaunchAgents/` are left in place so `meridian start` can bring everything back up. -Use this command before editing `~/.meridian/.env` so the daemon picks up the new values on the next `meridian start`. +Use this command before editing `~/.meridian/app/.env` so the daemon picks up the new values on the next `meridian start`. @@ -66,8 +95,8 @@ meridian status Queries launchd for the running state of every registered service and prints a colour-coded summary: - **✓ running (pid N)** — service is up and has a PID -- **⊘ loaded but not running** — launchd has the plist but the process is not active (e.g. the jira-updater between scheduled slots) -- **✗ not installed** — plist is missing; run `./install.sh` +- **⊘ loaded but not running** — launchd has the plist but the process is not active (e.g. a service paused between scheduled slots) +- **✗ not installed** — plist is missing; run `meridian setup` (or `./install.sh` for source builds) Run `meridian status` any time you are unsure whether the stack is up. @@ -87,13 +116,12 @@ Tails a log file from `~/.meridian/logs/`. All arguments are optional. |---|---| | `daemon` *(default)* | `~/.meridian/logs/daemon.log` | | `daemon-error` | `~/.meridian/logs/daemon-error.log` | -| `jira-updater` | `~/.meridian/logs/jira-updater.log` | +| `mlx-server` | `~/.meridian/logs/mlx-server.log` | +| `mlx-server-error` | `~/.meridian/logs/mlx-server-error.log` | | `screenpipe` | `~/.meridian/logs/screenpipe.log` | | `screenpipe-error` | `~/.meridian/logs/screenpipe-error.log` | | `ui` | `~/.meridian/logs/ui.log` | | `ui-error` | `~/.meridian/logs/ui-error.log` | -| `mlx-server` | `~/.meridian/logs/mlx-server.log` | -| `coding-agent-indexer` | `~/.meridian/logs/coding-agent-indexer.log` | **Flags** @@ -125,17 +153,17 @@ meridian doctor Runs a full suite of environment health checks and prints a pass/fail result for each one. Checks include: -- macOS detected -- `meridian-daemon` binary exists and is executable -- Service `.plist` files are installed and pass `plutil -lint` (daemon, jira-updater, screenpipe, UI) +- macOS on Apple Silicon detected +- `meridian` and `meridian-daemon` binaries exist and are executable +- Service `.plist` files are installed and pass `plutil -lint` (daemon, mlx-server, screenpipe, UI) - Daemon process is running -- `~/.meridian/.env` configuration file exists +- `~/.meridian/app/.env` configuration file exists - screenpipe binary is in `$PATH` - screenpipe database exists at `~/.screenpipe/db.sqlite` - screenpipe process is running -- 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) +- Python environment is set up for the MLX server +- MLX server is reachable on `127.0.0.1:$MLX_SERVER_PORT` +- Next.js UI has been built and the dashboard responds on `http://localhost:$MERIDIAN_UI_PORT` At the end, `doctor` prints a count of failed checks. A clean run looks like: @@ -153,7 +181,7 @@ Run `meridian doctor` as the first diagnostic step whenever something seems wron meridian config edit ``` -Opens `~/.meridian/.env` in your `$EDITOR` (falls back to `nano` if `$EDITOR` is not set). This is the canonical way to update API keys, change the poll interval, or toggle classification without hunting for the file path. +Opens `~/.meridian/app/.env` in your `$EDITOR` (falls back to `nano` if `$EDITOR` is not set). This is the canonical way to update API keys, change the poll interval, or toggle classification without hunting for the file path. On source-built installs, the same command opens the repo-root `.env`. After saving, run `meridian restart` so the daemon picks up the new values. @@ -173,13 +201,12 @@ EDITOR=code meridian config edit meridian permissions ``` -Walks you interactively through the three macOS privacy panes that screenpipe requires: +Walks you interactively through the two macOS privacy panes that screenpipe 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. -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 picks up the newly granted permissions. Audio capture is disabled by default, so no Microphone permission is required. Without Screen Recording permission, screenpipe cannot capture frames and Meridian will have no data to process. @@ -193,7 +220,7 @@ Without Screen Recording permission, screenpipe cannot capture frames and Meridi meridian uninstall ``` -Prompts for confirmation, then stops all daemons, runs each service's uninstall script, kills orphaned `mlx_lm.server` processes, and removes the `meridian` and `meridian-daemon` symlinks from `/usr/local/bin/` and `~/.local/bin/`. +Prompts for confirmation, then stops all daemons, runs each service's uninstall script, kills orphaned `mlx_lm.server` processes, and removes the `meridian` and `meridian-daemon` shims. After uninstall, you can also `npm uninstall -g @meridiona/meridian` to remove the CLI package itself. Your data at `~/.meridian/` is **not** removed. Delete it manually if you want to wipe everything: @@ -205,9 +232,9 @@ rm -rf ~/.meridian --- -## install.sh Flags +## install.sh Flags (source builds) -The installer (`./install.sh`) accepts flags that let you customise or automate the setup process. +Most users install from npm with `npm install -g @meridiona/meridian && meridian setup` and never touch `install.sh`. The source installer is only relevant if you cloned the repo to contribute to Meridian itself. It accepts the following flags to customise or automate the setup process. diff --git a/reference/environment-variables.mdx b/reference/environment-variables.mdx index 2f9f4b9..f160d4d 100644 --- a/reference/environment-variables.mdx +++ b/reference/environment-variables.mdx @@ -1,10 +1,10 @@ --- title: "Meridian Environment Variables and Configuration Reference" sidebarTitle: "Environment Variables" -description: "All environment variables Meridian reads from ~/.meridian/.env — core daemon, classification, Jira, GitHub, Linear, and MCP server settings." +description: "All environment variables Meridian reads from ~/.meridian/app/.env — core daemon, classification, Jira, GitHub, Linear, and MCP server settings." --- -Meridian reads its configuration from `~/.meridian/.env`, which the installer creates and populates during `./install.sh`. You can edit it at any time with `meridian config edit`. Changes take effect after a `meridian restart`. +Meridian reads its configuration from `~/.meridian/app/.env`, which `meridian setup` creates after `npm install -g @meridiona/meridian`. You can edit it at any time with `meridian config edit`. Changes take effect after a `meridian restart`. (Source-built contributors get the same variables in their repo-root `.env`.) Every variable has a safe default; you only need to set the ones relevant to your workflow. The sections below list every supported variable grouped by the part of Meridian that reads it. @@ -79,10 +79,10 @@ The MCP server reads one variable at startup to locate the database. ## Minimal Example Configuration -The block below shows the minimum set of variables needed to run the full Meridian stack with Jira classification enabled. Copy it to `~/.meridian/.env` and fill in your values, or use `meridian config edit` to open the file directly. +The block below shows the minimum set of variables needed to run the full Meridian stack with Jira classification enabled. Copy it to `~/.meridian/app/.env` and fill in your values, or use `meridian config edit` to open the file directly. ```bash -# ~/.meridian/.env +# ~/.meridian/app/.env # ── Core ────────────────────────────────────────────────────────────────────── POLL_INTERVAL_SECS=60 @@ -105,5 +105,5 @@ LINEAR_API_KEY=lin_api_your_key_here ``` -After editing `~/.meridian/.env`, run `meridian restart` to apply the new values. The daemon reads the file once at startup and does not hot-reload changes. +After editing `~/.meridian/app/.env`, run `meridian restart` to apply the new values. The daemon reads the file once at startup and does not hot-reload changes. diff --git a/reference/troubleshooting.mdx b/reference/troubleshooting.mdx index e7a0a64..392eb22 100644 --- a/reference/troubleshooting.mdx +++ b/reference/troubleshooting.mdx @@ -16,63 +16,70 @@ The sections below cover the most common failure patterns in more detail. ## Installation & Setup - + -The installer uses Homebrew to install system dependencies (Rust, Node, Python, screenpipe). If it fails at this step: +The current Meridian release ships an unsigned binary, so macOS may quarantine it on first launch with a "cannot be opened because the developer cannot be verified" error. -1. Make sure you have an active internet connection. -2. Ensure Xcode Command Line Tools are installed: +Clear the quarantine attribute and restart: ```bash -xcode-select --install +xattr -dr com.apple.quarantine ~/.meridian/app +meridian restart ``` -If the tools are already installed, the command exits immediately with a message to that effect. Otherwise, follow the on-screen prompt and re-run `./install.sh` after the installation completes. - - + -Meridian compiles the ETL daemon from Rust source. If the build fails, first check that the correct toolchain is active: +This happens when your npm global prefix is root-owned — typical with the stock macOS Node install at `/usr/local`. Running `npm install -g` (with or without `sudo`) is not the right fix; use the bootstrap one-liner instead. It redirects the prefix to `~/.npm-global` (user-owned), patches your shell profile so the change persists across terminals, and then installs Meridian and runs setup: ```bash -rustup show +curl -fsSL https://raw.githubusercontent.com/Meridiona/meridian/main/scripts/bootstrap.sh | bash ``` -The output should show a stable toolchain for `aarch64-apple-darwin` (Apple Silicon) or `x86_64-apple-darwin`. If `rustup` is not found at all, install it: +The script is idempotent and never uses `sudo`. Re-running it after a failed install is safe. -```bash -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` + + + + +`npm install -g @meridiona/meridian` puts the CLI on the npm global bin path. If your shell can't find it, that directory is not on your `PATH`. -Then re-run `./install.sh`. The `rust-toolchain.toml` file in the repo root pins the exact version the project requires, so `rustup` picks it up automatically. +1. Find the npm global bin: `npm bin -g` (typical values: `/usr/local/bin`, `~/.npm-global/bin`, or `~/.local/bin`). +2. Add it to your `PATH` in `~/.zshrc` (or `~/.bashrc`): + + ```bash + export PATH="$(npm bin -g):$PATH" + ``` + +3. Open a new shell or `source ~/.zshrc`. + +The bootstrap one-liner (`curl -fsSL .../bootstrap.sh | bash`) does this automatically — re-run it if you'd rather not edit your profile by hand. - + -The Python services (MLX inference server, Jira updater, task classifier) require Python 3.13. Check whether it is installed: +`meridian setup` uses Homebrew to install system dependencies (Python 3.11, ffmpeg, screenpipe). If it fails at this step: + +1. Make sure you have an active internet connection. +2. Ensure Xcode Command Line Tools are installed: ```bash -python3.13 --version +xcode-select --install ``` -If the command is not found, install it via Homebrew or pyenv: +If the tools are already installed, the command exits immediately with a message to that effect. Otherwise, follow the on-screen prompt and re-run `meridian setup` after the installation completes. -```bash -# Homebrew -brew install python@3.13 + -# pyenv -pyenv install 3.13 -pyenv global 3.13 -``` + -After installing Python 3.13, re-run the service setup: +These errors only apply to contributors who cloned the repo and ran `./install.sh` instead of installing from npm. The npm distribution ships a prebuilt binary and never needs Rust or a Python toolchain on your machine. -```bash -bash scripts/setup-services.sh -``` +**Rust toolchain:** `rustup show` should report a stable toolchain for `aarch64-apple-darwin`. If `rustup` itself is missing, install it from [rustup.rs](https://rustup.rs/). `rust-toolchain.toml` in the repo pins the required version. + +**Python:** the source build requires Python 3.11 (`brew install python@3.11` or `pyenv install 3.11`). After installing, re-run `./install.sh`. @@ -84,21 +91,18 @@ bash scripts/setup-services.sh The Rust daemon TCP-connects to the MLX inference server before entering its poll loop. If the MLX server is not running, the daemon exits immediately with an error message in the log. -**Fix — install and start the MLX server daemon:** - -```bash -bash services/scripts/install-mlx-server-daemon.sh -``` - -Then check that it started: +**Fix — restart the stack so launchd brings the MLX server back up:** ```bash +meridian restart meridian logs mlx-server -f ``` -Wait until you see `server: MLX model ready` (this can take up to 30 seconds on first run while the model downloads). +Wait until you see `server: MLX model ready` (this can take a few minutes on the very first run while the ~6 GB model downloads, then ~5 seconds from cache thereafter). -Alternatively, if you do not need session classification, set `CLASSIFICATION_ENABLED=false` in `~/.meridian/.env` and restart: +If the MLX plist is missing entirely (e.g. `meridian status` reports `not installed`), re-run `meridian setup` to re-register the launchd agents. + +Alternatively, if you do not need session classification, set `CLASSIFICATION_ENABLED=false` in `~/.meridian/app/.env` and restart: ```bash meridian config edit # set CLASSIFICATION_ENABLED=false @@ -161,7 +165,7 @@ meridian config edit # verify SCREENPIPE_DB if you customised it A 401 from the Jira API means either `JIRA_EMAIL` or `JIRA_API_TOKEN` is wrong, or the token has been revoked. -1. Open `~/.meridian/.env` with `meridian config edit`. +1. Open `~/.meridian/app/.env` with `meridian config edit`. 2. Verify that `JIRA_EMAIL` matches the email address of the Atlassian account that owns the token. 3. Regenerate the token at [id.atlassian.com/manage-profile/security/api-tokens](https://id.atlassian.com/manage-profile/security/api-tokens) and paste the new value into `JIRA_API_TOKEN`. 4. Restart: `meridian restart`. @@ -193,20 +197,21 @@ python3 scripts/refresh_pm_tasks.py --jql "project=KAN ORDER BY updated DESC" A GitHub 401 means the personal access token is expired, revoked, or was created without the `repo` scope. 1. Go to [github.com/settings/tokens](https://github.com/settings/tokens) and create a new classic PAT with at minimum the `repo` scope. -2. Update `GITHUB_TOKEN` in `~/.meridian/.env` via `meridian config edit`. +2. Update `GITHUB_TOKEN` in `~/.meridian/app/.env` via `meridian config edit`. 3. Restart: `meridian restart`. -1. Verify `LINEAR_API_KEY` is set correctly in `~/.meridian/.env`. +1. Verify `LINEAR_API_KEY` is set correctly in `~/.meridian/app/.env`. 2. Check `LINEAR_TEAM_IDS` — if set, confirm the team IDs are correct (visible in Linear's workspace settings URL). 3. Ensure the teams have open issues in a status that the connector picks up. -4. Check the jira-updater log (which also handles Linear sync) for error messages: +4. Check the daemon log (which handles all tracker sync) for error messages: ```bash -meridian logs jira-updater -n 100 +meridian logs daemon -n 100 +meridian logs daemon-error -n 100 ``` @@ -277,7 +282,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 and waits for you to confirm each one. (Audio capture is disabled, so no Microphone permission is required.) After granting access, restart the stack: ```bash meridian restart @@ -289,26 +294,11 @@ 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. - -If screenpipe is not listed in the Microphone pane yet: - -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. - -Alternatively, run `meridian permissions` to open all three panes in the correct order. - - - --- ## Dashboard - + 1. Check whether the UI service is running: @@ -323,17 +313,12 @@ meridian logs ui meridian logs ui-error ``` -3. If the UI has not been built yet (e.g. after a fresh clone or `--no-ui` install), build it: - -```bash -cd ui -npm ci -npm run build -``` +3. If the UI plist is missing entirely (`not installed`), re-run `meridian setup` to re-register the launchd agents. -4. Then bring the service back up: +4. If the port is in use, set `MERIDIAN_UI_PORT` in `~/.meridian/app/.env` to something else and restart: ```bash +meridian config edit meridian restart ```