Back to Baml

BEP Feedback Application

typescript2/app-beps/README.md

0.226.137.0 KB
Original Source

BEP Feedback Application

A standalone web application for managing BAML Enhancement Proposals (BEPs) and their feedback lifecycle. Built with Next.js 15 and Convex for real-time collaboration, it provides a centralized platform for proposal discussion, AI-assisted analysis, and knowledge consolidation.

Table of Contents


Features

BEP Management

  • Create and edit proposals with versioning support
  • Multi-page BEPs - each proposal can have additional wiki-like pages
  • Status tracking - Draft → Proposed → Accepted → Implemented/Rejected/Superseded
  • Full version history - every change creates a new version with diff viewing
  • Real-time updates - all changes sync instantly via Convex subscriptions

Commenting System

  • Threaded comments - hierarchical discussions with parent-child relationships
  • Inline comments - select text to create location-specific comments anchored to specific passages
  • Comment types - Discussion, Concern (blocking), Question
  • Reactions - emoji reactions (thumbs up/down, heart, thinking)
  • Resolution workflow - mark comments as resolved/unresolved
  • Version-scoped - comments are tied to specific BEP versions

Decision & Issue Tracking

  • Record decisions - capture key decisions with rationale and source comments
  • Track open issues - manage action items with assignment and resolution
  • Cross-version navigation - click linked comments to navigate to their version

AI Assistant

  • Interactive Q&A - ask questions about BEP content
  • Version comparison - analyze what changed between versions
  • Quick actions - summarize changes, list addressed concerns
  • Streaming responses - real-time AI responses using Claude

Import/Export

  • Export as ZIP - download BEP with all content, comments, decisions, issues
  • Agent-friendly format - inline comments embedded in markdown for AI readability
  • Import markdown - upload edited files to create new versions

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                              BROWSER                                         │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                     Next.js 15 App (App Router)                      │    │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────────────┐    │    │
│  │  │ BEP List │  │ BEP View │  │ Comments │  │ AI Assistant     │    │    │
│  │  │          │  │          │  │ (live)   │  │ (streaming)      │    │    │
│  │  └──────────┘  └──────────┘  └──────────┘  └──────────────────┘    │    │
│  │                                                                     │    │
│  │         Real-time subscriptions via Convex React hooks              │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                          WebSocket (automatic)
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                           CONVEX BACKEND                                     │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                        Queries (real-time reads)                     │    │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────┐  │    │
│  │  │ beps.list    │  │ comments.    │  │ decisions.byBep          │  │    │
│  │  │ beps.get     │  │   byBep      │  │ issues.byBep             │  │    │
│  │  └───��──────────┘  └──────────────┘  └──────────────────────────┘  │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                       Mutations (writes)                             │    │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────┐  │    │
│  │  │ beps.create  │  │ comments.add │  │ decisions.create         │  │    │
│  │  │ beps.update  │  │ comments.    │  │ issues.create            │  │    │
│  │  │              │  │   resolve    │  │ issues.resolve           │  │    │
│  │  └──────────────┘  └──────────────┘  └──────────────────────────┘  │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                        HTTP Actions (AI)                             │    │
│  │  ┌──────────────────────────────────────────────────────────────┐  │    │
│  │  │ /api/ai/stream-assistant - Streaming AI responses             │  │    │
│  │  └──────────────────────────────────────────────────────────────┘  │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                         CONVEX DATABASE                                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌───────────┐    │
│  │ users    │  │ beps     │  │ comments │  │ decisions│  │ summaries │    │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘  └───────────┘    │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────────────────────────────┐  │
│  │ bepPages │  │openIssues│  │ bepVersions (content history)           │  │
│  └──────────┘  └──────────┘  └──────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────────┘

Tech Stack

LayerTechnologyPurpose
FrameworkNext.js 15 (App Router)Server components, streaming
BackendConvexReal-time database, serverless functions
LanguageTypeScript 5Type safety
StylingTailwind CSS 4Utility-first styling
UI Componentsshadcn/ui (Radix primitives)Accessible, customizable components
IconsLucide ReactIcon library
Markdownreact-markdown + remark-gfmGitHub-flavored markdown rendering
AIAnthropic SDK (Claude Sonnet 4)AI-assisted analysis
Package ManagerBunFast installs, native TypeScript

