Local Development
Prerequisites
- Bun (workspace manager)
- Node (LTS)
- Supabase CLI (for local DB)
Setup
bun install
cp .env.example .env.local
Services
- Web apps via Turbo
- Workers run independently per package
- Storybook for UI component documentation
Shared UI (@eko/ui)
The @eko/ui package contains shared React components consumed by web and admin apps.
Adding new components:
cd packages/ui
bunx shadcn@latest add <component-name>
After adding, update imports from @/lib/utils to ../lib/utils and add 'use client' directive.
Tailwind CSS v4 integration:
Apps must include the @source directive in their globals.css:
@import "tailwindcss";
@source "../../packages/ui/src";
Required Environment Variables
After copying .env.example, ensure these AI provider keys are configured:
| Variable | Required | Purpose |
|---|---|---|
OPENAI_API_KEY | Yes | Default tier for fact extraction |
ANTHROPIC_API_KEY | Recommended | Mid/high tier for accuracy-critical tasks |
GOOGLE_API_KEY | Yes | Gemini 2.5 Flash powers the validation pipeline (Phases 3 and 4c) |
Note: The validation pipeline requires
GOOGLE_API_KEYfor cross-model verification and evidence corroboration via Gemini 2.5 Flash.
Queues
Local development uses either local Redis or Upstash dev credentials. Configure via environment variables.
Workers
Workers execute independently via Bun (worker-ingest, worker-facts, worker-validate).
Commands
bun run dev— parallel dev (web, admin)bun run test— workspace testsbun run check— format + lintbun storybook— run Storybook at http://localhost:6006bun run build-storybook— build static Storybook
Environment Validation
After adding or changing environment variables:
bun run env:check-example # Validate .env.example completeness
bun run env:check-local # Validate .env.local against .env.example
bun run env:check-typos # Check for common env file typos (.evn, etc.)
These checks run automatically in CI via the pre-push hook.
Pre-commit Hooks
The repo uses Husky for Git hooks and lint-staged for running linters on staged files.
What runs on commit:
- Secret scanning (gitleaks) - Blocks commits containing potential secrets
- Lint-staged - Runs Biome on staged
.ts,.tsx,.js,.jsx,.json,.mdfiles
Installing gitleaks
Secret scanning requires gitleaks to be installed locally:
# macOS
brew install gitleaks
# Linux (via go)
go install github.com/gitleaks/gitleaks/v8@latest
# Or download from releases
# https://github.com/gitleaks/gitleaks/releases
If gitleaks is not installed, the hook will warn but continue (allowing commits without secret scanning).
Handling False Positives
If gitleaks flags a false positive:
- Add the pattern to
.gitleaks.tomlallowlist - Or add
gitleaks:allowcomment on the line
Bypassing Hooks (Emergency Only)
git commit --no-verify -m "message"
Use sparingly - secrets in git history are permanent and expensive to remediate.
Local DB
supabase start
supabase db reset
Troubleshooting
- Stale diffs → clear render cache
- Type errors → ensure workspace tsconfig sync
- Storybook build fails with "Yallist is not a constructor" → The root
package.jsonhas anlru-cacheoverride to fix Babel compatibility. Runrm -rf node_modules bun.lock && bun installif the issue persists.
Dependency Management
All dependencies use explicit semver ranges (e.g., ^1.2.3) rather than latest. This ensures:
- Reproducible builds across environments
- Predictable CI behavior
- Easier security auditing
When adding dependencies, always specify a version range. The lockfile (bun.lock) pins exact versions.
Architecture source of truth: /STACK.md