> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meridian.study/llms.txt
> Use this file to discover all available pages before exploring further.

# Meridian CLI

> Coordinate work across Meridian and its closed-source modules

## Why the CLI Exists

Meridian depends on **closed-source modules** — private repos that are cloned into the monorepo during build (e.g. `backend/events`). Events-Backend is the first; more will follow. This split creates coordination challenges:

* **Branch drift** — Meridian and its modules can end up on different branches or commits, causing runtime mismatches
* **Lockfile discipline** — Heroku builds use `private-deps.lock` to clone each module at a pinned SHA. If the lockfile points at the wrong ref (unmerged branch, wrong SHA), deploys can fail or cause downtime
* **Manual coordination** — Without tooling, developers must remember to checkout all repos, push all branches, merge modules to main first, then update the lockfile — easy to get wrong

The Meridian CLI solves this by treating Meridian + its modules as a single workflow. It keeps all repos on the same branch, enforces the correct merge order (modules → main before syncing), and updates the lockfile so builds stay deterministic.

<Info>
  **Don't manually checkout across repos** unless you know what you're doing. The CLI prevents the mistakes that caused past downtime from mismatched subrepo commits.
</Info>

## Installation

For first-time installs (dependencies, Events-Backend, platform-specific PATH and `backend/events` linking), follow **[Getting Started](/getting-started)**.

**Recommended:** Link the CLI globally so you can run `meridian` from anywhere. From the Meridian root:

```bash theme={null}
npm link
```

After that, use the base command:

```bash theme={null}
meridian setup
meridian status
meridian start MER-123-Org-Forms
meridian ship
```

**Alternative** (without linking):

```bash theme={null}
npm run meridian -- <command>
# or
./m <command>
./mer <command>
```

## Workspace Layout

The expected workspace has Meridian and its modules as siblings:

```
<WORKSPACE>/
  Meridian/
  Events-Backend/    # first closed-source module; more can be added
```

If you follow the **suggested sibling layout** (sometimes called “Meridian-Mono” in docs), the parent folder contains **`Meridian/`** and **`Events-Backend/`** next to each other—that parent is **not** a git repository. The CLI auto-detects the workspace when run from **`Meridian/`**. If a required module is missing, the CLI will prompt you to clone it (e.g. Events-Backend):

```bash theme={null}
git clone git@github.com:Study-Compass/Events-Backend.git ../Events-Backend
```

Override workspace detection with `MERIDIAN_WORKSPACE=/path/to/parent`.

## Feature Development Flow

### 1. Start a feature

```bash theme={null}
meridian start MER-123-Your-Feature-Name
```

Creates `MER-123-Your-Feature-Name` from `origin/main` in both repos. Both must be clean.

### 2. Develop

Work in both repos as usual. Commit as you go.

### 3. Check status

```bash theme={null}
meridian status
```

Shows branch, clean/dirty, and lockfile state for both repos.

### 4. Ship

```bash theme={null}
meridian ship
```

Guides you through: push module(s) → create module PR(s) → merge to main → sync lockfile → push Meridian → create Meridian PR. You merge all PRs manually.

## Commands Reference

### `meridian setup`

Bootstraps local development from the `Meridian/` repo root.

* Clones `Events-Backend` into the workspace if missing (after confirmation)
* Runs `npm install` in `Meridian/`, `frontend/`, and `backend/`
* Offers to symlink `backend/events` to `../Events-Backend`

```bash theme={null}
meridian setup
# or
npm run setup
```

### `meridian status`

Shows the current state of both repos and the lockfile.

* Meridian: branch, clean/dirty, short SHA
* Each module (e.g. Events-Backend): branch, clean/dirty, short SHA
* Lockfile: pinned SHA(s), whether they match `origin/main` and local HEAD

```bash theme={null}
meridian status
```

### `meridian start <branch>`

Creates a fresh feature branch in both repos from `origin/main`.

**Branch name format:** `MER-<number>-<slug>` (e.g. `MER-123-Org-Forms`)

```bash theme={null}
meridian start MER-123-Org-Forms
```

