# The-Vibe-Company/companion: persistent Pi agents on Box, run locally first

> A TypeScript monorepo that gives each account isolated AI companions with their own Linux container, driven by Pi and a PostgreSQL control plane. The local path is complete; the hosted path is explicitly unfinished.

**The-Vibe-Company/companion** — Persistent AI companions on Box, powered by Pi. Simple web, durable execution, reproducible local development.

- Repository: https://github.com/The-Vibe-Company/companion
- Website: https://companions.build
- Stars: 2,400 · Forks: 291
- Language: TypeScript
- License: MIT
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/the-vibe-company-companion

## What problem companion solves, and for whom

Most agent demos forget everything the moment the process exits. companion takes the opposite position: each personal account owns an isolated set of Companions, conversations, connections, automations, templates, files and billing records, and PostgreSQL is described in the README as the durable control plane. A Companion is not a chat session. It is a record with an owner, a stored and validated model choice, and a Linux container it can run tools inside.

The audience is narrower than the tagline suggests. This is a repository for engineers who want to read the whole stack, not a service you sign up for. The README is blunt about scope: the repository currently implements the local product path and the hosted integration boundaries, and it is not evidence that the hosted service, provider OAuth applications, Stripe prices or cold Box performance are production ready. Anyone evaluating it as a finished hosted product will be disappointed by the project's own documentation.

It is also a migration artefact. The former Skills Hub now lives in The-Vibe-Company/skillpack, and docs/repository-migration.md covers the history and deployment boundaries. If you arrived looking for the older project, you are in the wrong repository.

## Pi as the agent harness, PostgreSQL as the durable layer

The architecture has four named parts. Pi is the agent harness, Bun packages the Linux runtime, PostgreSQL is the durable control plane, and the web client is React with shadcn/ui and AI Elements. The dependency list confirms the harness: @earendil-works/pi-ai, pi-coding-agent and pi-server are all pinned at 0.85.0, with overrides forcing the same version across pi-agent-core, pi-client, pi-protocol, pi-telemetry and pi-tui. That pinning matters, because mixing harness versions across the server and the container would be hard to debug.

Data flow in local mode is deliberately testable. The launcher starts isolated PostgreSQL, MinIO, Mailpit, API, worker, executor and web processes. Local mode uses a deterministic Pi test model by default, so no provider key is needed to exercise the loop. Create a Companion and send write-note to trigger a real Pi tool call inside its Linux container. Two further scripts exist for the failure paths: slow-write exercises cancellation, and crash-after-effect exercises recovery without repeating the tool effect. That last one is the interesting claim, because exactly-once tool effects across a crash is the part of agent infrastructure that usually gets hand-waved.

Schema handling is explicit rather than implicit. The local launcher applies the complete PostgreSQL schema before it starts any service. A hosted release must follow the same order: run bun run migrate as its release command, then start API, executor and worker with COMPANIONS_SCHEMA_PREPARED=1. Each service verifies the stored schema fingerprint before becoming ready. A service launched alone without that flag still performs the idempotent, advisory-locked migration and skips DDL when the current fingerprint is present. That is a sensible design, and it also means an operator can start a service out of order without corrupting the schema, at the cost of a slower first boot.

## Installing companion locally with python3 scripts/dev.py

Prerequisites are Python 3, Docker and Git. The launcher downloads checksum-verified Bun 1.4.2 inside the checkout, so you do not need Bun installed beforehand. Clone and run the launcher:

```bash
git clone https://github.com/The-Vibe-Company/companion.git
cd companion
python3 scripts/dev.py
```

Open the printed web address, enter an email, then use the link in the printed Mailpit address to sign in. With the default deterministic test model, create a Companion and send write-note to exercise a real Pi tool call inside its Linux container. Send slow-write to exercise cancellation, or crash-after-effect to exercise recovery without repeating the tool effect.

Each checkout derives its own ports, database, object bucket, mail inbox and labeled containers, so two clones on one machine do not collide. Set CONDUCTOR_PORT to choose an explicit web port; API is +1, PostgreSQL +2, MinIO +3, Mailpit SMTP +5 and Mailpit web +6. Ctrl-C stops resources owned by that checkout while retaining its local data.

