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
├── fp-cloud-cli/ # The `fp` CLI for FailproofAI Cloud (Python; PyPI: fp-cloud-cli)
├── sdk/ # Client SDKs, one directory per language
│ └── python/ # PyPI: failproofai-sdk, imported as `failproofai_sdk`
└── public/ # Static assets
fp-cloud-cli/andsdk/python/are the Python components in an otherwise TypeScript + Rust repo. Each is self-contained: its ownpyproject.toml, its ownuv.lock, its own pytest suite, its own CI job inci.yml, and its own PyPI project. Neither is part of the npm package, the Next.js build, or the Cargo workspace, and both version independently of the rootpackage.json— see CLAUDE.md.
sdk/is a directory rather than a flatfailproofai-sdk/because more languages are expected to land besidepython/. They will be siblings, not nested inside it.
| 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.