Getting Started

Prerequisites

Installation

  1. Clone the repository

    bash
    git clone <repository-url>
    cd beps-app
    
  2. Install dependencies

    bash
    bun install
    
  3. Set up Convex

    bash
    bunx convex dev --once
    

    This creates the convex/ folder and links to your Convex project.

  4. Configure environment variables

    Copy .env.local.example to .env.local and fill in the values:

    bash
    cp .env.local.example .env.local
    

    Required variables:

    env
    # Convex (populated automatically by `convex dev`)
    CONVEX_DEPLOYMENT=your-deployment-name
    NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
    
    # Anthropic API (for AI features)
    ANTHROPIC_API_KEY=sk-ant-...
    
    # GitHub OAuth (recommended)
    GITHUB_CLIENT_ID=your-github-client-id
    GITHUB_CLIENT_SECRET=your-github-client-secret
    
    # Login Page Passkey (optional fallback)
    LOGIN_PASSKEY=password
    

    Setting up GitHub OAuth:

    1. Go to GitHub Developer Settings
    2. Click "New OAuth App"
    3. Fill in the details:
      • Application name: BEP Feedback (or your preferred name)
      • Homepage URL: https://beps.boundaryml.com
      • Authorization callback URL: https://beps.boundaryml.com/api/auth/github/callback
    4. Copy the Client ID and generate a Client Secret
    5. Add them to your environment variables (Convex dashboard or hosting provider)

    Vercel Preview Deployments: GitHub OAuth works automatically with Vercel preview deployments. The OAuth flow routes through the production callback URL, then redirects back to the preview deployment with the authenticated user data. Allowed preview URL patterns:

    • *.vercel.app
    • *-boundaryml.vercel.app
    • localhost:* (for local development)
  5. Start the development server

    bash
    bun run dev
    

    This runs both Next.js and Convex dev servers in parallel.

  6. Open the app

    Navigate to http://localhost:3000

First-time Setup

  1. Visit the app - you'll be prompted to enter your name
  2. Your name-based identity is stored locally and synced with Convex
  3. Start creating BEPs!

Project Structure

beps-app/
├── convex/                           # Backend (Convex functions)
│   ├── schema.ts                     # Database schema definition
│   ├── users.ts                      # User queries/mutations
│   ├── beps.ts                       # BEP CRUD + versioning
│   ├── comments.ts                   # Comment operations
│   ├── decisions.ts                  # Decision tracking
│   ├── issues.ts                     # Issue management
│   ├── export.ts                     # Export query
│   ├── http.ts                       # HTTP endpoints (AI streaming)
│   ├── migrations.ts                 # Data migrations
│   └── lib/
│       └── prompts.ts                # AI prompt templates
│
├── src/
│   ├── app/                          # Next.js App Router pages
│   │   ├── layout.tsx                # Root layout with providers
│   │   ├── page.tsx                  # Home (BEP list)
│   │   ├── login/page.tsx            # Login page
│   │   ├── api/agent/beps/route.ts   # Public read-only BEP context API
│   │   └── beps/
│   │       ├── new/page.tsx          # Create BEP
│   │       └── [number]/
│   │           ├── page.tsx          # View BEP
│   │           └── edit/page.tsx     # Edit BEP
│   │
│   ├── components/
│   │   ├── ui/                       # shadcn/ui components
│   │   ├── providers/                # Context providers
│   │   ├── bep/                      # BEP-specific components
│   │   ├── comments/                 # Comment system
│   │   ├── decisions/                # Decision tracking
│   │   ├── issues/                   # Issue management
│   │   └── ai-assistant/             # AI assistant panel
│   │
│   ├── hooks/
│   │   └── use-text-selection.ts     # Text selection for inline comments
│   │
│   └── lib/
│       ├── utils.ts                  # Utility functions
│       ├── markdown.tsx              # Markdown styling
│       ├── export-utils.ts           # ZIP export formatting
│       └── import-utils.ts           # ZIP import parsing
│
├── package.json
├── tsconfig.json
├── next.config.ts
├── components.json                   # shadcn/ui config
└── .env.local.example