For real model responses, create an uncommitted .env. Google, Anthropic, OpenAI, OpenRouter and Z.AI Coding Plan are supported, and the UI projects the configured model catalog while storing a validated model choice per Companion. Restart the launcher after changing configuration.

```dotenv
AGENT_TEST_MODE=0
MODEL_PROVIDER=google
MODEL_ID=gemini-2.5-flash
GEMINI_API_KEY=your-key
```

The README also points at the worktree workflow for the agent development loop and the Herdr service control panel: ./dev setup --portless, then ./dev workspace. That panel starts, stops and restarts components and exposes service URLs and validation results. If you plan to work on the agent rather than just run it, start there.

## Running the production container and the three roles

The root image builds the Vite client and the frozen Linux agent with Bun 1.4.2. It defaults to the api role on 0.0.0.0:$PORT and serves the client from the same origin. Run migrate once for a release, then launch api, executor and worker as separate services from the same image:

```bash
docker build -t companions.build .
docker run --rm --env-file .env.production companions.build migrate
docker run --env-file .env.production --env-file .env.api -p 3000:3000 companions.build api
docker run --env-file .env.production --env-file .env.executor companions.build executor
docker run --env-file .env.production --env-file .env.worker companions.build worker
```

The ignored .env.production file holds shared configuration and must provide DATABASE_URL, the public HTTPS APP_URL, BETTER_AUTH_SECRET and a 64-character hexadecimal COMPANIONS_ENCRYPTION_KEY. Configure SMTP or Resend (EMAIL_PROVIDER=resend, EMAIL_FROM, RESEND_API_KEY) for magic-link login and S3 for chat files. Box, model-provider, OAuth and Stripe credentials are required only for the product surfaces enabled in that deployment; the README states that absence remains visible as unavailable and is not simulated. Only the API role needs an exposed port.

Trigger filters run inside the image's bounded QuickJS WebAssembly runtime, so API, executor and worker services do not need a Docker socket. LOCAL_RUNTIME=0 is the image default, and a hosted executor uses Box rather than attempting to launch local agent containers. The executor publishes and verifies a base named snapshot from the bundled agent distribution, recreates it if missing, and removes unreferenced older managed images after replacement. BOX_TEMPLATE is only needed when opting out with BOX_MANAGED_TEMPLATE=0.

For an invitation-only beta, set PRIVATE_BETA_EMAILS to an exact comma-separated list of emails on API, executor and worker. Those users sign in with a verified magic link and can work without Stripe activation, while other users cannot sign in or use existing sessions. An explicitly empty list closes access; removing the variable restores normal subscription requirements. Redeploy all three roles when changing the list, and keep BILLING_TEST_MODE disabled in production.

## Where companion is the wrong tool

The clearest limitation is the one the project states itself. The repository implements the local product path and the hosted integration boundaries, and the README warns that this is not evidence the hosted service, provider OAuth applications, Stripe prices or cold Box performance are production ready. docs/v0.md is where the gaps are enumerated. If you need a hosted multi-tenant agent product this quarter, the documentation is telling you no.

The rollout model is the second constraint. The routine publication-mode release requires a coordinated rollout rather than independent automatic deployments: pause those deployments before merging, stop the old API, worker and executor, then migrate and start all roles from the updated image, with the API last. The README is explicit that an old executor does not enforce the new publication modes, which means a partially rolled deployment is not merely stale, it is permissive in a way the new code is not. Teams used to canary deploys and independent service rollouts will find this uncomfortable, and rightly so.

There is also a hard dependency on external infrastructure that the local loop hides. Hosted execution needs Box; login needs SMTP or Resend; chat files need S3. The local launcher supplies PostgreSQL, MinIO and Mailpit so none of that is exercised until you deploy. A team that only ever runs the local path has not tested the parts most likely to break.

Finally, the runtime is pinned hard. Bun 1.4.2 is downloaded by the launcher and used by the Dockerfile, and the Pi packages sit at 0.85.0 with overrides holding the transitive set together. That is good for reproducibility and bad for anyone hoping to track upstream releases casually.

## How companion differs from a plain agent framework

A general agent framework such as the AI SDK packages this project already depends on gives you model calls, tool definitions and streaming. It does not give you an account model, a durable record per companion, an isolated Linux container per companion, or a migration story for schema changes across three services. companion is building the product shell around the harness, and the dependency list makes the layering visible: ai 7.0.93 and the @ai-sdk provider packages sit underneath, with @earendil-works/pi-* above them.

