# Linear Canal CLI

The command-line interface for **Linear Canal** — the Context Intelligence Layer for AI coding agents. Transforms your codebase into structured, agent-ready context via a 6-layer pipeline, then serves that context to Claude Code, Cursor, Gemini CLI, and any MCP-compatible agent over REST and SSE.

**Core value:** 80–95% token savings vs raw file exploration; eliminates agent hallucinations about architecture, imports, and dependencies.

---

## Installation

```bash
pip install linear-canal-cli
# or from source:
pip install -e ./cli
```

---

## Quick Start

```bash
cd your-project
linear-canal setup        # one-shot wizard: index + install agent configs
linear-canal serve        # start the MCP server at http://localhost:3141
```

---

## All Commands

### `setup`

Interactive zero-config wizard. Runs the full indexing pipeline locally (no Docker required), installs Claude Code plugin (skills + hooks + MCP auto-start), generates agent ambient files (`CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `AGENTS.md`), and writes MCP config for every detected agent.

```bash
linear-canal setup
```

---

### `init`

Initialise a project in the current directory. Creates `.linear_canal_data/` and registers the project in the global registry at `~/.linear-canal/data/projects.json`.

```bash
linear-canal init
```

---

### `serve`

Start the MCP + REST API server. Agents connect via SSE at `http://localhost:3141/mcp/v1`.

```bash
linear-canal serve
linear-canal serve --port 3141 --host 0.0.0.0
```

---

### `watch`

Watch the project for file changes and incrementally re-index modified files. Uses content-addressed hashing so only changed code is re-embedded.

```bash
linear-canal watch
```

---

### `status`

Show the current indexing status: pipeline phase, files indexed, vector count, tier breakdown (CRITICAL / HIGH / MEDIUM / LOW).

```bash
linear-canal status
```

---

### `db`

Full-screen TUI database and context browser. Opens either the local project or a global picker over all registered projects.

```bash
linear-canal db           # auto-detect: local project or global picker
linear-canal db local     # browse current project
linear-canal db --global  # browse all indexed projects
```

**TUI sections** (navigate with `← →` or `1–7`):

| # | Section | What it shows |
|---|---------|---------------|
| 1 | Overview | Index status, file counts, tier summary |
| 2 | Graph | Knowledge graph stats and relationships |
| 3 | Files | All tracked files with tier scores, scroll + page |
| 4 | Vectors | LanceDB collection sizes and embedding stats |
| 5 | CTX | Generated `.ctx` files with inline viewer |
| 6 | Branches | Context branch manager (see below) |
| 7 | Live | Real-time pipeline progress, auto-refreshes every 2 s |

**Branches panel key bindings:**

| Key | Action |
|-----|--------|
| `c` | Create a new context branch |
| `x` | Checkout / activate the selected branch |
| `d` | Delete branch + purge its LanceDB vectors |
| `m` | Merge two branches into a new one |
| `r` | Reindex the selected branch |
| `i` / `Enter` | Show detailed info panel for the selected branch |
| `f` | Diff two branches side by side |
| `l` | Show branch operation history log |
| `↑ ↓` | Select branch |

---

### `branch`

Git-style context branching system. Each branch is an isolated, focused index of the same codebase. Branches have their own ctx directory and LanceDB vector namespace (`<project_id>__<branch_name>`).

```
linear-canal branch <subcommand> [options]
```

#### `branch create <name>`

Create and index a new context branch with a named focus template or custom patterns.

```bash
linear-canal branch create ui                  # use the 'ui' focus template
linear-canal branch create my-branch          # interactive prompts for focus + patterns
linear-canal branch create my-branch --from backend  # copy config from existing branch
linear-canal branch create my-branch --skip-index    # create without indexing yet
```

**Focus templates:** `full`, `architecture`, `ui`, `backend`, `security`, `custom`

Each template pre-populates `include` patterns, `exclude` patterns, and `ctx_scope` (which `.ctx` file types apply to the branch).

#### `branch list`

List all branches with focus, active status, CTX file count, vector count, and last indexed timestamp.

```bash
linear-canal branch list
linear-canal branch list --vectors    # live-query LanceDB for real-time vector counts
```

#### `branch checkout <name>`

Switch the active context branch. Updates ambient agent files (`CLAUDE.md`, `.cursorrules`, etc.) so agents automatically use the new branch's ctx directory.

```bash
linear-canal branch checkout ui
```

#### `branch delete <name>`

Delete a branch, purge its LanceDB vectors, and remove its ctx directory. Asks for confirmation by default and shows the vector count that will be purged.

```bash
linear-canal branch delete old-branch          # confirm interactively
linear-canal branch delete old-branch --yes    # skip confirmation
linear-canal branch delete old-branch --no-purge  # skip LanceDB purge (keep vectors)
```

#### `branch show <name>`

Rich information panel for a branch. Shows all metadata, live LanceDB vector count (queried in real time), every `.ctx` file on disk with sizes, and the per-branch history log.

```bash
linear-canal branch show ui
```

#### `branch diff <a> <b>`

Side-by-side comparison of two branches. Shows focus, include/exclude patterns, CTX scope, live vector counts, and which `.ctx` files are unique to each branch or shared between them. Suggests the merge command at the end.

```bash
linear-canal branch diff ui backend
linear-canal branch diff full ui
```

#### `branch merge <a> <b>`

Merge two branches into a new one using a coverage-maximising strategy:

- **Includes** → union (covers everything either branch covers)
- **Excludes** → intersection (only drops files *both* branches agree to skip)
- **CTX scope** → union (if either is `null`, merged scope is also `null`)
- **CTX files** → seeded from both branches; branch A wins on conflict
- **merge_parents** stored in the manifest for traceability

```bash
linear-canal branch merge ui backend               # creates 'ui+backend'
linear-canal branch merge ui backend --name fullstack
linear-canal branch merge ui backend --skip-index  # create without re-indexing
```

#### `branch reindex <name>`

Re-run the full index pipeline on an existing branch. Updates `last_indexed`, `vector_count`, and `files_indexed` in the manifest.

```bash
linear-canal branch reindex ui
```

#### `branch rename <old> <new>`

Rename a branch. Updates the manifest, renames the directory on disk, and renames the LanceDB vector namespace by updating the `project_id` column on all rows. Updates ambient agent files if the renamed branch was active.

```bash
linear-canal branch rename old-name new-name
```

#### `branch log`

Colour-coded history of all branch operations, newest first.

```bash
linear-canal branch log                # last 20 entries
linear-canal branch log -n 50         # last 50 entries
linear-canal branch log --branch ui   # filter to a specific branch
```

**Action colours:** `create` = green · `checkout` = cyan · `merge` = magenta · `delete` = red · `reindex` = blue · `rename` = yellow

---

### `cleanup`

Manage tombstoned projects and purge stale data from deleted project directories. When a project folder is deleted, its LanceDB vectors and backups remain on disk until `cleanup` removes them.

```bash
linear-canal cleanup                    # scan + show status, prompt for overdue purges
linear-canal cleanup --dry-run          # show what would happen, no writes
linear-canal cleanup --purge-now        # immediately purge all overdue without prompting
linear-canal cleanup --grace-days 7     # set 7-day grace period instead of 30
linear-canal cleanup --restore <id>     # restore a tombstoned project's backup
linear-canal cleanup --restore <id> --target ./restored-project
```

**Lifecycle:**
1. Project directory deleted → directory goes missing
2. `cleanup` detects the missing path → project is **tombstoned** (`deleted_at` recorded)
3. Grace period passes (default 30 days) → marked as overdue
4. Next `cleanup` run → LanceDB vectors + backup files purged

Run `linear-canal setup` inside a restored project to re-activate it. The pipeline detects the backup and performs a fast incremental re-index instead of a full re-embed.

---

### `profile`

Manage resource profiles. Profiles control memory allocation and the embedding model used.

```bash
linear-canal profile show   # display the current profile and all available options
linear-canal profile set    # switch to a different profile
```

| Profile | RAM | Embedding Model | Use Case |
|---------|-----|-----------------|----------|
| `minimal` | ~2.3 GB | bge-small-en | Laptops, CI |
| `standard` | ~4.3 GB | nomic-embed-code | Dev (default) |
| `performance` | ~10+ GB | Ollama + GPU | Large codebases |

---

### `add`

Register an additional project with the global Linear Canal instance without running setup again.

```bash
linear-canal add
linear-canal add --path /path/to/project
```

---

### `logs`

Tail logs from Linear Canal services.

```bash
linear-canal logs
linear-canal logs --service indexer
linear-canal logs --follow
```

---

### `update`

Update the Linear Canal CLI to the latest version.

```bash
linear-canal update
```

---

## Branch Manifest Format

Branches are stored in `.linear_canal_data/<project_id>/branches/branches.json`:

```json
{
  "active": "ui",
  "branches": {
    "ui": {
      "name": "ui",
      "focus": "ui",
      "include": ["*.tsx", "*.css"],
      "exclude": ["**/node_modules/**"],
      "ctx_scope": null,
      "description": "Frontend / UI files only",
      "created_at": "2026-03-07T10:00:00+00:00",
      "updated_at": "2026-03-07T10:05:00+00:00",
      "parent_branch": "full",
      "merge_parents": [],
      "last_indexed": "2026-03-07T10:05:00+00:00",
      "vector_count": 1234,
      "files_indexed": 45
    }
  },
  "history": [
    { "action": "create",   "branch": "ui",       "at": "...", "parent": "full" },
    { "action": "checkout", "branch": "ui",        "at": "...", "prev": "full"   },
    { "action": "merge",    "branches": ["ui","backend"], "into": "ui+backend", "at": "..." }
  ]
}
```

---

## Storage Layout

```
~/.linear-canal/
  data/
    projects.json              ← global project registry
    lancedb_global_store/      ← all LanceDB vector tables (namespaced per project + branch)
  backups/
    <project_id>/              ← backup snapshots (used by cleanup --restore)

<project_root>/
  .linear_canal_data/
    <project_id>/
      index_status.json
      scout_status.json
      scores.json
      graph.db
      ctx/                     ← full branch ctx files
      branches/
        branches.json          ← branch manifest
        <branch_name>/
          ctx/                 ← branch-scoped ctx files
  .LC/
    CLAUDE.md                  ← ambient file updated on checkout
    GEMINI.md
    AGENTS.md
    .cursorrules
```

---

## Agent Integration

All agents connect via SSE at `http://localhost:3141/mcp/v1`. Config files auto-generated by `linear-canal setup`:

| Agent | Config File |
|-------|-------------|
| Claude Code | `.mcp.json` |
| Gemini CLI | `.gemini/settings.json` |
| Cursor | `.cursor/mcp.json` |
| OpenCode | `.opencode/config.json` |
| Kilo CLI | `kilo.config.json` |

**8 MCP tools exposed:** `lc_search`, `lc_impact`, `lc_context`, `lc_symbol`, `lc_risks`, `lc_module`, `lc_architecture`, `lc_history`
