Stack
drunk-cat-stack
A TypeScript monorepo template for code that agents write. One pnpm check fails on structure rules instead of leaving them to review.
Start
It is a GitHub template. Create a repo from it:
gh repo create <name> --template JakubSzwajka/drunk-cat-stack
Then run corepack enable and pnpm install. The install patches
tsc with the Effect diagnostics and puts the pre-commit hook in place.
Or paste this into your coding agent:
Read https://github.com/JakubSzwajka/drunk-cat-stack and use it as the
reference for how we set up TypeScript repos: exact pins, one
`pnpm check` that fails on structure rules, Effect 4 with typed
errors, and a fence that blocks `--no-verify`. Read its README,
AGENTS.md and skills before you write code. Follow its rules, and
tell me when my code breaks them. Already have a pnpm workspace? The Adapt it section of the README lists which files to copy.
Why
Every new project started with the same setup. Exact pins, lint and type rules, import boundaries, a pre-commit hook. I set it up by hand each time, and each repo ended up configured a little differently.
That setup matters more once agents write the code. An agent learns from what fails. A check that runs on every change gives it the same clear answer every time. A rule in a style guide gives it nothing to hit.
Joel Hooks' rat-stack showed me how to put all of this in one repo. drunk-cat-stack is my version of it. I start new projects from it and move fast without giving up on code quality or architecture. I care about both a lot, and I don't want speed to cost me either one.
Agents take the shortest path. A rule that lives only in prose gets skipped the first time
it is in the way. So every rule a tool can check lives in pnpm check, lefthook
runs it before each commit, and a Pi extension blocks --no-verify. The fence
does not make an agent good. It raises the floor, so the worst normal run still passes the
checks.
What is in it
Maintained tools, used as they are, each pinned to an exact version.
- pnpm and Turborepo
- One workspace, one lockfile, install policy, and the order of typecheck and test.
- Biome
- Formatting, plus a few lint rules such as no export * and no non-null assertions.
- ESLint with eslint-plugin-codebase-ai-rules ↗
- Comments stay one line and sit inside a function or class body.
My opinion This one is pure opinion. It is how I like comments. Opus 5 wrote comments like prose, and I hate that. So I wrote a rule for it and keep it in its own repo.
- TypeScript 7 with @effect/tsgo
- Strict types, and Effect diagnostics that fail the typecheck.
- Dependency Cruiser
- Import rules between apps, packages, and the layers inside an app.
- Vitest with @effect/vitest
- Tests that run Effects only through it.effect and it.layer.
- varlock
- Every variable in .env.schema resolves and matches its type.
- lefthook
- Runs pnpm check and pnpm test before each commit.
The rules they check fall into a few groups.
- Pins and supply chain
- Every dependency is an exact version, a full commit SHA, or workspace:<exact>. pnpm refuses a version younger than one day and any install script nobody approved.
- Typed Effect errors
- No floating Effects. No global Error, unknown, or any in an error channel, and no try/catch inside Effect.gen. No async, fetch, Date, or console where Effect has its own.
- Module boundaries
- No import cycles. A package never imports an app, and callers reach a package only through its src/index.ts. Use-cases never import delivery or server code.
- The fence
- lefthook runs the checks before each commit. A Pi extension blocks git commit --no-verify and the other ways to skip that hook.
The README table lists every rule with its tool and config file.
What pnpm check runs
pnpm check ─> pins ─> env:check ─> biome ─> lint ─> turbo run typecheck ─> deps
├─ @hosti/bookings typecheck
└─ @hosti/api typecheck (after bookings)
pnpm test ─> node --test tests/ ─> turbo run test
├─ @hosti/bookings typecheck ─> test
└─ @hosti/api typecheck ─> test The fence
git commit ──> lefthook pre-commit ──> pnpm check ──> pnpm test
Pi bash tool call
└─> .pi/extensions/git-interceptor.ts
└─> scripts/vcs-command-policy.mjs
├─ bypass ─> deny, with reason
└─ git or jj ─> allow Credit
drunk-cat-stack is heavily inspired by rat-stack by Joel Hooks. The fence, the Effect setup, and the pnpm and Turborepo setup are adapted from its repo under the MIT license. The NOTICE file lists each adapted file.