We'd like to try something a little different with this repo.
Given that coding agents write most underlying code now, we'd prefer contributions in the form of human-written text. Run your idea by us the same way you would a coworker — informally, over Slack. If we're aligned on the change, we're happy to burn our tokens on the implementation.
Please don't have AI expand a one-paragraph idea into a formal proposal. The paragraph was the useful part.
Submit changes as a PR adding a .txt or .md file to the adrs/ folder.
If you'd rather just send the code, that's fine too — but lead with why, and keep the diff small enough that a person can hold it in their head.
PS: Report security vulnerabilities privately — see SECURITY.md, not a public
issue.
Everything you need is in the README. Short version:
bun install
docker compose up -d
cp .env.example .env # fill in ALLOWED_SIGN_IN and the two Google values
bun run db:deploy && bun run db:seed
bun run devbun run check-types
bun run lint
bun run testAll three run on CI, and bun run format fixes most of what lint complains about.
A few things that trip people up:
- The tRPC router type is generated, and committed. If the app can't see a procedure you just
added, run
bun run --filter=api trpc:generateand commitapps/api/src/generated/server.tsalongside the router change.bun run devkeeps it in watch mode. - Schema changes need a migration, not
db:push.bun run db:migratecreates one. - New environment variables need a home. Add them to
.env.exampleand, if the API reads them, toapps/api/src/config/env.validation.ts. A variable that only exists in someone's shell is a variable that breaks the next person's clone.
The repo has opinions, and they're written down where the work happens rather than in a style guide:
AGENTS.md— the rules that apply to everything, and where the others live.docs/design.md— UI. Short version:packages/uiis the only place components come from, and you don't override its styles at the call site.docs/api.md— logging, tRPC, caching, and why intelligence never lives in the API.
Two that are worth stating here because they explain most review comments:
Comments say why, not what. The code already says what it does. A comment earns its place by recording the thing that isn't in the diff — the bug that made this necessary, the obvious approach that turned out wrong, the constraint that looks arbitrary until you know.
Nothing about a person is guessed. This is a CRM: a confidently wrong fact about a real customer is worse than a blank field, because nobody can tell it's wrong. Code that fills a gap with a plausible value is a bug here even when it's convenient.
Include what you expected, what happened, and enough to reproduce it. If it involves the agent, the session transcript is worth more than a description of it — but read it first and redact anything that belongs to a real customer.