This document provides instructions for AI agents working on the Vibed Coding codebase. Read this before making any changes.
Vibed Coding analyzes git history to reveal developer craftsmanship patterns. The stack is:
- Frontend: Next.js 14+ (App Router), TypeScript, Tailwind CSS, shadcn/ui
- Backend: Next.js Route Handlers (Vercel)
- Auth: Supabase Auth with GitHub OAuth
- Database: Supabase Postgres with Row Level Security
- Background Jobs: Inngest (primary) or standalone worker (fallback)
- LLM: Anthropic Claude, OpenAI, or Google Gemini (server-side only, configurable)
See docs/PRD.md for full product requirements and docs/architecture/inngest-integration.md for job processing details.
Key Reference Docs:
- How Vibe Coding Profile Works — Product-friendly explanation of analysis
- Vibed Analysis Pipeline — Technical architecture with algorithms and data flow
- Node.js 18+
- Docker (for local Supabase)
- Supabase CLI (
npm install -g supabase) - GitHub OAuth App credentials
IMPORTANT: Do not start the dev server automatically. The user typically runs it themselves in a separate terminal.
Before running any server commands, check if the server is already running:
# Check if Next.js dev server is running
lsof -i :8108
# Check if Supabase is running
npm run supabase:statusIf Supabase is not running:
npm run supabase:startCRITICAL: Always use the npm run supabase:* scripts instead of npx supabase directly. The npm scripts load environment variables (like GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET) from apps/web/.env.local before invoking Supabase commands. Using npx supabase directly will cause OAuth to fail with 400 errors.
If Next.js is not running and user asks you to start it:
npm run devCopy the example env file and fill in values:
cp .env.example apps/web/.env.localRequired variables:
# Supabase (from `npm run supabase:status` for local)
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=<from supabase status>
SUPABASE_SERVICE_ROLE_KEY=<from supabase status>
# GitHub OAuth (create at https://github.com/settings/developers)
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
# Claude API
ANTHROPIC_API_KEY=
# App
NEXT_PUBLIC_APP_URL=http://localhost:8108The local Supabase runs in Docker. Always develop against local first.
1. Get the database URL:
npm run supabase:status
# Look for "DB URL: postgresql://postgres:postgres@127.0.0.1:XXXXX/postgres"2. Run SQL using psql:
psql "postgresql://postgres:postgres@127.0.0.1:XXXXX/postgres" -c "YOUR SQL HERE"CRITICAL for AI Agents:
- Do NOT use MCP Supabase tools for local dev operations—they connect to remote projects
- Always use
psqlwith the local DB URL fromnpm run supabase:status - The MCP Supabase tools are for remote database operations only
The project may have multiple remote environments (development, staging, production). Use the Supabase CLI to switch:
# Check which environment is currently linked
npx supabase projects list
# Link to a specific project
npx supabase link --project-ref <PROJECT_REF>When to use each:
- Local: Default for all development work
- Development remote: Testing against shared dev data, deploying previews, pushing migrations
- Production remote: Only for production deployments or critical debugging
- Never modify existing migration files that have been applied
- Never reset the database unless absolutely necessary
- Always create new migration files for schema changes
- Test locally first before pushing to remote
# Create a new migration file
npm run supabase:migration:new <migration_name>
# This creates: supabase/migrations/<timestamp>_<migration_name>.sqlLocal (default approach):
# Apply pending migrations (preserves data)
npm run supabase:migration:up
# Check migration status
npm run supabase:statusRemote:
# Push migrations to linked remote project (use npx for remote operations)
npx supabase db pushOnly use npm run supabase:reset when:
- You need to completely rebuild the schema from scratch
- There are migration conflicts that cannot be resolved
- Explicitly requested by the user
WARNING: db reset destroys all local data including test users and analysis results.
-- Use gen_random_uuid() for UUID defaults (built-in)
id UUID PRIMARY KEY DEFAULT gen_random_uuid()
-- NOT uuid_generate_v4() which requires uuid-ossp extension
-- Always include IF NOT EXISTS for safety
CREATE TABLE IF NOT EXISTS users (...);
-- Use explicit schema references
CREATE TABLE public.users (...);
-- Add RLS policies in the same migration as the table
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;
CREATE POLICY users_select ON public.users
FOR SELECT USING (auth.uid() = id);# Local
npm run supabase:status
# Remote (after linking) - use npx for remote operations
npx supabase migration list --linkedFor testing authenticated flows locally, you can create a test user in the local Supabase instance.
To create a test user:
- Start local Supabase:
npm run supabase:start - Go to local Supabase Studio:
http://127.0.0.1:54323 - Navigate to Authentication → Users
- Click "Add User" and enter test credentials
Alternative via SQL:
# Get DB URL first
npm run supabase:status
# Create user (replace XXXXX with actual port, EMAIL and PASSWORD with your values)
psql "postgresql://postgres:postgres@127.0.0.1:XXXXX/postgres" -c "
INSERT INTO auth.users (
id,
email,
encrypted_password,
email_confirmed_at,
created_at,
updated_at
) VALUES (
gen_random_uuid(),
'YOUR_TEST_EMAIL',
crypt('YOUR_TEST_PASSWORD', gen_salt('bf')),
now(),
now(),
now()
);
"For GitHub OAuth testing locally:
- Create a GitHub OAuth App at https://github.com/settings/developers
- Set callback URL to
http://localhost:54321/auth/v1/callback - Add credentials to
apps/web/.env.local
- No
anytypes—use proper typing orunknownwith type guards - Use interfaces for object shapes, types for unions/primitives
- Export types from dedicated
types.tsfiles
- Store all timestamps as
TIMESTAMPTZin Postgres (UTC) - Use
date-fnsfor date manipulation - Convert to user's timezone only for display
import { format, parseISO } from 'date-fns';
import { formatInTimeZone } from 'date-fns-tz';
// Formatting for display
const displayDate = formatInTimeZone(
parseISO(commit.author_date),
userTimezone,
'MMM d, yyyy HH:mm'
);src/
├── app/ # Next.js App Router pages
│ ├── (auth)/ # Auth-related routes (grouped)
│ ├── (dashboard)/ # Authenticated routes (grouped)
│ └── api/ # Route handlers
├── components/
│ ├── ui/ # shadcn/ui components
│ └── [feature]/ # Feature-specific components
├── lib/
│ ├── supabase/ # Supabase client utilities
│ ├── github/ # GitHub API client
│ ├── analysis/ # Analysis logic
│ └── utils/ # Shared utilities
└── types/ # TypeScript type definitions
// External imports first
import { useState } from 'react';
import { useRouter } from 'next/navigation';
// Internal imports (absolute paths)
import { Button } from '@/components/ui/button';
import { analyzeCommits } from '@/lib/analysis';
import type { CommitEvent } from '@/types';// API routes: return proper error responses
export async function POST(request: Request) {
try {
// ... logic
} catch (error) {
console.error('Analysis failed:', error);
return Response.json(
{ error: 'Analysis failed' },
{ status: 500 }
);
}
}
// Client: use error boundaries and loading states1. PRD → 2. Implementation Tracker → 3. Database → 4. Backend → 5. UI → 6. Test → 7. Document
Database migrations MUST be applied before any other implementation.
- Read
docs/PRD.mdfor product context - Check
docs/implementation-trackers/for current progress - Verify local Supabase is running:
npm run supabase:status - Check for pending migrations:
npm run supabase:status
When creating implementation tasks, use this format:
### F1. Database Schema
**Task:** Create users and repos tables with RLS policies
**Deliverables:**
- [ ] Migration file created
- [ ] Tables created with all columns
- [ ] RLS policies applied
- [ ] Indexes added
**Files:** `supabase/migrations/XXXXXX_create_users_repos.sql`
**Success Criteria:** `npm run supabase:migration:up` succeeds, RLS tests pass
**Dependencies:** None
**Blocks:** F2, P1, P2Work that must complete before parallel work can begin:
- Database migrations
- Shared types and utilities
- Auth guards and middleware
Each task must declare what it blocks and what it depends on.
After foundation, work can proceed in parallel:
- Each phase is self-contained
- Clear inputs/outputs defined
- Minimal shared dependencies
- Use conventional commit format:
type(scope): description - Types:
feat,fix,docs,style,refactor,test,chore - Keep commits focused—one logical change per commit
# Good
feat(auth): implement GitHub OAuth flow
fix(analysis): handle repos with no commits
chore(deps): update supabase-js to 2.39.0
# Bad
update stuff
fix bugs
WIP- Only commit files you directly worked on for the current task
- Verify staged files:
git status --short git diff --stat --cached
- Run type check:
npm run type-check - Run lint:
npm run lint
When AI assists with code, include co-author:
feat(analysis): implement commit classification
Co-Authored-By: Claude <noreply@anthropic.com>
Before marking any task complete:
- TypeScript compiles without errors (
npm run type-check) - ESLint passes (
npm run lint) - Migrations apply cleanly (
npm run supabase:migration:up) - RLS policies tested (query as different users)
- Loading states implemented
- Error states handled
- No
console.logleft in production code - No hardcoded secrets or credentials
# Check Docker is running
docker ps
# Reset Supabase (destroys local data)
npm run supabase:stop
npm run supabase:start# Check current state
npm run supabase:status
# If stuck, repair migration history (careful!) - use npx for advanced operations
npx supabase migration repair --status applied <version>- Most common cause: Supabase was started without env vars. Restart with
npm run supabase:stop && npm run supabase:start - Stale browser state: Clear cookies and site data for
localhostin your browser, then try again - Check callback URL in GitHub OAuth App matches:
http://localhost:54321/auth/v1/callback - Verify
GITHUB_CLIENT_IDandGITHUB_CLIENT_SECRETare set inapps/web/.env.local - Check Supabase Auth settings in local Studio:
http://127.0.0.1:54323 - Use
localhost:8108consistently (not127.0.0.1:8108) to avoid OAuth state mismatches
MCP Supabase tools connect to remote projects, not local. For local development:
- Use
psqlwith local DB URL - Use Supabase Studio at
http://127.0.0.1:54323
| Command | Purpose |
|---|---|
npm run supabase:start |
Start local Supabase (loads env vars) |
npm run supabase:stop |
Stop local Supabase |
npm run supabase:status |
Show local URLs and keys |
npm run supabase:migration:new <name> |
Create migration |
npm run supabase:migration:up |
Apply migrations |
npm run supabase:reset |
Reset database (destroys data) |
npm run dev |
Start Next.js dev server |
npm run dev:web |
Start only the web app |
npm run type-check |
TypeScript check |
npm run lint |
ESLint check |
- Minimize new docs—update existing files instead
- Update implementation tracker when completing tasks
- Keep PRD.md current if requirements change
- This file (Agents.md) is the source of truth for agent behavior
When reviewing code or PRs, apply deep analysis ("ultrathink") to validate reasonableness:
- Check alignment: Does the code match the plan or PRD?
- Identify gaps: What will NOT work? What will break?
- Surface oversights: What was overlooked or not considered?
- Edge cases: Are all edge cases handled?
- Reduce complexity: Is there a simpler approach that achieves the same outcome?
- Remove redundancy: Are there unnecessary abstractions or indirections?
- Question scope: Is the change doing more than required?
- Existing functionality: Will this break current behavior?
- Dependent code: What other code relies on the modified paths?
- Test coverage: Are existing tests still valid? Do they need updates?
- Backward compatibility: Are APIs/interfaces preserved or properly versioned?
- Code matches PRD/plan intent
- No obvious failure modes overlooked
- Simplest reasonable approach used
- No unnecessary scope creep
- Existing tests still pass
- New tests cover changed behavior
- No breaking changes to existing functionality (or documented if intentional)
Last updated: 2026-01-22