Working in Sandbox & Dev Mode (PGlite)

Using Paperclip's embedded PGlite database as a zero-cost local sandbox: activation, where data lives on disk, running test heartbeats without real API calls, resetting sandbox state, and when to switch to real PostgreSQL.

Working in Sandbox & Dev Mode (PGlite)

What you'll learn

How Paperclip's embedded PGlite database works as a zero-cost local sandbox, how to run test heartbeats without spending real API credits, and when to switch to real PostgreSQL.


What is PGlite?

PGlite is a full PostgreSQL engine compiled to WebAssembly that runs in-process — no separate database server required. When DATABASE_URL is blank in your .env, Paperclip automatically uses PGlite as its persistence layer.

This means:
- Zero setup — no Postgres install, no Docker, no connection strings
- Full SQL compatibility — every Paperclip query runs identically
- Data lives on disk — in .paperclip/dev.db in the project root


Where sandbox data is stored

paperclip/
  .paperclip/
    dev.db          ← PGlite database file (all your sandbox data)
    dev.db-wal      ← write-ahead log (normal, auto-managed)

You can inspect this file with any SQLite-compatible viewer (e.g. the SQLite Viewer VS Code extension — PGlite files are SQLite-format compatible for reads).


Running test heartbeats without API costs

The fastest way to iterate in the sandbox is to use the dry-run flag, which runs the heartbeat scheduling logic but calls a mock adapter instead of the real AI:

# Trigger a dry-run heartbeat for all active agents
curl -X POST http://localhost:3100/api/heartbeat/trigger \
  -H "Content-Type: application/json" \
  -d '{"dry_run": true}'

A dry-run:
- Selects tasks exactly as a real run would
- Creates heartbeat_runs records with status: 'dry_run'
- Does not call any adapter (no API cost)
- Writes to activity_log so you can verify routing logic


Resetting sandbox state

When you want a clean slate:

Option A — Delete just the database file:

rm .paperclip/dev.db .paperclip/dev.db-wal
# Restart pnpm dev — Drizzle will re-run migrations automatically

Option B — Reset via the API (keeps the server running):

curl -X POST http://localhost:3100/api/dev/reset
# ⚠ Only available when NODE_ENV=development

Both options wipe all companies, agents, issues, and logs. The schema is recreated automatically on next startup.


Switching from PGlite to real PostgreSQL

When you're ready for production — or when you want to share a persistent sandbox with teammates — swap to a real PostgreSQL instance:

# .env
DATABASE_URL=postgresql://user:password@localhost:5432/paperclip_dev

Paperclip detects the DATABASE_URL and skips PGlite entirely. Drizzle runs the same migrations against the real database on startup.

No code changes needed — the switch is purely configuration. All Drizzle queries work identically against PGlite and PostgreSQL.


PGlite limitations to know

Limitation Impact
Single-process only Can't run two server instances pointing at the same PGlite file
No network access Can't connect external tools (pgAdmin, DBeaver) directly — use the API instead
File lock Stop pnpm dev before deleting dev.db
Not for production PGlite is a dev/test tool only — always use real PostgreSQL in production

Sandbox workflow summary

Start pnpm dev (PGlite auto-created)
     ↓
Create test company + agents
     ↓
Trigger dry-run heartbeats (zero cost)
     ↓
Verify routing, logging, task selection
     ↓
Switch to real adapter for live testing
     ↓
Reset sandbox when done → rm dev.db

Checkpoint ✓

Sign in for progress tracking & Q&A →