Data Model

Core Tables

Users

Simple name-based authentication for lightweight collaboration.

FieldTypeDescription
namestringDisplay name
avatarUrlstring?Optional avatar
role"admin" | "shepherd" | "member"User role
createdAtnumberCreation timestamp

BEPs (Enhancement Proposals)

The core entity representing a proposal.

FieldTypeDescription
numbernumberBEP number (e.g., 1, 2, 3)
titlestringProposal title
status"draft" | "proposed" | "accepted" | "implemented" | "rejected" | "superseded"Current status
contentstringMain markdown content
shepherdsId<"users">[]Assigned shepherds
createdAtnumberCreation timestamp
updatedAtnumberLast update timestamp

BEP Versions

Tracks content history - every edit creates a new version.

FieldTypeDescription
bepIdId<"beps">Parent BEP
versionnumberVersion number (1, 2, 3...)
titlestringTitle at this version
contentstringContent snapshot
pagesSnapshotPageSnapshot[]All pages at this version
editedById<"users">Who made this edit
editNotestring?Optional change description
createdAtnumberWhen version was created

BEP Pages

Additional wiki-like pages within a BEP.

FieldTypeDescription
bepIdId<"beps">Parent BEP
slugstringURL-friendly ID
titlestringPage title
contentstringMarkdown content
ordernumberSort order

Comments

Threaded discussions with inline commenting support.

FieldTypeDescription
bepIdId<"beps">Parent BEP
versionIdId<"bepVersions">Version this comment is on
pageIdId<"bepPages">?Page (null = main content)
authorIdId<"users">Comment author
parentIdId<"comments">?Parent for threading
type"discussion" | "concern" | "question"Comment type
contentstringMarkdown content
anchorAnchor?Inline comment position
reactionsReactions?Emoji reactions
resolvedbooleanResolution status

Anchor structure (for inline comments):

typescript
{
  selectedText: string;   // The exact text commented on
  lineNumber: number;     // Line number in content
  lineContent: string;    // Full line content for matching
}

Decisions

Records of key decisions made during discussion.

FieldTypeDescription
bepIdId<"beps">Parent BEP
titlestringDecision title
descriptionstringWhat was decided
rationalestring?Why this was decided
sourceCommentIdsId<"comments">[]Source comments
participantsId<"users">[]People involved
decidedAtnumberWhen decided

Open Issues

Action items and problems to be resolved.

FieldTypeDescription
bepIdId<"beps">Parent BEP
titlestringIssue title
descriptionstring?Details
raisedById<"users">Who raised it
assignedToId<"users">?Assignee
relatedCommentIdsId<"comments">[]?Related comments
resolvedbooleanResolution status
resolutionstring?How it was resolved

Key Concepts

Version-Scoped Comments

Comments are tied to specific BEP versions. When viewing a historical version:

  • You see only comments from that version
  • The comment form is disabled (read-only mode)
  • A banner indicates you're viewing history

This ensures feedback is always in context and prevents orphaned comments when content changes.

Inline Comments

Select any text in the BEP content to attach a comment directly to that passage:

  1. Select text in the content area
  2. Click the floating "Add Comment" button
  3. Choose comment type and write your feedback
  4. The comment appears as a marker in the right margin

Inline comments are anchored by:

  • The selected text
  • Line number
  • Line content (for matching)

Real-time Collaboration

All data updates are live via Convex WebSocket subscriptions:

  • Open a BEP in two browser windows
  • Add a comment in one - it appears instantly in the other
  • No refresh needed

Issues vs Decisions

  • Issues: Open problems that need resolution (action items)
  • Decisions: Recorded outcomes from discussions (historical record)

Both can be created from comments to maintain traceability.


API Reference

Convex Queries

QueryDescription
beps.list(status?, limit?)List BEPs with optional filtering
beps.getByNumber(number)Get BEP with all related data
beps.getNextNumber()Get next available BEP number
comments.byBep(bepId)All comments for a BEP
comments.byBepPage(...)Comments for specific page/version
decisions.byBep(bepId)All decisions for a BEP
issues.byBep(bepId)All issues for a BEP
export.getFullBepForExport(bepId)Complete BEP data for export

