The monorepo was on npm workspaces. pnpm gives it a content-addressed store shared between the eight packages, a lockfile that records the whole graph rather than a flattened view of it, and — the reason this mattered in practice — `workspace:*`, which makes an internal dependency unambiguous instead of a version range that npm may satisfy from the registry. Mechanics: - `packageManager: pnpm@11.21.0` pins the version; corepack installs it in CI and in the image, so all three environments resolve identically. - The npm `workspaces` array is replaced by `pnpm-workspace.yaml`. pnpm ignores the former, and keeping both would leave two sources of truth. - All six internal dependencies moved to `workspace:*`. - Root scripts use `pnpm -r --if-present` and `pnpm -F <pkg>`. Two findings worth recording, both from running it rather than reading it: `tsx` was a devDependency, but the server runs TypeScript directly in production — the container's command is `pnpm exec tsx apps/api/src/server.ts`. Under npm this was concealed by the runtime stage re-installing tsx by hand after pruning dev dependencies. Under `pnpm install --prod` that sleight of hand stops working and the image simply fails to start. tsx is now declared in `dependencies`, which is what it has always actually been. The first image build failed with ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY. That is not a pnpm bug: it had decided the modules directory was stale and wanted confirmation before deleting it, which a non-interactive build cannot give. The trigger was the host's `node_modules` reaching the build context — there was no `.dockerignore` at all. pnpm's tree is symlinks into a content-addressed store, so copying it into an image produces dangling links and a directory pnpm rightly considers corrupt. Fixed by adding `.dockerignore` and setting `CI=true`, which is required in any non-interactive pnpm build. `esbuild` is denied install scripts via `allowBuilds`. Its platform binary arrives through the optional dependency `@esbuild/linux-x64` and the postinstall only verifies it; confirmed by running the binary directly, which reports 0.25.12. Verified under pnpm: typecheck clean, 150 tests / 0 failures, e2e passes, web builds. The image was built and booted against a real Postgres — health ok, `/api/dashboard` 401 with an issuer configured, `/` and `/capacity` serve the SPA, `/og.png` serves as image/png, and the migrator runs from the pruned runtime stage. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🐷 PIG — Prime Intellect Growth
An open-source, agent-native CRM for two-sided AI-compute companies.
Self-hostable. Auditable. Built for teams that buy compute on one side and sell it on the other.
Why this exists
A company that aggregates GPU capacity and resells it does not run one pipeline. It runs two, and its business is the spread between them.
Generic CRMs — Salesforce, HubSpot, Attio — model a single pipeline of deals against companies. They have no concept of inventory, no concept of a commitment you already bought and are paying for, and therefore no way to answer the question the business actually turns on:
Which contracted capacity is sold, to whom, at what margin — and what is idle right now?
PIG is built around that question. One table, allocations,
joins a capacity_commitment (what you bought from a provider) to a
demand_deal (what you sold to a customer). Revenue minus cost is margin per
GPU-hour. Committed capacity with no allocation is money burning. Everything
else in PIG is ordinary CRM plumbing that exists to keep that ledger honest.
Who it's for
PIG models three teams, because two-sided compute companies have three constituencies competing for the same scarce capacity:
| Team | Job to be done |
|---|---|
| Supply | Source, qualify, price, and contract GPU capacity from providers |
| Demand | Sell compute and post-training; renew and expand accounts |
| Research | Consume capacity internally — real burn, no revenue |
Research is a first-class tenant rather than an afterthought. Internal research burn competes with revenue for the same GPUs, and margin math that cannot see it is wrong.
The team set is configurable. PIG ships with these three because they match the structure of the company it was designed for, not because they are universal.
Agent-native, not agent-decorated
PIG is a first-class application for agents and for humans, and neither is a degraded view of the other.
- An MCP server (
apps/mcp) exposes the CRM over both stdio and Streamable HTTP. Any MCP client connects: Claude Code, Codex, prime-agent, or a Buzz workspace agent via its ACP bridge. Each team member points their own agent at PIG and works from the terminal. - Piggy, the in-app agent, drains a leased database queue rather than being called over HTTP — so work survives the agent being down, and every action it takes is recorded with an idempotency key.
- Every agent-derived fact carries evidence. Enrichment writes to a
factstable with a confidence score, a band (verified / probable / possible), a source URL, and a status. Strong signals apply automatically; weak ones become proposals a human approves. A CRM that lets an agent write unattributed claims into the record is a hallucination store, not a database.
The architectural rule
Intelligence never lives in the API.
The API does HTTP, auth, validation, and sync. All research, enrichment, scoring, and identity matching lives in the agent. They communicate through a table, never a direct call. This separation is borrowed from Comp AI CRM and it is the single most load-bearing decision in the codebase.
What makes it compute-native
-
inventory_listingsmirrors the Prime Intellect availability API field-for-field —gpuType,socket,interconnectType,stockStatus,security(secure vs community cloud),prices.onDemand,provisioningTime. Sync is a straight mapping, not an ETL project. -
capacity_commitmentsrecords what you bought: term, GPU-hours, cost per GPU-hour, floor and ceiling. -
contractsis polymorphic over party and type — MSA, DPA, SLA, order form, capacity commitment — because the supply side negotiates heavyweight paper while the self-serve demand side runs on a reliability tier and a credits policy instead of a signed uptime guarantee. -
Two real pipelines, with stages taken from how this market actually operates rather than invented:
Demand: qualification → legal → scoping → proposal → procurement → POC → deployment → expansion Supply: sourced → qualifying → technical diligence → financial diligence → pricing → contracting → onboarding → live → renewalNote that legal sits second in the demand pipeline. MSA and DPA execution gates the deal rather than closing it. Most CRMs put contracts at the end and are wrong about it for this market.
Stack
| Layer | Choice |
|---|---|
| Web | React + Vite + TypeScript, Tailwind, shadcn/ui, light + dark |
| API | Hono + tRPC on Node 22+ |
| Database | PostgreSQL 16, Drizzle ORM |
| Auth | Supabase (JWT verification only — PIG stores no passwords) |
| Agent | Piggy — a worker draining a leased task queue |
| MCP | @modelcontextprotocol/sdk — stdio + Streamable HTTP |
| Deploy | Docker Compose behind any reverse proxy |
Authorization comes from PIG's own users table, never from the mere existence
of an auth account. An identity provider that PIG shares with another
application must not grant access here.
Quick start
git clone <this-repo> pig && cd pig
pnpm install
cp .env.example .env # then edit it
pnpm run db:migrate
pnpm run db:seed # optional — public, sourced, confidence-graded
pnpm run dev:api # :8920
pnpm run dev:web # :5173
Connect an agent:
claude mcp add pig -- npx -y @pig/mcp # stdio
# or point any MCP client at https://<your-host>/mcp
Repository layout
apps/
web/ React + Vite front end
api/ Hono + tRPC API, Supabase JWT verification
mcp/ MCP server — stdio and Streamable HTTP
packages/
db/ Drizzle schema, migrations, seed
core/ Shared domain types and the ontology
prime/ Typed client for the Prime Intellect compute API
docs/ Ontology, deployment, seed-data provenance
deploy/ Compose files and reverse-proxy snippets
Documentation
- AGENTS.md — start here if you are joining this codebase. Architecture rules, the traps that have already bitten, conventions, and where to start.
- Build plan — what remains, in dependency order
- Ontology — the domain model, and why it is shaped this way
- Seed data provenance — every claim, graded and cited
- Agent integration — Claude Code, Codex, prime-agent, Buzz
- Deployment — self-hosting
A note on seed data
PIG ships with a roster of publicly documented people so the application is legible on first run. Every record carries a confidence grade and a source URL. No email addresses are included or inferred. Records that could not be independently sourced are marked as such rather than quietly presented as fact, and people who are demonstrably not staff — alumni, residency participants — are labelled accordingly. See docs/seed-data.md.
If you are seeded here and would rather not be, open an issue and it will be removed.