diff --git a/reference/cli.mdx b/reference/cli.mdx index db9553e..21d3f9c 100644 --- a/reference/cli.mdx +++ b/reference/cli.mdx @@ -21,14 +21,16 @@ Enables and bootstraps every Meridian LaunchAgent, then prints a live status sum | Label | Service | |---|---| | `com.meridiona.screenpipe` | screenpipe ambient recorder | -| `com.meridiona.daemon` | Meridian Rust ETL daemon | -| `com.meridiona.jira-updater` | Jira / GitHub / Linear sync | +| `com.meridiona.daemon` | Meridian Rust ETL daemon (also runs the in-process PM worklog pipeline and the coding-agent indexer) | | `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 | 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. + +The PM worklog (Jira / GitHub / Linear) pipeline and the coding-agent indexer used to ship as their own LaunchAgents (`com.meridiona.jira-updater`, `com.meridiona.coding-agent-indexer`). They now run inside `com.meridiona.daemon`, so `meridian status` only reports the four labels above. + + 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. @@ -66,7 +68,7 @@ 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) +- **⊘ loaded but not running** — launchd has the plist but the process is not active - **✗ not installed** — plist is missing; run `./install.sh` Run `meridian status` any time you are unsure whether the stack is up. @@ -83,17 +85,18 @@ Tails a log file from `~/.meridian/logs/`. All arguments are optional. **Valid targets** +Each component has a normal log (everything) and a paired `-error` log (WARN/ERROR only) so you can grep for problems without scrolling past routine output. + | Target | File | |---|---| | `daemon` *(default)* | `~/.meridian/logs/daemon.log` | | `daemon-error` | `~/.meridian/logs/daemon-error.log` | -| `jira-updater` | `~/.meridian/logs/jira-updater.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` | +| `mlx-server-error` | `~/.meridian/logs/mlx-server-error.log` | **Flags** @@ -111,39 +114,187 @@ meridian logs daemon -f # Last 50 lines of the MLX server log meridian logs mlx-server -n 50 +# Stream daemon errors only (skip routine INFO output) +meridian logs daemon-error -f + +# Stream MLX server errors only +meridian logs mlx-server-error -f + # Tail errors from screenpipe meridian logs screenpipe-error ``` + +The Rust daemon also writes structured JSON logs to `~/.meridian/logs/meridian-rust.jsonl.` for `jq`-friendly grepping outside the CLI. + + - + + +```bash +meridian doctor [--fix] [--dry-run] [--porcelain] +``` + +Runs a comprehensive, read-only system-health sweep across every Meridian daemon and prints a colourised (when stdout is a TTY) by-daemon table, a root-cause **Diagnosis** section, and an escalation footer when anything needs attention. The CLI wrapper delegates to the daemon binary's health engine — if the binary is missing or stale, a minimal bash fallback runs so `meridian doctor` always produces something useful. + +Run `meridian doctor` as the first diagnostic step whenever something seems wrong: a missed Jira sync, a blank dashboard, a misclassified session, or a daemon that looks alive but isn't producing output. Every check is content-free — counts, timestamps, status codes, reachability — never screen content or ticket text. + +**Check groups** + +| Group | What it looks at | +|---|---| +| `system` | macOS detected, disk free, `.env` present, required toolchains | +| `meridian daemon` | ETL last-run status + freshness, frame cursor, summariser / classifier queue depth, subprocess-error sentinels | +| `screenpipe` | binary on PATH, plist installed, process live, DB frames, frame freshness, blank-text rate (Screen Recording permission proxy), per-app accessibility share, WAL size | +| `mlx-server` | `/health` reachability and backend, `/info` model-loaded readiness (liveness vs. readiness) | +| `jira` | `/myself` auth (distinguishes 401 expired from 403 scope), ticket sync freshness, candidate-ticket completeness | +| `ui` | launchd service up, `.next` built, `/` serves, a referenced `_next/static` asset fetches, serve mode (catches an `output: 'standalone'` build run with `next start`) | +| `mcp server` | `packages/meridian-mcp/dist/index.js` built | +| `worklog` | drafts awaiting review, hours stuck unprocessed, approved worklogs failing to post | +| `coding-agent` | Claude Code and Codex CLI presence, JSONL session directories, `~/.claude/commands/session-summary.md` skill file (without it, every Claude Code session falls back to MLX) | +| `observability` | OpenObserve reachability (so telemetry doesn't silently drop) | +| `config` | cross-process contract — DB path agreement (`MERIDIAN_DB` vs. `MERIDIAN_DB_PATH`), settings-file split-brain, dead env vars like `POLL_INTERVAL_SECS` | + +Each row is `✓ ok`, `⊘ warn`, `· info`, or `✗ critical`. Failing rows show a `→` remedy line with the exact command to fix them. The exit code is `0` on a clean run and `1` when any check is critical. + +**Flags** + +| Flag | Description | +|---|---| +| `--fix` | Apply tiered repairs to the warnings the sweep finds — see below | +| `--dry-run` | With `--fix`, plan the repairs without executing them | +| `--porcelain` | Emit TSV rows instead of the rich table — for scripts and dashboards | + +**`--fix` repair tiers** + +| Tier | Behaviour | +|---|---| +| auto | Safe + idempotent (e.g. restart a dead service) — run silently | +| guided | Shows the command and asks `y/N` before running (e.g. drain the summariser queue, re-classify sentinels, refresh Jira, rebuild UI). Defaults to **No** on non-interactive stdin so `--fix` never auto-runs a mutating action without a human. | +| manual | Only a human can do it (regenerate a token, align settings) — printed as instructions | + +Anything still failing after `--fix` is escalated: a content-free diagnostic bundle is written to `~/.meridian/` so you can share it with the team or hand it off to `claude`. + +**Examples** ```bash +# Default: full sweep with table, diagnosis, and escalation footer meridian doctor + +# See what --fix would do, without changing anything +meridian doctor --fix --dry-run + +# Apply auto fixes, prompt for guided ones, print remaining manuals +meridian doctor --fix + +# Machine-readable TSV for a dashboard or CI gate +meridian doctor --porcelain +``` + + +The daemon also runs a subset of these checks (capture-layer / L1 only) as a startup preflight, logging warn/error to `daemon.log`. The preflight is non-fatal — the daemon still runs — so always confirm with `meridian doctor` if you suspect a fault. + + + + + + +```bash +meridian worklog-status [--day YYYY-MM-DD] +``` + +Prints a read-only, human-readable report of the day's PM worklogs: the hour ledger (done / pending / stuck), worklogs grouped by state (`drafted`, `approved`, `posted`, `rejected`, `failed`), and a per-ticket table with the synthesised Jira comment for each row. Useful for a quick "what is the daemon about to post?" check before approving worklogs in the dashboard. + +This command is read-only — it never writes to the DB and never calls Jira / GitHub / Linear. It also skips daemon initialisation, so it's safe to run while the daemon is up. + +**Flags** + +| Flag | Description | +|---|---| +| `--day YYYY-MM-DD` | Report for the given day (default: today, in the daemon's local timezone) | + +**Examples** + +```bash +# Today's worklogs +meridian worklog-status + +# Backfill check for a specific day +meridian worklog-status --day 2026-05-30 +``` + + + + + +```bash +meridian pm-worklog [--day YYYY-MM-DD] +``` + +One-shot run of the Stage 4 PM worklog pipeline: walks the day's hour ledger and **drafts** one worklog per task per ready hour. Worklogs land in the `drafted` state — they are never auto-posted. Approve them in the dashboard (or run `meridian worklog-post-approved`) to send them to Jira / GitHub / Linear. + +Use this when you want to regenerate drafts for a past day, recover from a failed run, or kick the pipeline manually without waiting for the next daemon cycle. The daemon runs the same pipeline on a schedule, so under normal operation you do not need to call this command. + +**Flags** + +| Flag | Description | +|---|---| +| `--day YYYY-MM-DD` | Day to process (default: today) | + +**Examples** + +```bash +# Re-draft worklogs for yesterday +meridian pm-worklog --day 2026-06-01 + +# Draft today's worklogs now (skip waiting for the next daemon cycle) +meridian pm-worklog +``` + + +Running `meridian pm-worklog` while the in-daemon worklog pipeline is also active can have both processes hit the LLM at the same time. The global LLM gate prevents corruption, but for predictable behaviour run this against a stopped daemon (`meridian stop`) when backfilling. + + + + + + +```bash +meridian worklog-post-approved ``` -Runs a full suite of environment health checks and prints a pass/fail result for each one. Checks include: +Posts every worklog you have approved in the dashboard to its provider (Jira / GitHub / Linear) immediately. This is a one-shot run of the same approved-poster sweep the daemon performs every ~60 seconds, so use it when you want a result *now* — for example, right after approving a batch of worklogs in the dashboard and not wanting to wait for the next cycle. -- macOS detected -- `meridian-daemon` binary exists and is executable -- Service `.plist` files are installed and pass `plutil -lint` (daemon, jira-updater, screenpipe, UI) -- Daemon process is running -- `~/.meridian/.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) +This is the only CLI command that writes to a real ticketing system. Worklogs in any state other than `approved` are skipped. -At the end, `doctor` prints a count of failed checks. A clean run looks like: +**Example** +```bash +# Approve worklogs in the dashboard, then flush them to Jira now +meridian worklog-post-approved ``` -✓ all checks passed + + + + + +```bash +meridian coding-agent-install-skill ``` -Run `meridian doctor` as the first diagnostic step whenever something seems wrong. +Writes the `session-summary` Claude Code slash-command file to `~/.claude/commands/session-summary.md` so `claude -p /session-summary` resolves to the prompt Meridian uses to summarise coding-agent transcripts for the Jira worklog. + +Without this file, `claude -p /session-summary` returns *Unknown command* and the summariser silently falls back to the local MLX model for every Claude Code session — you lose subscription-claude quality on the transcript summaries that feed the worklog. Run this once per machine where Claude Code is installed. + +The command is idempotent (safe to re-run) and writes nothing if the file already exists. `meridian doctor` warns when the skill is missing, and `meridian doctor --fix` runs this command for you, so most users never need to invoke it directly. + +**Example** + +```bash +# First-time setup for Claude Code summarisation +meridian coding-agent-install-skill +``` @@ -187,6 +338,35 @@ Without Screen Recording permission, screenpipe cannot capture frames and Meridi + + +```bash +meridian update +``` + +Updates a source checkout to the latest `main` in one step: `git pull --ff-only`, rebuilds the Rust daemon (`cargo build --release`), rebuilds the Next.js UI (`npm run build`), then restarts every daemon via `meridian restart`. Use it after a release announcement, or any time you want to pull upstream fixes without running each step by hand. + +This command only works in a source checkout (the directory contains a `Cargo.toml`). For production installs from npm, upgrade with: + +```bash +npm install -g @meridiona/meridian@latest +``` + +If `git pull --ff-only` fails (local commits that haven't been pushed, or a non-fast-forward), `meridian update` exits without rebuilding so you can resolve the conflict yourself; rerun `meridian dev build` and `meridian restart` afterwards. + +**Example** + +```bash +# Pull, rebuild, and restart everything in a source checkout +meridian update +``` + + +The command prints the new version on success — either the contents of the `VERSION` file or the short Git SHA if `VERSION` is missing. + + + + ```bash