# Commands

> Every blop command with usage, flags and JSON fields, plus exit codes, environment variables and the JSON output contract.

<!-- Generated by apps/docs/scripts/gen-reference.mjs. Do not edit. -->

Local observability for coding agents: sessions, traces and issues.

```bash
blop <command> [flags]
```

Running `blop` with no command runs `blop home`.

### Global flags

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `-o, --output <fmt>` | text (default), json, ndjson or env, per command Values: text, json, ndjson, env. | text |  |
| `--json` | Same as -o json: one blop.cli/v1 document on stdout |  |  |
| `-p, --port <n>` | Collector port (default 27811, env BLOP_MONITOR_PORT) | 27811 | `BLOP_MONITOR_PORT` |
| `--url <url>` | Collector URL (env BLOP_MONITOR_URL) |  | `BLOP_MONITOR_URL` |
| `--no-color` | Disable colour (also NO_COLOR=1) |  | `NO_COLOR` |
| `--no-input` | Never prompt; a question exits 2 (also BLOP_NO_INPUT=1) |  | `BLOP_NO_INPUT` |
| `-q, --quiet` | Print only results and errors |  |  |
| `--debug` | Print stack traces (also BLOP_DEBUG=1) |  | `BLOP_DEBUG` |
| `-h, --help` | Show help for blop or a command |  |  |
| `-V, --version` | Print the version |  |  |

## Start commands

### blop up

Start the collector and inspector, or reuse a running one

In a terminal Blop stays in the foreground, with a banner and single keys: o opens the inspector, i the issues, m copies the MCP command, h lists the keys, q quits. It starts in the background instead, and returns once the collector answers, when a coding agent runs it, when stdout is not a terminal, or with --json. Windows always stays in the foreground unless you pass --detach. A collector already running is reused; a background one from an older Blop is restarted.

```bash
blop up [--detach | --foreground] [--port <n>] [--host <host>] [--project <id>] [--no-open] [--recover] [--compact] [--json]
```

Aliases: `blop start`.

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--project <id>` | Default authored-memory project (otherwise BLOP_PROJECT_ID, then all local projects) |  |  |
| `--detach` | Start in the background and return once it answers |  |  |
| `--foreground` | Stay in this terminal, even for an agent or a pipe |  |  |
| `--no-open` | Do not open the inspector (also BROWSER=none) |  |  |
| `--recover` | If the store is corrupt or from a newer Blop, move it aside (renamed, never deleted; the check may already have merged a pending WAL into it) and start an empty one |  |  |
| `--compact` | Before starting, evict to the size cap and VACUUM the store so deleted space returns to the disk (needs twice the store size free; refused while a collector serves it) |  |  |

JSON fields in `data`: `url`, `inspector_url`, `otlp_endpoint`, `port`, `pid`, `instance_id`, `version`, `cli_version`, `store`, `started`, `managed`, `mode`, `log_path`.

```bash
blop up  # Start the collector and inspector, or reuse a running one
blop up --recover  # Move a store Blop cannot open aside and start an empty one
blop up --detach  # Start in the background and print where it runs
```

See also: `blop status`, `blop stop`, `blop help environment`.

### blop run

Run a command with telemetry:  blop run -- npm run dev

With no command it runs the package.json dev script through the package manager the lockfile names (pnpm, yarn, bun, else npm; the lockfile may be in a parent workspace folder) and says so on stderr; a dev script that runs blop itself is refused. Before the command starts, one stderr line names the collector, the service name, whether content capture is on, and the agent SDKs found here (--no-summary drops it and the end summary). Inside another blop run that is still running (BLOP_LOCAL_RUN_ID) the command joins that run instead of starting its own, and its own --capture-content, --url and --port do not apply (it says so); a marker left by an ended run is ignored. --no-summary also drops the coding-agent block. The command keeps this terminal: its stdin, stdout and stderr are its own. With --json, Blop writes one blop.cli/v1 document to stderr after the command exits, and nothing else of its own: the last line Blop writes, on a line of its own, starting with {"schema_version". A background process the command started can still write after it, so --report <file> is the robust path: the document goes to that file (written atomically; if it cannot be written, to stderr with a report_not_written warning). ok is true when the command started, whatever its exit code; data.exit_code is the command's code. Signals: Ctrl-C or SIGTERM while the collector starts exits 130 or 143 and the command never runs (ok false, interrupted). While the command runs, SIGTERM and SIGHUP are forwarded to it (and Ctrl-C when no terminal already sent it); a command still running BLOP_RUN_KILL_GRACE_MS (10000) ms after SIGTERM or SIGHUP is killed, and Ctrl-C twice within 2 seconds kills it at once. After it exits, Ctrl-C skips the wait for late telemetry: the summary still prints (warning settle_interrupted) and the exit code stays the command's.

```bash
blop run [--capture-content] [--env <name>] [--trigger <kind>] [--trigger-id <id>] [--no-summary] [--json] [--report <file>] [--] [<cmd...>]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--capture-content` | Ask instrumented GenAI SDKs to record prompt and completion content |  |  |
| `--env <name>` | deployment.environment.name on the command's telemetry (an OTEL_RESOURCE_ATTRIBUTES value wins) |  |  |
| `--trigger <kind>` | What started the run (blop.trigger.kind): ci, schedule, manual or your own kind; default: detected CI, else manual |  |  |
| `--trigger-id <id>` | blop.trigger.id: a schedule id or CI run id (CI runs are detected with their run id) |  |  |
| `--report <file>` | Write the run summary as a blop.cli/v1 document to this file |  |  |
| `--no-summary` | No start line and no end summary on stderr (new issues and warnings still print) |  |  |

JSON fields in `data`: `run_id`, `command`, `command_line`, `cwd`, `git`, `exit_code`, `signal`, `started_at`, `ended_at`, `duration_ms`, `sessions`, `requests`, `failed_requests`, `new_issues`, `regressed_issues`, `collector_url`, `inspector_url`, `recorded`.

```bash
blop run -- npm run dev  # Run your app with OTel env, git stamp and a run record
blop run npm test  # The -- is optional: the first non-flag word starts the command
blop run --report r.json npm test  # Also write the run summary (JSON) to r.json
```

See also: `blop up`, `blop issues`, `blop help environment`.

### blop demo

Record a sample agent failure to explore before you instrument anything

Through the running collector (started in the background when it is stopped) it records two npm test runs in this repo: one that passed 10 minutes ago and one that failed, where an agent's bash tool call made the app's POST /api/pay answer 500 after the agent read the memory node demo:checkout-policy. Then blop why --last explains it. Everything it records is tagged blop.demo=true; running it again adds an occurrence to the same issue, never a second issue. --clean deletes only data tagged blop.demo=true (its traces with their runs, occurrences and issue, and the demo memory node with its reads): without --yes it only counts them and exits 1.

```bash
blop demo [--clean [--yes]] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--clean` | Delete the demo data instead (a preview unless --yes) |  |  |
| `--yes` | With --clean, delete it |  |  |

JSON fields in `data`: `issue_id`, `app_span_id`, `agent_step_span_id`, `runs`, `trace_ids`, `preview`, `traces`, `spans`, `issues`, `memory_nodes`, `memory_reads`.

```bash
blop demo  # Record the demo failure, then run blop why --last
blop demo --clean  # Count the demo data that --clean --yes would delete
blop demo --clean --yes  # Delete the demo data, nothing else
```

See also: `blop why`, `blop delete`.

### blop setup

Set up every coding agent on this machine (blop setup agents)

blop setup doctor is a read-only whole-loop audit: collector/status, store, browser, runtime, agent recipes, git and binding. Start here when evidence looks empty; failures print exact next commands (exit 1), never auto-repair. blop setup agents detects installed coding agents and installs their supported user-global hooks, starting or reusing a local collector. New capture follows the existing full-content default; --capture metadata-only excludes bodies. Existing capture modes and exclusions are preserved when --capture is omitted. blop setup mcp <client> adds Blop's MCP server (blop mcp) to a coding agent: through the client's own command for Claude Code (claude mcp add), Codex (codex mcp add) and Gemini CLI (gemini mcp add), or by editing one entry in its JSON config for Cursor, VS Code, OpenCode and Pi (comments kept, the previous file copied to Blop's state dir, the file read back). Pi requires pi-mcp-adapter; OMP reads project .mcp.json natively. For Windsurf and Claude Desktop it prints the entry and never writes. First it starts the command and checks that Blop's MCP server answers; a command that would not start is never written (exit 6). A second run changes nothing; a different blop entry is replaced only with --force; --remove undoes it; --print writes nothing. With no client it lists the coding agents it finds and reports stale blop entries (an old pinned version, npx while blop is on PATH, a command that no longer exists) with the command that updates each.

```bash
blop setup <agents|doctor|mcp|plugin|opencode> [flags]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `agents` | Detect installed agents and install their supported global hooks | `blop setup agents [--capture full\|conversation-only\|metadata-only] [--url URL\|--port N] [--json]` |
| `doctor` | Read-only whole-loop environment audit with exact fix commands | `blop setup doctor [--url URL\|--port N] [--acknowledge-non-loopback] [--json]` |
| `plugin` | Prepare Codex or Claude Desktop hosted plugin setup | `blop setup plugin <codex\|claude-desktop> --app-url URL [--print\|--remove] [--force] [--allow-loopback-development] [--json]` |
| `mcp` | Add Blop's MCP server to claude, codex, cursor, vscode, opencode, pi, omp, gemini, windsurf, claude-desktop | `blop setup mcp [<client>\|all] [--scope local\|project\|user] [--print] [--force] [--remove] [--json]` |
| `opencode` | Configure and start OpenCode monitoring | `blop setup opencode [--port <n>] [--remove] [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--capture <mode>` | agents: capture mode for detected agents; existing choices are preserved when omitted Values: full, conversation-only, metadata-only. |  |  |
| `--scope <scope>` | mcp: where the entry goes: local, project or user (when omitted, the client decides) Values: local, project, user. |  |  |
| `--print` | Print the setup entry/package instructions, write nothing |  |  |
| `--force` | Replace a different existing Blop entry/package |  |  |
| `--remove` | Remove the selected Blop entry/package instead (opencode: take back its config edits and setup record) |  |  |
| `--app-url <url>` | plugin: hosted public HTTPS app origin |  |  |
| `--allow-loopback-development` | plugin: explicitly permit Codex loopback development |  |  |
| `--acknowledge-non-loopback` | doctor: acknowledge a non-loopback target (never contacts external hosts) |  |  |

```bash
blop setup agents  # Detect installed agents and install global hooks
blop setup mcp claude  # Let Claude Code read Blop issues over MCP
blop setup doctor --json  # Audit the whole local loop without changing anything
```

See also: `blop mcp`, `blop doctor`.

### blop init

Detect agent frameworks and print or write the OTel setup

```bash
blop init [--write] [--mcp <client>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--write` | Update .gitignore and .env.blop (nothing else is touched) |  |  |
| `--mcp <client>` | Then add Blop's MCP server to this coding agent: claude, codex, cursor, vscode, opencode, pi, omp, gemini, windsurf or claude-desktop (same as blop setup mcp <client>) Values: claude, codex, cursor, vscode, opencode, pi, omp, gemini, windsurf, claude-desktop. |  |  |

JSON fields in `data`: `write`, `detections`, `changed`, `mcp`.

```bash
blop init  # Print the setup lines for the frameworks found here
blop init --write  # Also update .gitignore and .env.blop
blop init --mcp claude  # Then let Claude Code read Blop issues over MCP
```

See also: `blop run`, `blop doctor`.

### blop test

Authored browser checks: init, add, list, run, watch