Convex Mutations

MutationDescription
users.getOrCreate(name)Get or create user by name
beps.create(...)Create new BEP
beps.update(...)Update BEP (creates new version)
beps.updateStatus(...)Change BEP status
beps.importVersion(...)Import content as new version
comments.create(...)Add comment
comments.resolve(...)Mark comment resolved
decisions.create(...)Record decision
issues.create(...)Create issue
issues.resolve(...)Resolve issue

HTTP Endpoints

EndpointMethodDescription
/api/ai/stream-assistantPOSTStream AI responses for Q&A
/api/agent/bepsGETPublic read-only BEP listing/fetch for agents
/api/agent/bepsPOSTCreate a new BEP (requires API token)
/api/agent/bepsPUTUpdate an existing BEP (requires API token)
/api/agent/beps/pullGETDownload all BEPs as ZIP archive

Public Agent Endpoint

GET /api/agent/beps

  • Without query params: lists all BEPs.
  • With name=<bep-name-or-id> (also accepts query or q): fuzzy-matches and returns a BEP bundle.
  • Defaults to including all versions/history.
  • Add omitOtherVersions=true to omit historical versions from the returned bundle.
  • Add format=markdown to get raw markdown output instead of JSON.

Query Parameters

ParamTypeRequiredDescription
namestringNoFuzzy BEP matcher (preferred key).
querystringNoAlias for name.
qstringNoAlias for name.
omitOtherVersionsboolean-ishNoTruthy values (1, true, yes, y, on) omit history/* files.
formatstringNojson (default) or markdown.

Success Responses

200 list mode (GET /api/agent/beps with no query):

json
{
  "mode": "list",
  "total": 2,
  "beps": [
    {
      "id": "BEP-001",
      "number": 1,
      "title": "Structured Error Payloads",
      "status": "accepted",
      "updatedAt": "2026-02-18T20:13:34.000Z"
    }
  ],
  "usage": {
    "list": "/api/agent/beps",
    "fetch": "/api/agent/beps?name=<bep-name-or-id>",
    "omitOtherVersions": "/api/agent/beps?name=<bep-name-or-id>&omitOtherVersions=true"
  }
}

200 matched BEP JSON mode (GET /api/agent/beps?name=<...>):

json
{
  "mode": "bep",
  "query": "structured error payloads",
  "matched": {
    "id": "BEP-001",
    "number": 1,
    "title": "Structured Error Payloads",
    "status": "accepted",
    "score": 1.732
  },
  "currentVersion": 5,
  "omitOtherVersions": false,
  "markdown": "<!-- FILE: README.md -->\n# BEP-001 ...",
  "files": [
    {
      "path": "README.md",
      "content": "# BEP-001 ..."
    }
  ]
}

Schema for mode: "bep" JSON responses:

FieldTypeNotes
modestringAlways "bep" in this response shape.
querystringNormalized user query used for fuzzy matching.
matchedobjectMatched BEP metadata: id, number, title, status, score.
currentVersionnumberCurrent BEP version number.
omitOtherVersionsbooleanEchoes resolved filter flag from query params.
markdownstringFlattened markdown bundle content (all selected .md files).
filesarrayPer-file markdown entries: { path, content }.

200 matched BEP markdown mode (GET /api/agent/beps?name=<...>&format=markdown):

markdown
<!-- FILE: README.md -->
# BEP-001 Structured Error Payloads
...

Error Responses

404 (no fuzzy match found):

json
{
  "error": "Could not find a BEP that matches \"<query>\".",
  "suggestions": [
    { "id": "BEP-003", "title": "..." },
    { "id": "BEP-010", "title": "..." }
  ]
}

500 (server misconfiguration, missing Convex URL):

json
{
  "error": "Missing NEXT_PUBLIC_CONVEX_URL environment variable."
}

502 (upstream Convex failure, or unrecognized export payload shape):

json
{
  "error": "Failed to fetch BEP list.",
  "detail": "<error message>"
}
json
{
  "error": "Failed to fetch BEP export data.",
  "detail": "<error message>"
}
json
{
  "error": "Invalid BEP export payload shape."
}

CORS / Preflight

  • OPTIONS /api/agent/beps is supported for browser preflight and returns 204.
  • CORS headers: Access-Control-Allow-Origin: *, Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, Access-Control-Allow-Headers: Content-Type, Authorization.

You should install the beps skill through our skills repository.

Create BEP Endpoint

POST /api/agent/beps

Create a new BEP with optional additional pages (addenda).

Authentication

Requires a Bearer token in the Authorization header:

Authorization: Bearer bep_xxxxxxxxxxxxx

Get your API token from your profile page (/profile).

Request Body

json
{
  "title": "Your Proposal Title",
  "content": "# Your Proposal Title\n\n## Summary\n\n...",
  "pages": [
    {
      "slug": "background",
      "title": "Background Research",
      "content": "# Background\n\nDetailed research..."
    },
    {
      "slug": "examples",
      "title": "Code Examples",
      "content": "# Examples\n\nUsage examples..."
    }
  ]
}
FieldRequiredDescription
titleYesThe BEP title
contentYesFull markdown content
pagesNoArray of additional pages (addenda)

Page object:

FieldRequiredDescription
slugYesURL-safe identifier (e.g., "background", "examples")
titleYesDisplay title for the page
contentYesFull markdown content

Success Response

json
{
  "success": true,
  "bepId": "abc123...",
  "number": 15,
  "formattedId": "BEP-015",
  "createdBy": "Your Name",
  "url": "https://beps.boundaryml.com/beps/15"
}

Update BEP Endpoint

PUT /api/agent/beps

Update an existing BEP with optional page management.

Request Body

json
{
  "number": 15,
  "content": "# Updated Content\n\n...",
  "pages": [
    {
      "slug": "background",
      "title": "Updated Background",
      "content": "# Background\n\nUpdated research..."
    },
    {
      "slug": "new-addendum",
      "title": "New Addendum",
      "content": "# New Section\n\nNew content..."
    }
  ],
  "editNote": "Added new addendum, updated background",
  "versionMode": "new"
}
FieldRequiredDescription
numberYesThe BEP number to update
titleNoUpdated title
contentNo*Updated markdown content
pagesNo*Updated pages array (replaces all existing pages)
editNoteNoNote describing the changes
versionModeNo"new" (default) creates a new version, "current" updates in place

*At least one of title, content, or pages must be provided.

Page Behavior on Update:

  • Pages with matching slugs are updated
  • Pages with new slugs are created
  • Pages that exist but aren't in the array are deleted
  • To keep existing pages unchanged, omit the pages field entirely

Success Response

json
{
  "success": true,
  "bepId": "abc123...",
  "number": 15,
  "formattedId": "BEP-015",
  "versionNumber": 3,
  "versionAction": "created",
  "pagesCreated": 1,
  "pagesUpdated": 1,
  "pagesDeleted": 0,
  "updatedBy": "Your Name",
  "url": "https://beps.boundaryml.com/beps/15"
}

Pull All BEPs Endpoint

GET /api/agent/beps/pull

Download all BEPs as a ZIP archive. No authentication required.

Usage

bash
# Download to a new timestamped folder (copy mode)
curl -o all-beps.zip "https://beps.boundaryml.com/api/agent/beps/pull"
unzip all-beps.zip -d all-beps-$(date +%Y%m%d)

# Download and replace existing folder (inplace mode)
curl -o all-beps.zip "https://beps.boundaryml.com/api/agent/beps/pull"
rm -rf ./all-beps && unzip all-beps.zip -d .

Response

Returns a ZIP file (application/zip) containing:

all-beps/
├── Claude.md                    # Main index with status-sorted list
├── NEW-BEP/
│   └── INSTRUCTIONS.md          # API usage instructions
├── BEP-001-proposal-slug/
│   ├── meta.json                # Metadata (status, version, pages)
│   ├── README.md                # Full proposal content
│   └── pages/                   # Additional pages (if any)
└── BEP-002-another-slug/
    └── ...

Headers:

  • Content-Type: application/zip
  • Content-Disposition: attachment; filename="all-beps-YYYY-MM-DD.zip"

Export/Import

Export Format

When you export a BEP, you get a ZIP file with this structure:

BEP-001/
├── README.md                 # Main content with inline comments embedded
├── pages/
│   ├── background.md         # Additional pages with comments
│   ├── tooling.md
│   └── background/           # One level of nesting supported
│       └── research.md       # Child of the "background" page (parentSlug)
├── AGENT_CONTEXT.md          # AI-friendly summary
├── metadata.json             # Machine-readable metadata
├── discussion/
│   ├── issues.md             # Open and resolved issues
│   └── decisions.md          # Recorded decisions
└── history/
    ├── versions.md           # Version history
    └── summaries.md          # AI-generated summaries

Comment Embedding

Comments are embedded directly in the markdown content:

Inline comments appear next to the referenced text:

markdown
**catch as an operator on blocks**.

<!-- INLINE_COMMENT
version: 3
line: 4
selected_text: "catch as an operator on blocks"
author: Dave
date: 2025-01-20
type: suggestion
status: open
-->
> Should we add an example showing operator precedence?
<!-- /INLINE_COMMENT -->

General comments appear at the end:

markdown
---

<!-- GENERAL_COMMENTS -->

## Comments

### Concern by Alice (v2, 2025-01-15) [OUTDATED]
> This might confuse newcomers

<!-- /GENERAL_COMMENTS -->

Import Workflow

  1. Export a BEP
  2. Edit the markdown files externally (IDE, AI agent, etc.)
  3. Import the files back
  4. A new version is created with clean content (comments stripped)
  5. The new version starts with zero comments - users add fresh feedback

AI Integration

The AI Assistant uses Claude (Sonnet 4) to help analyze and understand BEPs.

Features

  • Version comparison: "What changed between v2 and v5?"
  • Summarize changes: Quick summary of what's different
  • List addressed concerns: Find which concerns were resolved
  • Custom questions: Ask anything about the BEP content

How It Works

  1. Open the AI Assistant panel on any BEP
  2. Select versions to compare (optional)
  3. Ask a question or use a quick action
  4. Watch the streaming response

The AI has full context including:

  • Content from both versions (if comparing)
  • All comments from those versions
  • Decisions and issues
  • Version metadata

Configuration

Set your Anthropic API key in the Convex dashboard:

  1. Go to your Convex project
  2. Navigate to Settings → Environment Variables
  3. Add ANTHROPIC_API_KEY with your key

Development

Theming

Colors and dark mode are defined in src/app/globals.css with semantic tokens. See docs/THEMING.md for usage and extension guidelines.

Markdown Code Block Tips

  • Unlabeled fenced code blocks default to TypeScript highlighting (useful for BAML snippets).

  • For ASCII/Unicode diagrams, use text or plaintext fences to preserve spacing/alignment:

    md
    ```text
    ┌───────┐
    │ Box   │
    └───────┘
    ```
    

Available Scripts

bash
# Development (runs Next.js + Convex in parallel)
bun run dev

# Run only Next.js
bun run dev:next

# Run only Convex
bun run dev:convex

# Build for production
bun run build

# Start production server
bun run start

# Run linting
bun run lint

# Check the BAML project
bun run baml:check

# Regenerate the ignored BAML v1 TypeScript SDK
bun run baml:generate

Adding shadcn/ui Components

bash
bunx --bun shadcn@latest add <component-name>

Components are added to src/components/ui/.

Database Migrations

When you need to migrate data, create a migration in convex/migrations.ts and run it via a Convex action.

Deploying

  1. Deploy Convex

    bash
    bunx convex deploy
    
  2. Deploy Next.js (e.g., to Vercel)

    • Connect your repository to Vercel
    • Set environment variables:
      • NEXT_PUBLIC_CONVEX_URL - Your production Convex URL
    • Deploy
  3. Set Convex environment variables

    • In Convex dashboard, add ANTHROPIC_API_KEY to production

Design Principles

  1. Data-first: BEPs, comments, decisions are structured data, not files
  2. Real-time by default: All data updates are live via Convex subscriptions
  3. AI as assistant, human as authority: AI suggests, humans approve
  4. Version everything: BEP content changes are tracked as versions
  5. Export-friendly: Data can always be exported to markdown/git if needed

License

[Add your license here]


Contributing

[Add contribution guidelines here]