The practical difference shows up in the test scripts. A framework-level test asserts that a tool was called. companion ships write-note to prove a real Pi tool call runs inside the Linux container, and crash-after-effect to prove recovery does not repeat the tool effect. That second scenario is a durable-execution concern, not a framework concern, and it is the reason PostgreSQL is described as the control plane rather than a database.

The trade-off is weight. You inherit Bun 1.4.2, a Debian-based agent runtime, PostgreSQL, MinIO, Mailpit, a worker, an executor and a web client before you have written a line of product code. If your goal is a single-process script that calls a model, this repository is several orders of magnitude more machinery than you need. Pick it when the persistence and isolation are the point.

## Licence, maintenance and upgrade cost

The licence is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are preserved. That is a permissive licence with no copyleft obligation on your own code. It says nothing about the terms of the hosted service, the model providers, Box, Stripe or the OAuth applications you will need to register, all of which carry their own agreements. This is not legal advice; read the LICENSE file and the terms of those services yourself.

Maintenance status is straightforward from the repository data. The project is not archived, and the last push was on 2026-09-16. Releases are less uniform: v0.2.0 landed on 2026-06-03, while the-companion-v0.95.0 and the-companion-v0.94.0 are dated 2026-04-01 and 2026-03-30. The two version series do not move together, so do not read the 0.95 tag as a statement about the repository as a whole.

Upgrade cost is dominated by the pins. Bun 1.4.2 is baked into both the launcher and the Dockerfile, and the @earendil-works packages are held at 0.85.0 through explicit overrides. Moving any one of them means moving the set. On the database side, migrations are ordered and fingerprinted, and every service verifies the stored schema fingerprint before becoming ready, so a partial upgrade fails loudly rather than silently. Budget for the coordinated rollout described in docs/dev-workflow.md rather than for independent service deploys.

## Conclusion

Adopt it if you want to read and modify the full stack of a persistent agent product: Pi harness, Bun-packaged Linux runtime, PostgreSQL control plane and a React client, all runnable from one checkout. Do not adopt it if you need a hosted service today, since the README states the repository implements the local product path and hosted integration boundaries only, and docs/v0.md lists the gaps. Before committing, verify that the pinned Bun 1.4.2 download and the isolated PostgreSQL, MinIO and Mailpit containers start on your machine, and read docs/dev-workflow.md for the routine publication rollout, because an old executor does not enforce the new publication modes.

## FAQ

### What is The-Vibe-Company/companion?

It is a TypeScript repository for persistent AI companions that each own a Linux container, with Pi as the agent harness, Bun packaging the runtime, PostgreSQL as the durable control plane and a React client. The README states it currently implements the local product path and the hosted integration boundaries.

### How do I install companion locally?

You need Python 3, Docker and Git. Clone the repository, then run python3 scripts/dev.py; the launcher downloads checksum-verified Bun 1.4.2 inside the checkout and starts isolated PostgreSQL, MinIO, Mailpit, API, worker, executor and web processes.

### Does companion need a model API key to run?

No. Local mode uses a deterministic Pi test model by default, and the local deterministic model requires no model key. For real model responses you create an uncommitted .env with AGENT_TEST_MODE=0, a MODEL_PROVIDER and the matching key, then restart the launcher.

### Which model providers does companion support?

The README lists Google, Anthropic, OpenAI, OpenRouter and Z.AI Coding Plan. The UI projects the configured model catalog and stores a validated model choice per Companion.

### How do I run companion in production?

Build the root image, run migrate once for the release, then start api, executor and worker as separate services from the same image. The ignored .env.production file must provide DATABASE_URL, the public HTTPS APP_URL, BETTER_AUTH_SECRET and a 64-character hexadecimal COMPANIONS_ENCRYPTION_KEY.

## Sources

- [License: MIT](https://github.com/The-Vibe-Company/companion/blob/main/LICENSE)
- [Project website](https://companions.build)
- [README](https://github.com/The-Vibe-Company/companion/blob/main/README.md)
- [Releases](https://github.com/The-Vibe-Company/companion/releases)
- [The-Vibe-Company/companion on GitHub](https://github.com/The-Vibe-Company/companion)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/the-vibe-company-companion