### `meridian switch <branch>`

Switches both repos to an existing branch (or creates it if missing). When switching, Git replaces `backend/events` with the submodule checkout. If you use a symlink for local dev, run `meridian symlink` after switching to restore it.

```bash theme={null}
meridian switch MER-123-Org-Forms
```

### `meridian symlink`

Replaces `backend/events` with a symlink to the sibling Events-Backend repo. Use this for local development so you can edit Events-Backend in place. Git checkout (e.g. `meridian switch`) replaces the symlink with a submodule checkout — run `meridian symlink` again after switching branches.

```bash theme={null}
meridian symlink
```

### `meridian sync`

Syncs `private-deps.lock` to the current `origin/main` SHA of each module. Use when you've already merged module changes to main and only need to update the lockfile.

```bash theme={null}
meridian sync
meridian sync --allow-main   # override main check
```

### `meridian ship`

Guided flow to ship a full-stack feature. Handles module PR(s), merge detection, lockfile sync, and Meridian PR.

```bash theme={null}
meridian ship
```

## The Lockfile

`private-deps.lock` pins each closed-source module by SHA. During Heroku builds, `bin/fetch_private_deps` clones each module at its pinned SHA. This ensures:

* **Deterministic builds** — Every deploy uses the exact same module code
* **No downtime** — We never pin unmerged or divergent commits

Each entry in the lockfile must reference a 40-character hex SHA that exists on `origin/main` in that module's repo. Branch names, tags, or arbitrary refs are not allowed.

## Troubleshooting

### Dirty state

**Error:** "Meridian has uncommitted changes" or a module repo has uncommitted changes

**Fix:** Commit, stash, or discard changes in both repos. The CLI does not auto-stash.

### Branch collision

**Error:** "Branch MER-123-X already exists on remote"

**Options:** Resume (checkout existing), Abort, or Force create new (requires different name).

### `gh` not found

**Symptom:** `meridian ship` prints URL templates instead of creating PRs.

**Fix:** Install [GitHub CLI](https://cli.github.com/) and run `gh auth login`.

### Module not found

**Fix:** Clone the missing module into the workspace (the CLI will print the URL). Example for Events-Backend:

```bash theme={null}
git clone git@github.com:Study-Compass/Events-Backend.git ../Events-Backend
```

Or set `MERIDIAN_WORKSPACE` to the parent directory containing Meridian and all modules.

### Invalid branch name

**Format:** `MER-<number>-<slug>` (e.g. `MER-123-Org-Forms`, `MER-456-Fix-Login`)

## Windows Notes

`npm link` works on Windows, but \*\*`meridian` may not be on your PATH`until you add the global npm bin folder manually** (see the Windows tab in [Getting Started](/getting-started)). Symlinks for`backend/events` often need **Developer Mode**, an elevated terminal, or a **junction** (`mklink /J\`) — same page has step-by-step options.

If you prefer not to link:

* Use `npm run meridian -- <cmd>` or `node bin/meridian.js <cmd>`
* Optional: create `m.cmd` and `mer.cmd` that call `node bin/meridian.js %*`

***

## Related pages

<CardGroup cols={2}>
  <Card title="Getting started" icon="rocket" href="/getting-started">
    `meridian setup`, PATH, and Windows symlink notes the CLI assumes.
  </Card>

  <Card title="Development" icon="wrench" href="/development">
    Running servers, debugging, and workflow after branches are aligned.
  </Card>

  <Card title="Deployment" icon="cloud" href="/deployment">
    Lockfile verification, CI, and promotion—where `meridian ship` fits.
  </Card>

  <Card title="Testing" icon="flask" href="/testing">
    What to run before opening a PR from a CLI-managed branch.
  </Card>

  <Card title="Update local database" icon="database" href="/update-local-db">
    Refresh local Mongo when your branch needs fresh tenant data.
  </Card>

  <Card title="Backend best practices" icon="server" href="/backend/best-practices">
    Code layout in `Meridian/backend` when modules sync via `backend/events`.
  </Card>
</CardGroup>
