better-chatbot
better-chatbot project conventions and standards. Use for contributing code, following three-tier tool system (MCP/Workflow/Default), or encountering server action validators, repository patterns, component design errors.
git clone --depth 1 https://github.com/secondsky/claude-skills /tmp/better-chatbot && cp -r /tmp/better-chatbot/plugins/better-chatbot/skills/better-chatbot ~/.claude/skills/better-chatbotSKILL.md
# better-chatbot Contribution & Standards Skill
**Status**: Production Ready
**Version**: 3.0.0 (Optimized with progressive disclosure)
**Last Updated**: 2025-12-17
**Dependencies**: None (references better-chatbot project)
**Latest Versions**: Next.js 16.0.3, Vercel AI SDK 5.0.98, Better Auth 1.3.34, Drizzle ORM 0.41.0
---
## Overview
**better-chatbot** is an open-source AI chatbot platform for individuals and teams, built with Next.js 15 and Vercel AI SDK v5. It combines multi-model AI support (OpenAI, Anthropic, Google, xAI, Ollama, OpenRouter) with advanced features like MCP (Model Context Protocol) tool integration, visual workflow builder, realtime voice assistant, and team collaboration.
**This skill teaches Claude the project-specific conventions and patterns** used in better-chatbot to ensure contributions follow established standards and avoid common pitfalls.
---
## Quick Start
### Setup Development Environment
```bash
# Clone and install
git clone https://github.com/cgoinglove/better-chatbot.git
cd better-chatbot
pnpm install
# Configure environment
cp .env.example .env
# Add your API keys: OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.
# Add database URL: DATABASE_URL="postgresql://..."
# Add auth secret: BETTER_AUTH_SECRET="your-secret"
# Run development server
pnpm dev
```
### Core Commands
- `pnpm dev` - Start development server
- `pnpm build` - Production build
- `pnpm test` - Run unit tests
- `pnpm test:e2e` - Run E2E tests (requires DB + API keys)
- `pnpm check` - Lint + type check + tests (run before PR)
### Repository Structure
```
better-chatbot/
├── src/
│ ├── app/ # Next.js routes + API
│ ├── components/ # UI components by domain
│ ├── lib/ # Core logic (ai, db, validations)
│ ├── hooks/ # React hooks
│ └── types/ # TypeScript types
├── tests/ # E2E Playwright tests
└── drizzle/ # Database migrations
```
---
## Core Architecture
### Three-Tier Tool System
Better-chatbot uses a three-tier tool architecture for AI capabilities:
1. **MCP Tools** - External tools via Model Context Protocol
2. **Workflow Tools** - Visual DAG-based workflows
3. **Default Tools** - Built-in app tools (web search, image generation, etc.)
**For details**: Load `references/tool-system.md` when implementing tools or understanding tool execution.
### API Patterns
Routes follow RESTful conventions with streaming-first architecture and defensive programming using `safe()` wrapper.
**For details**: Load `references/api-architecture.md` when building API routes or implementing streaming.
### Component Philosophy
Components organized by feature using compound component pattern. Tools execution separated from rendering.
**For details**: Load `references/component-patterns.md` when building UI components.
### Database & Repository Pattern
All database access abstracted through repository classes using Drizzle ORM.
**For details**: Load `references/database-patterns.md` when implementing database queries.
---
## Top 5 Errors (Must Know)
### Error #1: Forgetting Auth Checks in Server Actions
**Error**: Unauthorized users accessing protected actions
**Why**: Manual auth implementation is inconsistent
**Prevention**: Use `validatedActionWithUser` or `validatedActionWithAdminPermission`
```typescript
// ❌ BAD: Manual auth check
export async function updateProfile(data: ProfileData) {
const session = await getSession()
if (!session) throw new Error("Unauthorized")
// ... rest of logic
}
// ✅ GOOD: Use validator
export const updateProfile = validatedActionWithUser(
profileSchema,
async (data, formData, user) => {
// user is guaranteed to exist, auto-error handling
}
)
```
### Error #2: Tool Type Mismatches
**Error**: Runtime type errors when executing tools
**Why**: Not checking tool type before execution
**Prevention**: Use branded type tags for runtime narrowing
```typescript
// ❌ BAD: Assuming tool type
const result = await executeMcpTool(tool)
// ✅ GOOD: Check tool type
if (VercelAIMcpToolTag.isMaybe(tool)) {
const result = await executeMcpTool(tool)
} else if (VercelAIWorkflowToolTag.isMaybe(tool)) {
const result = await executeWorkflowTool(tool)
}
```
### Error #3: FormData Parsing Errors
**Error**: Inconsistent error handling for form submissions
**Why**: Manual FormData parsing with ad-hoc validation
**Prevention**: Validators handle parsing automatically
```typescript
// ❌ BAD: Manual parsing
const name = formData.get("name") as string
if (!name) throw new Error("Name required")
// ✅ GOOD: Validator with Zod
const schema = z.object({ name: z.string().min(1) })
export const action = validatedAction(schema, async (data) => {
// data.name is validated and typed
})
```
### Error #4: Cross-Field Validation Issues
**Error**: Password mismatch validation not working
**Why**: Separate validation for related fields
**Prevention**: Use Zod `superRefine`
```typescript
// ❌ BAD: Separate checks
if (data.password !== data.confirmPassword) { /* error */ }
// ✅ GOOD: Zod superRefine
const schema = z.object({
password: z.string(),
confirmPassword: z.string()
}).superRefine((data, ctx) => {
if (data.password !== data.confirmPassword) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Passwords don't match",
path: ["confirmPassword"]
})
}
})
```
### Error #5: Zustand State Mutation
**Error**: State updates not triggering re-renders
**Why**: Mutating state directly instead of creating new objects
**Prevention**: Use shallow updates with spread operator
```typescript
// ❌ BAD: Direct mutation
set((state) => {
state.user.name = "New Name" // Mutation!
})
// ✅ GOOD: Shallow update
set((state) => ({
user: { ...state.user, name: "New Name" }
}))
```
**For all errors**: Load `references/common-errors.md` when debugging issues beyond the top 5.
---
## Critical Rules
### Always Do
✅ Use `validatedActionWithUser`Role-based access control (RBAC) with permissions and policies. Use for admin dashboards, enterprise access, multi-tenant apps, fine-grained authorization, or encountering permission hierarchies, role inheritance, policy conflicts.
100+ animated React components (Aceternity UI) for Next.js with Tailwind. Use for hero sections, parallax, 3D effects, or encountering animation, shadcn CLI integration errors.
shadcn/ui AI chat components for conversational interfaces. Use for streaming chat, tool/function displays, reasoning visualization, or encountering Next.js App Router setup, Tailwind v4 integration, AI SDK v5 migration errors.
Vercel AI SDK v5 for backend AI (text generation, structured output, tools, agents). Multi-provider. Use for server-side AI or encountering AI_APICallError, AI_NoObjectGeneratedError, streaming failures.
Vercel AI SDK v5 React hooks (useChat, useCompletion, useObject) for AI chat interfaces. Use for React/Next.js AI apps or encountering parse stream errors, no response, streaming issues.
Secure API authentication with JWT, OAuth 2.0, API keys. Use for authentication systems, third-party integrations, service-to-service communication, or encountering token management, security headers, auth flow errors.
Creates comprehensive API changelogs documenting breaking changes, deprecations, and migration strategies for API consumers. Use when managing API versions, communicating breaking changes, or creating upgrade guides.
Verifies API contracts between services using consumer-driven contracts, schema validation, and tools like Pact. Use when testing microservices communication, preventing breaking changes, or validating OpenAPI specifications.