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

# Quickstart: Run Your First CL Pipelines Job in Minutes

> Install cl-pipelines, define two phases, wire up in-memory adapters, and run a crash-safe pipeline end-to-end in under five minutes.

This guide walks you through the complete lifecycle of a `cl-pipelines` job: installing the package, defining phases, connecting adapters, and confirming the run completed. You'll use the built-in in-memory adapters so there's nothing extra to configure — swap them for real adapters (like [Convex](https://claritylabs.inc/docs/cl-pipelines/adapters/convex.md)) when you're ready for production.

### Install the package

Install `@claritylabs/cl-pipelines` and its peer dependency `zod`:

```bash theme={"system"}
npm install @claritylabs/cl-pipelines zod
```

> [!NOTE]
>
> If you plan to use the agent loop (`runAgent`), also install the Vercel AI SDK: `npm install ai`

### Define your phases

A phase is a plain object with a `name` string and a `run` function. The `run` function receives a typed context and must return a `PhaseResult`. Define two phases — one that increments a counter and one that logs the final value:

```typescript theme={"system"}
import type { Phase } from "@claritylabs/cl-pipelines";

type CounterState = { count: number };

const countUp: Phase<CounterState> = {
  name: "countUp",
  run: async (ctx) => {
    const { count } = ctx.checkpoint.state;
    await ctx.log(`count is ${count}`);
    return { kind: "next", nextPhase: "logDone", state: { count: count + 1 } };
  },
};

const logDone: Phase<CounterState> = {
  name: "logDone",
  run: async (ctx) => {
    await ctx.log(`pipeline finished with count = ${ctx.checkpoint.state.count}`);
    return { kind: "done" };
  },
};
```

Each phase returns either `{ kind: "next", nextPhase, state }` to advance, or `{ kind: "done" }` to mark the pipeline complete.

### Wire up adapters

`cl-pipelines` talks to your infrastructure through two small interfaces: a `StorageAdapter` (for persisting job state) and a `SchedulerAdapter` (for triggering the next phase). For local development and tests, the library ships in-memory implementations of both:

```typescript theme={"system"}
import {
  createMemoryStorage,
  createMemoryScheduler,
  advancePhase,
} from "@claritylabs/cl-pipelines";

const storage = createMemoryStorage<CounterState>();
const scheduler = createMemoryScheduler();

// Tell the in-memory scheduler what to do when it fires
scheduler._bind((jobId) =>
  advancePhase({ jobId, phases: [countUp, logDone], storage, scheduler })
);
```

> [!NOTE]
>
> `scheduler._bind()` is a test-only hook. In production your scheduler (e.g. Convex) calls `advancePhase` directly from its own action handler.

### Run the pipeline

Call `runPipeline` to seed the job. It writes the initial checkpoint and enqueues the first phase advance — it does **not** execute any phase directly. Then call `scheduler.drain()` to flush all pending advances synchronously:

```typescript theme={"system"}
import { runPipeline } from "@claritylabs/cl-pipelines";

await runPipeline({
  jobId: "my-first-job",
  phases: [countUp, logDone],
  storage,
  scheduler,
  initialState: { count: 0 },
});

await scheduler.drain();

const jobs = storage._inspect();
console.log(jobs.get("my-first-job")!.status); // "complete"
```

### Verify the result

After `scheduler.drain()` resolves, every phase has run to completion. Use `storage._inspect()` (test-only) to read the final job record:

```typescript theme={"system"}
const job = jobs.get("my-first-job")!;

console.log(job.status);      // "complete"
console.log(job.checkpoint);  // null — cleared when done
console.log(job.log);         // array of LogEntry from ctx.log(...)
```

> [!TIP]
>
> Both `storage._inspect()` and `scheduler._bind()` are prefixed with `_` to signal they are test/development helpers. Your production `StorageAdapter` exposes the same public methods without those helpers.

## Next steps

> **[Core Concepts](https://claritylabs.inc/docs/cl-pipelines/concepts.md)**
>
> Understand phases, checkpoints, retry modes, and adapters in depth.

> **[Phases](https://claritylabs.inc/docs/cl-pipelines/phase-runner/phases.md)**
>
> Learn mid-phase checkpointing with ctx.saveState for large workloads.

> **[Convex Adapter](https://claritylabs.inc/docs/cl-pipelines/adapters/convex.md)**
>
> Connect cl-pipelines to a real durable backend with Convex.

> **[Agent Loop](https://claritylabs.inc/docs/cl-pipelines/agent/overview.md)**
>
> Add a crash-safe LLM agent loop to your pipeline.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.