pleach
Get Started

Project layout

Pleach doesn't prescribe a layout. The runtime is constructed in user code; adapters are constructor args. A working default plus per-use-case shapes.

Pleach is a library, not a framework. There's no pleach.config.ts, no defineConfig, no required directory. The runtime is a class you construct; adapters are constructor arguments; storage paths live in whichever adapter you wire.

This page exists because that freedom is unhelpful on day one. So: what's actually load-bearing, what a layout looks like when you stop thinking about it, and what each use case adds on top.

What the runtime actually requires

Three things. Everything else is convention.

RequirementWhere it livesPage
Exactly one SessionRuntime per host processA module you write — typically exports the instanceSessionRuntime
A ProviderDecisionLedger you've pickedPassed into the SessionRuntime constructorAudit ledger
A host adapter, if you serve HTTPA route handler in your web frameworkHost adapter · API routes

The ledger choice is the one that catches people. The default is MemoryProviderDecisionLedger — fine for tests, lost on restart. NoopProviderDecisionLedger writes nowhere; pick it deliberately, not by accident. Anything durable is an adapter you wire.

A layout that works

A Next.js App Router app with one agent, one tool, and an HTTP route. Move any of these — the runtime resolves whatever your imports resolve.

my-app/
  src/
    pleach/
      runtime.ts             # constructs and exports `runtime`
      tools/
        search.ts            # → /docs/tools
      prompts/
        triage.ts            # → /docs/prompt-builder
    app/
      api/
        agents/[id]/route.ts # → /docs/api-routes
      page.tsx               # → /docs/react
  package.json

The split is convention, not contract:

  • src/pleach/runtime.ts — the single place new SessionRuntime(...) is called. Exports the instance so the host route and any background worker import the same one.
  • src/pleach/tools/ — each file exports a defineTool(...) call. The runtime doesn't scan this directory; you import the tools where you register them.
  • src/pleach/prompts/ — plain modules that build prompt objects. The runtime doesn't scan this directory either.
  • src/app/api/agents/[id]/route.ts — exports createPleachRoute() from @pleach/core/quickstart. This is the shipped host adapter the runtime expects when it's behind HTTP.

Read the inverse to internalize the model: nothing the runtime does depends on directory names. Rename pleach/ to agents/, flatten everything into src/, split per-feature — the runtime boots the same. The only thing it sees is the SessionRuntime you handed it.

A common second instinct: "where do checkpoints and the audit database live on disk?" Wherever the adapter you wired writes them. MemoryProviderDecisionLedger writes nowhere; the SQLite recipe writes to a path you pass in; a managed-DB adapter writes to a connection string. Pleach doesn't pick the path because Pleach doesn't know whether you're on one machine, a Lambda, or a multi-region cluster.

Descend into a use case

Each shape adds a small, predictable delta to the baseline above. Open the page for the shape closest to yours; the layout grows in one of a few directions, not many.

Filesystem-touching recipes

Recipes are the small, copy-pasteable pieces. Three touch the project's on-disk shape directly:

RecipeWhat it adds
Next.js App Router chat with streamingThe app/api/agents/[id]/route.ts + client component pair the baseline assumes.
Custom storage adapter: SQLiteA durable adapter that picks a real on-disk path for the audit ledger. The first thing past MemoryProviderDecisionLedger.
Building a custom event-log projectionWhere projection state lives — typically alongside the ledger, in whatever store the ledger writes to.

What Pleach won't tell you to do

A short list because each of these is a deliberate non-choice.

  • No config file. The runtime is wired in code so the TypeScript compiler sees every adapter you pass and your IDE jumps to the definition. A pleach.config.ts would buy convention at the cost of static analysis.
  • No reserved directory. Nothing called .pleach/ is created by the runtime. Storage paths live in whichever adapter you wire — the deployment shape (one machine vs. Lambda vs. managed DB) decides the path, not the library.
  • No agents/ folder convention. The agents/<specName>/ prefix you'll see in Agents is an internal channel-path prefix the runtime uses to namespace agent state. It's a string in the runtime's address space, not a directory on your disk.
  • No required test layout. Eval and replay reads recorded sessions, not test files. Put tests wherever your test runner finds them.

If a piece of structure isn't on this page, the runtime doesn't have an opinion on it — and that's the contract.

On this page