Thanks for your interest in contributing! Here's how to get started.
- Bun >= 1.3.0 — required, not optional.
bun installrunsprepare→bun run build, which shells out tobun build, so there is no Node-only setup path. - Node.js >= 20.9.0 — what the published package targets, and what runs the in-repo dev hooks' launcher.
git clone https://github.com/failproofai/failproofai.git
cd failproofai
bun install # runs the `prepare` script → `bun run build`, which creates dist/
bun run devThe dev server starts at http://localhost:8020.
This repo dogfoods failproofai on itself: .claude/settings.json (and the
sibling .codex/, .cursor/, .github/hooks/, … configs) register hooks that run
node scripts/dev-hook.mjs --hook <Event> --cli <cli>. That launcher locates bun
(across PATH, $BUN_INSTALL/bin, ~/.bun/bin, Homebrew, and every
~/.nvm/versions/node/*/bin), builds dist/index.js if it is missing, then hands off
to bin/failproofai.mjs. See scripts/dev-hook.mjs for why node fronts a bun-only
binary. Those hooks load the custom policies in .failproofai/policies/*.mjs, which
import the failproofai package — resolved against the compiled dist/index.js
bundle.
If dist/ is missing the launcher rebuilds it for you and says so on stderr. If it is
stale — you changed src/index.ts and the bundle predates it — nothing detects that,
and you'll get policies enforcing yesterday's code. When the bundle is missing and the
launcher can't run, the errors look like:
[failproofai:hook] ERROR failed to load custom hooks from
.failproofai/policies/review-policies.mjs: Cannot find package 'failproofai' …
bun install builds dist/ for you via its prepare script, so a clean clone
just works. Rebuild explicitly whenever you've changed src/ (the hooks load the
compiled bundle, not your live src/):
bun run build # full build (Next.js + dist/)
# …or, just the hook bundle (much faster while iterating on policies):
bun build --target=node --format=cjs --outfile=dist/index.js src/index.ts| Script | Description |
|---|---|
bun run dev |
Start the development server |
bun run lint |
Run ESLint |
bunx tsc --noEmit |
Type-check without emitting |
bun run test:run |
Run tests once (Vitest) |
bun run test |
Run tests in watch mode |
bun run build |
Production build (Next.js) |
failproofai/
├── app/ # Next.js app router (pages, layouts, server actions)
├── bin/ # CLI entry point
├── components/ # Shared React components
├── contexts/ # React context providers
├── lib/ # Core logic (logging, telemetry, paths, URL utils)
├── src/hooks/ # Hook handler, built-in policies, custom hooks loader
├── scripts/ # Dev/start/build helper scripts
├── __tests__/ # Test files
├── examples/ # Example custom hook policies
└── public/ # Static assets
| Directory | Description |
|---|---|
src/hooks/ |
Hook handler, built-in policies, custom hooks loader |
app/actions/ |
Next.js server actions |
app/components/ |
Session viewer, project list, log viewer |
| Variable | Description |
|---|---|
CLAUDE_PROJECTS_PATH |
Path to Claude projects directory |
FAILPROOFAI_LOG_LEVEL |
Log level: info, warn, error (default: warn) |
FAILPROOFAI_TELEMETRY_DISABLED |
Set to 1 to disable anonymous telemetry |
FAILPROOFAI_DISABLE_PAGES |
Comma-separated pages to disable: policies, projects |
- Keep changes focused — one concern per PR.
- Make sure all checks pass before requesting review:
bun run lint && bunx tsc --noEmit && bun run test:run && bun run build
- Include a clear description of what the PR does and why.
- Add tests for new functionality when applicable.
Found a bug or have a feature idea? Open an issue. The issue templates will guide you through providing the right details.