blop flows is the same group (ls means list). Aliases: test <spec>/run <spec> -> test run; watch/list -> test watch/list; init --flow -> test init. Evidence is launch provenance, never proof of a fix. Targets still come from the reviewed spec/config or --base-url. Use authorized systems and synthetic data.

```bash
blop test init|add|list|run|watch [patterns...] [flags]
```

Aliases: `blop flows`.

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `init` | Create a starter spec | `blop test init [file] [--force]` |
| `add` | Add another starter spec | `blop test add [file] [--force]` |
| `list` | List authored checks without a browser | `blop test list [patterns...] [--json]` |
| `ls` | Alias for list | `blop flows ls [patterns...] [--json]` |
| `run` | Run authored checks, optionally from local evidence | `blop flows run [patterns...] [--from trace <id>\|--from finding <code>] [flags]` |
| `watch` | Re-run checks when specs change | `blop test watch [patterns...] [flags]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `-u, --base-url <url>` | Base URL for the app under test (local, CI, staging, or HTTPS production) |  |  |
| `--report-dir <dir>` | Report output directory (default .blop) | .blop |  |
| `--coverage` | Collect executed JavaScript source coverage (Chromium only) |  |  |
| `--coverage-endpoint <url>` | Send coverage to this local collector base URL (requires --coverage) |  |  |
| `--progress-file <file>` | Append live NDJSON progress (test_start, action, frame, test_finish) |  |  |
| `--capture-screenshots` | Save a screenshot after each browser action (and stream live frames) |  |  |
| `--no-stream` | Disable the live CDP screencast (use per-action screenshots) |  |  |
| `--frame-interval <ms>` | Min ms between streamed frame progress lines (default 200) | 200 |  |
| `--force` | init/add: overwrite an existing spec without asking |  |  |
| `--headed` | Run browser headed |  |  |
| `--browser <name>` | Browser to run: chromium, camoufox, firefox or webkit Values: chromium, camoufox, firefox, webkit. |  |  |
| `--containerized` | Run the browser in a separate warm Docker container |  |  |
| `--viewport <size>` | Viewport as WIDTHxHEIGHT, for example 390x844 |  |  |
| `-c, --config <file>` | Config file path |  |  |
| `--provider <provider>` | Agent provider for the native agent loop (env BLOP_AGENT_PROVIDER) |  | `BLOP_AGENT_PROVIDER` |
| `--model <model>` | Agent model for the native agent loop (env BLOP_AGENT_MODEL) |  | `BLOP_AGENT_MODEL` |
| `--api-key <key>` | Agent API key for the native agent loop (env BLOP_AGENT_API_KEY) |  | `BLOP_AGENT_API_KEY` |
| `--max-steps <n>` | Optional hard cap on agent tool steps |  |  |
| `--workers <n>` | Run up to this many agent tests concurrently (default 1) | 1 |  |
| `-r, --reporter <reporter>` | Report format: basic, json, junit or all Values: basic, json, junit, all. |  |  |
| `--otel-endpoint <url>` | OTLP/HTTP endpoint for flow telemetry; setting it turns export on (env OTEL_EXPORTER_OTLP_ENDPOINT) |  | `OTEL_EXPORTER_OTLP_ENDPOINT` |
| `--otel-service-name <name>` | service.name on exported spans (default blop-runner, env OTEL_SERVICE_NAME) | blop-runner | `OTEL_SERVICE_NAME` |
| `--otel-environment <name>` | deployment.environment.name on exported telemetry |  |  |
| `--otel-propagate` | Send W3C traceparent to the app under test (also BLOP_OTEL_PROPAGATE_TO_APP=1) |  | `BLOP_OTEL_PROPAGATE_TO_APP` |
| `--otel-propagate-allowlist <hosts>` | Comma-separated hosts allowed to receive it (env BLOP_OTEL_PROPAGATE_ALLOWLIST) |  | `BLOP_OTEL_PROPAGATE_ALLOWLIST` |
| `-v, --verbose` | Print agent stream events in real time |  |  |
| `--from <kind id>` | Launch provenance: --from trace <id> or --from finding <code> |  |  |
| `--db <path>` | Existing local evidence database (env BLOP_MONITOR_DB_PATH) |  | `BLOP_MONITOR_DB_PATH` |
| `--since <duration>` | Evidence lookback, at most 24h (default 15m) | 15m |  |

```bash
blop test init  # Create a reviewed starter spec
blop flows run tests/checkout.blop.ts --from finding app_error --json  # Run with bounded local launch provenance
blop flows ls  # List authored checks
```

## Investigate commands

### blop issues

List issues, current branch first

```bash
blop issues [--branch <name>] [--state open|muted|fixed|all] [--failure-kind <kind>] [--limit <n>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--branch <name>` | Only issues seen on this branch |  |  |
| `--failure-kind <kind>` | Only issues whose sessions blop classify most often labeled app_error, tool_error, model_error, guardrail_denied or agent_error Values: app_error, tool_error, model_error, guardrail_denied, agent_error. |  |  |
| `--state <state>` | open (default), muted, fixed or all Values: open, muted, fixed, all. | open |  |
| `--limit <n>` | Maximum issues (default 50) | 50 |  |
| `--header` | Piped output: print the column names first |  |  |

JSON fields in `data`: `id`, `fingerprint`, `code`, `title`, `agent`, `service`, `severity`, `certainty`, `state`, `status`, `badges`, `occurrences`, `sessions`, `requests`, `on_branch`, `trend_24h`, `trend24h`, `trend7d`, `priority`, `first_seen_ms`, `last_seen_ms`, `first_seen_run_id`, `first_seen_commit`, `first_seen_branch`, `fixed_ms`, `regressed_ms`, `not_seen_in_latest_run`, `failure_kind`, `url`.

```bash
blop issues  # Open issues, current branch first
blop issues --json  # Current issues as JSON for a script or agent
blop issues --state all --header  # Tab-separated with a header row when piped
```

See also: `blop issue`, `blop tail`, `blop help json`.

### blop issue

Show one issue: causal chain, evidence and fix context

```bash
blop issue <issue-id> [--fix-context | --web] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--fix-context` | Print the issue's fix context (markdown) for a coding agent |  |  |
| `--web` | Open the issue in the inspector (same as blop open <issue-id>) |  |  |

JSON fields in `data`: `issue`, `status`, `badges`, `chain`, `occurrences`, `selected`, `nav`, `excerpt`, `different`, `activity`, `branches`, `run`, `runs`, `not_seen_in_latest_run`, `cli`, `fix_context_url`, `url`, `id`, `markdown`.

```bash
blop issue iss_0123abcd  # Causal chain, occurrences and the inspector link
blop issue iss_0123abcd --fix-context  # Markdown to paste into a coding agent
blop issue iss_0123abcd --web  # Open it in the inspector
```

See also: `blop issues`, `blop trace`, `blop open`, `blop mcp`.

### blop why

Explain a failure: what broke, where, why, and which memory was read

Explains one failure with ids: the issue (what broke), the agent step span and the app span it made fail (where), the MAST failure mode or none with a reason, plus the failure kind and where it came from (why), and the memory reads recorded for that session. With no id (or --last) it explains the newest failing run in this repo (real runs before demo runs) through its newest issue, else the newest open issue in this repo or with no project. --all-projects widens that to every project. It ends with the next command and an inspector link. An id this collector does not hold exits 4.

```bash
blop why [<run|issue|session|trace id> | --last] [--all-projects] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--last` | Explain the newest failing run in this repo (the default) |  |  |
| `--all-projects` | With --last, look at runs and issues of every project |  |  |

JSON fields in `data`: `schema`, `target`, `demo`, `issue`, `where`, `why`, `memory`, `next`, `links`, `reason`.

```bash
blop why  # The newest failure in this repo
blop why iss_0123abcd  # One issue
blop why --last --all-projects --json  # The newest failure anywhere, for a coding agent
```

See also: `blop issue`, `blop issues`, `blop open`.

### blop runs

List the runs blop run recorded, or inspect one against the previous run

Lists the runs `blop run` recorded in this repo, newest first: status, command, branch, when, how long and the issues each run first saw. Runs from other projects, or recorded with no project, are left out and counted on stderr; --all-projects shows them. A run Blop's demo seeded carries (demo). --failed keeps runs that exited non-zero without being stopped by a signal. `blop runs show <id>` prints one run with the issues it saw and how it differs from the previous run of the same command on the same branch; --timeline adds its spans in time order (at most 200). Each answer ends with the next command and an inspector link. An id this collector does not hold exits 4.

```bash
blop runs [--failed] [--since <duration>] [--limit <n>] [--branch <name>] [--all-projects] [--json]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `show` | One run, compared with the previous run of the same command on the branch | `blop runs show <run-id> [--timeline] [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--failed` | Only runs that failed (a non-zero exit, not stopped by a signal) |  |  |
| `--since <duration>` | Only runs started within this window, e.g. 15m, 1h, 2d, 7d |  |  |
| `--limit <n>` | Maximum runs, 1 to 200 (default 20) | 20 |  |
| `--branch <name>` | Only runs on this branch |  |  |
| `--all-projects` | Runs of every project, not only this repo |  |  |
| `--header` | Piped output: print the column names first |  |  |
| `--timeline` | show: also list the run's spans in time order |  |  |

JSON fields in `data`: `schema`, `scope`, `filters`, `runs`, `hidden_elsewhere`, `next`, `links`.

```bash
blop runs  # This repo's recent runs
blop runs --failed --since 1h  # What failed in the last hour
blop runs show run_abcdefghijklmnopqrst --timeline  # One run, its comparison and its spans
```

See also: `blop why`, `blop run`, `blop issues`.

### blop tail

Stream new issues, runs and sessions as they happen

```bash
blop tail [-o text|ndjson] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |

JSON fields in `data`: `schema_version`, `type`, `reason`, `id`, `title`, `url`, `state`, `status`, `exit_code`, `signal`, `end_reason`, `kind`, `trace_id`, `service`.

```bash
blop tail  # Watch new issues, runs and sessions as they happen
blop tail -o ndjson  # One JSON event per line (--json is the same)
```

See also: `blop issues`.

### blop open

Open the inspector at an issue, session, run or trace

Opens the inspector page of an issue (iss_...), session (ses_...), run (run_...) or trace (32 hex), or a page: home (the default), sessions, issues, runs, connect or settings, on the collector this folder resolves to. A path starting with / (what the web app's blop open chip copies, e.g. /map?env=production&range=24h) opens that screen of the hosted app the blop auth profile (--profile, default "default") is signed in to. It prints the URL instead of opening a browser with --print or --json, for a coding agent, with --no-input, with BROWSER=none, over SSH and where there is no display. It does not check that the object exists.

```bash
blop open [<issue|session|run|trace id> | <page> | /<web path>] [--profile NAME] [--print] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--print` | Print the URL, do not open a browser |  |  |
| `--profile <name>` | The blop auth profile whose hosted app a /path opens on |  |  |

JSON fields in `data`: `url`, `kind`, `id`, `view`, `opened`.

```bash
blop open  # The inspector's Home
blop open iss_0123abcd  # One issue
blop open runs --print  # Print the Runs page URL (for SSH)
```

See also: `blop issue`, `blop issues`, `blop up`.

### blop evaluation

Author source-scoped scores and review annotation queues locally

Explicit local authoring, not hosted authority or MCP writes. Grants bind one recorded source, principal and permission set for at most 24 hours. Feedback credentials stay in a trusted backend, never browser code. Every mutation names a stable idempotency key and updates name an expected revision. Corrections never replace recorded output.

```bash
blop evaluation <grant|revoke|call> [flags]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `grant` | Issue a bounded source grant as the local database OS owner | `blop evaluation grant --db PATH --input FILE --token-file NEW_FILE [--json]` |
| `revoke` | Revoke one local grant immediately | `blop evaluation revoke <grant-id> --db PATH [--json]` |
| `call` | Call the local evaluation HTTP owner with a source-scoped grant | `blop evaluation call <action> --input FILE_OR_DASH --token-file FILE --url URL [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--input <file-or-dash>` | Strict JSON input file or - for stdin (maximum 32 KiB) |  |  |
| `--db <path>` | Explicit local collector database for OS-owner grant administration only |  |  |
| `--token-file <path>` | Private local evaluation credential file; grant creates it exclusively with mode 0600 |  |  |

```bash
blop evaluation grant --db /tmp/review/telemetry.sqlite --input grant.json --token-file /tmp/review/reviewer.key --json  # Create exact-source local human/producer authority without printing the credential
blop evaluation call subject --input subject.json --token-file /tmp/review/reviewer.key --url http://127.0.0.1:27811 --json  # Resolve an immutable source reference before annotating
blop evaluation call scores.put --input score.json --token-file /tmp/review/reviewer.key --url http://127.0.0.1:27811 --json  # Author a typed score through the actual local HTTP surface
```

### blop report

Render a bounded local evidence packet without network access

One local read-only snapshot; no collector discovery, startup, HTTP, analysis, or upload. Findings are stored issues, flows are retained SDK scenario spans. Outcomes and verification are separate: unknown is never success. --until pins the window; identical evidence and options render identically. JSON generated_at is the window end, not the rendering clock. Save stdout to share; publication is a separate explicit operation.

```bash
blop report [--since 2h] [--scope service|session|finding] [--format markdown|junit|json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--db <path>` | Local collector database (otherwise project/environment configuration) (env BLOP_MONITOR_DB_PATH) |  | `BLOP_MONITOR_DB_PATH` |
| `--since <duration>` | Window duration, 1m through 1d (default 2h) | 2h |  |
| `--until <timestamp>` | Fixed exclusive window end for reproducible rendering (ISO UTC) |  |  |
| `--scope <kind>` | Scope kind: service, session or finding; requires its matching selector Values: service, session, finding. |  |  |
| `--service <name>` | Exact service name with --scope service |  |  |
| `--session <id>` | Exact recorded session ID with --scope session |  |  |
| `--finding <id>` | Exact stored issue/finding ID with --scope finding |  |  |
| `--format <format>` | Packet format: markdown (default), junit or json Values: markdown, junit, json. | markdown |  |
| `--limit <n>` | Source rows per section, 1–100 (default 20) | 20 |  |
| `--max-bytes <n>` | Whole output byte cap, 4096–262144 (default 65536) | 65536 |  |

JSON fields in `data`: `window`, `collector`, `scope`, `limits`, `coverage`, `unavailable`, `truncated`, `reproduce`, `services`, `errors`, `logs`, `findings`, `flows`.

```bash
blop report --since 2h --format markdown  # Print local evidence for a PR or agent handoff
blop report --scope service --service checkout --format junit  # Render service evidence for CI (no upload)
blop report --since 2h --until 2026-10-21T12:00:00Z --format json  # Pin a window for deterministic rendering
```

### blop failure-context

Read bounded source-scoped failure evidence without diagnosing a cause

One read-only local-plane snapshot. Source plus at least one selector is required; selectors intersect. Metadata only, with exact IDs, deterministic ranks/reasons, capture coverage and next queries. No inferred links, hosted runs, model diagnosis or verification. Repeat with both --until and --revision; an invalidated snapshot is an explicit conflict. Empty evidence is not a passing check. JSON generated_at is the pinned window end.

```bash
blop failure-context --source KEY [--trace ID|--service NAME|--session ID|--attempt ID] [--since 15m] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--source <key>` | Exact 64-hex source key from /api/observations/sources |  |  |
| `--trace <id>` | Exact 32-hex retained trace ID |  |  |
| `--span <id>` | Exact 16-hex span ID within the selected scope |  |  |
| `--log <id>` | Exact retained decimal log ID within the selected scope |  |  |
| `--service <name>` | Exact service name within the source |  |  |
| `--session <id>` | Exact recorded session, never a timestamp association |  |  |
| `--attempt <id>` | Exact recorded attempt; absent identity remains unknown |  |  |
| `--since <duration>` | Bounded window duration, 1m through 1d (default 15m) | 15m |  |
| `--until <timestamp>` | Pinned exclusive window end (ISO UTC) |  |  |
| `--revision <revision>` | Require this evidence revision; stale snapshots are rejected |  |  |
| `--limit <n>` | Maximum symptoms, 1–100 (default 20) | 20 |  |
| `--max-bytes <n>` | Data byte cap, 4096–262144 (default 65536) | 65536 |  |
| `--deadline-ms <ms>` | Server read deadline, 1–5000 ms (default 2000) | 2000 |  |
| `--db <path>` | Read an existing local database instead of HTTP; no collector startup |  |  |

JSON fields in `data`: `schema_version`, `state`, `source`, `collector`, `window`, `scope`, `limits`, `coverage`, `symptoms`, `associations`, `verification`, `independently_recorded_outcomes`, `unavailable`, `next`, `truncated`.

```bash
blop failure-context --source "$SOURCE" --trace "$TRACE" --since 15m --json  # Read a standalone application failure
blop failure-context --source "$SOURCE" --session "$SESSION" --until "$END" --revision "$REVISION" --json  # Require the exact retained snapshot
```

### blop map

Show the agent map: who hands work to whom, which apps they touch

Reads the collector's agent map over a window: coding-agent sessions and named agents (OTel invoke_agent spans) with runs per hour, error rate and p95, the apps their requests reached, and handoffs recorded by exact parent ids (a parent span, or the parent session a hook reported). Agents active at the same time are never connected.

```bash
blop map [--range 1h|24h|7d|30d] [--env <name>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--range <range>` | Window: 1h, 24h (default), 7d or 30d |  |  |
| `--env <name>` | Only runs that recorded this deployment.environment.name |  |  |

```bash
blop map  # The last 24 hours, every environment
blop map --range 7d --env production --json  # A week of production, machine-readable
```

See also: `blop session`, `blop open`.

### blop events

Show product events: what users did in your app, and how the newest version changed it

Reads the collector's product events over a window: OTel log records that carry an event name (the OTLP event_name field or an event.name attribute), counted per event, with the apps that sent them. When an app's newest service.version was first seen inside the window, each of that app's events also shows its count before and after, over equal windows; the version names the coding agent whose run carried it in the same trace, else none. Names and counts only, never a record's body.

```bash
blop events [--range 1h|24h|7d|30d] [--env <name>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--range <range>` | Window: 1h, 24h (default), 7d or 30d |  |  |
| `--env <name>` | Only events that recorded this deployment.environment.name |  |  |

```bash
blop events  # The last 24 hours, every environment
blop events --range 7d --env production --json  # A week of production, machine-readable
```

See also: `blop map`, `blop init`, `blop open`.

### blop classify

Label agent runs with intent, outcome and failure kind (a local batch job)

run (the default) labels the window's coding-agent sessions and named agents as blop.class.intent (change, operate, explore, converse, unknown), blop.class.outcome (success, failure, running) and blop.class.failure_kind (app_error, tool_error, model_error, guardrail_denied, agent_error). Labels are structural and deterministic: outcome and failure kind come from recorded status, errors and guardrail stops, intent from the tools a run called. --llm lets the configured chat provider (BLOP_AGENT_PROVIDER, _MODEL, _API_KEY; default a free OpenRouter model, BLOP_CLASSIFY_MODEL to override) refine intent from the first retained prompt, for full-capture sessions only. Labels feed Issues, the Agent Map and alert filters; they are evidence aids, not verdicts. list reads the stored labels. Runs outside the collector, which need not be running.

```bash
blop classify [run|list] [--range 1h|24h|7d|30d] [--llm] [--relabel] [--failure-kind <kind>] [--outcome <o>] [--intent <i>] [--agent <id>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--range <range>` | Window: 1h, 24h (default), 7d or 30d Values: 1h, 24h, 7d, 30d. |  |  |
| `--llm` | run: refine intent with the configured model (full-capture sessions only) |  |  |
| `--relabel` | run: label again runs this version already labeled |  |  |
| `--failure-kind <kind>` | list: only this failure kind: app_error, tool_error, model_error, guardrail_denied or agent_error Values: app_error, tool_error, model_error, guardrail_denied, agent_error. |  |  |
| `--outcome <outcome>` | list: only this outcome: success, failure or running Values: success, failure, running. |  |  |
| `--intent <intent>` | list: only this intent: change, operate, explore, converse or unknown Values: change, operate, explore, converse, unknown. |  |  |
| `--agent <id>` | list: only this map agent, e.g. harness:claude-code |  |  |
| `--limit <n>` | list: at most this many (1-1000, default 200) |  |  |

```bash
blop classify  # Label the last 24 hours of runs
blop classify list --failure-kind tool_error --json  # Runs that failed on a tool, machine-readable
BLOP_AGENT_API_KEY=... blop classify --llm --range 7d  # Refine a week of intents with the free default model
```

See also: `blop issues`, `blop map`, `blop alerts`.

### blop alerts

Alert rules on agent telemetry: list, add, pause, test and route them

Rules watch one Agent Map metric (agent_error_rate, agent_p95_ms, app_outcome, handoff_failure_share, memory_low_trust_reads, agent_guardrail_denials) over 1h or 24h, on one node (--target) or the worst one. The collector evaluates them every minute and records each change into or out of firing. blop alerts connect --profile NAME --project ID sends firings to the hosted app with that blop auth profile, which posts them to the project's Slack route; without it they stay local. The same link sends the commits an agent made in a blop run (ids only) to GitHub & CI's Agent-authored view. Rates take 25% or 0.25; p95 takes milliseconds.

```bash
blop alerts [list|add|enable|disable|remove|test|connect] [<rule-id>] [flags]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--name <text>` | Rule name (add) |  |  |
| `--metric <metric>` | Metric (add): agent_error_rate, agent_p95_ms, app_outcome, handoff_failure_share, memory_low_trust_reads or agent_guardrail_denials Values: agent_error_rate, agent_p95_ms, app_outcome, handoff_failure_share, memory_low_trust_reads, agent_guardrail_denials. |  |  |
| `--above <value>` | Fire when the value is above this (add) |  |  |
| `--below <value>` | Fire when the value is below this (add) |  |  |
| `--target <id>` | One map node or edge id (add), e.g. agent:harness:claude-code; default the worst one |  |  |
| `--range <range>` | Window (add): 1h (default) or 24h Values: 1h, 24h. |  |  |
| `--severity <severity>` | Severity (add): critical, warning or info Values: critical, warning, info. |  |  |
| `--failure-kind <kind>` | agent_error_rate (add): count only runs blop classify labeled app_error, tool_error, model_error, guardrail_denied or agent_error Values: app_error, tool_error, model_error, guardrail_denied, agent_error. |  |  |
| `--send` | test: also deliver a marked test firing to the connected destination |  |  |
| `--profile <name>` | connect: the blop auth profile that delivers firings |  |  |
| `--project <id>` | connect: the hosted project whose Slack route gets them |  |  |
| `--disconnect` | connect: keep firings local again |  |  |

```bash
blop alerts add --name "Agent failing" --metric agent_error_rate --above 25% --severity critical  # Fire when any agent's error rate passes 25% over the last hour
blop alerts add --name "Checkout outcome" --metric app_outcome --below 85% --target app:checkout-web  # Watch one app's outcome
blop alerts connect --profile team --project <project-id>  # Send firings to the project's Slack route through the hosted app
blop alerts test alr_0123456789abcdef --send  # Evaluate now and send a marked test firing
```

See also: `blop map`, `blop auth`.

### blop session

Show one coding-agent session as an agent graph

```bash
blop session [<session-id>|<trace-id>] [--steps] [--view tree|dag] [--limit <n>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--conversation <id>` | A span-only agent conversation id (with --service) |  |  |
| `--service <name>` | The agent service that carried --conversation |  |  |
| `--steps` | One node per step instead of grouping repeats |  |  |
| `--view <view>` | Draw the graph as a box tree or an ASCII flowchart |  |  |
| `--limit <n>` | Maximum graph nodes |  |  |

```bash
blop session  # The newest session as an agent tree
blop session ses_8f2 --view dag  # As a flowchart
blop session 4bf92f3577b34da6a3ce929d0e0e4736 --steps --json  # Every step, machine-readable
```

See also: `blop trace`, `blop issue`, `blop open`.

### blop replay

Step through one coding-agent session: prompts, model turns, tool calls and edit diffs

Reads one session's recorded steps in order from the local collector: each prompt, model turn and tool call with its status and timing, and, where the capture policy recorded content, the prompt text, the tool's input and output, and an edit's diff. Content stays local: the hosted app shows the same replay without it. A session captured metadata-only or conversation-only says so and prints the command that turns full capture on. Without an id it replays the newest session; --conversation takes a Claude Code or Codex session id (the hook service by default).

```bash
blop replay [<session-id>|<trace-id>|--conversation <id> [--service <name>]] [--step <n>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--conversation <id>` | A hook-captured session id (the host's session id) |  |  |
| `--service <name>` | The service that carried --conversation (default blop-agent-hook) |  |  |
| `--step <n>` | Only this step, with its full captured content |  |  |

```bash
blop replay  # The newest session, step by step
blop replay --conversation 2f1c9a7e-4b1d-4b7e-9f0e-3c6d1a2b8e90 --step 12  # One step of a Claude Code session, with its diff
blop replay ses_8f2 --json  # Every step, machine-readable
```

See also: `blop session`, `blop agents`, `blop open`.

### blop trace

Print one trace as a span tree

```bash
blop trace <trace-id> [--include logs] [--web] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--include <list>` | Also include, comma separated (logs) |  |  |
| `--web` | Open the trace in the inspector (same as blop open <trace-id>) |  |  |

```bash
blop trace 4bf92f3577b34da6a3ce929d0e0e4736 --include logs  # Spans plus their logs
blop trace 4bf92f3577b34da6a3ce929d0e0e4736 --web  # Open it in the inspector
blop session <trace-id>  # The same trace as an agent graph
```

See also: `blop issue`, `blop open`, `blop help query`.

### blop metrics

Exact retained OTLP metric points and per-series totals

Reads bounded durable metric facts, preserving exact numeric and nanosecond strings. Totals remain per series, with known/unknown provenance; they are never added to span-derived usage. Use --source to isolate an exact recorded source. A missing cost or currency is not inferred.

```bash
blop metrics [--session <id>] [--source <key>] [--since 1h|all] [--name <name>] [--worktree <path>] [--limit <n>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--session <id>` | Exact recorded session ID (not inferred from traces) |  |  |
| `--source <key>` | Exact 64-hex recorded source key |  |  |
| `--since <duration>` | Positive integer duration in s, m, h or d, or all (default 24h) | 24h |  |
| `--name <name>` | Exact metric name |  |  |
| `--worktree <path>` | Exact recorded worktree |  |  |
| `--limit <n>` | Maximum raw points, 1 to 10000 (default 100) | 100 |  |

JSON fields in `data`: `filters`, `window`, `points`, `totals`, `truncated`, `limit`, `revision`.

```bash
blop metrics --session SESSION --source SOURCE_KEY --since 1h --json  # Exact source-scoped metric facts and totals
```

See also: `blop usage`, `blop open`, `blop help json`.

### blop usage

Token usage per service, agent or model

Sums the token counters already retained on spans (gen_ai.usage.*, codex.turn.token_usage.*). A counter no span reported is unknown, never 0; spans without usage count only in coverage. Input includes cache read/write and output includes reasoning. Cost remains unknown in this span report; blop metrics reads separate recorded metric facts.

```bash
blop usage [--since 1h|24h|all] [--service <name>] [--agent <id>] [--group-by service|agent|model] [--limit <n>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--since <duration>` | Window: a duration such as 1h or 24h, or all (default 24h) | 24h |  |
| `--service <name>` | Only this service |  |  |
| `--agent <id>` | Only spans with this blop.agent.id |  |  |
| `--group-by <field>` | Group by service (default), agent or model Values: service, agent, model. | service |  |
| `--limit <n>` | Maximum groups, 1 to 100 (default 20) | 20 |  |

JSON fields in `data`: `window`, `group_by`, `filters`, `coverage`, `totals`, `cost`, `groups`, `truncated`, `limit`.

```bash
blop usage  # Tokens per service over the last 24 hours
blop usage --since all --group-by model  # Tokens per model over everything retained
blop usage --agent codex --json  # One agent's tokens as a blop.cli/v1 document
```

See also: `blop traces`, `blop help json`.

## Agents commands

### blop mcp

Serve issues and sessions to a coding agent over MCP (stdio)

The default local read-only MCP server preserves list_issues, get_issue, get_fix_context and get_session, and adds bounded authored-memory reads without implicit model downloads. It speaks both MCP eras: initialize (2024-11-05 to 2025-11-25) and the stateless 2026-07-28 revision (server/discover, per-request _meta). Each call reads the collector of the client's project: BLOP_PROJECT_DIR, else CLAUDE_PROJECT_DIR, else the working directory; --url or BLOP_MONITOR_URL pins one. When several collectors run and none matches, a call says which run and how to choose (BLOP_MONITOR_URL); it never guesses. Add it to a coding agent with blop setup mcp <client> (claude, codex, cursor, vscode, opencode, pi, omp, gemini, windsurf, claude-desktop). Use --target web --profile NAME only for the optional official-SDK bridge to hosted management; it preserves actual enabled schemas and browser approvals, never fetches local telemetry through the web, and never automatically retries a write.

```bash
blop mcp [--url <collector-url>] [--target web --profile NAME]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--target <target>` | MCP authority: local (default) or web; local remains read-only Values: local, web. | local |  |
| `--profile <name>` | Hosted origin/workspace-bound OAuth profile (web target only) |  |  |

```bash
blop setup mcp claude  # Register Blop with Claude Code (or any other client)
claude mcp add blop -- blop mcp  # By hand; blop must be on PATH
blop setup mcp  # List coding agents and whether blop is registered (and up to date) in each
```

See also: `blop setup mcp`, `blop issues`, `blop issue`.

### blop claude

Start Claude Code with Blop capture wired

Starts Claude Code with its terminal and exit code: ensures the Blop collector runs, wires Claude Code into Blop for this repo when it is not connected yet (its hooks, Blop's MCP server and the capture binding, project scope, never a prompt; the first launch lists on stderr every file it changed), then runs claude. It fails open: if the collector cannot start or the wiring is refused (a symlinked settings file, drift, a conflicting entry), one warning on stderr names the problem and the fix, and claude starts anyway without capture. To wire an agent without launching it, use blop agents setup and blop setup mcp. Arguments after -- go to claude; without --, every argument but --no-connect does. Before --, only --no-connect, -p <n> and --url <url> are accepted. Blop's help is this page: for Claude Code's own, run blop claude -- --help. A missing claude binary exits 127 with an install hint.

```bash
blop claude [--no-connect] [-p <n> | --url <url>] [-- <claude args>]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--no-connect` | Do not connect Claude Code to Blop first; just start it (capture runs only if it is already connected) |  |  |

```bash
blop claude  # Start Claude Code, connected to Blop
blop claude -- --resume abc  # Pass arguments to Claude Code
blop claude --no-connect -- --help  # Claude Code's own help, without connecting anything
```

See also: `blop agents setup`, `blop setup mcp`, `blop run`.

### blop codex

Start Codex with Blop capture wired

Starts Codex with its terminal and exit code: ensures the Blop collector runs, wires Codex into Blop for this repo when it is not connected yet (its hooks, Blop's MCP server and the capture binding, project scope, never a prompt; the first launch lists on stderr every file it changed), then runs codex. It fails open: if the collector cannot start or the wiring is refused (a symlinked settings file, drift, a conflicting entry), one warning on stderr names the problem and the fix, and codex starts anyway without capture. To wire an agent without launching it, use blop agents setup and blop setup mcp. Arguments after -- go to codex; without --, every argument but --no-connect does. Before --, only --no-connect, -p <n> and --url <url> are accepted. Blop's help is this page: for Codex's own, run blop codex -- --help. A missing codex binary exits 127 with an install hint.

```bash
blop codex [--no-connect] [-p <n> | --url <url>] [-- <codex args>]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--no-connect` | Do not connect Codex to Blop first; just start it (capture runs only if it is already connected) |  |  |

```bash
blop codex  # Start Codex, connected to Blop
blop codex -- resume --last  # Pass arguments to Codex
blop codex --no-connect -- --help  # Codex's own help, without connecting anything
```

See also: `blop agents setup`, `blop setup mcp`, `blop run`.

### blop opencode

Start OpenCode with Blop capture wired

Starts OpenCode with its terminal and exit code: ensures the Blop collector runs, wires OpenCode into Blop for this repo when it is not connected yet (its hooks, Blop's MCP server and the capture binding, project scope, never a prompt; the first launch lists on stderr every file it changed), then runs opencode. It fails open: if the collector cannot start or the wiring is refused (a symlinked settings file, drift, a conflicting entry), one warning on stderr names the problem and the fix, and opencode starts anyway without capture. To wire an agent without launching it, use blop agents setup and blop setup mcp. Arguments after -- go to opencode; without --, every argument but --no-connect does. Before --, only --no-connect, -p <n> and --url <url> are accepted. Blop's help is this page: for OpenCode's own, run blop opencode -- --help. A missing opencode binary exits 127 with an install hint.

```bash
blop opencode [--no-connect] [-p <n> | --url <url>] [-- <opencode args>]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--no-connect` | Do not connect OpenCode to Blop first; just start it (capture runs only if it is already connected) |  |  |

```bash
blop opencode  # Start OpenCode, connected to Blop
blop opencode -- --model anthropic/claude-sonnet-4  # Pass arguments to OpenCode
blop opencode --no-connect -- --help  # OpenCode's own help, without connecting anything
```

See also: `blop agents setup`, `blop setup mcp`, `blop run`.

### blop memory

Recall authored memory and read-only Markdown knowledge

Unbound reads use the accountless local graph. An explicit repository binding selects hosted reads across subdirectories/worktrees; --scope local stays offline. Bindings contain no credentials and never upload local files. Writes retain explicit scope/profile requirements and expected revisions; organization policy changes require browser approval.

```bash
blop memory <context|search|get|reads|neighbors|history|skills|bind|binding|unbind|markdown|index|add|edit|patch|batch|retire|restore|purge|propose|publish> [flags]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `bind` | Bind this Git repository/worktrees to a verified hosted memory project | `blop memory bind --profile NAME --project ID [--json]` |
| `binding` | Inspect credential-free repository memory destination, offline | `blop memory binding [--json]` |
| `unbind` | Remove this repository memory destination without deleting knowledge | `blop memory unbind [--json]` |
| `markdown` | Initialize, attach, index, list or detach a read-only local Markdown source (no model) | `blop memory markdown <init\|attach\|index\|list\|detach> [folder\|attachmentId] [--project ID] [--json]` |
| `context` | Read live graph context | `blop memory context [--text TEXT] [--scope local\|organization] [--profile NAME] [--project ID] [--json]` |
| `search` | Read live graph search | `blop memory search [--text TEXT] [--scope local\|organization] [--profile NAME] [--project ID] [--json]` |
| `get` | Read one node or bounded document section | `blop memory get <nodeId> [--revision N] [--field SECTION] [--body-offset N] [--body-length N] [--scope organization --profile NAME] [--json]` |
| `reads` | Count which agents read which nodes (ids and counts, never content) | `blop memory reads [--project ID] [--node ID] [--agent ID] [--range 1h\|24h\|7d\|30d] [--scope organization --profile NAME] [--json]` |
| `neighbors` | Read node neighbors | `blop memory neighbors <nodeId> [--scope organization --profile NAME] [--limit N] [--cursor CURSOR] [--json]` |
| `history` | Read node history | `blop memory history <nodeId> [--scope organization --profile NAME] [--limit N] [--cursor CURSOR] [--json]` |
| `skills` | Progressive procedure lookup: list or get | `blop memory skills <list\|get> [nodeId] [--document ID] [--field SECTION] [--scope organization --profile NAME] [--json]` |
| `index` | Explicitly index memory with current pinned model status | `blop memory index [--scope organization --profile NAME] [--project ID] [--json]` |
| `add` | Add memory with flags or a shared graph change document | `blop memory add (--kind KIND --title TEXT --body TEXT [--tags a,b] [--id namespace:name] \| --input FILE_OR_DASH) [--project ID] [--scope organization --profile NAME] [--json]` |
| `patch` | Explicit patch using the shared graph change schema | `blop memory patch --input FILE_OR_DASH [--scope organization --profile NAME] [--project ID] [--idempotency-key KEY] [--expected-policy-revision N] [--json]` |
| `edit` | Explicit edit using the shared graph change schema | `blop memory edit --input FILE_OR_DASH [--scope organization --profile NAME] [--project ID] [--idempotency-key KEY] [--expected-policy-revision N] [--json]` |
| `batch` | Explicit batch using the shared graph change schema | `blop memory batch --input FILE_OR_DASH [--scope organization --profile NAME] [--project ID] [--idempotency-key KEY] [--expected-policy-revision N] [--json]` |
| `retire` | Explicit retire using the shared graph change schema | `blop memory retire --input FILE_OR_DASH [--scope organization --profile NAME] [--project ID] [--idempotency-key KEY] [--expected-policy-revision N] [--json]` |
| `restore` | Explicit restore using the shared graph change schema | `blop memory restore --input FILE_OR_DASH [--scope organization --profile NAME] [--project ID] [--idempotency-key KEY] [--expected-policy-revision N] [--json]` |
| `purge` | Explicit purge using the shared graph change schema | `blop memory purge --input FILE_OR_DASH [--scope organization --profile NAME] [--project ID] [--idempotency-key KEY] [--expected-policy-revision N] [--json]` |
| `propose` | Explicit propose using the shared graph change schema | `blop memory propose --input FILE_OR_DASH [--scope organization --profile NAME] [--project ID] [--idempotency-key KEY] [--expected-policy-revision N] [--json]` |
| `publish` | Preview/publish one selected authored node or Markdown snapshot | `blop memory publish <nodeId> --profile NAME --project ID [--dry-run] [--reviewed-hash SHA256] [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--input <file-or-dash>` | Finite JSON input file, or - for stdin (maximum 1 MiB) |  |  |
| `--idempotency-key <key>` | Retained unique key for the exact write attempt |  |  |
| `--expected-policy-revision <revision>` | Reviewed live policy revision; stale revisions are rejected |  |  |
| `--profile <name>` | Named origin/workspace-bound OAuth profile (default default) | default |  |
| `--kind <kind>` | Kind of memory to add: entity, document, finding, decision, rule or procedure; cannot combine with --input Values: entity, document, finding, decision, rule, procedure. |  |  |
| `--title <text>` | Memory title; required with --kind |  |  |
| `--body <text>` | Memory body; required with --kind |  |  |
| `--tags <a,b>` | Comma-separated tags for convenience add |  |  |
| `--id <namespace:name>` | Explicit memory identity; default local: plus SHA-256 of JSON.stringify([title, body]) in UTF-8 |  |  |
| `--scope <scope>` | Authority plane: local or organization; overrides repository read binding; organization requires a profile Values: local, organization. | local unless bound |  |
| `--project <id>` | Explicit project ID selector (not authorization) |  |  |
| `--limit <n>` | Bounded page size |  |  |
| `--cursor <cursor>` | Opaque page cursor |  |  |
| `--text <text>` | Context or search query text |  |  |
| `--revision <n>` | Exact stored node revision |  |  |
| `--document <id>` | Load one document explicitly referenced by the selected procedure |  |  |
| `--field <section>` | Address content or complete metadata JSON without losing omitted references Values: body, whenToUse, procedure, pitfalls, verification, metadata. |  |  |
| `--body-offset <n>` | Content/metadata section offset in Unicode code points |  |  |
| `--body-length <n>` | Maximum section length (1–4,000 Unicode code points; byte limits may shorten it) |  |  |
| `--reviewed-hash <sha256>` | Hash of the exact reviewed publication payload |  |  |
| `--dry-run` | Preview exact selected content without publishing |  |  |
| `--agent <id>` | Agent id recorded with this read (default $BLOP_AGENT_ID); for reads, filter by it |  |  |
| `--session <id>` | Session id recorded with this read (default $BLOP_SESSION_ID) |  |  |
| `--node <id>` | Only reads of this node |  |  |
| `--range <range>` | Read-log window: 1h, 24h (default), 7d or 30d Values: 1h, 24h, 7d, 30d. | 24h |  |

```bash
blop memory context --json  # Recall local knowledge without an account
blop memory context --scope organization --profile team --project project-id --json  # Read hosted authority explicitly
blop memory reads --range 7d --json  # See which agents read which memory nodes
blop memory publish local:finding --profile team --project project-id --dry-run --json  # Review the exact payload before sharing
```

### blop prompts

Author, version, label and fetch prompts in a local registry

Local and account-free: no network, no model, no hosted authority. Prompts live in prompts.db beside the telemetry store and never change capture or retention. Versions are immutable and numbered from 1; create always moves the managed latest label. Labels start with a letter, so a label can never be read as a version, and get refuses --version together with --label. A missing prompt, version or label exits 2 with no fallback. get reports its selector's cache entry: cold (never fetched), fresh (within --cache-ttl and the same version), stale (expired, or the label moved) or disabled (--cache-ttl 0). Up to 10,000 prompts, 1,000 versions and 32 labels each; a full registry exits 4. JSON data (blop.cli/v1): list gives prompts[] of {name, version, versions, labels[{label, version}], sha256, bytes, updated_at} with page {limit, returned, truncated}; get gives name, version, selector {kind, value}, labels, content, sha256, bytes, created_at and cache {status, reason, ttl_seconds, previous_version, previous_fetched_at}; create gives name, version, labels, sha256, bytes, created_at; label gives name, label, version, previous_version.

```bash
blop prompts <list|get|create|label> [flags]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `list` | List prompts, one line each, in name order | `blop prompts list [--name <name>] [--label <label>] [--limit <n>] [--json]` |
| `get` | Fetch one version by label (default latest) or number | `blop prompts get <name> [--version <n> \| --label <label>] [--cache-ttl <seconds>] [--json]` |
| `create` | Store the next immutable version from a file | `blop prompts create <name> --file <path> [--label <label>] [--json]` |
| `label` | Point a label at an existing version | `blop prompts label <name> <version> <label> [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--name <name>` | Only the prompt with this exact name |  |  |
| `--label <label>` | list: only prompts carrying this label; get: fetch the version it names; create: also assign it |  |  |
| `--limit <n>` | Most prompts to list (1-200) (default 50) | 50 |  |
| `--version <n>` | Fetch this exact immutable version |  |  |
| `--cache-ttl <seconds>` | Seconds a fetched selector stays fresh (0 disables the cache, maximum 86400) (default 60) | 60 |  |
| `--file <path>` | UTF-8 prompt text, or - for stdin (maximum 64 KiB) |  |  |

```bash
blop prompts create support/triage --file triage.md --label staging  # Store a new version and label it staging
blop prompts label support/triage 3 production  # Promote version 3 to production
blop prompts get support/triage --label production --json  # Fetch the production version with its cache status
blop prompts list --label production  # One line per prompt that has a production label
```

See also: `blop memory`, `blop help json`.

### blop agents

Detect, configure, or launch a coding agent

```bash
blop agents list|status|doctor|info|setup|install-hooks|run|capture-policy|env|hook-config [<id>] [flags]
```

Aliases: `blop agent`.

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `list` | Detect installed coding agents | `blop agents list` |
| `detect` | Detect installed coding agents | `blop agents detect` |
| `status` | Show detection, selected-scope configuration and capture evidence separately | `blop agents status [--scope global\|project] [--project <local-id>]` |
| `doctor` | Diagnose the selected capture scope; never starts a collector or calls a provider | `blop agents doctor <id> [--scope global\|project] [--project <local-id>]` |
| `info` | Inspect one agent | `blop agents info <id>` |
| `setup` | Enable selected-scope capture or remove owned setup; global is the default | `blop agents setup <id> [--scope global\|project] [--project <local-id>] [--capture <mode>] [--collector-url <url>] [--remove]` |
| `install-hooks` | Install selected-scope user-level hooks for plain launches; preview unless --apply | `blop agents install-hooks <id> [--scope global\|project] [--project <local-id>] [--apply] [--remove]` |
| `run` | Launch a configured capture scope without changing normal extensions | `blop agents run <id> [--scope global\|project] [--project <local-id>] -- <host args>` |
| `capture-policy` | Read or change selected-scope capture without deleting history | `blop agents capture-policy show\|set <id> [--scope global\|project] [--project <local-id>] [--mode <mode>] [--exclude <class> ...\|--clear-exclusions] [--enabled true\|false] [--retention-hours <hours>] [--inject on\|off]` |
| `env` | Print telemetry exports; capture permission follows the selected binding | `blop agents env <id> [--scope global\|project] [--project <local-id>] [--collector-url <url>]` |
| `hook-config` | Print hook registration instructions | `blop agents hook-config <id>` |
| `hook` | Emit best-effort metadata from a stdin event | `blop agent hook --agent <id> [--collector-url <url>] [--timeout-ms <n>]` |
| `context` | Print opt-in memory context for a harness to inject (capture-policy --inject on) | `blop agent context --agent <id> --event session_start\|turn_start --session <id>` |
| `guard` | Answer one tool call against approved guardrail rules (allow prints nothing) | `blop agent guard --agent <id>` |
| `launch` | Launch an agent with telemetry injected | `blop agent launch <id> [-- args...]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--agent <id>` | Agent registry ID |  |  |
| `--collector-url <url>` | Exact local collector origin |  |  |
| `--project <local-id>` | Local project binding |  |  |
| `--capture <mode>` | New capture mode; existing choices are preserved when omitted Values: full, conversation-only, metadata-only. |  |  |
| `--scope <scope>` | Capture scope: global (all working directories) or project; defaults global without --project Values: global, project. |  |  |
| `--mode <mode>` | Change capture mode without clearing class exclusions Values: full, conversation-only, metadata-only. |  |  |
| `--exclude <class>` | Exclude a content class; repeat for an explicit exclusion set |  |  |
| `--clear-exclusions` | Explicitly clear the class exclusion set |  |  |
| `--enabled <boolean>` | Enable or disable this binding without removing its setup Values: true, false. |  |  |
| `--retention-hours <hours>` | Body retention from original observation; integer1–720 |  |  |
| `--remove` | Remove matching owned hook setup; install-hooks restores pre-install bytes with --apply |  |  |
| `--apply` | Apply native hook changes; otherwise print an exact diff without writing |  |  |
| `--inject <on\|off>` | Inject scoped memory context into the harness (Claude Code only; off by default) Values: on, off. |  |  |

## Manage commands

### blop status

Show whether Blop is running, where, and what it stores

One quick call to the collector this folder resolves to. It shows the URL, how it runs (background, foreground or outside this state dir), pid, instance id, collector and CLI versions, uptime, store, retention and telemetry counts. -o env prints the OTel variables blop run sets as export lines, quoted for eval or an env file. --logs prints the background collector's log; blop logs is the OTel log query.

```bash
blop status [-o text|json|env] [--logs [-f]]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--logs` | Print the background collector's log instead |  |  |
| `-f, --follow` | With --logs: keep printing new lines until Ctrl-C |  |  |

JSON fields in `data`: `ok`, `service`, `version`, `url`, `pid`, `instance_id`, `collector_id`, `last_retention`, `compaction`, `hook_capture`, `started_at`, `workdir`, `database_path`, `db_size_bytes`, `retention_hours`, `max_db_size_mb`, `stats`, `observation`, `reachable`, `source_lifecycle`, `ingestion`, `running`, `inspector_url`, `otlp_endpoint`, `port`, `mode`, `managed`, `cli_version`, `collector_version`, `uptime_ms`, `log_path`, `memory_project`, `mcp_command`, `connected_agents`, `storage`, `last_ingest_at`, `hooks`, `failing_run_id`, `next`.

```bash
blop status  # Where Blop runs, its versions and its store
blop status --json  # The same as one blop.cli/v1 document
eval "$(blop status -o env)"  # Point this shell's OTel SDKs at Blop
```

See also: `blop up`, `blop stop`, `blop doctor`.

### blop stop

Stop the background collector

Stops the collector this folder started, or every one with --all, but only collectors recorded in this state dir whose identity checks out: the process, its launch line or its /api/health answer must match the record. It sends SIGTERM, waits up to 5 seconds, then SIGKILL, and removes the record. Nothing running is not an error (exit 0). A collector in the foreground of another terminal is left running (exit 1, press q or Ctrl-C there) unless you pass --force.

```bash
blop stop [--all] [--force] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--all` | Stop every collector recorded in this state dir |  |  |
| `--force` | Also stop a collector running in the foreground of another terminal |  |  |

JSON fields in `data`: `collectors`, `not_running`.

```bash
blop stop  # Stop the collector started from this folder
blop stop --all  # Stop every collector this state dir knows
blop stop --force  # Also stop one running in another terminal
```

See also: `blop up`, `blop status`.

### blop doctor

Check the setup end to end and print the fix for each failure

```bash
blop doctor [--profile NAME] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--profile <name>` | Also verify hosted grant, MCP, capabilities and memory |  |  |

JSON fields in `data`: `id`, `category`, `status`, `ok`, `detail`, `fix`, `advisory`.

```bash
blop doctor  # Collector, OTLP ingest, git, setup and stitching checks
blop doctor --json  # The same checks as one blop.cli/v1 document
```

See also: `blop status`, `blop help exit-codes`.

### blop config

Show every effective setting and where it came from

Shows each setting once, with its value and its source: the flag, a BLOP_* environment variable, the project .blop/config.json (the older .blop/monitor.json is still read; config.json wins when both exist), the user file $XDG_CONFIG_HOME/blop/config.json (~/.config/blop/config.json when unset), or the default. That is also the order of precedence, first match wins. A project file that sets no port keeps the one shared collector; a project port means a collector and store of its own. Values whose name looks like a credential print as ***.

```bash
blop config show [--port <n>] [--host <host>] [--json]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `show` | Show every effective setting and its source | `blop config show [--port <n>] [--host <host>] [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |

```bash
blop config show  # Every setting with its source
blop config show --json  # The same as data.<key> = {value, source, path}
BLOP_MONITOR_RETENTION_HOURS=48 blop config show  # See an environment variable take over
```

See also: `blop init`, `blop doctor`.

### blop completion

Print a shell completion script

Prints a completion script for commands, subcommands, flags and their values, generated from this version of Blop; issue and run ids complete live from the running collector (nothing when it is down). Install it once, and again after upgrading Blop. Bash: add eval "$(blop completion bash)" to ~/.bashrc. Zsh: add source <(blop completion zsh) to ~/.zshrc, after compinit. Fish: write it to ~/.config/fish/completions/blop.fish.

```bash
blop completion bash|zsh|fish
```

```bash
blop completion bash  # Bash: add eval "$(blop completion bash)" to ~/.bashrc
blop completion zsh  # Zsh: add source <(blop completion zsh) to ~/.zshrc
blop completion fish  # Fish: save it as ~/.config/fish/completions/blop.fish
```

See also: `blop help`.

### blop auth

Authorize and verify a hosted workspace without passwords

Device login prints the provider's verification URL and user code, then waits for browser consent. Status verifies current membership/grants online. Logout revokes the remote refresh grant before removing credentials; uncertain revocation is reported separately.

```bash
blop auth <login|status|logout> [flags]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `login` | Authorize using the provider device flow | `blop auth login --app-url URL [--profile NAME] [--scopes SCOPES] [--no-open] [--json]` |
| `status` | Verify the current grant and workspace online | `blop auth status [--profile NAME] [--json]` |
| `logout` | Revoke remotely, then remove local credentials | `blop auth logout [--profile NAME] [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--profile <name>` | Named origin/workspace-bound OAuth profile (default default) | default |  |
| `--app-url <url>` | Hosted HTTPS app origin (loopback HTTP for development) |  |  |
| `--scopes <scopes>` | Space/comma-separated public OAuth scopes; include blop:read. Defaults to all non-admin scopes; request blop:admin explicitly as an owner |  |  |
| `--no-open` | Do not open the device verification page |  |  |

```bash
blop auth login --app-url https://blop.example --profile team  # Choose workspace/projects and approve the displayed non-admin access
blop auth login --app-url https://blop.example --profile owner --scopes 'blop:read blop:write blop:execute blop:admin blop:memory:read blop:memory:write'  # Explicit owner-only full administrative grant
blop auth status --profile team --json  # Verify the grant rather than decoding token claims
```

### blop cloud

Discover and call the enabled hosted operations

Calls use current server schemas, no cached operation list or automatic write retries. Requires-approval is not completion; queued is acceptance, not verification. A policy change is never silently retried with a new revision.

```bash
blop cloud <operations|call|action> [flags]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `operations` | Read a bounded page of actual enabled schemas | `blop cloud operations [--profile NAME] [--limit N] [--cursor CURSOR] [--json]` |
| `call` | Call one enabled operation with exact JSON input | `blop cloud call <operationId> --input FILE_OR_DASH [--idempotency-key KEY] [--expected-policy-revision N] [--profile NAME] [--json]` |
| `action` | Observe a durable action (never approve it) | `blop cloud action <actionId> [--profile NAME] [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--profile <name>` | Named origin/workspace-bound OAuth profile (default default) | default |  |
| `--input <file-or-dash>` | Finite JSON input file, or - for stdin (maximum 1 MiB) |  |  |
| `--idempotency-key <key>` | Retained unique key for the exact write attempt |  |  |
| `--expected-policy-revision <revision>` | Reviewed live policy revision; stale revisions are rejected |  |  |
| `--limit <n>` | Catalog page size (1–100) (default 100) | 100 |  |
| `--cursor <cursor>` | Opaque next catalog cursor |  |  |

```bash
blop cloud operations --profile team --json  # Discover enabled capabilities and schemas
blop cloud call workspace.context --input context.json --profile team --json  # Read current authorized workspace context
```

### blop delete

Preview, then delete one trace, session or source

Without --yes nothing is removed: it prints the exact rows per table (spans, span attributes, logs, metric points/series, observation rows, issues, run links and fully removed session bookmarks) and their stored bytes. IDs are exact, never patterns or names: a 32-hex trace ID, a session ID (with --source when it exists under more than one source) or a 64-hex observation source key. --yes recomputes the same selection and removes it in one bounded transaction, then prints what it removed and any difference. Retention settings and capture policy are not changed.

```bash
blop delete --scope trace|session|source --id <id> [--source <key>] [--since <window>] [--yes] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--scope <kind>` | What to delete: trace, session or source Values: trace, session, source. |  |  |
| `--id <id>` | The exact trace ID, session ID or source key |  |  |
| `--source <key>` | With --scope session: the exact source key, when the session ID is ambiguous |  |  |
| `--since <window>` | Only evidence that started within this window, e.g. 1h, 7d |  |  |
| `--yes` | Apply the deletion; without it the command only previews |  |  |
| `--db <path>` | SQLite database path (env BLOP_MONITOR_DB_PATH) |  | `BLOP_MONITOR_DB_PATH` |

JSON fields in `data`: `preview`, `scope`, `counts`, `bytes`, `total`, `traces`, `limit`, `planned`, `delta`, `not_touched`.

```bash
blop delete --scope trace --id 4bf92f3577b34da6a3ce929d0e0e4736  # Preview what deleting one trace removes
blop delete --scope trace --id 4bf92f3577b34da6a3ce929d0e0e4736 --yes  # Remove it and print the removed counts
blop delete --scope session --id ses_123 --since 1h --json  # Preview the last hour of one session as JSON
```

See also: `blop traces`, `blop status`, `blop help json`.

## Query commands

### blop services

Services seen in the lookback window

```bash
blop services [--summary] [--since <duration>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--summary` | Return the bounded per-service window summary |  |  |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |

See also: `blop help query`.

### blop workers

Authenticated worker observations (also: overview, detail)

```bash
blop workers [overview|detail] [--limit <n>] [--json]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `overview` | Live bounded overview of observed workers | `blop workers overview [--machine <id>] [--state <state>] [--limit <n>] [--snapshot <file>] [--json]` |
| `detail` | One exact worker attempt | `blop workers detail --machine <id> --worker <id> --attempt <id> --instance <id> --revision <n> [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--limit <n>` | Maximum rows |  |  |

See also: `blop help query`.

### blop traces

Search traces

```bash
blop traces [--service <name>] [--status ok|error] [--operation <name>] [--since <duration>] [--duration-min <ms>] [--limit <n>] [--cursor <token>] [attr.key=value] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--service <name>` | Only this service |  |  |
| `--status <status>` | Only spans with this status: ok or error Values: ok, error. |  |  |
| `--operation <name>` | Only this operation name |  |  |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |
| `--duration-min <ms>` | Only traces at least this long (ms) |  |  |
| `--limit <n>` | Maximum rows |  |  |
| `--cursor <token>` | Continue from a previous page |  |  |
| `--header` | Piped output: print the column names first |  |  |

See also: `blop help query`.

### blop spans

Search spans

```bash
blop spans [--service <name>] [--trace-id <id>] [--operation <name>] [--status ok|error] [--since <duration>] [--limit <n>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--service <name>` | Only this service |  |  |
| `--trace-id <id>` | Only this trace |  |  |
| `--operation <name>` | Only this operation name |  |  |
| `--parent-operation <name>` | Only children of this operation |  |  |
| `--status <status>` | Only spans with this status: ok or error Values: ok, error. |  |  |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |
| `--limit <n>` | Maximum rows |  |  |

See also: `blop help query`.

### blop span

Print one span

```bash
blop span <span-id> [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |

See also: `blop help query`.

### blop logs

Search logs

```bash
blop logs [--service <name>] [--severity <level>] [--trace-id <id>] [--span-id <id>] [--contains <text>] [--since <duration>] [--limit <n>] [--cursor <token>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--service <name>` | Only this service |  |  |
| `--severity <level>` | Minimum log severity, e.g. WARN |  |  |
| `--trace-id <id>` | Only this trace |  |  |
| `--span-id <id>` | Only this span |  |  |
| `--contains <text>` | Log body contains this text |  |  |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |
| `--limit <n>` | Maximum rows |  |  |
| `--cursor <token>` | Continue from a previous page |  |  |

See also: `blop help query`.

### blop trace-logs

Logs of one trace

```bash
blop trace-logs <trace-id> [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |
| `--limit <n>` | Maximum rows |  |  |
| `--cursor <token>` | Continue from a previous page |  |  |

See also: `blop help query`.

### blop span-logs

Logs of one span

```bash
blop span-logs <span-id> [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |
| `--limit <n>` | Maximum rows |  |  |
| `--cursor <token>` | Continue from a previous page |  |  |

See also: `blop help query`.

### blop trace-stats

Aggregate traces

```bash
blop trace-stats <groupBy> <count|avg_duration|p95_duration|error_rate> [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--group-by <field>` | Group by this field |  |  |
| `--agg <agg>` | Aggregation |  |  |
| `--service <name>` | Only this service |  |  |
| `--status <status>` | Only spans with this status: ok or error Values: ok, error. |  |  |
| `--operation <name>` | Only this operation name |  |  |
| `--duration-min <ms>` | Only traces at least this long (ms) |  |  |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |
| `--limit <n>` | Maximum rows |  |  |

See also: `blop help query`.

### blop log-stats

Aggregate logs

```bash
blop log-stats <groupBy> [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--group-by <field>` | Group by this field |  |  |
| `--agg <agg>` | Aggregation |  |  |
| `--service <name>` | Only this service |  |  |
| `--trace-id <id>` | Only this trace |  |  |
| `--span-id <id>` | Only this span |  |  |
| `--contains <text>` | Log body contains this text |  |  |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |
| `--limit <n>` | Maximum rows |  |  |

See also: `blop help query`.

### blop facets

Distinct values of a field

```bash
blop facets <traces|logs> <field> [--key <name>] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--type <type>` | Facet source: traces or logs Values: traces, logs. |  |  |
| `--field <field>` | Facet field |  |  |
| `--key <name>` | Attribute key for attribute facets |  |  |
| `--service <name>` | Only this service |  |  |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |
| `--limit <n>` | Maximum rows |  |  |

See also: `blop help query`.

### blop audit

Deterministic audit against a baseline

```bash
blop audit [--service <name>] [--since <duration>] [--baseline <duration>] [--duration-min <ms>] [--fail-on error|regression|never] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--service <name>` | Only this service |  |  |
| `--since <duration>` | Lookback window, e.g. 15m, 2h, 1d (default 15m) | 15m |  |
| `--baseline <duration>` | Baseline window to compare against |  |  |
| `--duration-min <ms>` | Only traces at least this long (ms) |  |  |
| `--fail-on <when>` | Exit 1 on this audit outcome: error, regression or never (default) Values: error, regression, never. | never |  |

See also: `blop help query`.

## Other commands

### blop home

Status and the next step

Starts the collector in the background when it is stopped, then prints where Blop runs, what is connected and stored, and one next command. It never stays in the foreground and never asks a question; --detach and --no-open are accepted for compatibility and have no effect (it always detaches and never opens the browser); --foreground is rejected (exit 2). blop up is the foreground collector with its banner and keys.

```bash
blop [--port <n>] [--host <host>] [--project <id>] [--recover] [--compact] [--json]
```

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--project <id>` | Default authored-memory project (otherwise BLOP_PROJECT_ID, then all local projects) |  |  |
| `--detach` | Start in the background and return once it answers |  |  |
| `--foreground` | Stay in this terminal, even for an agent or a pipe |  |  |
| `--no-open` | Do not open the inspector (also BROWSER=none) |  |  |
| `--recover` | If the store is corrupt or from a newer Blop, move it aside (renamed, never deleted; the check may already have merged a pending WAL into it) and start an empty one |  |  |
| `--compact` | Before starting, evict to the size cap and VACUUM the store so deleted space returns to the disk (needs twice the store size free; refused while a collector serves it) |  |  |

JSON fields in `data`: `inspector_url`, `otlp_endpoint`, `mcp_command`, `connected_agents`, `storage`, `retention_hours`, `version`, `last_ingest_at`, `hooks`, `failing_run_id`, `next`.

```bash
blop  # Start Blop if it is stopped, show its status and the next step
blop -p 28100  # The same on another port
```

See also: `blop up`, `blop status`.

### blop monitor

Old names for up, stop and status, plus init

```bash
blop monitor init|start|stop|status [--port <n>] [--db <path>] [--detach] [--json]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `init` | Initialize project-local monitor config | `blop monitor init [--port <n>]` |
| `start` | Now blop up --foreground (or blop up --detach) | `blop monitor start [--host <host>] [--port <n>] [--db <path>] [--project <id>] [--detach] [--recover]` |
| `stop` | Now blop stop | `blop monitor stop [--json]` |
| `status` | Now blop status | `blop monitor status [--json]` |
| `daemon` | Now blop up --detach | `blop monitor daemon [--project <id>] [--json]` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `--host <host>` | Collector host (default 127.0.0.1, env BLOP_MONITOR_HOST) | 127.0.0.1 | `BLOP_MONITOR_HOST` |
| `--db <path>` | SQLite database path (env BLOP_MONITOR_DB_PATH) |  | `BLOP_MONITOR_DB_PATH` |
| `--project <id>` | Default authored-memory project (otherwise BLOP_PROJECT_ID, then all local projects) |  |  |
| `--detach` | Same as blop up --detach |  |  |
| `--recover` | Same as blop up --recover |  |  |

```bash
blop monitor start --detach  # Now blop up --detach
blop monitor stop  # Now blop stop
```

See also: `blop up`, `blop stop`, `blop status`.

### blop version

Print the Blop version

```bash
blop version [--json]
```

JSON fields in `data`: `version`, `node`.

```bash
blop version --json  # The version as a blop.cli/v1 document
```

### blop schema

Print the JSON Schema of the --json output (blop.cli/v1)

Without a name, lists the schemas. With one, prints that JSON Schema (draft 2020-12) as it ships in the package under schema/: envelope, error, or the data of a command (issues, issue, run, status, tail, ...).

```bash
blop schema [<name> | <command>] [--json]
```

JSON fields in `data`: `schemas`, `name`, `id`, `schema`.

```bash
blop schema  # List the schemas
blop schema envelope  # The document every --json prints
blop schema issues  # The data schema of blop issues (blop schema tail for tail lines)
```

See also: `blop help json`.

### blop flow

Browser Harness flow checks: test, watch, list, init

Flow checks drive a browser through Browser Harness and need no hosted Blop account. HTTPS production targets are supported. Use test-safe accounts and data, and only target systems you are authorized to test.

```bash
blop flow test|watch|list|init [patterns...] [flags]
```

| Subcommand | Purpose | Usage |
| --- | --- | --- |
| `test` | Run Browser Harness-backed flow checks | `blop flow test [patterns...] [flags]` |
| `watch` | Re-run flow checks when specs change | `blop flow watch [patterns...] [flags]` |
| `list` | List discovered flow checks | `blop flow list [patterns...] [--config <file>]` |
| `init` | Create a starter flow spec | `blop flow init [file] [--force] (default tests/homepage.blop.ts)` |

| Flag | Description | Default | Environment |
| --- | --- | --- | --- |
| `-u, --base-url <url>` | Base URL for the app under test (local, CI, staging, or HTTPS production) |  |  |
| `--report-dir <dir>` | Report output directory (default .blop) | .blop |  |
| `--coverage` | Collect executed JavaScript source coverage (Chromium only) |  |  |
| `--coverage-endpoint <url>` | Send coverage to this local collector base URL (requires --coverage) |  |  |
| `--progress-file <file>` | Append live NDJSON progress (test_start, action, frame, test_finish) |  |  |
| `--capture-screenshots` | Save a screenshot after each browser action (and stream live frames) |  |  |
| `--no-stream` | Disable the live CDP screencast (use per-action screenshots) |  |  |
| `--frame-interval <ms>` | Min ms between streamed frame progress lines (default 200) | 200 |  |
| `--force` | init/add: overwrite an existing spec without asking |  |  |
| `--headed` | Run browser headed |  |  |
| `--browser <name>` | Browser to run: chromium, camoufox, firefox or webkit Values: chromium, camoufox, firefox, webkit. |  |  |
| `--containerized` | Run the browser in a separate warm Docker container |  |  |
| `--viewport <size>` | Viewport as WIDTHxHEIGHT, for example 390x844 |  |  |
| `-c, --config <file>` | Config file path |  |  |
| `--provider <provider>` | Agent provider for the native agent loop (env BLOP_AGENT_PROVIDER) |  | `BLOP_AGENT_PROVIDER` |
| `--model <model>` | Agent model for the native agent loop (env BLOP_AGENT_MODEL) |  | `BLOP_AGENT_MODEL` |
| `--api-key <key>` | Agent API key for the native agent loop (env BLOP_AGENT_API_KEY) |  | `BLOP_AGENT_API_KEY` |
| `--max-steps <n>` | Optional hard cap on agent tool steps |  |  |
| `--workers <n>` | Run up to this many agent tests concurrently (default 1) | 1 |  |
| `-r, --reporter <reporter>` | Report format: basic, json, junit or all Values: basic, json, junit, all. |  |  |
| `--otel-endpoint <url>` | OTLP/HTTP endpoint for flow telemetry; setting it turns export on (env OTEL_EXPORTER_OTLP_ENDPOINT) |  | `OTEL_EXPORTER_OTLP_ENDPOINT` |
| `--otel-service-name <name>` | service.name on exported spans (default blop-runner, env OTEL_SERVICE_NAME) | blop-runner | `OTEL_SERVICE_NAME` |
| `--otel-environment <name>` | deployment.environment.name on exported telemetry |  |  |
| `--otel-propagate` | Send W3C traceparent to the app under test (also BLOP_OTEL_PROPAGATE_TO_APP=1) |  | `BLOP_OTEL_PROPAGATE_TO_APP` |
| `--otel-propagate-allowlist <hosts>` | Comma-separated hosts allowed to receive it (env BLOP_OTEL_PROPAGATE_ALLOWLIST) |  | `BLOP_OTEL_PROPAGATE_ALLOWLIST` |
| `-v, --verbose` | Print agent stream events in real time |  |  |

```bash
blop flow test tests/checkout.blop.ts --base-url http://localhost:3000  # Run one spec against a local app
blop flow init  # Create tests/homepage.blop.ts
```

See also: `blop help environment`.

## Exit codes

| Code | Label | Meaning |
| --- | --- | --- |
| 0 | ok | Success |
| 1 | failure | The command ran and reported a failure (an audit threshold, a failed doctor check), or the collector failed while answering |
| 2 | usage error | Usage error: unknown command or flag, bad value, port taken, invalid project config, a prompt under --no-input. Nothing was sent |
| 3 | Blop not running | Blop is not running at the resolved URL. Start it with blop up |
| 4 | query rejected | The collector rejected the query, for example an unknown issue id |
| 5 | timeout | The collector did not answer in time |
| 6 | could not verify | Could not verify (blop init, blop setup mcp): the result could not be confirmed, or nothing was written because it would not work |
| 78 | store unrecoverable | Store unrecoverable or incompatible. Do not retry; run blop up --recover |
| 127 | not found | The command was not found: blop run's wrapped command, or the agent binary a launcher (blop claude, codex, opencode) starts |
| 129 | hangup | The terminal closed (SIGHUP) before the command finished |
| 130 | interrupted | Interrupted (Ctrl-C) |
| 143 | terminated | Stopped by SIGTERM (for example blop stop or kill) before the command finished |

blop run and the launchers (blop claude, codex, opencode) exit with the child's own code, or 128+N when it dies from signal N.

## Environment

| Variable | Description | Flag |
| --- | --- | --- |
| `BLOP_MONITOR_PORT` | Collector port (default 27811) | `--port` |
| `BLOP_MONITOR_URL` | Collector URL | `--url` |
| `NO_COLOR` | Disable colour | `--no-color` |
| `BLOP_NO_INPUT` | Never prompt; a question exits 2 | `--no-input` |
| `BLOP_DEBUG` | Print stack traces | `--debug` |
| `BLOP_MONITOR_DB_PATH` | Local collector database (otherwise project/environment configuration) | `--db` |
| `BLOP_MONITOR_HOST` | Collector host (default 127.0.0.1) | `--host` |
| `BLOP_AGENT_PROVIDER` | Agent provider for the native agent loop | `--provider` |
| `BLOP_AGENT_MODEL` | Agent model for the native agent loop | `--model` |
| `BLOP_AGENT_API_KEY` | Agent API key for the native agent loop | `--api-key` |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP/HTTP endpoint for flow telemetry; setting it turns export on | `--otel-endpoint` |
| `OTEL_SERVICE_NAME` | service.name on exported spans (default blop-runner) | `--otel-service-name` |
| `BLOP_OTEL_PROPAGATE_TO_APP` | Send W3C traceparent to the app under test | `--otel-propagate` |
| `BLOP_OTEL_PROPAGATE_ALLOWLIST` | Comma-separated hosts allowed to receive it | `--otel-propagate-allowlist` |

### Output, colour and agents (every command)

| Variable | Description | Default |
| --- | --- | --- |
| `FORCE_COLOR` | Colour even in a pipe; 0 turns it off. Wins over NO_COLOR |  |
| `CLICOLOR_FORCE` | Colour even in a pipe, unless NO_COLOR is set |  |
| `CLICOLOR` | 0 turns colour off |  |
| `COLUMNS` | Table width when stdout is not a terminal that reports one |  |
| `BLOP_FORCE_TTY` | 1 prints the terminal layout (aligned tables) into a pipe |  |
| `FORCE_HYPERLINK` | 1 or 0 turns clickable ids (OSC 8) on or off |  |
| `BROWSER` | none: blop up and blop open never open a browser (blop open prints the URL). Any other value is the command that opens one |  |
| `BLOP_AGENT` | Name of the coding agent running blop, or 0 for none. Without it Blop reads AI_AGENT, CLAUDECODE, CODEX_THREAD_ID, CURSOR_AGENT, OPENCODE, GEMINI_CLI and other agents' own variables. An agent gets no prompts |  |

### Collector and inspector (blop up, blop monitor)

| Variable | Description | Default |
| --- | --- | --- |
| `BLOP_MONITOR_STATE_DIR` | Where the collector registry, PID and log files live |  |
| `BLOP_MONITOR_RETENTION_HOURS` | Hours of telemetry the store keeps | 720 |
| `BLOP_MONITOR_MAX_DB_SIZE_MB` | Store size cap in MB; the oldest data goes first | 1024 |
| `BLOP_MONITOR_OPEN` | true or false: whether the inspector opens on start (blop config show lists it) | true |
| `BLOP_MONITOR_CAPTURE_CONTENT` | true or false: whether prompt and response content is captured (blop config show lists it) | false |
| `BLOP_MONITOR_RETENTION_INTERVAL_SECONDS` | Seconds between retention passes |  |
| `BLOP_MONITOR_RETENTION_TRACE_BATCH` | Traces deleted per retention pass |  |
| `BLOP_MONITOR_RETENTION_LOG_BATCH` | Logs deleted per retention pass |  |
| `BLOP_MONITOR_TRACE_LOOKBACK_MINUTES` | Collector-side lookback in minutes when a query names none |  |
| `BLOP_MONITOR_TRACE_LIMIT` | Collector-side trace rows when a query sets no limit |  |
| `BLOP_MONITOR_LOG_LIMIT` | Collector-side log rows when a query sets no limit |  |
| `BLOP_LEDGER_POLICY_FILE` | Private operator policy file for worker ledgers |  |
| `BLOP_SOURCE_POLICY_FILE` | Private capture-consent policy file for application and filelog sources |  |
| `BLOP_AGENT_PROVIDER` | Model provider for the inspector chat |  |
| `BLOP_AGENT_MODEL` | Model for the inspector chat |  |
| `BLOP_AGENT_API_KEY` | API key for the inspector chat |  |
| `BLOP_PROJECT_ID` | Default authored-memory project at collector startup (overridden by --project); also the hosted project receiving flow results |  |
| `BLOP_PROJECT_DIR` | blop mcp: the project whose collector to read (user-scope Cursor and VS Code entries set it to ${workspaceFolder}); else CLAUDE_PROJECT_DIR, else the working directory |  |
| `CLAUDE_PROJECT_DIR` | blop mcp: set by Claude Code for the servers it starts; the project when BLOP_PROJECT_DIR is unset |  |
| `BLOP_MCP_VERIFY` | Internal, set by blop setup mcp for its start check; do not set it. blop mcp then contacts no collector and every tool call says so |  |
| `BLOP_MCP_HANDSHAKE_TIMEOUT_MS` | blop setup mcp: how long to wait for blop mcp to answer its start check (10000, or 20000 for npx) |  |

### Wrapped commands (blop run)

| Variable | Description | Default |
| --- | --- | --- |
| `BLOP_RUN_KILL_GRACE_MS` | Milliseconds the command has to exit after blop run forwards a SIGTERM or SIGHUP, before it is SIGKILLed | 10000 |

### Flow checks (blop flow)

| Variable | Description | Default |
| --- | --- | --- |
| `BLOP_AGENT_BASE_URL` | Base URL of the agent model API, for any provider |  |
| `BLOP_OTEL_TEAM` | Team name recorded on flow runs |  |
| `BLOP_INGEST_URL` | Hosted Blop ingest URL for flow results |  |
| `BLOP_INGEST_SECRET` | Hosted Blop ingest secret for flow results |  |
| `BLOP_TRIGGER` | What started the flow run (for example ci), sent with results |  |
| `BLOP_RUN_ID` | Run id to report results under, when CI dispatched the run |  |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | http/protobuf (default) or http/json for flow telemetry |  |
| `OTEL_EXPORTER_OTLP_HEADERS` | Headers sent with flow telemetry, key=value pairs |  |
| `OTEL_EXPORTER_OTLP_TIMEOUT` | Export timeout in ms for flow telemetry |  |
| `OTEL_EXPORTER_OTLP_<SIGNAL>_*` | Per-signal ENDPOINT, PROTOCOL, TIMEOUT and HEADERS, where SIGNAL is TRACES, METRICS or LOGS |  |
| `OTEL_RESOURCE_ATTRIBUTES` | service.name and deployment.environment.name when no flag sets them |  |

### Opencode (blop setup opencode, blop opencode)

| Variable | Description | Default |
| --- | --- | --- |
| `BLOP_OPENCODE_BIN` | OpenCode executable to configure and launch |  |
| `BLOP_OPENCODE_SETUP_PATH` | Where blop setup opencode records its state |  |
| `BLOP_OTLP_ENDPOINT` | Collector the Blop OpenCode plugin exports to (else OTEL_EXPORTER_OTLP_ENDPOINT) |  |
| `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | Ignored by the Blop OpenCode plugin, which never sends OpenCode's own headers to Blop |  |

### Set for the command blop run starts (otel_* only when unset)

| Variable | Description | Default |
| --- | --- | --- |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | The collector's OTLP endpoint (always set) |  |
| `BLOP_OTLP_ENDPOINT` | Same endpoint, for the Blop OpenCode plugin (always set) |  |
| `OTEL_RESOURCE_ATTRIBUTES` | blop.run.id, the git branch, commit and dirty flag, and blop.trigger.kind/id (plus blop.trigger.person, git user.name, on a manual run to a local collector), merged into yours |  |
| `BLOP_TRIGGER_KIND` | What started the run (--trigger, detected CI, else manual), so agents and hooks it starts keep it; BLOP_TRIGGER (as blop flow reads it) is honoured too |  |
| `BLOP_TRIGGER_ID` | The schedule or CI run id (--trigger-id, or the CI's run id) |  |
| `BLOP_TRIGGER_PERSON` | git user.name on a manual run to a local collector; never set otherwise |  |
| `OTEL_SERVICE_NAME` | The package.json name, else the folder name |  |
| `OTEL_TRACES_EXPORTER` | otlp |  |
| `OTEL_LOGS_EXPORTER` | otlp |  |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | http/protobuf |  |
| `OTEL_BSP_SCHEDULE_DELAY` | 1000, so spans reach Blop within a second |  |
| `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` | true, with --capture-content only |  |
| `OTEL_LOG_USER_PROMPTS` | 1, with --capture-content only |  |
| `BLOP_LOCAL_RUN_ID` | The run's id (set with or without a collector). A blop run inside it joins that run while its blop runs, and a bare blop run there is refused |  |
| `BLOP_LOCAL_RUN_PID` | The pid of the blop run that owns BLOP_LOCAL_RUN_ID; with BLOP_LOCAL_RUN_START it tells a live run from an ended one |  |
| `BLOP_LOCAL_RUN_START` | That process's start identity, so a reused pid does not count as the run |  |
| `BLOP_LOCAL_RUN_DEPTH` | How many blop runs enclose the command; at 8, blop run refuses to start another |  |
| `TRACEPARENT` | The run's root span, so the command's spans join the run |  |
| `CLAUDE_CODE_ENABLE_TELEMETRY` | 1, so Claude Code exports its telemetry |  |

### Set for opencode by blop opencode

| Variable | Description | Default |
| --- | --- | --- |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | The collector's OTLP endpoint |  |
| `BLOP_OTLP_ENDPOINT` | The same endpoint, for the Blop OpenCode plugin |  |
| `OTEL_RESOURCE_ATTRIBUTES` | The project namespace, merged into yours |  |

### Set for the background collector

| Variable | Description | Default |
| --- | --- | --- |
| `BLOP_MONITOR_INSTANCE_ID` | Identity the managed collector reports, so blop can verify it |  |
| `BLOP_MONITOR_STATE_DIR` | The state directory the managed collector was started with |  |

## JSON output

Every command prints a `blop.cli/v1` document with `--json`.

| Field | Meaning |
| --- | --- |
| `schema_version` | Always blop.cli/v1 for this shape |
| `command` | The command that ran, or null when it was not recognised |
| `generated_at` | When the document was made (ISO 8601, UTC); setup doctor uses a documented fixed epoch sentinel, not the audit time, for deterministic output |
| `ok` | true exactly when the exit code is 0. blop run is the one exception: true when the wrapped command started, whatever its exit code (data.exit_code) |
| `data` | The result. blop help <command> lists its JSON FIELDS. It may be kept on a failure, for example doctor's checks |
| `page` | For lists: limit, lookback, returned, truncated, coverage and next_cursor. null otherwise |
| `warnings` | Notes that did not stop the command: a list of {code, message} |
| `next` | Commands worth running next, most useful first: a list of {command, when}. On a failure, the same list as error.next |
| `error` | Only when ok is false: code, message, hint, docs and next |

### Error fields

| Field | Meaning |
| --- | --- |
| `code` | Stable snake_case id to branch on, for example collector_not_running |
| `message` | One sentence for a person |
| `hint` | A command to run or one sentence, or null |
| `docs` | A link with more detail, or null |
| `next` | Steps worth trying, most useful first: a list of {command, when} |
