folksbase uses Conventional Commits. Every commit message follows this pattern:
Common types:
| Type | When to use |
|---|
feat | New feature or enhancement |
fix | Bug fix |
chore | Dependency updates, config changes |
docs | Documentation changes |
test | Adding or updating tests |
refactor | Code restructuring without behavior change |
Examples:
feat: add natural language search to contacts
fix: handle malformed CSV headers gracefully
chore: update Drizzle to 0.39
docs: add large-imports guide to Mintlify
test: add unit tests for csv-ai.service
refactor: extract gravatar logic to contacts.service
Branch Naming
Branches follow the same type prefix:
feat/column-mapper-ui
fix/inngest-retry-on-blob-timeout
chore/update-dependencies
Pull Requests
- PRs must pass CI before merge (Biome lint + typecheck + tests + build)
- Squash merge to keep history clean
- No force-pushes to
main
CI Pipeline
The CI workflow (.github/workflows/ci.yml) runs on every PR to main:
- Lint —
pnpm lint (Biome)
- Typecheck —
pnpm typecheck
- Test —
pnpm test (Vitest)
- Build —
pnpm build (runs only after lint, typecheck, and test pass)
- Claude Code Review — AI-powered review that checks the PR against AGENTS.md rules
Concurrent CI runs on the same branch are automatically cancelled.
Local Git Hooks
Git hooks live in .githooks/ and are auto-configured when you run pnpm install (via pnpm prepare, which sets core.hooksPath).
| Hook | What it runs |
|---|
pre-commit | pnpm lint |
pre-push | pnpm typecheck → pnpm test → pnpm build |
These hooks catch issues before they reach CI. Don’t bypass them with --no-verify unless you have a good reason.
The pre-push hook runs typecheck, tests, and a full build. This can take a minute or two — it’s intentional. Better to catch issues locally than wait for CI.
Storybook Deploy
The Storybook deploy workflow (.github/workflows/deploy-storybook.yml) triggers on pushes to main when component files, Storybook config, or shared types change. It can also be triggered manually via workflow_dispatch.