# Quickstart

Get from a fresh clone to a running Cairnloop operator dashboard in a few minutes.
This guide follows the example app at `examples/cairnloop_example/` as its reference.

## Prerequisites

- **Elixir 1.15+ / OTP 26+**
- **Postgres 16+** with the `pgvector` extension installed

The `pgvector` extension powers Cairnloop's Knowledge Base embeddings. If you need a
containerized Postgres with pgvector, the repository ships a `docker-compose.yml` at the
repo root. From the repo root run:

```bash
docker compose up -d db
```

## Install

Cairnloop ships an [Igniter](https://hexdocs.pm/igniter) installer that adds the
dependency and generates the database migration for you.

First, fetch deps:

```bash
mix deps.get
```

Then run the installer:

```bash
mix cairnloop.install
```

The installer does two things:

1. Adds `{:cairnloop, "~> 0.1.0"}` to your `mix.exs` dependencies.
2. Detects your Ecto repo via `Igniter.Libs.Ecto.select_repo/1` and generates a
   `create_cairnloop_tables` migration that creates `cairnloop_conversations` and
   `cairnloop_messages` with the correct schema.

If no Ecto repo is found, the installer emits:

```
No Ecto repo found. Please create a migration manually for cairnloop tables.
```

In that case, create a `priv/repo/migrations/<timestamp>_create_cairnloop_tables.exs`
migration by hand before running `mix ecto.migrate`.

### Run migrations

After the installer has run, apply both your host app's migrations and the Cairnloop
library's own migrations:

```bash
# Run host migrations (generated by the installer or written by hand)
mix ecto.migrate

# Run the Cairnloop library's own migrations
mix ecto.migrate --migrations-path deps/cairnloop/priv/repo/migrations
```

The library ships 15+ additional migrations (knowledge base, retrieval corpus, gap
candidates, article suggestions, outbound, and more) that `mix ecto.migrate` alone will
not apply. Skipping this second command will cause `Postgrex.Error` relation-not-found
errors the first time any non-chat feature is exercised.

> **Tip:** Add both commands to your `ecto.setup` alias in `mix.exs` so they always run
> together:
>
> ```elixir
> "ecto.setup": ["ecto.create", "ecto.migrate",
>   "ecto.migrate --migrations-path deps/cairnloop/priv/repo/migrations",
>   "run priv/repo/seeds.exs"]
> ```

### Manual install (without Igniter)

If you prefer not to use Igniter, add Cairnloop to your deps directly:

```elixir
# mix.exs
def deps do
  [
    {:cairnloop, "~> 0.1.0"}
  ]
end
```

Then create the `create_cairnloop_tables` migration manually.

## Mount the Dashboard

Import the `cairnloop_dashboard/2` macro and mount it under a scope in your router.
The example app uses `/support`:

```elixir
# lib/my_app_web/router.ex
import Cairnloop.Router, only: [cairnloop_dashboard: 2]

scope "/support", MyAppWeb do
  pipe_through :browser

  cairnloop_dashboard("/", session: %{"host_user_id" => "demo_operator"})
end
```

The `cairnloop_dashboard/2` macro mounts routes under whatever path you pass as its
first argument. With the `/support` scope above:

- **Cockpit Home** (the task-oriented landing) is at `/support`
- **Inbox** is at `/support/inbox`
- **A conversation** is at `/support/:id`
- **Knowledge Base** is at `/support/knowledge-base`
- **Settings** is at `/support/settings`

This guide assumes `/support` as in the example app. Adjust paths to match your own
scope if you mount elsewhere.

> **Route convention:** Always use the path you pass to `cairnloop_dashboard/2`.
> The internal integration-test routes (not the shipped macro routes) will 404 for adopters.

## Styling

Cairnloop ships a self-contained, themeable stylesheet in the package at
`priv/static/cairnloop.css`. It defines the design tokens (`--cl-*`) and the `.cl-*`
component classes the dashboard renders — no Tailwind or daisyUI required in your app.
Include it once.

If you bundle CSS (esbuild/Tailwind), import it from your own stylesheet:

```css
@import "../../deps/cairnloop/priv/static/cairnloop.css";
```

Or serve the packaged asset directly and link it from your root layout:

```elixir
# endpoint.ex
plug Plug.Static, at: "/cairnloop", from: {:cairnloop, "priv/static"}, only: ["cairnloop.css"]
```

```html
<link rel="stylesheet" href="/cairnloop/cairnloop.css" />
```

**Theming:** override any `--cl-*` token in CSS loaded *after* `cairnloop.css` to re-skin
the dashboard to your brand, and toggle dark mode by setting `data-theme="dark"` on `<html>`.

## Boot

The commands below are for the example app. Switch into it first, then set up the
database and start the server:

```bash
cd examples/cairnloop_example
mix setup
mix phx.server
```

Then visit [http://localhost:4000](http://localhost:4000) for the guided demo index — it frames
the Trailmark scenario and links to every stage of the [JTBD Walkthrough](02-jtbd-walkthrough.html).
Or jump straight to the operator inbox at
[http://localhost:4000/support](http://localhost:4000/support).

You should see the Cairnloop operator inbox. The example app's seed places 20 conversations across
all lifecycle states — including ones pre-positioned in each JTBD state — so every screen is live
and clickable immediately.

> **Port already in use?** Start the server with a different port: `PORT=4010 mix phx.server`
> (and set `PGPORT` if your Postgres isn't on 5433). The example honors both.

## Next Steps

- **[JTBD Walkthrough](02-jtbd-walkthrough.html)** — walk the full Jobs-To-Be-Done
  lifecycle in the seeded example: inbox → conversation workspace → cmd+k search →
  AI draft approval → governed tool approval → resolve → outbound trigger → bulk recovery.
- **[Host Integration](03-host-integration.html)** — implement the four host behaviour
  contracts (`ContextProvider`, `Notifier`, `AutomationPolicy`, `SLAPolicyProvider`)
  so Cairnloop knows your app's context and policy.
- **[Auth & Operator Identity](07-auth-and-operator-identity.html)** — wire your real
  authenticated operator into the dashboard so the audit log attributes actions correctly.
  **Read this before going past the demo** — the hardcoded `host_user_id` shown in quickstarts
  is a trap in production.
- **[Troubleshooting](04-troubleshooting.html)** — resolve common install, migration,
  pgvector, and mount-config errors.
