checkpoint: pre-split branch cleanup

This commit is contained in:
ZenchantLive 2026-03-03 16:43:42 -08:00
parent 4c2ae2e5b7
commit b5db7a7753
276 changed files with 35912 additions and 60119 deletions

1
.agent/skills/shadcn-ui Symbolic link
View file

@ -0,0 +1 @@
/mnt/c/Users/Zenchant/codex/beadboard/.agents/skills/shadcn-ui/

File diff suppressed because it is too large Load diff

View file

@ -1,306 +0,0 @@
### shadcn/ui Chart Component - Installation
Source: https://ui.shadcn.com/docs/components/chart
The chart component in shadcn/ui is built on Recharts, providing direct access to all Recharts capabilities with consistent theming.
```bash
npx shadcn@latest add chart
```
--------------------------------
### shadcn/ui Chart Component - Basic Usage
Source: https://ui.shadcn.com/docs/components/chart
The ChartContainer wraps your Recharts component and accepts a config prop for theming. Requires `min-h-[value]` for responsiveness.
```tsx
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
]
export function BarChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - ChartConfig with Custom Colors
Source: https://ui.shadcn.com/docs/components/chart
You can define custom colors directly in the configuration using hex values or CSS variables.
```tsx
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
theme: {
light: "#2563eb",
dark: "#60a5fa",
},
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
```
--------------------------------
### shadcn/ui Chart Component - CSS Variables
Source: https://ui.shadcn.com/docs/components/chart
Add chart color variables to your globals.css for consistent theming.
```css
:root {
/* Chart colors */
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.546 0.198 38.228);
--chart-4: oklch(0.596 0.151 343.253);
--chart-5: oklch(0.546 0.158 49.157);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.698 0.141 24.311);
--chart-4: oklch(0.676 0.172 171.196);
--chart-5: oklch(0.578 0.192 302.85);
}
```
--------------------------------
### shadcn/ui Chart Component - Line Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a line chart with shadcn/ui charts component.
```tsx
import { Line, LineChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
price: {
label: "Price",
color: "var(--chart-1)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", price: 186 },
{ month: "February", price: 305 },
{ month: "March", price: 237 },
{ month: "April", price: 203 },
{ month: "May", price: 276 },
]
export function LineChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<LineChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} tickFormatter={(value) => `$${value}`} />
<Line
dataKey="price"
stroke="var(--color-price)"
strokeWidth={2}
dot={false}
/>
<ChartTooltip content={<ChartTooltipContent />} />
</LineChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Area Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating an area chart with gradient fill and legend.
```tsx
import { Area, AreaChart, XAxis, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
desktop: { label: "Desktop", color: "var(--chart-1)" },
mobile: { label: "Mobile", color: "var(--chart-2)" },
} satisfies import("@/components/ui/chart").ChartConfig
export function AreaChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<AreaChart data={chartData}>
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} />
<Area
dataKey="desktop"
fill="var(--color-desktop)"
stroke="var(--color-desktop)"
fillOpacity={0.3}
/>
<Area
dataKey="mobile"
fill="var(--color-mobile)"
stroke="var(--color-mobile)"
fillOpacity={0.3}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</AreaChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Pie Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a pie/donut chart with shadcn/ui.
```tsx
import { Pie, PieChart } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
chrome: { label: "Chrome", color: "var(--chart-1)" },
safari: { label: "Safari", color: "var(--chart-2)" },
firefox: { label: "Firefox", color: "var(--chart-3)" },
} satisfies import("@/components/ui/chart").ChartConfig
const pieData = [
{ browser: "Chrome", visitors: 275, fill: "var(--color-chrome)" },
{ browser: "Safari", visitors: 200, fill: "var(--color-safari)" },
{ browser: "Firefox", visitors: 187, fill: "var(--color-firefox)" },
]
export function PieChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<PieChart>
<Pie
data={pieData}
dataKey="visitors"
nameKey="browser"
cx="50%"
cy="50%"
outerRadius={80}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</PieChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui ChartTooltipContent Props
Source: https://ui.shadcn.com/docs/components/chart
The ChartTooltipContent component accepts these props for customizing tooltip behavior.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `labelKey` | string | "label" | Key for tooltip label |
| `nameKey` | string | "name" | Key for tooltip name |
| `indicator` | "dot" \| "line" \| "dashed" | "dot" | Indicator style |
| `hideLabel` | boolean | false | Hide label |
| `hideIndicator` | boolean | false | Hide indicator |
--------------------------------
### shadcn/ui Chart Component - Accessibility
Source: https://ui.shadcn.com/docs/components/chart
Enable keyboard navigation and screen reader support by adding the accessibilityLayer prop.
```tsx
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" />
<Bar dataKey="desktop" fill="var(--color-desktop)" />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
```
This adds:
- Keyboard arrow key navigation
- ARIA labels for chart elements
- Screen reader announcements for data values
--------------------------------
### shadcn/ui Chart Component - Recharts Dependencies
Source: https://ui.shadcn.com/docs/components/chart
The chart component requires the following Recharts dependencies to be installed.
```bash
pnpm add recharts
npm install recharts
yarn add recharts
```
Recharts provides the following chart types:
- Area, Bar, Line, Pie, Composed
- Radar, RadialBar, Scatter
- Funnel, Treemap

View file

@ -1,145 +0,0 @@
# shadcn/ui Learning Guide
This guide helps you learn shadcn/ui from basics to advanced patterns.
## Learning Path
### 1. Understanding the Philosophy
shadcn/ui is different from traditional component libraries:
- **Copy-paste components**: Components are copied into your project, not installed as packages
- **Full customization**: You own the code and can modify it freely
- **Built on Radix UI**: Provides accessibility primitives
- **Styled with Tailwind**: Uses utility classes for consistent styling
### 2. Core Concepts to Master
#### Class Variance Authority (CVA)
Most components use CVA for variant management:
```tsx
const buttonVariants = cva(
"base-classes",
{
variants: {
variant: {
default: "variant-classes",
destructive: "destructive-classes",
},
size: {
default: "size-classes",
sm: "small-classes",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
```
#### cn Utility Function
The `cn` function combines classes and resolves conflicts:
```tsx
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
```
### 3. Installation Checklist
- [ ] Initialize a new project (Next.js, Vite, or Remix)
- [ ] Install Tailwind CSS
- [ ] Run `npx shadcn@latest init`
- [ ] Configure CSS variables
- [ ] Install first component: `npx shadcn@latest add button`
### 4. Essential Components to Learn First
1. **Button** - Learn variants and sizes
2. **Input** - Form inputs with labels
3. **Card** - Container components
4. **Form** - Form handling with React Hook Form
5. **Dialog** - Modal windows
6. **Select** - Dropdown selections
7. **Toast** - Notifications
### 5. Common Patterns
#### Form Pattern
Every form follows this structure:
```tsx
1. Define Zod schema
2. Create form with useForm
3. Wrap with Form component
4. Add FormField for each input
5. Handle submission
```
#### Component Customization Pattern
To customize a component:
1. Copy component to your project
2. Modify the variants
3. Add new props if needed
4. Update types
### 6. Best Practices
- Always use TypeScript
- Follow the existing component structure
- Use semantic HTML when possible
- Test with screen readers for accessibility
- Keep components small and focused
### 7. Advanced Topics
- Creating custom components from scratch
- Building complex forms with validation
- Implementing dark mode
- Optimizing for performance
- Testing components
## Practice Exercises
### Exercise 1: Basic Setup
1. Create a new Next.js project
2. Set up shadcn/ui
3. Install and customize a Button component
4. Add a new variant "gradient"
### Exercise 2: Form Building
1. Create a contact form with:
- Name input (required)
- Email input (email validation)
- Message textarea (min length)
- Submit button with loading state
### Exercise 3: Component Combination
1. Build a settings page using:
- Card for layout
- Sheet for mobile menu
- Select for dropdowns
- Switch for toggles
- Toast for notifications
### Exercise 4: Custom Component
1. Create a custom Badge component
2. Support variants: default, secondary, destructive, outline
3. Support sizes: sm, default, lg
4. Add icon support
## Resources
- [Official Documentation](https://ui.shadcn.com)
- [GitHub Repository](https://github.com/shadcn/ui)
- [Examples Gallery](https://ui.shadcn.com/examples)
- [Radix UI Primitives](https://www.radix-ui.com/primitives)
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)

File diff suppressed because it is too large Load diff

View file

@ -1,586 +0,0 @@
# shadcn.io Component Library
shadcn.io is a comprehensive React UI component library built on shadcn/ui principles, providing developers with production-ready, composable components for modern web applications. The library serves as a centralized resource for React developers who need high-quality UI components with TypeScript support, ranging from basic interactive elements to advanced AI-powered integrations. Unlike traditional component libraries that require package installations, shadcn.io components are designed to be copied directly into your project, giving you full control and customization capabilities.
The library encompasses four major categories: composable UI components (terminal, dock, credit cards, QR codes, color pickers), chart components built with Recharts, animation components with Tailwind CSS integration, and custom React hooks for state management and lifecycle operations. Each component follows best practices for accessibility, performance, and developer experience, with comprehensive TypeScript definitions and Next.js compatibility. The platform emphasizes flexibility and customization, allowing developers to modify components at the source level rather than being constrained by package APIs.
## Core Components
### Terminal Component
Interactive terminal emulator with typing animations and command execution simulation for developer-focused interfaces.
```tsx
import { Terminal } from "@/components/ui/terminal"
export default function DemoTerminal() {
return (
npm install @repo/terminalInstalling dependencies...npm start
)
}
```
### Dock Component
macOS-style application dock with smooth magnification effects on hover, perfect for navigation menus.
```tsx
import { Dock, DockIcon } from "@/components/ui/dock"
import { Home, Settings, User, Mail } from "lucide-react"
export default function AppDock() {
return (
)
}
```
### Credit Card Component
Interactive 3D credit card component with flip animations for payment forms and card displays.
```tsx
import { CreditCard } from "@/components/ui/credit-card"
import { useState } from "react"
export default function PaymentForm() {
const [cardData, setCardData] = useState({
number: "4532 1234 5678 9010",
holder: "JOHN DOE",
expiry: "12/28",
cvv: "123"
})
return (
console.log("Card flipped:", flipped)}
/>
)
}
```
### Image Zoom Component
Zoomable image component with smooth modal transitions for image galleries and product displays.
```tsx
import { ImageZoom } from "@/components/ui/image-zoom"
export default function ProductGallery() {
return (
)
}
```
### QR Code Component
Generate and display customizable QR codes with styling options for links, contact information, and authentication.
```tsx
import { QRCode } from "@/components/ui/qr-code"
export default function ShareDialog() {
const shareUrl = "https://shadcn.io"
return (
Scan to visit shadcn.io
)
}
```
### Color Picker Component
Advanced color selection component supporting multiple color formats (HEX, RGB, HSL) with preview.
```tsx
import { ColorPicker } from "@/components/ui/color-picker"
import { useState } from "react"
export default function ThemeCustomizer() {
const [color, setColor] = useState("#3b82f6")
return (
Selected: {color}
)
}
```
## Chart Components
### Bar Chart Component
Clean bar chart component for data comparison and categorical analysis using Recharts.
```tsx
import { BarChart } from "@/components/ui/bar-chart"
export default function SalesChart() {
const data = [
{ month: "Jan", sales: 4000, revenue: 2400 },
{ month: "Feb", sales: 3000, revenue: 1398 },
{ month: "Mar", sales: 2000, revenue: 9800 },
{ month: "Apr", sales: 2780, revenue: 3908 },
{ month: "May", sales: 1890, revenue: 4800 },
{ month: "Jun", sales: 2390, revenue: 3800 }
]
return (
`$${value.toLocaleString()}`}
yAxisWidth={60}
/>
)
}
```
### Line Chart Component
Smooth line chart for visualizing trends and time-series data with multiple data series support.
```tsx
import { LineChart } from "@/components/ui/line-chart"
export default function MetricsChart() {
const data = [
{ date: "2024-01", users: 1200, sessions: 3400 },
{ date: "2024-02", users: 1800, sessions: 4200 },
{ date: "2024-03", users: 2400, sessions: 5800 },
{ date: "2024-04", users: 3100, sessions: 7200 },
{ date: "2024-05", users: 3800, sessions: 8900 }
]
return (
)
}
```
### Pie Chart Component
Donut chart component for displaying proportional data and percentage distributions.
```tsx
import { PieChart } from "@/components/ui/pie-chart"
export default function MarketShareChart() {
const data = [
{ name: "Product A", value: 400, fill: "#3b82f6" },
{ name: "Product B", value: 300, fill: "#10b981" },
{ name: "Product C", value: 300, fill: "#f59e0b" },
{ name: "Product D", value: 200, fill: "#ef4444" }
]
return (
`${entry.name}: ${entry.value}`}
/>
)
}
```
### Area Chart Component
Stacked area chart for visualizing volume changes over time with multiple data series.
```tsx
import { AreaChart } from "@/components/ui/area-chart"
export default function TrafficChart() {
const data = [
{ month: "Jan", mobile: 2000, desktop: 3000, tablet: 1000 },
{ month: "Feb", mobile: 2200, desktop: 3200, tablet: 1100 },
{ month: "Mar", mobile: 2800, desktop: 3800, tablet: 1300 },
{ month: "Apr", mobile: 3200, desktop: 4200, tablet: 1500 },
{ month: "May", mobile: 3800, desktop: 4800, tablet: 1800 }
]
return (
)
}
```
### Radar Chart Component
Multi-axis chart for comparing multiple variables across different categories simultaneously.
```tsx
import { RadarChart } from "@/components/ui/radar-chart"
export default function SkillsChart() {
const data = [
{ skill: "JavaScript", score: 85, industry: 75 },
{ skill: "TypeScript", score: 80, industry: 70 },
{ skill: "React", score: 90, industry: 80 },
{ skill: "Node.js", score: 75, industry: 72 },
{ skill: "CSS", score: 88, industry: 78 }
]
return (
)
}
```
### Mixed Chart Component
Combined bar and line chart for displaying multiple data types with different visualization methods.
```tsx
import { MixedChart } from "@/components/ui/mixed-chart"
export default function PerformanceChart() {
const data = [
{ month: "Jan", revenue: 4000, growth: 5.2 },
{ month: "Feb", revenue: 4200, growth: 5.0 },
{ month: "Mar", revenue: 4800, growth: 14.3 },
{ month: "Apr", revenue: 5200, growth: 8.3 },
{ month: "May", revenue: 5800, growth: 11.5 }
]
return (
)
}
```
## Animation Components
### Magnetic Effect Component
Magnetic hover effect that smoothly follows cursor movement for interactive buttons and cards.
```tsx
import { Magnetic } from "@/components/ui/magnetic"
export default function InteractiveButton() {
return (
Hover me
)
}
```
### Animated Cursor Component
Custom animated cursor with interactive effects and particle trails for immersive experiences.
```tsx
import { AnimatedCursor } from "@/components/ui/animated-cursor"
export default function Layout({ children }) {
return (
<>
{children}
)
}
```
### Apple Hello Effect Component
Recreation of Apple's iconic "hello" animation with multi-language text transitions.
```tsx
import { AppleHello } from "@/components/ui/apple-hello"
export default function WelcomeScreen() {
const greetings = [
{ text: "Hello", lang: "en" },
{ text: "Bonjour", lang: "fr" },
{ text: "こんにちは", lang: "ja" },
{ text: "Hola", lang: "es" },
{ text: "你好", lang: "zh" }
]
return (
)
}
```
### Liquid Button Component
Button with fluid liquid animation effect on hover for engaging call-to-action elements.
```tsx
import { LiquidButton } from "@/components/ui/liquid-button"
export default function CTASection() {
return (
console.log("CTA clicked")}
>
Get Started
)
}
```
### Rolling Text Component
Text animation that creates a rolling effect with smooth character transitions.
```tsx
import { RollingText } from "@/components/ui/rolling-text"
export default function AnimatedHeading() {
return (
)
}
```
### Shimmering Text Component
Text with animated shimmer effect for attention-grabbing headings and highlights.
```tsx
import { ShimmeringText } from "@/components/ui/shimmering-text"
export default function Hero() {
return (
)
}
```
## React Hooks
### useBoolean Hook
Enhanced boolean state management with toggle, enable, and disable methods for cleaner component logic.
```tsx
import { useBoolean } from "@/hooks/use-boolean"
export default function TogglePanel() {
const modal = useBoolean(false)
const loading = useBoolean(false)
const handleSubmit = async () => {
loading.setTrue()
try {
await submitForm()
modal.setFalse()
} finally {
loading.setFalse()
}
}
return (
<>
Toggle Modal
{modal.value && (
Status: {loading.value ? "Saving..." : "Ready"}
Submit
)}
)
}
```
### useCounter Hook
Counter hook with increment, decrement, reset, and set functionality for numeric state management.
```tsx
import { useCounter } from "@/hooks/use-counter"
export default function CartCounter() {
const quantity = useCounter(0, { min: 0, max: 99 })
return (
-
{quantity.value}
+
Reset
)
}
```
### useLocalStorage Hook
Persist state in browser localStorage with automatic serialization and deserialization.
```tsx
import { useLocalStorage } from "@/hooks/use-local-storage"
export default function UserPreferences() {
const [theme, setTheme] = useLocalStorage("theme", "light")
const [settings, setSettings] = useLocalStorage("settings", {
notifications: true,
emailUpdates: false
})
return (
setTheme(e.target.value)}>
LightDark setSettings({
...settings,
notifications: e.target.checked
})}
/>
Enable Notifications
)
}
```
### useDebounceValue Hook
Debounce values to prevent excessive updates and API calls during rapid user input.
```tsx
import { useDebounceValue } from "@/hooks/use-debounce-value"
import { useState, useEffect } from "react"
export default function SearchBox() {
const [search, setSearch] = useState("")
const debouncedSearch = useDebounceValue(search, 500)
const [results, setResults] = useState([])
const [apiCalls, setApiCalls] = useState(0)
useEffect(() => {
if (debouncedSearch) {
setApiCalls(prev => prev + 1)
fetch(`/api/search?q=${debouncedSearch}`)
.then(res => res.json())
.then(setResults)
}
}, [debouncedSearch])
return (
setSearch(e.target.value)}
placeholder="Search..."
/>
API calls: {apiCalls}
)
}
```
### useHover Hook
Track hover state on elements with customizable enter and leave delays for tooltip and preview functionality.
```tsx
import { useHover } from "@/hooks/use-hover"
import { useRef } from "react"
export default function ImagePreview() {
const hoverRef = useRef(null)
const isHovering = useHover(hoverRef, {
enterDelay: 200,
leaveDelay: 100
})
return (
![Preview](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/thumbnail.jpg)
{isHovering && (
![Full size](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/full-size.jpg)
)}
)
}
```
### useCountdown Hook
Countdown timer with play, pause, reset controls and completion callbacks for time-limited features.
```tsx
import { useCountdown } from "@/hooks/use-countdown"
export default function OTPTimer() {
const countdown = useCountdown({
initialSeconds: 60,
onComplete: () => alert("OTP expired! Request a new code.")
})
return (
{countdown.seconds}s
{!countdown.isRunning ? (
Start
) : (
Pause
)}
Reset
Status: {countdown.isComplete ? "Expired" : countdown.isRunning ? "Active" : "Paused"}
)
}
```
## Installation and Usage
### CLI Installation
Install components directly into your project using the shadcn CLI for instant integration.
```bash
# Initialize shadcn in your project
npx shadcn@latest init
# Add individual components
npx shadcn@latest add terminal
npx shadcn@latest add dock
npx shadcn@latest add credit-card
# Add multiple components at once
npx shadcn@latest add bar-chart line-chart pie-chart
# Add hooks
npx shadcn@latest add use-boolean use-counter use-local-storage
```
### Project Configuration
Configure your project to work with shadcn.io components using TypeScript and Tailwind CSS.
```typescript
// tailwind.config.ts
import type { Config } from "tailwindcss"
const config: Config = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
],
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
},
},
},
plugins: [require("tailwindcss-animate")],
}
export default config
```
## Summary
The shadcn.io component library serves as a comprehensive toolkit for React developers building modern web applications with Next.js and TypeScript. The library's primary use cases include rapid prototyping of user interfaces, building data-rich dashboards with interactive charts, creating engaging user experiences with animations and effects, and implementing common UI patterns without writing boilerplate code. The copy-paste approach gives developers complete ownership of their components, allowing for deep customization while maintaining consistency with shadcn/ui design principles. Components are particularly well-suited for SaaS applications, admin panels, marketing websites, and e-commerce platforms that require professional, accessible UI elements.
Integration patterns center around composability and customization rather than rigid package dependencies. Developers can cherry-pick individual components using the CLI, modify them at the source level to match their design system, and combine them with existing shadcn/ui components for a cohesive interface. The library supports both light and dark themes through CSS variables, integrates seamlessly with Tailwind CSS utility classes, and follows React best practices for performance and accessibility. Custom hooks provide reusable logic patterns that complement the visual components, creating a complete ecosystem for building feature-rich applications. The TypeScript-first approach ensures type safety throughout the development process, while the Recharts integration for data visualization provides powerful charting capabilities without additional configuration overhead.

File diff suppressed because it is too large Load diff

1
.augment/skills/shadcn-ui Symbolic link
View file

@ -0,0 +1 @@
/mnt/c/Users/Zenchant/codex/beadboard/.agents/skills/shadcn-ui/

File diff suppressed because it is too large Load diff

View file

@ -1,306 +0,0 @@
### shadcn/ui Chart Component - Installation
Source: https://ui.shadcn.com/docs/components/chart
The chart component in shadcn/ui is built on Recharts, providing direct access to all Recharts capabilities with consistent theming.
```bash
npx shadcn@latest add chart
```
--------------------------------
### shadcn/ui Chart Component - Basic Usage
Source: https://ui.shadcn.com/docs/components/chart
The ChartContainer wraps your Recharts component and accepts a config prop for theming. Requires `min-h-[value]` for responsiveness.
```tsx
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
]
export function BarChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - ChartConfig with Custom Colors
Source: https://ui.shadcn.com/docs/components/chart
You can define custom colors directly in the configuration using hex values or CSS variables.
```tsx
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
theme: {
light: "#2563eb",
dark: "#60a5fa",
},
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
```
--------------------------------
### shadcn/ui Chart Component - CSS Variables
Source: https://ui.shadcn.com/docs/components/chart
Add chart color variables to your globals.css for consistent theming.
```css
:root {
/* Chart colors */
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.546 0.198 38.228);
--chart-4: oklch(0.596 0.151 343.253);
--chart-5: oklch(0.546 0.158 49.157);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.698 0.141 24.311);
--chart-4: oklch(0.676 0.172 171.196);
--chart-5: oklch(0.578 0.192 302.85);
}
```
--------------------------------
### shadcn/ui Chart Component - Line Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a line chart with shadcn/ui charts component.
```tsx
import { Line, LineChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
price: {
label: "Price",
color: "var(--chart-1)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", price: 186 },
{ month: "February", price: 305 },
{ month: "March", price: 237 },
{ month: "April", price: 203 },
{ month: "May", price: 276 },
]
export function LineChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<LineChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} tickFormatter={(value) => `$${value}`} />
<Line
dataKey="price"
stroke="var(--color-price)"
strokeWidth={2}
dot={false}
/>
<ChartTooltip content={<ChartTooltipContent />} />
</LineChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Area Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating an area chart with gradient fill and legend.
```tsx
import { Area, AreaChart, XAxis, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
desktop: { label: "Desktop", color: "var(--chart-1)" },
mobile: { label: "Mobile", color: "var(--chart-2)" },
} satisfies import("@/components/ui/chart").ChartConfig
export function AreaChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<AreaChart data={chartData}>
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} />
<Area
dataKey="desktop"
fill="var(--color-desktop)"
stroke="var(--color-desktop)"
fillOpacity={0.3}
/>
<Area
dataKey="mobile"
fill="var(--color-mobile)"
stroke="var(--color-mobile)"
fillOpacity={0.3}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</AreaChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Pie Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a pie/donut chart with shadcn/ui.
```tsx
import { Pie, PieChart } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
chrome: { label: "Chrome", color: "var(--chart-1)" },
safari: { label: "Safari", color: "var(--chart-2)" },
firefox: { label: "Firefox", color: "var(--chart-3)" },
} satisfies import("@/components/ui/chart").ChartConfig
const pieData = [
{ browser: "Chrome", visitors: 275, fill: "var(--color-chrome)" },
{ browser: "Safari", visitors: 200, fill: "var(--color-safari)" },
{ browser: "Firefox", visitors: 187, fill: "var(--color-firefox)" },
]
export function PieChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<PieChart>
<Pie
data={pieData}
dataKey="visitors"
nameKey="browser"
cx="50%"
cy="50%"
outerRadius={80}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</PieChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui ChartTooltipContent Props
Source: https://ui.shadcn.com/docs/components/chart
The ChartTooltipContent component accepts these props for customizing tooltip behavior.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `labelKey` | string | "label" | Key for tooltip label |
| `nameKey` | string | "name" | Key for tooltip name |
| `indicator` | "dot" \| "line" \| "dashed" | "dot" | Indicator style |
| `hideLabel` | boolean | false | Hide label |
| `hideIndicator` | boolean | false | Hide indicator |
--------------------------------
### shadcn/ui Chart Component - Accessibility
Source: https://ui.shadcn.com/docs/components/chart
Enable keyboard navigation and screen reader support by adding the accessibilityLayer prop.
```tsx
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" />
<Bar dataKey="desktop" fill="var(--color-desktop)" />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
```
This adds:
- Keyboard arrow key navigation
- ARIA labels for chart elements
- Screen reader announcements for data values
--------------------------------
### shadcn/ui Chart Component - Recharts Dependencies
Source: https://ui.shadcn.com/docs/components/chart
The chart component requires the following Recharts dependencies to be installed.
```bash
pnpm add recharts
npm install recharts
yarn add recharts
```
Recharts provides the following chart types:
- Area, Bar, Line, Pie, Composed
- Radar, RadialBar, Scatter
- Funnel, Treemap

View file

@ -1,145 +0,0 @@
# shadcn/ui Learning Guide
This guide helps you learn shadcn/ui from basics to advanced patterns.
## Learning Path
### 1. Understanding the Philosophy
shadcn/ui is different from traditional component libraries:
- **Copy-paste components**: Components are copied into your project, not installed as packages
- **Full customization**: You own the code and can modify it freely
- **Built on Radix UI**: Provides accessibility primitives
- **Styled with Tailwind**: Uses utility classes for consistent styling
### 2. Core Concepts to Master
#### Class Variance Authority (CVA)
Most components use CVA for variant management:
```tsx
const buttonVariants = cva(
"base-classes",
{
variants: {
variant: {
default: "variant-classes",
destructive: "destructive-classes",
},
size: {
default: "size-classes",
sm: "small-classes",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
```
#### cn Utility Function
The `cn` function combines classes and resolves conflicts:
```tsx
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
```
### 3. Installation Checklist
- [ ] Initialize a new project (Next.js, Vite, or Remix)
- [ ] Install Tailwind CSS
- [ ] Run `npx shadcn@latest init`
- [ ] Configure CSS variables
- [ ] Install first component: `npx shadcn@latest add button`
### 4. Essential Components to Learn First
1. **Button** - Learn variants and sizes
2. **Input** - Form inputs with labels
3. **Card** - Container components
4. **Form** - Form handling with React Hook Form
5. **Dialog** - Modal windows
6. **Select** - Dropdown selections
7. **Toast** - Notifications
### 5. Common Patterns
#### Form Pattern
Every form follows this structure:
```tsx
1. Define Zod schema
2. Create form with useForm
3. Wrap with Form component
4. Add FormField for each input
5. Handle submission
```
#### Component Customization Pattern
To customize a component:
1. Copy component to your project
2. Modify the variants
3. Add new props if needed
4. Update types
### 6. Best Practices
- Always use TypeScript
- Follow the existing component structure
- Use semantic HTML when possible
- Test with screen readers for accessibility
- Keep components small and focused
### 7. Advanced Topics
- Creating custom components from scratch
- Building complex forms with validation
- Implementing dark mode
- Optimizing for performance
- Testing components
## Practice Exercises
### Exercise 1: Basic Setup
1. Create a new Next.js project
2. Set up shadcn/ui
3. Install and customize a Button component
4. Add a new variant "gradient"
### Exercise 2: Form Building
1. Create a contact form with:
- Name input (required)
- Email input (email validation)
- Message textarea (min length)
- Submit button with loading state
### Exercise 3: Component Combination
1. Build a settings page using:
- Card for layout
- Sheet for mobile menu
- Select for dropdowns
- Switch for toggles
- Toast for notifications
### Exercise 4: Custom Component
1. Create a custom Badge component
2. Support variants: default, secondary, destructive, outline
3. Support sizes: sm, default, lg
4. Add icon support
## Resources
- [Official Documentation](https://ui.shadcn.com)
- [GitHub Repository](https://github.com/shadcn/ui)
- [Examples Gallery](https://ui.shadcn.com/examples)
- [Radix UI Primitives](https://www.radix-ui.com/primitives)
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)

File diff suppressed because it is too large Load diff

View file

@ -1,586 +0,0 @@
# shadcn.io Component Library
shadcn.io is a comprehensive React UI component library built on shadcn/ui principles, providing developers with production-ready, composable components for modern web applications. The library serves as a centralized resource for React developers who need high-quality UI components with TypeScript support, ranging from basic interactive elements to advanced AI-powered integrations. Unlike traditional component libraries that require package installations, shadcn.io components are designed to be copied directly into your project, giving you full control and customization capabilities.
The library encompasses four major categories: composable UI components (terminal, dock, credit cards, QR codes, color pickers), chart components built with Recharts, animation components with Tailwind CSS integration, and custom React hooks for state management and lifecycle operations. Each component follows best practices for accessibility, performance, and developer experience, with comprehensive TypeScript definitions and Next.js compatibility. The platform emphasizes flexibility and customization, allowing developers to modify components at the source level rather than being constrained by package APIs.
## Core Components
### Terminal Component
Interactive terminal emulator with typing animations and command execution simulation for developer-focused interfaces.
```tsx
import { Terminal } from "@/components/ui/terminal"
export default function DemoTerminal() {
return (
npm install @repo/terminalInstalling dependencies...npm start
)
}
```
### Dock Component
macOS-style application dock with smooth magnification effects on hover, perfect for navigation menus.
```tsx
import { Dock, DockIcon } from "@/components/ui/dock"
import { Home, Settings, User, Mail } from "lucide-react"
export default function AppDock() {
return (
)
}
```
### Credit Card Component
Interactive 3D credit card component with flip animations for payment forms and card displays.
```tsx
import { CreditCard } from "@/components/ui/credit-card"
import { useState } from "react"
export default function PaymentForm() {
const [cardData, setCardData] = useState({
number: "4532 1234 5678 9010",
holder: "JOHN DOE",
expiry: "12/28",
cvv: "123"
})
return (
console.log("Card flipped:", flipped)}
/>
)
}
```
### Image Zoom Component
Zoomable image component with smooth modal transitions for image galleries and product displays.
```tsx
import { ImageZoom } from "@/components/ui/image-zoom"
export default function ProductGallery() {
return (
)
}
```
### QR Code Component
Generate and display customizable QR codes with styling options for links, contact information, and authentication.
```tsx
import { QRCode } from "@/components/ui/qr-code"
export default function ShareDialog() {
const shareUrl = "https://shadcn.io"
return (
Scan to visit shadcn.io
)
}
```
### Color Picker Component
Advanced color selection component supporting multiple color formats (HEX, RGB, HSL) with preview.
```tsx
import { ColorPicker } from "@/components/ui/color-picker"
import { useState } from "react"
export default function ThemeCustomizer() {
const [color, setColor] = useState("#3b82f6")
return (
Selected: {color}
)
}
```
## Chart Components
### Bar Chart Component
Clean bar chart component for data comparison and categorical analysis using Recharts.
```tsx
import { BarChart } from "@/components/ui/bar-chart"
export default function SalesChart() {
const data = [
{ month: "Jan", sales: 4000, revenue: 2400 },
{ month: "Feb", sales: 3000, revenue: 1398 },
{ month: "Mar", sales: 2000, revenue: 9800 },
{ month: "Apr", sales: 2780, revenue: 3908 },
{ month: "May", sales: 1890, revenue: 4800 },
{ month: "Jun", sales: 2390, revenue: 3800 }
]
return (
`$${value.toLocaleString()}`}
yAxisWidth={60}
/>
)
}
```
### Line Chart Component
Smooth line chart for visualizing trends and time-series data with multiple data series support.
```tsx
import { LineChart } from "@/components/ui/line-chart"
export default function MetricsChart() {
const data = [
{ date: "2024-01", users: 1200, sessions: 3400 },
{ date: "2024-02", users: 1800, sessions: 4200 },
{ date: "2024-03", users: 2400, sessions: 5800 },
{ date: "2024-04", users: 3100, sessions: 7200 },
{ date: "2024-05", users: 3800, sessions: 8900 }
]
return (
)
}
```
### Pie Chart Component
Donut chart component for displaying proportional data and percentage distributions.
```tsx
import { PieChart } from "@/components/ui/pie-chart"
export default function MarketShareChart() {
const data = [
{ name: "Product A", value: 400, fill: "#3b82f6" },
{ name: "Product B", value: 300, fill: "#10b981" },
{ name: "Product C", value: 300, fill: "#f59e0b" },
{ name: "Product D", value: 200, fill: "#ef4444" }
]
return (
`${entry.name}: ${entry.value}`}
/>
)
}
```
### Area Chart Component
Stacked area chart for visualizing volume changes over time with multiple data series.
```tsx
import { AreaChart } from "@/components/ui/area-chart"
export default function TrafficChart() {
const data = [
{ month: "Jan", mobile: 2000, desktop: 3000, tablet: 1000 },
{ month: "Feb", mobile: 2200, desktop: 3200, tablet: 1100 },
{ month: "Mar", mobile: 2800, desktop: 3800, tablet: 1300 },
{ month: "Apr", mobile: 3200, desktop: 4200, tablet: 1500 },
{ month: "May", mobile: 3800, desktop: 4800, tablet: 1800 }
]
return (
)
}
```
### Radar Chart Component
Multi-axis chart for comparing multiple variables across different categories simultaneously.
```tsx
import { RadarChart } from "@/components/ui/radar-chart"
export default function SkillsChart() {
const data = [
{ skill: "JavaScript", score: 85, industry: 75 },
{ skill: "TypeScript", score: 80, industry: 70 },
{ skill: "React", score: 90, industry: 80 },
{ skill: "Node.js", score: 75, industry: 72 },
{ skill: "CSS", score: 88, industry: 78 }
]
return (
)
}
```
### Mixed Chart Component
Combined bar and line chart for displaying multiple data types with different visualization methods.
```tsx
import { MixedChart } from "@/components/ui/mixed-chart"
export default function PerformanceChart() {
const data = [
{ month: "Jan", revenue: 4000, growth: 5.2 },
{ month: "Feb", revenue: 4200, growth: 5.0 },
{ month: "Mar", revenue: 4800, growth: 14.3 },
{ month: "Apr", revenue: 5200, growth: 8.3 },
{ month: "May", revenue: 5800, growth: 11.5 }
]
return (
)
}
```
## Animation Components
### Magnetic Effect Component
Magnetic hover effect that smoothly follows cursor movement for interactive buttons and cards.
```tsx
import { Magnetic } from "@/components/ui/magnetic"
export default function InteractiveButton() {
return (
Hover me
)
}
```
### Animated Cursor Component
Custom animated cursor with interactive effects and particle trails for immersive experiences.
```tsx
import { AnimatedCursor } from "@/components/ui/animated-cursor"
export default function Layout({ children }) {
return (
<>
{children}
)
}
```
### Apple Hello Effect Component
Recreation of Apple's iconic "hello" animation with multi-language text transitions.
```tsx
import { AppleHello } from "@/components/ui/apple-hello"
export default function WelcomeScreen() {
const greetings = [
{ text: "Hello", lang: "en" },
{ text: "Bonjour", lang: "fr" },
{ text: "こんにちは", lang: "ja" },
{ text: "Hola", lang: "es" },
{ text: "你好", lang: "zh" }
]
return (
)
}
```
### Liquid Button Component
Button with fluid liquid animation effect on hover for engaging call-to-action elements.
```tsx
import { LiquidButton } from "@/components/ui/liquid-button"
export default function CTASection() {
return (
console.log("CTA clicked")}
>
Get Started
)
}
```
### Rolling Text Component
Text animation that creates a rolling effect with smooth character transitions.
```tsx
import { RollingText } from "@/components/ui/rolling-text"
export default function AnimatedHeading() {
return (
)
}
```
### Shimmering Text Component
Text with animated shimmer effect for attention-grabbing headings and highlights.
```tsx
import { ShimmeringText } from "@/components/ui/shimmering-text"
export default function Hero() {
return (
)
}
```
## React Hooks
### useBoolean Hook
Enhanced boolean state management with toggle, enable, and disable methods for cleaner component logic.
```tsx
import { useBoolean } from "@/hooks/use-boolean"
export default function TogglePanel() {
const modal = useBoolean(false)
const loading = useBoolean(false)
const handleSubmit = async () => {
loading.setTrue()
try {
await submitForm()
modal.setFalse()
} finally {
loading.setFalse()
}
}
return (
<>
Toggle Modal
{modal.value && (
Status: {loading.value ? "Saving..." : "Ready"}
Submit
)}
)
}
```
### useCounter Hook
Counter hook with increment, decrement, reset, and set functionality for numeric state management.
```tsx
import { useCounter } from "@/hooks/use-counter"
export default function CartCounter() {
const quantity = useCounter(0, { min: 0, max: 99 })
return (
-
{quantity.value}
+
Reset
)
}
```
### useLocalStorage Hook
Persist state in browser localStorage with automatic serialization and deserialization.
```tsx
import { useLocalStorage } from "@/hooks/use-local-storage"
export default function UserPreferences() {
const [theme, setTheme] = useLocalStorage("theme", "light")
const [settings, setSettings] = useLocalStorage("settings", {
notifications: true,
emailUpdates: false
})
return (
setTheme(e.target.value)}>
LightDark setSettings({
...settings,
notifications: e.target.checked
})}
/>
Enable Notifications
)
}
```
### useDebounceValue Hook
Debounce values to prevent excessive updates and API calls during rapid user input.
```tsx
import { useDebounceValue } from "@/hooks/use-debounce-value"
import { useState, useEffect } from "react"
export default function SearchBox() {
const [search, setSearch] = useState("")
const debouncedSearch = useDebounceValue(search, 500)
const [results, setResults] = useState([])
const [apiCalls, setApiCalls] = useState(0)
useEffect(() => {
if (debouncedSearch) {
setApiCalls(prev => prev + 1)
fetch(`/api/search?q=${debouncedSearch}`)
.then(res => res.json())
.then(setResults)
}
}, [debouncedSearch])
return (
setSearch(e.target.value)}
placeholder="Search..."
/>
API calls: {apiCalls}
)
}
```
### useHover Hook
Track hover state on elements with customizable enter and leave delays for tooltip and preview functionality.
```tsx
import { useHover } from "@/hooks/use-hover"
import { useRef } from "react"
export default function ImagePreview() {
const hoverRef = useRef(null)
const isHovering = useHover(hoverRef, {
enterDelay: 200,
leaveDelay: 100
})
return (
![Preview](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/thumbnail.jpg)
{isHovering && (
![Full size](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/full-size.jpg)
)}
)
}
```
### useCountdown Hook
Countdown timer with play, pause, reset controls and completion callbacks for time-limited features.
```tsx
import { useCountdown } from "@/hooks/use-countdown"
export default function OTPTimer() {
const countdown = useCountdown({
initialSeconds: 60,
onComplete: () => alert("OTP expired! Request a new code.")
})
return (
{countdown.seconds}s
{!countdown.isRunning ? (
Start
) : (
Pause
)}
Reset
Status: {countdown.isComplete ? "Expired" : countdown.isRunning ? "Active" : "Paused"}
)
}
```
## Installation and Usage
### CLI Installation
Install components directly into your project using the shadcn CLI for instant integration.
```bash
# Initialize shadcn in your project
npx shadcn@latest init
# Add individual components
npx shadcn@latest add terminal
npx shadcn@latest add dock
npx shadcn@latest add credit-card
# Add multiple components at once
npx shadcn@latest add bar-chart line-chart pie-chart
# Add hooks
npx shadcn@latest add use-boolean use-counter use-local-storage
```
### Project Configuration
Configure your project to work with shadcn.io components using TypeScript and Tailwind CSS.
```typescript
// tailwind.config.ts
import type { Config } from "tailwindcss"
const config: Config = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
],
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
},
},
},
plugins: [require("tailwindcss-animate")],
}
export default config
```
## Summary
The shadcn.io component library serves as a comprehensive toolkit for React developers building modern web applications with Next.js and TypeScript. The library's primary use cases include rapid prototyping of user interfaces, building data-rich dashboards with interactive charts, creating engaging user experiences with animations and effects, and implementing common UI patterns without writing boilerplate code. The copy-paste approach gives developers complete ownership of their components, allowing for deep customization while maintaining consistency with shadcn/ui design principles. Components are particularly well-suited for SaaS applications, admin panels, marketing websites, and e-commerce platforms that require professional, accessible UI elements.
Integration patterns center around composability and customization rather than rigid package dependencies. Developers can cherry-pick individual components using the CLI, modify them at the source level to match their design system, and combine them with existing shadcn/ui components for a cohesive interface. The library supports both light and dark themes through CSS variables, integrates seamlessly with Tailwind CSS utility classes, and follows React best practices for performance and accessibility. Custom hooks provide reusable logic patterns that complement the visual components, creating a complete ecosystem for building feature-rich applications. The TypeScript-first approach ensures type safety throughout the development process, while the Recharts integration for data visualization provides powerful charting capabilities without additional configuration overhead.

File diff suppressed because it is too large Load diff

View file

@ -1,23 +1,23 @@
#!/usr/bin/env sh
# bd-shim v1
# bd-hooks-version: 0.53.0
#
# bd (beads) post-checkout hook - thin shim
#
# This shim delegates to 'bd hook post-checkout' which contains
# the actual hook logic. This pattern ensures hook behavior is always
# in sync with the installed bd version - no manual updates needed.
#
# The 'bd hook' command (singular) supports:
# - Guard against frequent firing (only imports if JSONL changed)
# - Per-worktree state tracking
# - Dolt branch-then-merge pattern
# - Hook chaining configuration
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
# Silently skip - post-checkout is called frequently
exit 0
fi
exec bd hook post-checkout "$@"
#!/usr/bin/env sh
# bd-shim v1
# bd-hooks-version: 0.53.0
#
# bd (beads) post-checkout hook - thin shim
#
# This shim delegates to 'bd hook post-checkout' which contains
# the actual hook logic. This pattern ensures hook behavior is always
# in sync with the installed bd version - no manual updates needed.
#
# The 'bd hook' command (singular) supports:
# - Guard against frequent firing (only imports if JSONL changed)
# - Per-worktree state tracking
# - Dolt branch-then-merge pattern
# - Hook chaining configuration
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
# Silently skip - post-checkout is called frequently
exit 0
fi
exec bd hook post-checkout "$@"

View file

@ -1,24 +1,24 @@
#!/usr/bin/env sh
# bd-shim v1
# bd-hooks-version: 0.53.0
#
# bd (beads) post-merge hook - thin shim
#
# This shim delegates to 'bd hook post-merge' which contains
# the actual hook logic. This pattern ensures hook behavior is always
# in sync with the installed bd version - no manual updates needed.
#
# The 'bd hook' command (singular) supports:
# - Branch-then-merge pattern for Dolt (cell-level conflict resolution)
# - Per-worktree state tracking
# - Hook chaining configuration
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
echo "Warning: bd command not found in PATH, skipping post-merge hook" >&2
echo " Install bd: brew install beads" >&2
echo " Or add bd to your PATH" >&2
exit 0
fi
exec bd hook post-merge "$@"
#!/usr/bin/env sh
# bd-shim v1
# bd-hooks-version: 0.53.0
#
# bd (beads) post-merge hook - thin shim
#
# This shim delegates to 'bd hook post-merge' which contains
# the actual hook logic. This pattern ensures hook behavior is always
# in sync with the installed bd version - no manual updates needed.
#
# The 'bd hook' command (singular) supports:
# - Branch-then-merge pattern for Dolt (cell-level conflict resolution)
# - Per-worktree state tracking
# - Hook chaining configuration
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
echo "Warning: bd command not found in PATH, skipping post-merge hook" >&2
echo " Install bd: brew install beads" >&2
echo " Or add bd to your PATH" >&2
exit 0
fi
exec bd hook post-merge "$@"

View file

@ -1,25 +1,25 @@
#!/usr/bin/env sh
# bd-shim v2
# bd-hooks-version: 0.53.0
#
# bd (beads) pre-commit hook — thin shim
#
# Delegates to 'bd hook pre-commit' which contains the actual hook logic.
# This pattern ensures hook behavior is always in sync with the installed
# bd version — no manual updates needed.
#
# The 'bd hook' command supports:
# - Per-worktree export state tracking
# - Dolt in-process export (no lock deadlocks)
# - Sync-branch routing
# - Hook chaining configuration
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
echo "Warning: bd command not found in PATH, skipping pre-commit hook" >&2
echo " Install bd: brew install beads" >&2
echo " Or add bd to your PATH" >&2
exit 0
fi
exec bd hook pre-commit "$@"
#!/usr/bin/env sh
# bd-shim v2
# bd-hooks-version: 0.53.0
#
# bd (beads) pre-commit hook — thin shim
#
# Delegates to 'bd hook pre-commit' which contains the actual hook logic.
# This pattern ensures hook behavior is always in sync with the installed
# bd version — no manual updates needed.
#
# The 'bd hook' command supports:
# - Per-worktree export state tracking
# - Dolt in-process export (no lock deadlocks)
# - Sync-branch routing
# - Hook chaining configuration
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
echo "Warning: bd command not found in PATH, skipping pre-commit hook" >&2
echo " Install bd: brew install beads" >&2
echo " Or add bd to your PATH" >&2
exit 0
fi
exec bd hook pre-commit "$@"

View file

@ -1,19 +1,19 @@
#!/usr/bin/env sh
# bd-shim v1
# bd-hooks-version: 0.53.0
#
# bd (beads) pre-push hook - thin shim
#
# This shim delegates to 'bd hooks run pre-push' which contains
# the actual hook logic. This pattern ensures hook behavior is always
# in sync with the installed bd version - no manual updates needed.
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
echo "Warning: bd command not found in PATH, skipping pre-push hook" >&2
echo " Install bd: brew install beads" >&2
echo " Or add bd to your PATH" >&2
exit 0
fi
exec bd hooks run pre-push "$@"
#!/usr/bin/env sh
# bd-shim v1
# bd-hooks-version: 0.53.0
#
# bd (beads) pre-push hook - thin shim
#
# This shim delegates to 'bd hooks run pre-push' which contains
# the actual hook logic. This pattern ensures hook behavior is always
# in sync with the installed bd version - no manual updates needed.
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
echo "Warning: bd command not found in PATH, skipping pre-push hook" >&2
echo " Install bd: brew install beads" >&2
echo " Or add bd to your PATH" >&2
exit 0
fi
exec bd hooks run pre-push "$@"

View file

@ -1,24 +1,24 @@
#!/usr/bin/env sh
# bd-shim v1
# bd-hooks-version: 0.48.0
#
# bd (beads) prepare-commit-msg hook - thin shim
#
# This shim delegates to 'bd hooks run prepare-commit-msg' which contains
# the actual hook logic. This pattern ensures hook behavior is always
# in sync with the installed bd version - no manual updates needed.
#
# Arguments:
# $1 = path to the commit message file
# $2 = source of commit message (message, template, merge, squash, commit)
# $3 = commit SHA-1 (if -c, -C, or --amend)
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
echo "Warning: bd command not found in PATH, skipping prepare-commit-msg hook" >&2
echo " Install bd: brew install beads" >&2
echo " Or add bd to your PATH" >&2
exit 0
fi
exec bd hooks run prepare-commit-msg "$@"
#!/usr/bin/env sh
# bd-shim v1
# bd-hooks-version: 0.48.0
#
# bd (beads) prepare-commit-msg hook - thin shim
#
# This shim delegates to 'bd hooks run prepare-commit-msg' which contains
# the actual hook logic. This pattern ensures hook behavior is always
# in sync with the installed bd version - no manual updates needed.
#
# Arguments:
# $1 = path to the commit message file
# $2 = source of commit message (message, template, merge, squash, commit)
# $3 = commit SHA-1 (if -c, -C, or --amend)
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
echo "Warning: bd command not found in PATH, skipping prepare-commit-msg hook" >&2
echo " Install bd: brew install beads" >&2
echo " Or add bd to your PATH" >&2
exit 0
fi
exec bd hooks run prepare-commit-msg "$@"

3
.beads/agent.txt Normal file
View file

@ -0,0 +1,3 @@
✓ Created issue: beadboard-8bs — Agent: Antigravity Graph Orchestrator
Priority: P0
Status: open

61
.beads/create_help.txt Normal file
View file

@ -0,0 +1,61 @@
Create a new issue (or multiple issues from markdown file)
Usage:
bd create [title] [flags]
Aliases:
create, new
Flags:
--acceptance string Acceptance criteria
--agent-rig string Agent's rig name (requires --type=agent)
--append-notes string Append to existing notes (with newline separator)
-a, --assignee string Assignee
--body-file string Read description from file (use - for stdin)
--defer string Defer until date (issue hidden from bd ready until then). Same formats as --due
--deps strings Dependencies in format 'type:id' or 'id' (e.g., 'discovered-from:bd-20,blocks:bd-15' or 'bd-20')
-d, --description string Issue description
--design string Design notes
--dry-run Preview what would be created without actually creating
--due string Due date/time. Formats: +6h, +1d, +2w, tomorrow, next monday, 2025-01-15
--ephemeral Create as ephemeral (short-lived, subject to TTL compaction)
-e, --estimate int Time estimate in minutes (e.g., 60 for 1 hour)
--event-actor string Entity URI who caused this event (requires --type=event)
--event-category string Event category (e.g., patrol.muted, agent.started) (requires --type=event)
--event-payload string Event-specific JSON data (requires --type=event)
--event-target string Entity URI or bead ID affected (requires --type=event)
--external-ref string External reference (e.g., 'gh-9', 'jira-ABC')
-f, --file string Create multiple issues from markdown file
--force Force creation even if prefix doesn't match database prefix
-h, --help help for create
--id string Explicit issue ID (e.g., 'bd-42' for partitioning)
-l, --labels strings Labels (comma-separated)
--metadata string Set custom metadata (JSON string or @file.json to read from file)
--mol-type string Molecule type: swarm (multi-polecat), patrol (recurring ops), work (default)
--no-inherit-labels Don't inherit labels from parent issue
--notes string Additional notes
--parent string Parent issue ID for hierarchical child (e.g., 'bd-a3f8e9')
--prefix string Create issue in rig by prefix (e.g., --prefix bd- or --prefix bd or --prefix beads)
-p, --priority string Priority (0-4 or P0-P4, 0=highest) (default "2")
--repo string Target repository for issue (overrides auto-routing)
--rig string Create issue in a different rig (e.g., --rig beads)
--silent Output only the issue ID (for scripting)
--spec-id string Link to specification document
--title string Issue title (alternative to positional argument)
-t, --type string Issue type (bug|feature|task|epic|chore|decision); custom types require types.custom config; aliases: enhancement/feat→feature, dec/adr→decision (default "task")
--validate Validate description contains required sections for issue type
--waits-for string Spawner issue ID to wait for (creates waits-for dependency for fanout gate)
--waits-for-gate string Gate type: all-children (wait for all) or any-children (wait for first) (default "all-children")
--wisp-type string Wisp type for TTL-based compaction: heartbeat, ping, patrol, gc_report, recovery, error, escalation
Global Flags:
--actor string Actor name for audit trail (default: $BD_ACTOR, git user.name, $USER)
--allow-stale Allow operations on potentially stale data (skip staleness check)
--db string Database path (default: auto-discover .beads/*.db)
--dolt-auto-commit string Dolt auto-commit policy (off|on|batch). 'on': commit after each write. 'batch': defer commits to bd sync / bd dolt commit; uncommitted changes persist in the working set until then. SIGTERM/SIGHUP flush pending batch commits. Default: off. Override via config key dolt.auto-commit
--json Output in JSON format
--profile Generate CPU profile for performance analysis
-q, --quiet Suppress non-essential output (errors only)
--readonly Read-only mode: block write operations (for worker sandboxes)
--sandbox Sandbox mode: disables auto-sync
-v, --verbose Enable verbose/debug output

1
.beads/debug.txt Normal file
View file

@ -0,0 +1 @@
✓ Updated issue: beadboard-txj.2 — Apply Status Colors and Transitive Context to Graph Edges

42
.beads/dep_help.txt Normal file
View file

@ -0,0 +1,42 @@
Manage dependencies between issues.
When called with an issue ID and --blocks flag, creates a blocking dependency:
bd dep <blocker-id> --blocks <blocked-id>
This is equivalent to:
bd dep add <blocked-id> <blocker-id>
Examples:
bd dep bd-xyz --blocks bd-abc # bd-xyz blocks bd-abc
bd dep add bd-abc bd-xyz # Same as above (bd-abc depends on bd-xyz)
Usage:
bd dep [issue-id] [flags]
bd dep [command]
Available Commands:
add Add a dependency
cycles Detect dependency cycles
list List dependencies or dependents of an issue
relate Create a bidirectional relates_to link between issues
remove Remove a dependency
tree Show dependency tree
unrelate Remove a relates_to link between issues
Flags:
-b, --blocks string Issue ID that this issue blocks (shorthand for: bd dep add <blocked> <blocker>)
-h, --help help for dep
Global Flags:
--actor string Actor name for audit trail (default: $BD_ACTOR, git user.name, $USER)
--allow-stale Allow operations on potentially stale data (skip staleness check)
--db string Database path (default: auto-discover .beads/*.db)
--dolt-auto-commit string Dolt auto-commit policy (off|on|batch). 'on': commit after each write. 'batch': defer commits to bd sync / bd dolt commit; uncommitted changes persist in the working set until then. SIGTERM/SIGHUP flush pending batch commits. Default: off. Override via config key dolt.auto-commit
--json Output in JSON format
--profile Generate CPU profile for performance analysis
-q, --quiet Suppress non-essential output (errors only)
--readonly Read-only mode: block write operations (for worker sandboxes)
--sandbox Sandbox mode: disables auto-sync
-v, --verbose Enable verbose/debug output
Use "bd dep [command] --help" for more information about a command.

View file

@ -1 +1 @@
3840
1910

View file

@ -1 +0,0 @@
1772407425

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
60816

View file

@ -1 +0,0 @@
3307

3
.beads/epic_create.txt Normal file
View file

@ -0,0 +1,3 @@
✓ Created issue: beadboard-txj — Epic: Enhanced Graph Edge Visualization
Priority: P0
Status: open

60
.beads/lint_output.txt Normal file
View file

@ -0,0 +1,60 @@
> beadboard@0.1.0 lint
> eslint .
C:\Users\Zenchant\codex\beadboard\.beads\fix.js
1:12 error A `require()` style import is forbidden @typescript-eslint/no-require-imports
2:14 error A `require()` style import is forbidden @typescript-eslint/no-require-imports
C:\Users\Zenchant\codex\beadboard\.beads\fix2.js
1:12 error A `require()` style import is forbidden @typescript-eslint/no-require-imports
2:14 error A `require()` style import is forbidden @typescript-eslint/no-require-imports
C:\Users\Zenchant\codex\beadboard\src\components\activity\activity-panel.tsx
285:16 warning 'e' is defined but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\components\activity\swarm-command-feed.tsx
83:22 warning 'e' is defined but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\components\graph\dependency-graph-page.tsx
641:17 warning 'unused_' is assigned a value but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\components\graph\smart-dag.tsx
38:15 warning 'hideClosedProp' is assigned a value but never used @typescript-eslint/no-unused-vars
56:45 warning '_id' is defined but never used @typescript-eslint/no-unused-vars
62:44 warning '_id' is defined but never used @typescript-eslint/no-unused-vars
84:5 warning 'signalById' is assigned a value but never used @typescript-eslint/no-unused-vars
85:5 warning 'cycleNodeIdSet' is assigned a value but never used @typescript-eslint/no-unused-vars
87:5 warning 'blockerTooltipMap' is assigned a value but never used @typescript-eslint/no-unused-vars
170:53 warning 'shouldOpenDrawer' is defined but never used @typescript-eslint/no-unused-vars
176:9 warning 'selectedIssue' is assigned a value but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\components\shared\top-bar.tsx
93:82 warning 'toggleBlockedOnly' is assigned a value but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\components\shared\unified-shell.tsx
42:55 warning 'panel' is assigned a value but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\components\shared\workflow-graph.tsx
251:17 warning 'unused_' is assigned a value but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\components\social\social-card.tsx
116:3 warning 'onOpenThread' is defined but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\components\swarm\swarm-detail.tsx
4:15 warning 'SwarmCardData' is defined but never used @typescript-eslint/no-unused-vars
6:10 warning 'cn' is defined but never used @typescript-eslint/no-unused-vars
53:16 warning 'e' is defined but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\components\swarm\swarm-page.tsx
18:53 warning 'LayoutGrid' is defined but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\hooks\use-mission-graph.ts
33:16 warning '_e' is defined but never used @typescript-eslint/no-unused-vars
C:\Users\Zenchant\codex\beadboard\src\hooks\use-swarm-topology.ts
35:16 warning '_err' is defined but never used @typescript-eslint/no-unused-vars
Γ£û 25 problems (4 errors, 21 warnings)

123
.beads/mem.txt Normal file
View file

@ -0,0 +1,123 @@
✓ beadboard-116 · [MEMORY][WORKFLOW][HARD] Evidence before completion claims [● P1 · CLOSED]
Owner: ZenchantLive · Type: decision
Created: 2026-03-02 · Updated: 2026-03-02
Close reason: Ratified canonical memory
DESCRIPTION
Scope: All new implementation tasks that change behavior or data flow.
Out of Scope: Purely informational discussions without code or workflow changes.
Rule: Start from explicit verification evidence and update work state in bd before claiming progress complete.
Rationale: Prevents status drift and false completion claims.
Failure Mode: Unverified completion claims lead to regressions and mistrust.
NOTES
Provenance linked: bb-92d.6, beadboard-jgy, beadboard-yz6
ACCEPTANCE CRITERIA
Given an implementation task, when work begins and ends, then bd state transitions and verification command evidence are recorded.
Verification command(s): bd show <task-id>; npm run typecheck; npm run lint; npm run test
LABELS: mem-canonical, mem-hard, memory, memory-workflow
METADATA
domain: memory-workflow
effective_date: 2026-03-02
evidence_ids: bb-92d.6,beadboard-jgy,beadboard-yz6
memory_strength: hard
memory_version: 1
owner: team
plan_refs: docs/plans/2026-03-01-beads-native-memory.md,docs/plans/2026-03-02-bd-memory-fabric-design.md
superseded_by: null
supersedes: null
RELATED
↔ ✓ bb-92d.6: Add guardrail test preventing direct writes to .beads/issues.jsonl ● P0
↔ ✓ beadboard-jgy: Document memory workflow in help/memory and AGENTS manuals ● P1
↔ ○ beadboard-nq9: (EPIC) [MEMORY-ANCHOR] Workflow Protocol ● P1
↔ ✓ beadboard-yz6: Bootstrap Phase 1 Memory Fabric (anchors + canonical nodes) ● P1
────────────────────────────────────────────────────────────
✓ beadboard-60a · [MEMORY][ARCH][HARD] Dependencies model execution order, not visual order [● P1 · CLOSED]
Owner: ZenchantLive · Type: decision
Created: 2026-03-02 · Updated: 2026-03-02
Close reason: Ratified canonical memory
DESCRIPTION
Scope: Dependency graph design and updates.
Out of Scope: Visual layout decisions that do not alter execution semantics.
Rule: Dependencies encode execution order and blocking semantics, never visual grouping.
Rationale: Keeps ready/blocked states truthful and machine-reliable.
Failure Mode: Incorrect dependency direction causes false blocking or unsafe parallelism.
NOTES
Provenance linked: bb-bvn, beadboard-r1i, beadboard-68k
ACCEPTANCE CRITERIA
Given a dependency update, when graph state is queried, then blocked/ready outcomes match intended execution order.
Verification command(s): bd dep tree <issue-id>; bd blocked; bd ready
LABELS: mem-canonical, mem-hard, memory, memory-arch
METADATA
domain: memory-arch
effective_date: 2026-03-02
evidence_ids: bb-bvn,beadboard-r1i,beadboard-68k
memory_strength: hard
memory_version: 1
owner: team
plan_refs: docs/plans/2026-02-22-dag-views-ux-design.md
superseded_by: null
supersedes: null
RELATED
↔ ✓ bb-bvn: Dependency Graph (React Flow) ● P0
↔ ✓ beadboard-68k: Phase 0: UX Wiring Fixes ● P0
↔ ○ beadboard-76p: (EPIC) [MEMORY-ANCHOR] Architecture ● P1
↔ ✓ beadboard-r1i: Phase 1: Contextual Right Panel ● P0
────────────────────────────────────────────────────────────
✓ beadboard-zas · [MEMORY][ARCH][HARD] Shared logic for cross-view behavior [● P1 · CLOSED]
Owner: ZenchantLive · Type: decision
Created: 2026-03-02 · Updated: 2026-03-02
Close reason: Ratified canonical memory
DESCRIPTION
Scope: Repeated logic used by multiple views or pages.
Out of Scope: One-off prototypes and disposable experiments.
Rule: Reuse shared paths/components for cross-view behavior; avoid one-off logic drift.
Rationale: Prevents silent divergence between Kanban, Graph, and API views.
Failure Mode: Patching one surface only creates inconsistent user behavior.
NOTES
Provenance linked: beadboard-68k.4, beadboard-68k.5, beadboard-r1i.1
ACCEPTANCE CRITERIA
Given a behavior change touching multiple views, when implementation lands, then shared logic path is reused and covered by tests.
Verification command(s): rg "<shared-function-or-hook>" src tests; npm run test
LABELS: mem-canonical, mem-hard, memory, memory-arch
METADATA
domain: memory-arch
effective_date: 2026-03-02
evidence_ids: beadboard-68k.4,beadboard-68k.5,beadboard-r1i.1
memory_strength: hard
memory_version: 1
owner: team
plan_refs: docs/plans/2026-02-22-dag-views-ux-design.md,docs/plans/2026-02-15-unified-ux-prd.md
superseded_by: null
supersedes: null
RELATED
↔ ✓ beadboard-68k.4: Fix thread drawer status badge (hardcoded 'In Progress') ● P0
↔ ✓ beadboard-68k.5: Wire TopBar metric tiles from live issue data ● P0
↔ ○ beadboard-76p: (EPIC) [MEMORY-ANCHOR] Architecture ● P1
↔ ✓ beadboard-r1i.1: Extend ContextualRightPanel props and thread taskId/swarmId from shell ● P0

794
.beads/npm_test_output.txt Normal file
View file

@ -0,0 +1,794 @@
> beadboard@0.1.0 test
> node --test tests/bootstrap.test.mjs && node --import tsx --test tests/components/shared/base-card.test.tsx && node --import tsx --test tests/components/shared/agent-avatar.test.tsx && node --import tsx --test tests/components/sessions/sessions-header.test.ts && node --import tsx --test tests/components/sessions/agent-station-logic.test.ts && node --import tsx --test tests/lib/parser.test.ts && node --import tsx --test tests/lib/pathing.test.ts && node --import tsx --test tests/components/shared/left-panel.test.tsx && node --import tsx --test tests/components/shared/top-bar.test.tsx && node --import tsx --test tests/components/shared/mobile-nav.test.tsx && node --import tsx --test tests/components/swarm/swarm-card.test.tsx && node --import tsx --test tests/hooks/url-state-integration.test.ts && node --import tsx --test tests/hooks/use-graph-analysis.test.ts && node --import tsx --test tests/components/graph/smart-dag.test.tsx && node --import tsx --test tests/components/unified-shell.test.tsx && node --import tsx --test tests/components/blocked-triage-modal.test.tsx && node --import tsx --test tests/components/graph/graph-node-labels.test.tsx && node --import tsx --test tests/components/graph/graph-node-assign.test.tsx && node --import tsx --test tests/components/graph/graph-node-conversation.test.tsx && node --import tsx --test tests/lib/coord-schema.test.ts && node --import tsx --test tests/lib/install-manifest.test.ts && node --import tsx --test tests/lib/coord-events.test.ts && node --import tsx --test tests/api/coord-events-route.test.ts && node --import tsx --test tests/lib/coord-projections-inbox.test.ts && node --import tsx --test tests/lib/coord-projections-reservations.test.ts && node --import tsx --test tests/components/sessions/conversation-drawer-coord.test.tsx && node --import tsx --test tests/scripts/beadboard-launcher.test.ts && node --import tsx --test tests/scripts/install-wrappers-contract.test.ts && node --import tsx --test tests/scripts/install-sh-smoke.test.ts && node --import tsx --test tests/scripts/installer-ci-contract.test.ts && node --import tsx --test tests/docs/installer-quickstart-contract.test.ts && node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts && node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts && node --import tsx --test tests/skills/beadboard-driver/generate-agent-name.test.ts && node --import tsx --test tests/skills/beadboard-driver/readiness-report.test.ts && node --import tsx --test tests/skills/beadboard-driver/skill-local-runner.test.ts && node --import tsx --test tests/skills/beadboard-driver/diagnose-env.test.ts && node --import tsx --test tests/skills/beadboard-driver/heal-common-issues.test.ts && node --import tsx --test tests/lib/epic-graph.test.ts && node --import tsx --test tests/components/shared/left-panel-filtering.test.ts && node --import tsx --test tests/hooks/use-beads-subscription-contract.test.ts && node --import tsx --test tests/components/graph/dependency-graph-hide-closed-contract.test.ts && node --import tsx --test tests/components/shared/unified-shell-hide-closed-contract.test.ts
TAP version 13
# Subtest: bootstrap scaffold files exist
ok 1 - bootstrap scaffold files exist
---
duration_ms: 1.5408
...
# Subtest: package.json has next/react/typescript scripts and deps
ok 2 - package.json has next/react/typescript scripts and deps
---
duration_ms: 0.6082
...
1..2
# tests 2
# suites 0
# pass 2
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 89.6484
TAP version 13
# Subtest: BaseCard Component Contract
# Subtest: exports BaseCard component
ok 1 - exports BaseCard component
---
duration_ms: 48.4903
...
1..1
ok 1 - BaseCard Component Contract
---
duration_ms: 49.1763
type: 'suite'
...
# Subtest: BaseCard Styling Logic
# Subtest: should be possible to import the component
ok 1 - should be possible to import the component
---
duration_ms: 1.6433
...
# Subtest: applies correct status border class for "ready" status
ok 2 - applies correct status border class for "ready" status
---
duration_ms: 8.9211
...
# Subtest: applies correct status border class for "blocked" status
ok 3 - applies correct status border class for "blocked" status
---
duration_ms: 1.9781
...
# Subtest: applies selection ring when selected prop is true
ok 4 - applies selection ring when selected prop is true
---
duration_ms: 1.3742
...
1..4
ok 2 - BaseCard Styling Logic
---
duration_ms: 14.3343
type: 'suite'
...
1..2
# tests 5
# suites 2
# pass 5
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 359.7963
TAP version 13
# Subtest: AgentAvatar Component Contract
# Subtest: exports AgentAvatar component
ok 1 - exports AgentAvatar component
---
duration_ms: 112.1114
...
1..1
ok 1 - AgentAvatar Component Contract
---
duration_ms: 112.7409
type: 'suite'
...
# Subtest: AgentAvatar Role Styling
# Subtest: applies correct role color class for "ui" role
ok 1 - applies correct role color class for "ui" role
---
duration_ms: 7.7314
...
# Subtest: applies correct role color class for "orchestrator" role
ok 2 - applies correct role color class for "orchestrator" role
---
duration_ms: 2.3245
...
1..2
ok 2 - AgentAvatar Role Styling
---
duration_ms: 10.3257
type: 'suite'
...
# Subtest: AgentAvatar ZFC States
# Subtest: applies working pulse glow
ok 1 - applies working pulse glow
---
duration_ms: 1.7868
...
1..1
ok 3 - AgentAvatar ZFC States
---
duration_ms: 2.1043
type: 'suite'
...
1..3
# tests 4
# suites 3
# pass 4
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 414.8522
TAP version 13
# Subtest: SessionsHeader: Agent Grouping
# Subtest: groups agents by swarm
ok 1 - groups agents by swarm
---
duration_ms: 2.028
...
# Subtest: shows fallback bucket for unassigned agents
ok 2 - shows fallback bucket for unassigned agents
---
duration_ms: 0.163
...
# Subtest: handles empty swarm groups
ok 3 - handles empty swarm groups
---
duration_ms: 0.1271
...
1..3
ok 1 - SessionsHeader: Agent Grouping
---
duration_ms: 3.2566
type: 'suite'
...
1..1
# tests 3
# suites 1
# pass 3
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 259.5842
TAP version 13
# Subtest: getAgentRoleColor returns correct color for known roles
ok 1 - getAgentRoleColor returns correct color for known roles
---
duration_ms: 0.7893
...
# Subtest: getAgentRoleColor returns default for unknown role
ok 2 - getAgentRoleColor returns default for unknown role
---
duration_ms: 0.1416
...
1..2
# tests 2
# suites 0
# pass 2
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 260.6046
TAP version 13
# Subtest: parseIssuesJsonl applies defaults and preserves priority 0
ok 1 - parseIssuesJsonl applies defaults and preserves priority 0
---
duration_ms: 1.1468
...
# Subtest: parseIssuesJsonl skips malformed and blank lines
ok 2 - parseIssuesJsonl skips malformed and blank lines
---
duration_ms: 0.2118
...
# Subtest: parseIssuesJsonl filters tombstones by default
ok 3 - parseIssuesJsonl filters tombstones by default
---
duration_ms: 0.1758
...
# Subtest: parseIssuesJsonl can include tombstones when requested
ok 4 - parseIssuesJsonl can include tombstones when requested
---
duration_ms: 0.1626
...
# Subtest: parseIssuesJsonl supports beads dependency schema with depends_on_id and parent-child
ok 5 - parseIssuesJsonl supports beads dependency schema with depends_on_id and parent-child
---
duration_ms: 0.7949
...
1..5
# tests 5
# suites 0
# pass 5
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 269.9367
TAP version 13
# Subtest: canonicalizeWindowsPath normalizes separators and drive casing
ok 1 - canonicalizeWindowsPath normalizes separators and drive casing
---
duration_ms: 1.4342
...
# Subtest: windowsPathKey is case-insensitive stable key
ok 2 - windowsPathKey is case-insensitive stable key
---
duration_ms: 0.4737
...
# Subtest: toDisplayPath renders forward slashes for UI readability
ok 3 - toDisplayPath renders forward slashes for UI readability
---
duration_ms: 0.2287
...
# Subtest: sameWindowsPath handles case/separator differences
ok 4 - sameWindowsPath handles case/separator differences
---
duration_ms: 0.2269
...
1..4
# tests 4
# suites 0
# pass 4
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 290.6242
TAP version 13
# Subtest: LeftPanel Component Contract
# Subtest: exports LeftPanel component
ok 1 - exports LeftPanel component
---
duration_ms: 291.6468
...
# Subtest: LeftPanel accepts issues and onEpicSelect props
ok 2 - LeftPanel accepts issues and onEpicSelect props
---
duration_ms: 1.3553
...
1..2
ok 1 - LeftPanel Component Contract
---
duration_ms: 294.0487
type: 'suite'
...
# Subtest: LeftPanel Tree Structure
# Subtest: renders epics as expandable tree items
ok 1 - renders epics as expandable tree items
---
duration_ms: 1.1796
...
# Subtest: groups beads under their parent epic
ok 2 - groups beads under their parent epic
---
duration_ms: 1.1357
...
1..2
ok 2 - LeftPanel Tree Structure
---
duration_ms: 2.5592
type: 'suite'
...
# Subtest: LeftPanel Responsive Behavior
# Subtest: applies responsive classes for desktop, tablet, and mobile
ok 1 - applies responsive classes for desktop, tablet, and mobile
---
duration_ms: 1.4154
...
1..1
ok 3 - LeftPanel Responsive Behavior
---
duration_ms: 1.6082
type: 'suite'
...
# Subtest: LeftPanel Scope Controls
# Subtest: renders scope section
ok 1 - renders scope section
---
duration_ms: 1.2414
...
1..1
ok 4 - LeftPanel Scope Controls
---
duration_ms: 1.5705
type: 'suite'
...
1..4
# tests 6
# suites 4
# pass 6
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 586.4632
TAP version 13
# Subtest: TopBar Component Contract
# Subtest: exports TopBar component
ok 1 - exports TopBar component
---
duration_ms: 576.3556
...
# Subtest: TopBar component can be imported without errors
ok 2 - TopBar component can be imported without errors
---
duration_ms: 1.4049
...
1..2
ok 1 - TopBar Component Contract
---
duration_ms: 578.6933
type: 'suite'
...
# Subtest: TopBar View Tabs
# Subtest: renders view tabs: Social, Graph
ok 1 - renders view tabs: Social, Graph
---
duration_ms: 1.1653
...
# Subtest: active tab has bold text and accent underline
ok 2 - active tab has bold text and accent underline
---
duration_ms: 1.0756
...
1..2
ok 2 - TopBar View Tabs
---
duration_ms: 2.4564
type: 'suite'
...
# Subtest: TopBar Filter and Controls
# Subtest: renders filter/search input placeholder
ok 1 - renders filter/search input placeholder
---
duration_ms: 1.2466
...
# Subtest: renders settings placeholder
ok 2 - renders settings placeholder
---
duration_ms: 1.0997
...
1..2
ok 3 - TopBar Filter and Controls
---
duration_ms: 2.7634
type: 'suite'
...
1..3
# tests 6
# suites 3
# pass 6
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 843.1609
TAP version 13
# Subtest: Mobile Navigation - Hamburger Menu
# Subtest: exports MobileNav component
ok 1 - exports MobileNav component
---
duration_ms: 122.7061
...
# Subtest: renders tab buttons: Social, Graph
ok 2 - renders tab buttons: Social, Graph
---
duration_ms: 1.5081
...
# Subtest: highlights active tab with accent color
ok 3 - highlights active tab with accent color
---
duration_ms: 1.5626
...
# Subtest: uses setView from useUrlState on tab click
ok 4 - uses setView from useUrlState on tab click
---
duration_ms: 1.3467
...
1..4
ok 1 - Mobile Navigation - Hamburger Menu
---
duration_ms: 128.9482
type: 'suite'
...
# Subtest: TopBar Hamburger Menu
# Subtest: shows hamburger button on mobile and tablet
ok 1 - shows hamburger button on mobile and tablet
---
duration_ms: 487.0038
...
# Subtest: hamburger button opens left panel drawer
ok 2 - hamburger button opens left panel drawer
---
duration_ms: 1.478
...
# Subtest: hides hamburger on desktop
ok 3 - hides hamburger on desktop
---
duration_ms: 1.1051
...
1..3
ok 2 - TopBar Hamburger Menu
---
duration_ms: 490.1177
type: 'suite'
...
1..2
# tests 7
# suites 2
# pass 7
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 899.3239
TAP version 13
# Subtest: SwarmCard Component Contract
# Subtest: exports SwarmCard component
ok 1 - exports SwarmCard component
---
duration_ms: 238.5797
...
# Subtest: SwarmCard component can be imported without errors
ok 2 - SwarmCard component can be imported without errors
---
duration_ms: 1.6861
...
1..2
ok 1 - SwarmCard Component Contract
---
duration_ms: 241.2828
type: 'suite'
...
# Subtest: SwarmCard Agent Roster
# Subtest: renders agent avatars with liveness glow
ok 1 - renders agent avatars with liveness glow
---
duration_ms: 1.7451
...
# Subtest: displays agent current task when available
ok 2 - displays agent current task when available
---
duration_ms: 1.4825
...
1..2
ok 2 - SwarmCard Agent Roster
---
duration_ms: 3.5718
type: 'suite'
...
# Subtest: SwarmCard Progress Bar
# Subtest: renders progress bar showing completion percentage
ok 1 - renders progress bar showing completion percentage
---
duration_ms: 1.6795
...
1..1
ok 3 - SwarmCard Progress Bar
---
duration_ms: 1.8984
type: 'suite'
...
# Subtest: SwarmCard Attention Items
# Subtest: renders attention items with warning styling
ok 1 - renders attention items with warning styling
---
duration_ms: 1.7077
...
1..1
ok 4 - SwarmCard Attention Items
---
duration_ms: 2.1567
type: 'suite'
...
# Subtest: SwarmCard View-Jump Icons
# Subtest: renders view-jump icons for navigation
ok 1 - renders view-jump icons for navigation
---
duration_ms: 1.7431
...
1..1
ok 5 - SwarmCard View-Jump Icons
---
duration_ms: 2.0339
type: 'suite'
...
1..5
# tests 7
# suites 5
# pass 7
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 515.754
TAP version 13
# Subtest: URL State Integration - bb-ui2.22
# Subtest: Valid URL Patterns - Social View
# Subtest: /?view=social - defaults to social view
ok 1 - /?view=social - defaults to social view
---
duration_ms: 0.8379
...
# Subtest: /?view=social&task=bb-buff.1&panel=open - task selected, panel open
ok 2 - /?view=social&task=bb-buff.1&panel=open - task selected, panel open
---
duration_ms: 0.2068
...
# Subtest: /?view=social&task=bb-ui2.22 - task with dots in ID
ok 3 - /?view=social&task=bb-ui2.22 - task with dots in ID
---
duration_ms: 0.1241
...
1..3
ok 1 - Valid URL Patterns - Social View
---
duration_ms: 1.803
type: 'suite'
...
# Subtest: Valid URL Patterns - Graph View
# Subtest: /?view=graph - graph view default
not ok 1 - /?view=graph - graph view default
---
duration_ms: 3.2799
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:2578'
failureType: 'testCodeFailure'
error: |-
Expected values to be strictly equal:
'overview' !== 'flow'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: 'flow'
actual: 'overview'
operator: 'strictEqual'
stack: |-
TestContext.<anonymous> (C:\Users\Zenchant\codex\beadboard\tests\hooks\url-state-integration.test.ts:53:14)
Test.runInAsyncScope (node:async_hooks:211:14)
Test.run (node:internal/test_runner/test:934:25)
Test.start (node:internal/test_runner/test:833:17)
node:internal/test_runner/test:1318:71
node:internal/per_context/primordials:483:82
new Promise (<anonymous>)
new SafePromise (node:internal/per_context/primordials:451:29)
node:internal/per_context/primordials:483:9
Array.map (<anonymous>)
...
# Subtest: /?view=graph&task=bb-buff.1 - graph with task selected
ok 2 - /?view=graph&task=bb-buff.1 - graph with task selected
---
duration_ms: 0.1241
...
# Subtest: /?view=graph&graphTab=flow - flow tab selected
ok 3 - /?view=graph&graphTab=flow - flow tab selected
---
duration_ms: 0.2827
...
# Subtest: /?view=graph&graphTab=overview - overview tab selected
ok 4 - /?view=graph&graphTab=overview - overview tab selected
---
duration_ms: 0.1152
...
# Subtest: /?view=graph&swarm=bb-buff - graph filtered by swarm
ok 5 - /?view=graph&swarm=bb-buff - graph filtered by swarm
---
duration_ms: 0.3114
...
1..5
not ok 2 - Valid URL Patterns - Graph View
---
duration_ms: 4.4826
type: 'suite'
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:2515'
failureType: 'subtestsFailed'
error: '1 subtest failed'
code: 'ERR_TEST_FAILURE'
...
# Subtest: Deprecated Swarm View Fallback
# Subtest: /?view=swarm - falls back to social (swarm view deprecated)
ok 1 - /?view=swarm - falls back to social (swarm view deprecated)
---
duration_ms: 0.176
...
# Subtest: /?view=swarm&swarm=bb-buff - falls back to social but preserves swarmId
ok 2 - /?view=swarm&swarm=bb-buff - falls back to social but preserves swarmId
---
duration_ms: 0.3375
...
# Subtest: /?view=swarm&swarm=bb-buff&panel=open - falls back to social with panel open
ok 3 - /?view=swarm&swarm=bb-buff&panel=open - falls back to social with panel open
---
duration_ms: 0.1203
...
1..3
ok 3 - Deprecated Swarm View Fallback
---
duration_ms: 0.8018
type: 'suite'
...
# Subtest: Valid URL Patterns - Activity View
# Subtest: /?view=activity - activity view default
ok 1 - /?view=activity - activity view default
---
duration_ms: 0.1469
...
# Subtest: /?view=activity&agent=bb-silver-castle - filtered by agent
ok 2 - /?view=activity&agent=bb-silver-castle - filtered by agent
---
duration_ms: 0.0856
...
# Subtest: /?view=activity&swarm=bb-buff - filtered by swarm
ok 3 - /?view=activity&swarm=bb-buff - filtered by swarm
---
duration_ms: 0.0813
...
1..3
ok 4 - Valid URL Patterns - Activity View
---
duration_ms: 0.4565
type: 'suite'
...
# Subtest: Invalid Param Handling
# Subtest: /?view=invalid - invalid view defaults to social
ok 1 - /?view=invalid - invalid view defaults to social
---
duration_ms: 0.1489
...
# Subtest: /?view=graph&graphTab=invalid - invalid graphTab defaults to flow
not ok 2 - /?view=graph&graphTab=invalid - invalid graphTab defaults to flow
---
duration_ms: 0.4762
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:6479'
failureType: 'testCodeFailure'
error: |-
Expected values to be strictly equal:
'overview' !== 'flow'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: 'flow'
actual: 'overview'
operator: 'strictEqual'
stack: |-
TestContext.<anonymous> (C:\Users\Zenchant\codex\beadboard\tests\hooks\url-state-integration.test.ts:138:14)
Test.runInAsyncScope (node:async_hooks:211:14)
Test.run (node:internal/test_runner/test:934:25)
Suite.processPendingSubtests (node:internal/test_runner/test:633:18)
Test.postRun (node:internal/test_runner/test:1045:19)
Test.run (node:internal/test_runner/test:973:12)
async Promise.all (index 0)
async Suite.run (node:internal/test_runner/test:1320:7)
async Suite.processPendingSubtests (node:internal/test_runner/test:633:7)
...
# Subtest: /?panel=invalid - invalid panel defaults to open
ok 3 - /?panel=invalid - invalid panel defaults to open
---
duration_ms: 0.1006
...
# Subtest: /?task=invalid-id - invalid task ID still parsed (no validation)
ok 4 - /?task=invalid-id - invalid task ID still parsed (no validation)
---
duration_ms: 0.0841
...
1..4
not ok 5 - Invalid Param Handling
---
duration_ms: 0.9701
type: 'suite'
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:6178'
failureType: 'subtestsFailed'
error: '1 subtest failed'
code: 'ERR_TEST_FAILURE'
...
# Subtest: URL Building - State to URL
# Subtest: builds social view URL
ok 1 - builds social view URL
---
duration_ms: 0.2194
...
# Subtest: builds graph view with task URL
ok 2 - builds graph view with task URL
---
duration_ms: 0.0932
...
# Subtest: builds swarm view with swarm param
ok 3 - builds swarm view with swarm param
---
duration_ms: 0.085
...
# Subtest: builds activity view with agent filter
ok 4 - builds activity view with agent filter
---
duration_ms: 0.1405
...
# Subtest: preserves existing params when adding new ones
ok 5 - preserves existing params when adding new ones
---
duration_ms: 0.1868
...
# Subtest: removes params when set to null
ok 6 - removes params when set to null
---
duration_ms: 0.1154
...
# Subtest: returns root when all params cleared
ok 7 - returns root when all params cleared
---
duration_ms: 0.0926
...
1..7
ok 6 - URL Building - State to URL
---
duration_ms: 1.1103
type: 'suite'
...
# Subtest: Complex URL Scenarios
# Subtest: handles all params together
ok 1 - handles all params together
---
duration_ms: 0.123
...
# Subtest: empty string values treated as null/empty
ok 2 - empty string values treated as null/empty
---
duration_ms: 0.0893
...
1..2
ok 7 - Complex URL Scenarios
---
duration_ms: 0.351
type: 'suite'
...
# Subtest: Deep Link Patterns - From Card Icons
# Subtest: SocialCard Graph icon: /?view=graph&task={id}
ok 1 - SocialCard Graph icon: /?view=graph&task={id}
---
duration_ms: 0.1287
...
# Subtest: SwarmCard Graph icon: /?view=graph&swarm={id}
ok 2 - SwarmCard Graph icon: /?view=graph&swarm={id}
---
duration_ms: 0.0785
...
# Subtest: SwarmCard Timeline icon: /?view=activity&swarm={id}
ok 3 - SwarmCard Timeline icon: /?view=activity&swarm={id}
---
duration_ms: 0.1411
...
# Subtest: Agent avatar click: /?view=activity&agent={id}
ok 4 - Agent avatar click: /?view=activity&agent={id}
---
duration_ms: 0.076
...
1..4
ok 8 - Deep Link Patterns - From Card Icons
---
duration_ms: 0.5678
type: 'suite'
...
1..8
not ok 1 - URL State Integration - bb-ui2.22
---
duration_ms: 11.4418
type: 'suite'
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:1269'
failureType: 'subtestsFailed'
error: '2 subtests failed'
code: 'ERR_TEST_FAILURE'
...
1..1
# tests 31
# suites 9
# pass 29
# fail 2
# cancelled 0
# skipped 0
# todo 0
# duration_ms 447.3716

919
.beads/npm_test_output2.txt Normal file
View file

@ -0,0 +1,919 @@
> beadboard@0.1.0 test
> node --test tests/bootstrap.test.mjs && node --import tsx --test tests/components/shared/base-card.test.tsx && node --import tsx --test tests/components/shared/agent-avatar.test.tsx && node --import tsx --test tests/components/sessions/sessions-header.test.ts && node --import tsx --test tests/components/sessions/agent-station-logic.test.ts && node --import tsx --test tests/lib/parser.test.ts && node --import tsx --test tests/lib/pathing.test.ts && node --import tsx --test tests/components/shared/left-panel.test.tsx && node --import tsx --test tests/components/shared/top-bar.test.tsx && node --import tsx --test tests/components/shared/mobile-nav.test.tsx && node --import tsx --test tests/components/swarm/swarm-card.test.tsx && node --import tsx --test tests/hooks/url-state-integration.test.ts && node --import tsx --test tests/hooks/use-graph-analysis.test.ts && node --import tsx --test tests/components/graph/smart-dag.test.tsx && node --import tsx --test tests/components/unified-shell.test.tsx && node --import tsx --test tests/components/blocked-triage-modal.test.tsx && node --import tsx --test tests/components/graph/graph-node-labels.test.tsx && node --import tsx --test tests/components/graph/graph-node-assign.test.tsx && node --import tsx --test tests/components/graph/graph-node-conversation.test.tsx && node --import tsx --test tests/lib/coord-schema.test.ts && node --import tsx --test tests/lib/install-manifest.test.ts && node --import tsx --test tests/lib/coord-events.test.ts && node --import tsx --test tests/api/coord-events-route.test.ts && node --import tsx --test tests/lib/coord-projections-inbox.test.ts && node --import tsx --test tests/lib/coord-projections-reservations.test.ts && node --import tsx --test tests/components/sessions/conversation-drawer-coord.test.tsx && node --import tsx --test tests/scripts/beadboard-launcher.test.ts && node --import tsx --test tests/scripts/install-wrappers-contract.test.ts && node --import tsx --test tests/scripts/install-sh-smoke.test.ts && node --import tsx --test tests/scripts/installer-ci-contract.test.ts && node --import tsx --test tests/docs/installer-quickstart-contract.test.ts && node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts && node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts && node --import tsx --test tests/skills/beadboard-driver/generate-agent-name.test.ts && node --import tsx --test tests/skills/beadboard-driver/readiness-report.test.ts && node --import tsx --test tests/skills/beadboard-driver/skill-local-runner.test.ts && node --import tsx --test tests/skills/beadboard-driver/diagnose-env.test.ts && node --import tsx --test tests/skills/beadboard-driver/heal-common-issues.test.ts && node --import tsx --test tests/lib/epic-graph.test.ts && node --import tsx --test tests/components/shared/left-panel-filtering.test.ts && node --import tsx --test tests/hooks/use-beads-subscription-contract.test.ts && node --import tsx --test tests/components/graph/dependency-graph-hide-closed-contract.test.ts && node --import tsx --test tests/components/shared/unified-shell-hide-closed-contract.test.ts
TAP version 13
# Subtest: bootstrap scaffold files exist
ok 1 - bootstrap scaffold files exist
---
duration_ms: 2.2085
...
# Subtest: package.json has next/react/typescript scripts and deps
ok 2 - package.json has next/react/typescript scripts and deps
---
duration_ms: 0.5581
...
1..2
# tests 2
# suites 0
# pass 2
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 140.1608
TAP version 13
# Subtest: BaseCard Component Contract
# Subtest: exports BaseCard component
ok 1 - exports BaseCard component
---
duration_ms: 58.211
...
1..1
ok 1 - BaseCard Component Contract
---
duration_ms: 58.9965
type: 'suite'
...
# Subtest: BaseCard Styling Logic
# Subtest: should be possible to import the component
ok 1 - should be possible to import the component
---
duration_ms: 2.4528
...
# Subtest: applies correct status border class for "ready" status
ok 2 - applies correct status border class for "ready" status
---
duration_ms: 10.367
...
# Subtest: applies correct status border class for "blocked" status
ok 3 - applies correct status border class for "blocked" status
---
duration_ms: 2.0545
...
# Subtest: applies selection ring when selected prop is true
ok 4 - applies selection ring when selected prop is true
---
duration_ms: 1.3688
...
1..4
ok 2 - BaseCard Styling Logic
---
duration_ms: 16.6551
type: 'suite'
...
1..2
# tests 5
# suites 2
# pass 5
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 447.2767
TAP version 13
# Subtest: AgentAvatar Component Contract
# Subtest: exports AgentAvatar component
ok 1 - exports AgentAvatar component
---
duration_ms: 154.6347
...
1..1
ok 1 - AgentAvatar Component Contract
---
duration_ms: 155.6009
type: 'suite'
...
# Subtest: AgentAvatar Role Styling
# Subtest: applies correct role color class for "ui" role
ok 1 - applies correct role color class for "ui" role
---
duration_ms: 11.7114
...
# Subtest: applies correct role color class for "orchestrator" role
ok 2 - applies correct role color class for "orchestrator" role
---
duration_ms: 2.6704
...
1..2
ok 2 - AgentAvatar Role Styling
---
duration_ms: 14.7057
type: 'suite'
...
# Subtest: AgentAvatar ZFC States
# Subtest: applies working pulse glow
ok 1 - applies working pulse glow
---
duration_ms: 2.4504
...
1..1
ok 3 - AgentAvatar ZFC States
---
duration_ms: 2.8198
type: 'suite'
...
1..3
# tests 4
# suites 3
# pass 4
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 539.4517
TAP version 13
# Subtest: SessionsHeader: Agent Grouping
# Subtest: groups agents by swarm
ok 1 - groups agents by swarm
---
duration_ms: 2.114
...
# Subtest: shows fallback bucket for unassigned agents
ok 2 - shows fallback bucket for unassigned agents
---
duration_ms: 0.1808
...
# Subtest: handles empty swarm groups
ok 3 - handles empty swarm groups
---
duration_ms: 0.1339
...
1..3
ok 1 - SessionsHeader: Agent Grouping
---
duration_ms: 3.4059
type: 'suite'
...
1..1
# tests 3
# suites 1
# pass 3
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 283.1807
TAP version 13
# Subtest: getAgentRoleColor returns correct color for known roles
ok 1 - getAgentRoleColor returns correct color for known roles
---
duration_ms: 0.8966
...
# Subtest: getAgentRoleColor returns default for unknown role
ok 2 - getAgentRoleColor returns default for unknown role
---
duration_ms: 0.1598
...
1..2
# tests 2
# suites 0
# pass 2
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 309.895
TAP version 13
# Subtest: parseIssuesJsonl applies defaults and preserves priority 0
ok 1 - parseIssuesJsonl applies defaults and preserves priority 0
---
duration_ms: 1.1101
...
# Subtest: parseIssuesJsonl skips malformed and blank lines
ok 2 - parseIssuesJsonl skips malformed and blank lines
---
duration_ms: 0.1784
...
# Subtest: parseIssuesJsonl filters tombstones by default
ok 3 - parseIssuesJsonl filters tombstones by default
---
duration_ms: 0.1475
...
# Subtest: parseIssuesJsonl can include tombstones when requested
ok 4 - parseIssuesJsonl can include tombstones when requested
---
duration_ms: 0.1428
...
# Subtest: parseIssuesJsonl supports beads dependency schema with depends_on_id and parent-child
ok 5 - parseIssuesJsonl supports beads dependency schema with depends_on_id and parent-child
---
duration_ms: 0.7034
...
1..5
# tests 5
# suites 0
# pass 5
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 279.9641
TAP version 13
# Subtest: canonicalizeWindowsPath normalizes separators and drive casing
ok 1 - canonicalizeWindowsPath normalizes separators and drive casing
---
duration_ms: 0.9528
...
# Subtest: windowsPathKey is case-insensitive stable key
ok 2 - windowsPathKey is case-insensitive stable key
---
duration_ms: 0.2036
...
# Subtest: toDisplayPath renders forward slashes for UI readability
ok 3 - toDisplayPath renders forward slashes for UI readability
---
duration_ms: 0.1337
...
# Subtest: sameWindowsPath handles case/separator differences
ok 4 - sameWindowsPath handles case/separator differences
---
duration_ms: 0.1696
...
1..4
# tests 4
# suites 0
# pass 4
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 300.62
TAP version 13
# Subtest: LeftPanel Component Contract
# Subtest: exports LeftPanel component
ok 1 - exports LeftPanel component
---
duration_ms: 306.6047
...
# Subtest: LeftPanel accepts issues and onEpicSelect props
ok 2 - LeftPanel accepts issues and onEpicSelect props
---
duration_ms: 1.3879
...
1..2
ok 1 - LeftPanel Component Contract
---
duration_ms: 309.0712
type: 'suite'
...
# Subtest: LeftPanel Tree Structure
# Subtest: renders epics as expandable tree items
ok 1 - renders epics as expandable tree items
---
duration_ms: 1.345
...
# Subtest: groups beads under their parent epic
ok 2 - groups beads under their parent epic
---
duration_ms: 1.7164
...
1..2
ok 2 - LeftPanel Tree Structure
---
duration_ms: 3.332
type: 'suite'
...
# Subtest: LeftPanel Responsive Behavior
# Subtest: applies responsive classes for desktop, tablet, and mobile
ok 1 - applies responsive classes for desktop, tablet, and mobile
---
duration_ms: 1.3508
...
1..1
ok 3 - LeftPanel Responsive Behavior
---
duration_ms: 1.5231
type: 'suite'
...
# Subtest: LeftPanel Scope Controls
# Subtest: renders scope section
ok 1 - renders scope section
---
duration_ms: 1.3167
...
1..1
ok 4 - LeftPanel Scope Controls
---
duration_ms: 1.7059
type: 'suite'
...
1..4
# tests 6
# suites 4
# pass 6
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 598.9805
TAP version 13
# Subtest: TopBar Component Contract
# Subtest: exports TopBar component
ok 1 - exports TopBar component
---
duration_ms: 683.336
...
# Subtest: TopBar component can be imported without errors
ok 2 - TopBar component can be imported without errors
---
duration_ms: 1.848
...
1..2
ok 1 - TopBar Component Contract
---
duration_ms: 686.5443
type: 'suite'
...
# Subtest: TopBar View Tabs
# Subtest: renders view tabs: Social, Graph
ok 1 - renders view tabs: Social, Graph
---
duration_ms: 1.4361
...
# Subtest: active tab has bold text and accent underline
ok 2 - active tab has bold text and accent underline
---
duration_ms: 1.6179
...
1..2
ok 2 - TopBar View Tabs
---
duration_ms: 3.3478
type: 'suite'
...
# Subtest: TopBar Filter and Controls
# Subtest: renders filter/search input placeholder
ok 1 - renders filter/search input placeholder
---
duration_ms: 1.7411
...
# Subtest: renders settings placeholder
ok 2 - renders settings placeholder
---
duration_ms: 1.2955
...
1..2
ok 3 - TopBar Filter and Controls
---
duration_ms: 3.5576
type: 'suite'
...
1..3
# tests 6
# suites 3
# pass 6
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 991.5175
TAP version 13
# Subtest: Mobile Navigation - Hamburger Menu
# Subtest: exports MobileNav component
ok 1 - exports MobileNav component
---
duration_ms: 160.2862
...
# Subtest: renders tab buttons: Social, Graph
ok 2 - renders tab buttons: Social, Graph
---
duration_ms: 1.5794
...
# Subtest: highlights active tab with accent color
ok 3 - highlights active tab with accent color
---
duration_ms: 1.2026
...
# Subtest: uses setView from useUrlState on tab click
ok 4 - uses setView from useUrlState on tab click
---
duration_ms: 1.1548
...
1..4
ok 1 - Mobile Navigation - Hamburger Menu
---
duration_ms: 166.2933
type: 'suite'
...
# Subtest: TopBar Hamburger Menu
# Subtest: shows hamburger button on mobile and tablet
ok 1 - shows hamburger button on mobile and tablet
---
duration_ms: 520.9119
...
# Subtest: hamburger button opens left panel drawer
ok 2 - hamburger button opens left panel drawer
---
duration_ms: 1.9043
...
# Subtest: hides hamburger on desktop
ok 3 - hides hamburger on desktop
---
duration_ms: 1.566
...
1..3
ok 2 - TopBar Hamburger Menu
---
duration_ms: 525.0916
type: 'suite'
...
1..2
# tests 7
# suites 2
# pass 7
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 1031.056
TAP version 13
# Subtest: SwarmCard Component Contract
# Subtest: exports SwarmCard component
ok 1 - exports SwarmCard component
---
duration_ms: 263.9758
...
# Subtest: SwarmCard component can be imported without errors
ok 2 - SwarmCard component can be imported without errors
---
duration_ms: 1.4629
...
1..2
ok 1 - SwarmCard Component Contract
---
duration_ms: 266.6715
type: 'suite'
...
# Subtest: SwarmCard Agent Roster
# Subtest: renders agent avatars with liveness glow
ok 1 - renders agent avatars with liveness glow
---
duration_ms: 1.3692
...
# Subtest: displays agent current task when available
ok 2 - displays agent current task when available
---
duration_ms: 1.5995
...
1..2
ok 2 - SwarmCard Agent Roster
---
duration_ms: 3.3144
type: 'suite'
...
# Subtest: SwarmCard Progress Bar
# Subtest: renders progress bar showing completion percentage
ok 1 - renders progress bar showing completion percentage
---
duration_ms: 1.8139
...
1..1
ok 3 - SwarmCard Progress Bar
---
duration_ms: 2.0726
type: 'suite'
...
# Subtest: SwarmCard Attention Items
# Subtest: renders attention items with warning styling
ok 1 - renders attention items with warning styling
---
duration_ms: 1.8572
...
1..1
ok 4 - SwarmCard Attention Items
---
duration_ms: 2.3816
type: 'suite'
...
# Subtest: SwarmCard View-Jump Icons
# Subtest: renders view-jump icons for navigation
ok 1 - renders view-jump icons for navigation
---
duration_ms: 1.7362
...
1..1
ok 5 - SwarmCard View-Jump Icons
---
duration_ms: 1.9907
type: 'suite'
...
1..5
# tests 7
# suites 5
# pass 7
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 586.4929
TAP version 13
# Subtest: URL State Integration - bb-ui2.22
# Subtest: Valid URL Patterns - Social View
# Subtest: /?view=social - defaults to social view
ok 1 - /?view=social - defaults to social view
---
duration_ms: 0.8523
...
# Subtest: /?view=social&task=bb-buff.1&panel=open - task selected, panel open
ok 2 - /?view=social&task=bb-buff.1&panel=open - task selected, panel open
---
duration_ms: 0.2088
...
# Subtest: /?view=social&task=bb-ui2.22 - task with dots in ID
ok 3 - /?view=social&task=bb-ui2.22 - task with dots in ID
---
duration_ms: 0.1511
...
1..3
ok 1 - Valid URL Patterns - Social View
---
duration_ms: 1.865
type: 'suite'
...
# Subtest: Valid URL Patterns - Graph View
# Subtest: /?view=graph - graph view default
ok 1 - /?view=graph - graph view default
---
duration_ms: 0.2128
...
# Subtest: /?view=graph&task=bb-buff.1 - graph with task selected
ok 2 - /?view=graph&task=bb-buff.1 - graph with task selected
---
duration_ms: 0.1196
...
# Subtest: /?view=graph&graphTab=flow - flow tab selected
ok 3 - /?view=graph&graphTab=flow - flow tab selected
---
duration_ms: 0.1573
...
# Subtest: /?view=graph&graphTab=overview - overview tab selected
ok 4 - /?view=graph&graphTab=overview - overview tab selected
---
duration_ms: 0.116
...
# Subtest: /?view=graph&swarm=bb-buff - graph filtered by swarm
ok 5 - /?view=graph&swarm=bb-buff - graph filtered by swarm
---
duration_ms: 0.2221
...
1..5
ok 2 - Valid URL Patterns - Graph View
---
duration_ms: 1.1579
type: 'suite'
...
# Subtest: Deprecated Swarm View Fallback
# Subtest: /?view=swarm - falls back to social (swarm view deprecated)
ok 1 - /?view=swarm - falls back to social (swarm view deprecated)
---
duration_ms: 0.7522
...
# Subtest: /?view=swarm&swarm=bb-buff - falls back to social but preserves swarmId
ok 2 - /?view=swarm&swarm=bb-buff - falls back to social but preserves swarmId
---
duration_ms: 0.2523
...
# Subtest: /?view=swarm&swarm=bb-buff&panel=open - falls back to social with panel open
ok 3 - /?view=swarm&swarm=bb-buff&panel=open - falls back to social with panel open
---
duration_ms: 0.1228
...
1..3
ok 3 - Deprecated Swarm View Fallback
---
duration_ms: 1.276
type: 'suite'
...
# Subtest: Valid URL Patterns - Activity View
# Subtest: /?view=activity - activity view default
ok 1 - /?view=activity - activity view default
---
duration_ms: 0.1366
...
# Subtest: /?view=activity&agent=bb-silver-castle - filtered by agent
ok 2 - /?view=activity&agent=bb-silver-castle - filtered by agent
---
duration_ms: 0.0823
...
# Subtest: /?view=activity&swarm=bb-buff - filtered by swarm
ok 3 - /?view=activity&swarm=bb-buff - filtered by swarm
---
duration_ms: 0.0788
...
1..3
ok 4 - Valid URL Patterns - Activity View
---
duration_ms: 0.4389
type: 'suite'
...
# Subtest: Invalid Param Handling
# Subtest: /?view=invalid - invalid view defaults to social
ok 1 - /?view=invalid - invalid view defaults to social
---
duration_ms: 0.1141
...
# Subtest: /?view=graph&graphTab=invalid - invalid graphTab defaults to flow
ok 2 - /?view=graph&graphTab=invalid - invalid graphTab defaults to flow
---
duration_ms: 0.0807
...
# Subtest: /?panel=invalid - invalid panel defaults to open
ok 3 - /?panel=invalid - invalid panel defaults to open
---
duration_ms: 0.0801
...
# Subtest: /?task=invalid-id - invalid task ID still parsed (no validation)
ok 4 - /?task=invalid-id - invalid task ID still parsed (no validation)
---
duration_ms: 0.086
...
1..4
ok 5 - Invalid Param Handling
---
duration_ms: 0.4767
type: 'suite'
...
# Subtest: URL Building - State to URL
# Subtest: builds social view URL
ok 1 - builds social view URL
---
duration_ms: 0.2155
...
# Subtest: builds graph view with task URL
ok 2 - builds graph view with task URL
---
duration_ms: 0.1448
...
# Subtest: builds swarm view with swarm param
ok 3 - builds swarm view with swarm param
---
duration_ms: 0.0849
...
# Subtest: builds activity view with agent filter
ok 4 - builds activity view with agent filter
---
duration_ms: 0.0913
...
# Subtest: preserves existing params when adding new ones
ok 5 - preserves existing params when adding new ones
---
duration_ms: 0.1507
...
# Subtest: removes params when set to null
ok 6 - removes params when set to null
---
duration_ms: 0.1207
...
# Subtest: returns root when all params cleared
ok 7 - returns root when all params cleared
---
duration_ms: 0.0871
...
1..7
ok 6 - URL Building - State to URL
---
duration_ms: 1.0559
type: 'suite'
...
# Subtest: Complex URL Scenarios
# Subtest: handles all params together
ok 1 - handles all params together
---
duration_ms: 0.1183
...
# Subtest: empty string values treated as null/empty
ok 2 - empty string values treated as null/empty
---
duration_ms: 0.0817
...
1..2
ok 7 - Complex URL Scenarios
---
duration_ms: 0.2733
type: 'suite'
...
# Subtest: Deep Link Patterns - From Card Icons
# Subtest: SocialCard Graph icon: /?view=graph&task={id}
ok 1 - SocialCard Graph icon: /?view=graph&task={id}
---
duration_ms: 0.1285
...
# Subtest: SwarmCard Graph icon: /?view=graph&swarm={id}
ok 2 - SwarmCard Graph icon: /?view=graph&swarm={id}
---
duration_ms: 0.1297
...
# Subtest: SwarmCard Timeline icon: /?view=activity&swarm={id}
ok 3 - SwarmCard Timeline icon: /?view=activity&swarm={id}
---
duration_ms: 0.0782
...
# Subtest: Agent avatar click: /?view=activity&agent={id}
ok 4 - Agent avatar click: /?view=activity&agent={id}
---
duration_ms: 0.0769
...
1..4
ok 8 - Deep Link Patterns - From Card Icons
---
duration_ms: 0.5198
type: 'suite'
...
1..8
ok 1 - URL State Integration - bb-ui2.22
---
duration_ms: 7.8584
type: 'suite'
...
1..1
# tests 31
# suites 9
# pass 31
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 435.1391
TAP version 13
# Subtest: useGraphAnalysis - module exports
ok 1 - useGraphAnalysis - module exports
---
duration_ms: 29.8133
...
# Subtest: useGraphAnalysis underlying logic - graphModel is built correctly
ok 2 - useGraphAnalysis underlying logic - graphModel is built correctly
---
duration_ms: 10.1561
...
# Subtest: useGraphAnalysis underlying logic - cycleNodeIdSet detects cycles
ok 3 - useGraphAnalysis underlying logic - cycleNodeIdSet detects cycles
---
duration_ms: 0.5465
...
# Subtest: useGraphAnalysis underlying logic - cycleNodeIdSet empty for acyclic graph
ok 4 - useGraphAnalysis underlying logic - cycleNodeIdSet empty for acyclic graph
---
duration_ms: 0.1687
...
# Subtest: useGraphAnalysis underlying logic - blockerAnalysis returns blockers
ok 5 - useGraphAnalysis underlying logic - blockerAnalysis returns blockers
---
duration_ms: 0.4643
...
# Subtest: useGraphAnalysis underlying logic - blockerTooltipMap shows blocker info
ok 6 - useGraphAnalysis underlying logic - blockerTooltipMap shows blocker info
---
duration_ms: 0.3071
...
1..6
# tests 6
# suites 0
# pass 6
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 559.0462
TAP version 13
# Subtest: SmartDag - file exists and exports
ok 1 - SmartDag - file exists and exports
---
duration_ms: 4.3779
...
# Subtest: SmartDag - contains Filters toggle button
ok 2 - SmartDag - contains Filters toggle button
---
duration_ms: 0.949
...
# Subtest: SmartDag - contains Assign toggle button
ok 3 - SmartDag - contains Assign toggle button
---
duration_ms: 0.7066
...
# Subtest: SmartDag - contains WorkflowTabs
ok 4 - SmartDag - contains WorkflowTabs
---
duration_ms: 1.1698
...
# Subtest: SmartDag - supports onAssignModeChange callback
ok 5 - SmartDag - supports onAssignModeChange callback
---
duration_ms: 1.4824
...
# Subtest: SmartDag - supports onSelectedIssueChange callback
ok 6 - SmartDag - supports onSelectedIssueChange callback
---
duration_ms: 0.8891
...
# Subtest: SmartDag - imports TaskCardGrid
ok 7 - SmartDag - imports TaskCardGrid
---
duration_ms: 0.93
...
# Subtest: SmartDag - imports WorkflowGraph
ok 8 - SmartDag - imports WorkflowGraph
---
duration_ms: 0.8032
...
# Subtest: SmartDag - passes assignMode to WorkflowGraph
ok 9 - SmartDag - passes assignMode to WorkflowGraph
---
duration_ms: 0.9817
...
# Subtest: SmartDag - manages hideClosed filter
ok 10 - SmartDag - manages hideClosed filter
---
duration_ms: 1.1005
...
# Subtest: SmartDag - manages sortReadyFirst filter
ok 11 - SmartDag - manages sortReadyFirst filter
---
duration_ms: 0.7155
...
# Subtest: SmartDag - uses useGraphAnalysis hook
ok 12 - SmartDag - uses useGraphAnalysis hook
---
duration_ms: 0.6575
...
1..12
# tests 12
# suites 0
# pass 12
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 326.9817
TAP version 13
# Subtest: UnifiedShell - file exists and exports
ok 1 - UnifiedShell - file exists and exports
---
duration_ms: 4.1613
...
# Subtest: UnifiedShell - has assignMode state
ok 2 - UnifiedShell - has assignMode state
---
duration_ms: 1.0953
...
# Subtest: UnifiedShell - has selectedAssignIssue state
ok 3 - UnifiedShell - has selectedAssignIssue state
---
duration_ms: 0.7628
...
# Subtest: UnifiedShell - passes onAssignModeChange to SmartDag
ok 4 - UnifiedShell - passes onAssignModeChange to SmartDag
---
duration_ms: 0.7559
...
# Subtest: UnifiedShell - passes onSelectedIssueChange to SmartDag
ok 5 - UnifiedShell - passes onSelectedIssueChange to SmartDag
---
duration_ms: 1.3606
...
# Subtest: UnifiedShell - imports AssignmentPanel
ok 6 - UnifiedShell - imports AssignmentPanel
---
duration_ms: 0.9392
...
# Subtest: UnifiedShell - checks bd health and renders setup warning
ok 7 - UnifiedShell - checks bd health and renders setup warning
---
duration_ms: 0.7768
...
# Subtest: UnifiedShell - renders AssignmentPanel conditionally
not ok 8 - UnifiedShell - renders AssignmentPanel conditionally
---
duration_ms: 1.9496
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\components\\unified-shell.test.tsx:2:3626'
failureType: 'testCodeFailure'
error: 'Should check view === graph && assignMode condition for AssignmentPanel'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: true
actual: false
operator: '=='
stack: |-
TestContext.<anonymous> (C:\Users\Zenchant\codex\beadboard\tests\components\unified-shell.test.tsx:53:10)
async Test.run (node:internal/test_runner/test:935:9)
async Test.processPendingSubtests (node:internal/test_runner/test:633:7)
...
# Subtest: UnifiedShell - does not import SwarmWorkspace
ok 9 - UnifiedShell - does not import SwarmWorkspace
---
duration_ms: 1.647
...
# Subtest: UnifiedShell - does not import SwarmMissionPicker
ok 10 - UnifiedShell - does not import SwarmMissionPicker
---
duration_ms: 1.0699
...
1..10
# tests 10
# suites 0
# pass 9
# fail 1
# cancelled 0
# skipped 0
# todo 0
# duration_ms 309.2239

1395
.beads/npm_test_output3.txt Normal file

File diff suppressed because it is too large Load diff

3
.beads/task1.txt Normal file
View file

@ -0,0 +1,3 @@
✓ Created issue: beadboard-txj.1 — Implement graph transitive reduction algorithm
Priority: P0
Status: open

3
.beads/task2.txt Normal file
View file

@ -0,0 +1,3 @@
✓ Created issue: beadboard-txj.2 — Apply Status Colors and Transitive Context to Graph Edges
Priority: P0
Status: open

3
.beads/task3.txt Normal file
View file

@ -0,0 +1,3 @@
✓ Created issue: beadboard-txj.3 — Implement Graph Focus (Selection) Interactivity
Priority: P1
Status: open

790
.beads/test_output.txt Normal file
View file

@ -0,0 +1,790 @@
TAP version 13
# Subtest: bootstrap scaffold files exist
ok 1 - bootstrap scaffold files exist
---
duration_ms: 1.7879
...
# Subtest: package.json has next/react/typescript scripts and deps
ok 2 - package.json has next/react/typescript scripts and deps
---
duration_ms: 0.7269
...
1..2
# tests 2
# suites 0
# pass 2
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 109.641
TAP version 13
# Subtest: BaseCard Component Contract
# Subtest: exports BaseCard component
ok 1 - exports BaseCard component
---
duration_ms: 49.7712
...
1..1
ok 1 - BaseCard Component Contract
---
duration_ms: 50.4334
type: 'suite'
...
# Subtest: BaseCard Styling Logic
# Subtest: should be possible to import the component
ok 1 - should be possible to import the component
---
duration_ms: 1.6802
...
# Subtest: applies correct status border class for "ready" status
ok 2 - applies correct status border class for "ready" status
---
duration_ms: 14.5164
...
# Subtest: applies correct status border class for "blocked" status
ok 3 - applies correct status border class for "blocked" status
---
duration_ms: 5.9515
...
# Subtest: applies selection ring when selected prop is true
ok 4 - applies selection ring when selected prop is true
---
duration_ms: 2.9283
...
1..4
ok 2 - BaseCard Styling Logic
---
duration_ms: 25.6463
type: 'suite'
...
1..2
# tests 5
# suites 2
# pass 5
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 387.1692
TAP version 13
# Subtest: AgentAvatar Component Contract
# Subtest: exports AgentAvatar component
ok 1 - exports AgentAvatar component
---
duration_ms: 116.5064
...
1..1
ok 1 - AgentAvatar Component Contract
---
duration_ms: 117.1492
type: 'suite'
...
# Subtest: AgentAvatar Role Styling
# Subtest: applies correct role color class for "ui" role
ok 1 - applies correct role color class for "ui" role
---
duration_ms: 7.4888
...
# Subtest: applies correct role color class for "orchestrator" role
ok 2 - applies correct role color class for "orchestrator" role
---
duration_ms: 1.8762
...
1..2
ok 2 - AgentAvatar Role Styling
---
duration_ms: 9.6138
type: 'suite'
...
# Subtest: AgentAvatar ZFC States
# Subtest: applies working pulse glow
ok 1 - applies working pulse glow
---
duration_ms: 1.3946
...
1..1
ok 3 - AgentAvatar ZFC States
---
duration_ms: 1.6685
type: 'suite'
...
1..3
# tests 4
# suites 3
# pass 4
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 435.7079
TAP version 13
# Subtest: SessionsHeader: Agent Grouping
# Subtest: groups agents by swarm
ok 1 - groups agents by swarm
---
duration_ms: 2.0443
...
# Subtest: shows fallback bucket for unassigned agents
ok 2 - shows fallback bucket for unassigned agents
---
duration_ms: 0.1574
...
# Subtest: handles empty swarm groups
ok 3 - handles empty swarm groups
---
duration_ms: 0.1261
...
1..3
ok 1 - SessionsHeader: Agent Grouping
---
duration_ms: 3.2814
type: 'suite'
...
1..1
# tests 3
# suites 1
# pass 3
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 267.9904
TAP version 13
# Subtest: getAgentRoleColor returns correct color for known roles
ok 1 - getAgentRoleColor returns correct color for known roles
---
duration_ms: 0.7796
...
# Subtest: getAgentRoleColor returns default for unknown role
ok 2 - getAgentRoleColor returns default for unknown role
---
duration_ms: 0.1221
...
1..2
# tests 2
# suites 0
# pass 2
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 250.2131
TAP version 13
# Subtest: parseIssuesJsonl applies defaults and preserves priority 0
ok 1 - parseIssuesJsonl applies defaults and preserves priority 0
---
duration_ms: 1.1101
...
# Subtest: parseIssuesJsonl skips malformed and blank lines
ok 2 - parseIssuesJsonl skips malformed and blank lines
---
duration_ms: 0.1893
...
# Subtest: parseIssuesJsonl filters tombstones by default
ok 3 - parseIssuesJsonl filters tombstones by default
---
duration_ms: 0.148
...
# Subtest: parseIssuesJsonl can include tombstones when requested
ok 4 - parseIssuesJsonl can include tombstones when requested
---
duration_ms: 0.1451
...
# Subtest: parseIssuesJsonl supports beads dependency schema with depends_on_id and parent-child
ok 5 - parseIssuesJsonl supports beads dependency schema with depends_on_id and parent-child
---
duration_ms: 0.7609
...
1..5
# tests 5
# suites 0
# pass 5
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 275.8118
TAP version 13
# Subtest: canonicalizeWindowsPath normalizes separators and drive casing
ok 1 - canonicalizeWindowsPath normalizes separators and drive casing
---
duration_ms: 0.9571
...
# Subtest: windowsPathKey is case-insensitive stable key
ok 2 - windowsPathKey is case-insensitive stable key
---
duration_ms: 0.2276
...
# Subtest: toDisplayPath renders forward slashes for UI readability
ok 3 - toDisplayPath renders forward slashes for UI readability
---
duration_ms: 0.1456
...
# Subtest: sameWindowsPath handles case/separator differences
ok 4 - sameWindowsPath handles case/separator differences
---
duration_ms: 0.1285
...
1..4
# tests 4
# suites 0
# pass 4
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 257.9372
TAP version 13
# Subtest: LeftPanel Component Contract
# Subtest: exports LeftPanel component
ok 1 - exports LeftPanel component
---
duration_ms: 476.382
...
# Subtest: LeftPanel accepts issues and onEpicSelect props
ok 2 - LeftPanel accepts issues and onEpicSelect props
---
duration_ms: 2.427
...
1..2
ok 1 - LeftPanel Component Contract
---
duration_ms: 480.2344
type: 'suite'
...
# Subtest: LeftPanel Tree Structure
# Subtest: renders epics as expandable tree items
ok 1 - renders epics as expandable tree items
---
duration_ms: 2.4781
...
# Subtest: groups beads under their parent epic
ok 2 - groups beads under their parent epic
---
duration_ms: 2.3032
...
1..2
ok 2 - LeftPanel Tree Structure
---
duration_ms: 5.297
type: 'suite'
...
# Subtest: LeftPanel Responsive Behavior
# Subtest: applies responsive classes for desktop, tablet, and mobile
ok 1 - applies responsive classes for desktop, tablet, and mobile
---
duration_ms: 2.5744
...
1..1
ok 3 - LeftPanel Responsive Behavior
---
duration_ms: 2.8537
type: 'suite'
...
# Subtest: LeftPanel Scope Controls
# Subtest: renders scope section
ok 1 - renders scope section
---
duration_ms: 2.4409
...
1..1
ok 4 - LeftPanel Scope Controls
---
duration_ms: 3.207
type: 'suite'
...
1..4
# tests 6
# suites 4
# pass 6
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 762.0118
TAP version 13
# Subtest: TopBar Component Contract
# Subtest: exports TopBar component
ok 1 - exports TopBar component
---
duration_ms: 928.6733
...
# Subtest: TopBar component can be imported without errors
ok 2 - TopBar component can be imported without errors
---
duration_ms: 1.5359
...
1..2
ok 1 - TopBar Component Contract
---
duration_ms: 931.4628
type: 'suite'
...
# Subtest: TopBar View Tabs
# Subtest: renders view tabs: Social, Graph
ok 1 - renders view tabs: Social, Graph
---
duration_ms: 2.2099
...
# Subtest: active tab has bold text and accent underline
ok 2 - active tab has bold text and accent underline
---
duration_ms: 1.9226
...
1..2
ok 2 - TopBar View Tabs
---
duration_ms: 4.5329
type: 'suite'
...
# Subtest: TopBar Filter and Controls
# Subtest: renders filter/search input placeholder
ok 1 - renders filter/search input placeholder
---
duration_ms: 1.6872
...
# Subtest: renders settings placeholder
ok 2 - renders settings placeholder
---
duration_ms: 1.1945
...
1..2
ok 3 - TopBar Filter and Controls
---
duration_ms: 3.3144
type: 'suite'
...
1..3
# tests 6
# suites 3
# pass 6
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 1275.1308
TAP version 13
# Subtest: Mobile Navigation - Hamburger Menu
# Subtest: exports MobileNav component
ok 1 - exports MobileNav component
---
duration_ms: 146.0955
...
# Subtest: renders tab buttons: Social, Graph
ok 2 - renders tab buttons: Social, Graph
---
duration_ms: 2.4626
...
# Subtest: highlights active tab with accent color
ok 3 - highlights active tab with accent color
---
duration_ms: 2.4243
...
# Subtest: uses setView from useUrlState on tab click
ok 4 - uses setView from useUrlState on tab click
---
duration_ms: 2.3011
...
1..4
ok 1 - Mobile Navigation - Hamburger Menu
---
duration_ms: 155.4009
type: 'suite'
...
# Subtest: TopBar Hamburger Menu
# Subtest: shows hamburger button on mobile and tablet
ok 1 - shows hamburger button on mobile and tablet
---
duration_ms: 594.7571
...
# Subtest: hamburger button opens left panel drawer
ok 2 - hamburger button opens left panel drawer
---
duration_ms: 1.5433
...
# Subtest: hides hamburger on desktop
ok 3 - hides hamburger on desktop
---
duration_ms: 1.3406
...
1..3
ok 2 - TopBar Hamburger Menu
---
duration_ms: 598.2042
type: 'suite'
...
1..2
# tests 7
# suites 2
# pass 7
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 1074.08
TAP version 13
# Subtest: SwarmCard Component Contract
# Subtest: exports SwarmCard component
ok 1 - exports SwarmCard component
---
duration_ms: 301.3252
...
# Subtest: SwarmCard component can be imported without errors
ok 2 - SwarmCard component can be imported without errors
---
duration_ms: 1.6098
...
1..2
ok 1 - SwarmCard Component Contract
---
duration_ms: 304.0952
type: 'suite'
...
# Subtest: SwarmCard Agent Roster
# Subtest: renders agent avatars with liveness glow
ok 1 - renders agent avatars with liveness glow
---
duration_ms: 2.012
...
# Subtest: displays agent current task when available
ok 2 - displays agent current task when available
---
duration_ms: 1.5509
...
1..2
ok 2 - SwarmCard Agent Roster
---
duration_ms: 3.8907
type: 'suite'
...
# Subtest: SwarmCard Progress Bar
# Subtest: renders progress bar showing completion percentage
ok 1 - renders progress bar showing completion percentage
---
duration_ms: 1.4962
...
1..1
ok 3 - SwarmCard Progress Bar
---
duration_ms: 1.7516
type: 'suite'
...
# Subtest: SwarmCard Attention Items
# Subtest: renders attention items with warning styling
ok 1 - renders attention items with warning styling
---
duration_ms: 2.1433
...
1..1
ok 4 - SwarmCard Attention Items
---
duration_ms: 2.818
type: 'suite'
...
# Subtest: SwarmCard View-Jump Icons
# Subtest: renders view-jump icons for navigation
ok 1 - renders view-jump icons for navigation
---
duration_ms: 2.1341
...
1..1
ok 5 - SwarmCard View-Jump Icons
---
duration_ms: 2.4614
type: 'suite'
...
1..5
# tests 7
# suites 5
# pass 7
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 612.9682
TAP version 13
# Subtest: URL State Integration - bb-ui2.22
# Subtest: Valid URL Patterns - Social View
# Subtest: /?view=social - defaults to social view
ok 1 - /?view=social - defaults to social view
---
duration_ms: 0.9839
...
# Subtest: /?view=social&task=bb-buff.1&panel=open - task selected, panel open
ok 2 - /?view=social&task=bb-buff.1&panel=open - task selected, panel open
---
duration_ms: 0.2403
...
# Subtest: /?view=social&task=bb-ui2.22 - task with dots in ID
ok 3 - /?view=social&task=bb-ui2.22 - task with dots in ID
---
duration_ms: 0.1425
...
1..3
ok 1 - Valid URL Patterns - Social View
---
duration_ms: 2.0615
type: 'suite'
...
# Subtest: Valid URL Patterns - Graph View
# Subtest: /?view=graph - graph view default
not ok 1 - /?view=graph - graph view default
---
duration_ms: 3.8342
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:2578'
failureType: 'testCodeFailure'
error: |-
Expected values to be strictly equal:
'overview' !== 'flow'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: 'flow'
actual: 'overview'
operator: 'strictEqual'
stack: |-
TestContext.<anonymous> (C:\Users\Zenchant\codex\beadboard\tests\hooks\url-state-integration.test.ts:53:14)
Test.runInAsyncScope (node:async_hooks:211:14)
Test.run (node:internal/test_runner/test:934:25)
Test.start (node:internal/test_runner/test:833:17)
node:internal/test_runner/test:1318:71
node:internal/per_context/primordials:483:82
new Promise (<anonymous>)
new SafePromise (node:internal/per_context/primordials:451:29)
node:internal/per_context/primordials:483:9
Array.map (<anonymous>)
...
# Subtest: /?view=graph&task=bb-buff.1 - graph with task selected
ok 2 - /?view=graph&task=bb-buff.1 - graph with task selected
---
duration_ms: 0.2386
...
# Subtest: /?view=graph&graphTab=flow - flow tab selected
ok 3 - /?view=graph&graphTab=flow - flow tab selected
---
duration_ms: 0.1616
...
# Subtest: /?view=graph&graphTab=overview - overview tab selected
ok 4 - /?view=graph&graphTab=overview - overview tab selected
---
duration_ms: 0.1198
...
# Subtest: /?view=graph&swarm=bb-buff - graph filtered by swarm
ok 5 - /?view=graph&swarm=bb-buff - graph filtered by swarm
---
duration_ms: 0.2708
...
1..5
not ok 2 - Valid URL Patterns - Graph View
---
duration_ms: 5.0492
type: 'suite'
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:2515'
failureType: 'subtestsFailed'
error: '1 subtest failed'
code: 'ERR_TEST_FAILURE'
...
# Subtest: Deprecated Swarm View Fallback
# Subtest: /?view=swarm - falls back to social (swarm view deprecated)
ok 1 - /?view=swarm - falls back to social (swarm view deprecated)
---
duration_ms: 0.2049
...
# Subtest: /?view=swarm&swarm=bb-buff - falls back to social but preserves swarmId
ok 2 - /?view=swarm&swarm=bb-buff - falls back to social but preserves swarmId
---
duration_ms: 0.271
...
# Subtest: /?view=swarm&swarm=bb-buff&panel=open - falls back to social with panel open
ok 3 - /?view=swarm&swarm=bb-buff&panel=open - falls back to social with panel open
---
duration_ms: 0.1949
...
1..3
ok 3 - Deprecated Swarm View Fallback
---
duration_ms: 0.8363
type: 'suite'
...
# Subtest: Valid URL Patterns - Activity View
# Subtest: /?view=activity - activity view default
ok 1 - /?view=activity - activity view default
---
duration_ms: 0.1634
...
# Subtest: /?view=activity&agent=bb-silver-castle - filtered by agent
ok 2 - /?view=activity&agent=bb-silver-castle - filtered by agent
---
duration_ms: 0.0883
...
# Subtest: /?view=activity&swarm=bb-buff - filtered by swarm
ok 3 - /?view=activity&swarm=bb-buff - filtered by swarm
---
duration_ms: 0.0828
...
1..3
ok 4 - Valid URL Patterns - Activity View
---
duration_ms: 0.5275
type: 'suite'
...
# Subtest: Invalid Param Handling
# Subtest: /?view=invalid - invalid view defaults to social
ok 1 - /?view=invalid - invalid view defaults to social
---
duration_ms: 0.167
...
# Subtest: /?view=graph&graphTab=invalid - invalid graphTab defaults to flow
not ok 2 - /?view=graph&graphTab=invalid - invalid graphTab defaults to flow
---
duration_ms: 0.3965
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:6479'
failureType: 'testCodeFailure'
error: |-
Expected values to be strictly equal:
'overview' !== 'flow'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: 'flow'
actual: 'overview'
operator: 'strictEqual'
stack: |-
TestContext.<anonymous> (C:\Users\Zenchant\codex\beadboard\tests\hooks\url-state-integration.test.ts:138:14)
Test.runInAsyncScope (node:async_hooks:211:14)
Test.run (node:internal/test_runner/test:934:25)
Suite.processPendingSubtests (node:internal/test_runner/test:633:18)
Test.postRun (node:internal/test_runner/test:1045:19)
Test.run (node:internal/test_runner/test:973:12)
async Promise.all (index 0)
async Suite.run (node:internal/test_runner/test:1320:7)
async Suite.processPendingSubtests (node:internal/test_runner/test:633:7)
...
# Subtest: /?panel=invalid - invalid panel defaults to open
ok 3 - /?panel=invalid - invalid panel defaults to open
---
duration_ms: 0.1068
...
# Subtest: /?task=invalid-id - invalid task ID still parsed (no validation)
ok 4 - /?task=invalid-id - invalid task ID still parsed (no validation)
---
duration_ms: 0.0904
...
1..4
not ok 5 - Invalid Param Handling
---
duration_ms: 0.9102
type: 'suite'
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:6178'
failureType: 'subtestsFailed'
error: '1 subtest failed'
code: 'ERR_TEST_FAILURE'
...
# Subtest: URL Building - State to URL
# Subtest: builds social view URL
ok 1 - builds social view URL
---
duration_ms: 0.2367
...
# Subtest: builds graph view with task URL
ok 2 - builds graph view with task URL
---
duration_ms: 0.0983
...
# Subtest: builds swarm view with swarm param
ok 3 - builds swarm view with swarm param
---
duration_ms: 0.0888
...
# Subtest: builds activity view with agent filter
ok 4 - builds activity view with agent filter
---
duration_ms: 0.159
...
# Subtest: preserves existing params when adding new ones
ok 5 - preserves existing params when adding new ones
---
duration_ms: 0.1957
...
# Subtest: removes params when set to null
ok 6 - removes params when set to null
---
duration_ms: 0.1242
...
# Subtest: returns root when all params cleared
ok 7 - returns root when all params cleared
---
duration_ms: 0.0988
...
1..7
ok 6 - URL Building - State to URL
---
duration_ms: 1.1817
type: 'suite'
...
# Subtest: Complex URL Scenarios
# Subtest: handles all params together
ok 1 - handles all params together
---
duration_ms: 0.1361
...
# Subtest: empty string values treated as null/empty
ok 2 - empty string values treated as null/empty
---
duration_ms: 0.0964
...
1..2
ok 7 - Complex URL Scenarios
---
duration_ms: 0.317
type: 'suite'
...
# Subtest: Deep Link Patterns - From Card Icons
# Subtest: SocialCard Graph icon: /?view=graph&task={id}
ok 1 - SocialCard Graph icon: /?view=graph&task={id}
---
duration_ms: 0.1474
...
# Subtest: SwarmCard Graph icon: /?view=graph&swarm={id}
ok 2 - SwarmCard Graph icon: /?view=graph&swarm={id}
---
duration_ms: 0.086
...
# Subtest: SwarmCard Timeline icon: /?view=activity&swarm={id}
ok 3 - SwarmCard Timeline icon: /?view=activity&swarm={id}
---
duration_ms: 0.2482
...
# Subtest: Agent avatar click: /?view=activity&agent={id}
ok 4 - Agent avatar click: /?view=activity&agent={id}
---
duration_ms: 0.1616
...
1..4
ok 8 - Deep Link Patterns - From Card Icons
---
duration_ms: 0.8134
type: 'suite'
...
1..8
not ok 1 - URL State Integration - bb-ui2.22
---
duration_ms: 12.6296
type: 'suite'
location: 'C:\\Users\\Zenchant\\codex\\beadboard\\tests\\hooks\\url-state-integration.test.ts:2:1269'
failureType: 'subtestsFailed'
error: '2 subtests failed'
code: 'ERR_TEST_FAILURE'
...
1..1
# tests 31
# suites 9
# pass 29
# fail 2
# cancelled 0
# skipped 0
# todo 0
# duration_ms 481.6532

1
.claude/skills/shadcn-ui Symbolic link
View file

@ -0,0 +1 @@
/mnt/c/Users/Zenchant/codex/beadboard/.agents/skills/shadcn-ui/

File diff suppressed because it is too large Load diff

View file

@ -1,306 +0,0 @@
### shadcn/ui Chart Component - Installation
Source: https://ui.shadcn.com/docs/components/chart
The chart component in shadcn/ui is built on Recharts, providing direct access to all Recharts capabilities with consistent theming.
```bash
npx shadcn@latest add chart
```
--------------------------------
### shadcn/ui Chart Component - Basic Usage
Source: https://ui.shadcn.com/docs/components/chart
The ChartContainer wraps your Recharts component and accepts a config prop for theming. Requires `min-h-[value]` for responsiveness.
```tsx
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
]
export function BarChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - ChartConfig with Custom Colors
Source: https://ui.shadcn.com/docs/components/chart
You can define custom colors directly in the configuration using hex values or CSS variables.
```tsx
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
theme: {
light: "#2563eb",
dark: "#60a5fa",
},
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
```
--------------------------------
### shadcn/ui Chart Component - CSS Variables
Source: https://ui.shadcn.com/docs/components/chart
Add chart color variables to your globals.css for consistent theming.
```css
:root {
/* Chart colors */
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.546 0.198 38.228);
--chart-4: oklch(0.596 0.151 343.253);
--chart-5: oklch(0.546 0.158 49.157);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.698 0.141 24.311);
--chart-4: oklch(0.676 0.172 171.196);
--chart-5: oklch(0.578 0.192 302.85);
}
```
--------------------------------
### shadcn/ui Chart Component - Line Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a line chart with shadcn/ui charts component.
```tsx
import { Line, LineChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
price: {
label: "Price",
color: "var(--chart-1)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", price: 186 },
{ month: "February", price: 305 },
{ month: "March", price: 237 },
{ month: "April", price: 203 },
{ month: "May", price: 276 },
]
export function LineChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<LineChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} tickFormatter={(value) => `$${value}`} />
<Line
dataKey="price"
stroke="var(--color-price)"
strokeWidth={2}
dot={false}
/>
<ChartTooltip content={<ChartTooltipContent />} />
</LineChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Area Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating an area chart with gradient fill and legend.
```tsx
import { Area, AreaChart, XAxis, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
desktop: { label: "Desktop", color: "var(--chart-1)" },
mobile: { label: "Mobile", color: "var(--chart-2)" },
} satisfies import("@/components/ui/chart").ChartConfig
export function AreaChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<AreaChart data={chartData}>
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} />
<Area
dataKey="desktop"
fill="var(--color-desktop)"
stroke="var(--color-desktop)"
fillOpacity={0.3}
/>
<Area
dataKey="mobile"
fill="var(--color-mobile)"
stroke="var(--color-mobile)"
fillOpacity={0.3}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</AreaChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Pie Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a pie/donut chart with shadcn/ui.
```tsx
import { Pie, PieChart } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
chrome: { label: "Chrome", color: "var(--chart-1)" },
safari: { label: "Safari", color: "var(--chart-2)" },
firefox: { label: "Firefox", color: "var(--chart-3)" },
} satisfies import("@/components/ui/chart").ChartConfig
const pieData = [
{ browser: "Chrome", visitors: 275, fill: "var(--color-chrome)" },
{ browser: "Safari", visitors: 200, fill: "var(--color-safari)" },
{ browser: "Firefox", visitors: 187, fill: "var(--color-firefox)" },
]
export function PieChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<PieChart>
<Pie
data={pieData}
dataKey="visitors"
nameKey="browser"
cx="50%"
cy="50%"
outerRadius={80}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</PieChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui ChartTooltipContent Props
Source: https://ui.shadcn.com/docs/components/chart
The ChartTooltipContent component accepts these props for customizing tooltip behavior.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `labelKey` | string | "label" | Key for tooltip label |
| `nameKey` | string | "name" | Key for tooltip name |
| `indicator` | "dot" \| "line" \| "dashed" | "dot" | Indicator style |
| `hideLabel` | boolean | false | Hide label |
| `hideIndicator` | boolean | false | Hide indicator |
--------------------------------
### shadcn/ui Chart Component - Accessibility
Source: https://ui.shadcn.com/docs/components/chart
Enable keyboard navigation and screen reader support by adding the accessibilityLayer prop.
```tsx
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" />
<Bar dataKey="desktop" fill="var(--color-desktop)" />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
```
This adds:
- Keyboard arrow key navigation
- ARIA labels for chart elements
- Screen reader announcements for data values
--------------------------------
### shadcn/ui Chart Component - Recharts Dependencies
Source: https://ui.shadcn.com/docs/components/chart
The chart component requires the following Recharts dependencies to be installed.
```bash
pnpm add recharts
npm install recharts
yarn add recharts
```
Recharts provides the following chart types:
- Area, Bar, Line, Pie, Composed
- Radar, RadialBar, Scatter
- Funnel, Treemap

View file

@ -1,145 +0,0 @@
# shadcn/ui Learning Guide
This guide helps you learn shadcn/ui from basics to advanced patterns.
## Learning Path
### 1. Understanding the Philosophy
shadcn/ui is different from traditional component libraries:
- **Copy-paste components**: Components are copied into your project, not installed as packages
- **Full customization**: You own the code and can modify it freely
- **Built on Radix UI**: Provides accessibility primitives
- **Styled with Tailwind**: Uses utility classes for consistent styling
### 2. Core Concepts to Master
#### Class Variance Authority (CVA)
Most components use CVA for variant management:
```tsx
const buttonVariants = cva(
"base-classes",
{
variants: {
variant: {
default: "variant-classes",
destructive: "destructive-classes",
},
size: {
default: "size-classes",
sm: "small-classes",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
```
#### cn Utility Function
The `cn` function combines classes and resolves conflicts:
```tsx
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
```
### 3. Installation Checklist
- [ ] Initialize a new project (Next.js, Vite, or Remix)
- [ ] Install Tailwind CSS
- [ ] Run `npx shadcn@latest init`
- [ ] Configure CSS variables
- [ ] Install first component: `npx shadcn@latest add button`
### 4. Essential Components to Learn First
1. **Button** - Learn variants and sizes
2. **Input** - Form inputs with labels
3. **Card** - Container components
4. **Form** - Form handling with React Hook Form
5. **Dialog** - Modal windows
6. **Select** - Dropdown selections
7. **Toast** - Notifications
### 5. Common Patterns
#### Form Pattern
Every form follows this structure:
```tsx
1. Define Zod schema
2. Create form with useForm
3. Wrap with Form component
4. Add FormField for each input
5. Handle submission
```
#### Component Customization Pattern
To customize a component:
1. Copy component to your project
2. Modify the variants
3. Add new props if needed
4. Update types
### 6. Best Practices
- Always use TypeScript
- Follow the existing component structure
- Use semantic HTML when possible
- Test with screen readers for accessibility
- Keep components small and focused
### 7. Advanced Topics
- Creating custom components from scratch
- Building complex forms with validation
- Implementing dark mode
- Optimizing for performance
- Testing components
## Practice Exercises
### Exercise 1: Basic Setup
1. Create a new Next.js project
2. Set up shadcn/ui
3. Install and customize a Button component
4. Add a new variant "gradient"
### Exercise 2: Form Building
1. Create a contact form with:
- Name input (required)
- Email input (email validation)
- Message textarea (min length)
- Submit button with loading state
### Exercise 3: Component Combination
1. Build a settings page using:
- Card for layout
- Sheet for mobile menu
- Select for dropdowns
- Switch for toggles
- Toast for notifications
### Exercise 4: Custom Component
1. Create a custom Badge component
2. Support variants: default, secondary, destructive, outline
3. Support sizes: sm, default, lg
4. Add icon support
## Resources
- [Official Documentation](https://ui.shadcn.com)
- [GitHub Repository](https://github.com/shadcn/ui)
- [Examples Gallery](https://ui.shadcn.com/examples)
- [Radix UI Primitives](https://www.radix-ui.com/primitives)
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)

File diff suppressed because it is too large Load diff

View file

@ -1,586 +0,0 @@
# shadcn.io Component Library
shadcn.io is a comprehensive React UI component library built on shadcn/ui principles, providing developers with production-ready, composable components for modern web applications. The library serves as a centralized resource for React developers who need high-quality UI components with TypeScript support, ranging from basic interactive elements to advanced AI-powered integrations. Unlike traditional component libraries that require package installations, shadcn.io components are designed to be copied directly into your project, giving you full control and customization capabilities.
The library encompasses four major categories: composable UI components (terminal, dock, credit cards, QR codes, color pickers), chart components built with Recharts, animation components with Tailwind CSS integration, and custom React hooks for state management and lifecycle operations. Each component follows best practices for accessibility, performance, and developer experience, with comprehensive TypeScript definitions and Next.js compatibility. The platform emphasizes flexibility and customization, allowing developers to modify components at the source level rather than being constrained by package APIs.
## Core Components
### Terminal Component
Interactive terminal emulator with typing animations and command execution simulation for developer-focused interfaces.
```tsx
import { Terminal } from "@/components/ui/terminal"
export default function DemoTerminal() {
return (
npm install @repo/terminalInstalling dependencies...npm start
)
}
```
### Dock Component
macOS-style application dock with smooth magnification effects on hover, perfect for navigation menus.
```tsx
import { Dock, DockIcon } from "@/components/ui/dock"
import { Home, Settings, User, Mail } from "lucide-react"
export default function AppDock() {
return (
)
}
```
### Credit Card Component
Interactive 3D credit card component with flip animations for payment forms and card displays.
```tsx
import { CreditCard } from "@/components/ui/credit-card"
import { useState } from "react"
export default function PaymentForm() {
const [cardData, setCardData] = useState({
number: "4532 1234 5678 9010",
holder: "JOHN DOE",
expiry: "12/28",
cvv: "123"
})
return (
console.log("Card flipped:", flipped)}
/>
)
}
```
### Image Zoom Component
Zoomable image component with smooth modal transitions for image galleries and product displays.
```tsx
import { ImageZoom } from "@/components/ui/image-zoom"
export default function ProductGallery() {
return (
)
}
```
### QR Code Component
Generate and display customizable QR codes with styling options for links, contact information, and authentication.
```tsx
import { QRCode } from "@/components/ui/qr-code"
export default function ShareDialog() {
const shareUrl = "https://shadcn.io"
return (
Scan to visit shadcn.io
)
}
```
### Color Picker Component
Advanced color selection component supporting multiple color formats (HEX, RGB, HSL) with preview.
```tsx
import { ColorPicker } from "@/components/ui/color-picker"
import { useState } from "react"
export default function ThemeCustomizer() {
const [color, setColor] = useState("#3b82f6")
return (
Selected: {color}
)
}
```
## Chart Components
### Bar Chart Component
Clean bar chart component for data comparison and categorical analysis using Recharts.
```tsx
import { BarChart } from "@/components/ui/bar-chart"
export default function SalesChart() {
const data = [
{ month: "Jan", sales: 4000, revenue: 2400 },
{ month: "Feb", sales: 3000, revenue: 1398 },
{ month: "Mar", sales: 2000, revenue: 9800 },
{ month: "Apr", sales: 2780, revenue: 3908 },
{ month: "May", sales: 1890, revenue: 4800 },
{ month: "Jun", sales: 2390, revenue: 3800 }
]
return (
`$${value.toLocaleString()}`}
yAxisWidth={60}
/>
)
}
```
### Line Chart Component
Smooth line chart for visualizing trends and time-series data with multiple data series support.
```tsx
import { LineChart } from "@/components/ui/line-chart"
export default function MetricsChart() {
const data = [
{ date: "2024-01", users: 1200, sessions: 3400 },
{ date: "2024-02", users: 1800, sessions: 4200 },
{ date: "2024-03", users: 2400, sessions: 5800 },
{ date: "2024-04", users: 3100, sessions: 7200 },
{ date: "2024-05", users: 3800, sessions: 8900 }
]
return (
)
}
```
### Pie Chart Component
Donut chart component for displaying proportional data and percentage distributions.
```tsx
import { PieChart } from "@/components/ui/pie-chart"
export default function MarketShareChart() {
const data = [
{ name: "Product A", value: 400, fill: "#3b82f6" },
{ name: "Product B", value: 300, fill: "#10b981" },
{ name: "Product C", value: 300, fill: "#f59e0b" },
{ name: "Product D", value: 200, fill: "#ef4444" }
]
return (
`${entry.name}: ${entry.value}`}
/>
)
}
```
### Area Chart Component
Stacked area chart for visualizing volume changes over time with multiple data series.
```tsx
import { AreaChart } from "@/components/ui/area-chart"
export default function TrafficChart() {
const data = [
{ month: "Jan", mobile: 2000, desktop: 3000, tablet: 1000 },
{ month: "Feb", mobile: 2200, desktop: 3200, tablet: 1100 },
{ month: "Mar", mobile: 2800, desktop: 3800, tablet: 1300 },
{ month: "Apr", mobile: 3200, desktop: 4200, tablet: 1500 },
{ month: "May", mobile: 3800, desktop: 4800, tablet: 1800 }
]
return (
)
}
```
### Radar Chart Component
Multi-axis chart for comparing multiple variables across different categories simultaneously.
```tsx
import { RadarChart } from "@/components/ui/radar-chart"
export default function SkillsChart() {
const data = [
{ skill: "JavaScript", score: 85, industry: 75 },
{ skill: "TypeScript", score: 80, industry: 70 },
{ skill: "React", score: 90, industry: 80 },
{ skill: "Node.js", score: 75, industry: 72 },
{ skill: "CSS", score: 88, industry: 78 }
]
return (
)
}
```
### Mixed Chart Component
Combined bar and line chart for displaying multiple data types with different visualization methods.
```tsx
import { MixedChart } from "@/components/ui/mixed-chart"
export default function PerformanceChart() {
const data = [
{ month: "Jan", revenue: 4000, growth: 5.2 },
{ month: "Feb", revenue: 4200, growth: 5.0 },
{ month: "Mar", revenue: 4800, growth: 14.3 },
{ month: "Apr", revenue: 5200, growth: 8.3 },
{ month: "May", revenue: 5800, growth: 11.5 }
]
return (
)
}
```
## Animation Components
### Magnetic Effect Component
Magnetic hover effect that smoothly follows cursor movement for interactive buttons and cards.
```tsx
import { Magnetic } from "@/components/ui/magnetic"
export default function InteractiveButton() {
return (
Hover me
)
}
```
### Animated Cursor Component
Custom animated cursor with interactive effects and particle trails for immersive experiences.
```tsx
import { AnimatedCursor } from "@/components/ui/animated-cursor"
export default function Layout({ children }) {
return (
<>
{children}
)
}
```
### Apple Hello Effect Component
Recreation of Apple's iconic "hello" animation with multi-language text transitions.
```tsx
import { AppleHello } from "@/components/ui/apple-hello"
export default function WelcomeScreen() {
const greetings = [
{ text: "Hello", lang: "en" },
{ text: "Bonjour", lang: "fr" },
{ text: "こんにちは", lang: "ja" },
{ text: "Hola", lang: "es" },
{ text: "你好", lang: "zh" }
]
return (
)
}
```
### Liquid Button Component
Button with fluid liquid animation effect on hover for engaging call-to-action elements.
```tsx
import { LiquidButton } from "@/components/ui/liquid-button"
export default function CTASection() {
return (
console.log("CTA clicked")}
>
Get Started
)
}
```
### Rolling Text Component
Text animation that creates a rolling effect with smooth character transitions.
```tsx
import { RollingText } from "@/components/ui/rolling-text"
export default function AnimatedHeading() {
return (
)
}
```
### Shimmering Text Component
Text with animated shimmer effect for attention-grabbing headings and highlights.
```tsx
import { ShimmeringText } from "@/components/ui/shimmering-text"
export default function Hero() {
return (
)
}
```
## React Hooks
### useBoolean Hook
Enhanced boolean state management with toggle, enable, and disable methods for cleaner component logic.
```tsx
import { useBoolean } from "@/hooks/use-boolean"
export default function TogglePanel() {
const modal = useBoolean(false)
const loading = useBoolean(false)
const handleSubmit = async () => {
loading.setTrue()
try {
await submitForm()
modal.setFalse()
} finally {
loading.setFalse()
}
}
return (
<>
Toggle Modal
{modal.value && (
Status: {loading.value ? "Saving..." : "Ready"}
Submit
)}
)
}
```
### useCounter Hook
Counter hook with increment, decrement, reset, and set functionality for numeric state management.
```tsx
import { useCounter } from "@/hooks/use-counter"
export default function CartCounter() {
const quantity = useCounter(0, { min: 0, max: 99 })
return (
-
{quantity.value}
+
Reset
)
}
```
### useLocalStorage Hook
Persist state in browser localStorage with automatic serialization and deserialization.
```tsx
import { useLocalStorage } from "@/hooks/use-local-storage"
export default function UserPreferences() {
const [theme, setTheme] = useLocalStorage("theme", "light")
const [settings, setSettings] = useLocalStorage("settings", {
notifications: true,
emailUpdates: false
})
return (
setTheme(e.target.value)}>
LightDark setSettings({
...settings,
notifications: e.target.checked
})}
/>
Enable Notifications
)
}
```
### useDebounceValue Hook
Debounce values to prevent excessive updates and API calls during rapid user input.
```tsx
import { useDebounceValue } from "@/hooks/use-debounce-value"
import { useState, useEffect } from "react"
export default function SearchBox() {
const [search, setSearch] = useState("")
const debouncedSearch = useDebounceValue(search, 500)
const [results, setResults] = useState([])
const [apiCalls, setApiCalls] = useState(0)
useEffect(() => {
if (debouncedSearch) {
setApiCalls(prev => prev + 1)
fetch(`/api/search?q=${debouncedSearch}`)
.then(res => res.json())
.then(setResults)
}
}, [debouncedSearch])
return (
setSearch(e.target.value)}
placeholder="Search..."
/>
API calls: {apiCalls}
)
}
```
### useHover Hook
Track hover state on elements with customizable enter and leave delays for tooltip and preview functionality.
```tsx
import { useHover } from "@/hooks/use-hover"
import { useRef } from "react"
export default function ImagePreview() {
const hoverRef = useRef(null)
const isHovering = useHover(hoverRef, {
enterDelay: 200,
leaveDelay: 100
})
return (
![Preview](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/thumbnail.jpg)
{isHovering && (
![Full size](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/full-size.jpg)
)}
)
}
```
### useCountdown Hook
Countdown timer with play, pause, reset controls and completion callbacks for time-limited features.
```tsx
import { useCountdown } from "@/hooks/use-countdown"
export default function OTPTimer() {
const countdown = useCountdown({
initialSeconds: 60,
onComplete: () => alert("OTP expired! Request a new code.")
})
return (
{countdown.seconds}s
{!countdown.isRunning ? (
Start
) : (
Pause
)}
Reset
Status: {countdown.isComplete ? "Expired" : countdown.isRunning ? "Active" : "Paused"}
)
}
```
## Installation and Usage
### CLI Installation
Install components directly into your project using the shadcn CLI for instant integration.
```bash
# Initialize shadcn in your project
npx shadcn@latest init
# Add individual components
npx shadcn@latest add terminal
npx shadcn@latest add dock
npx shadcn@latest add credit-card
# Add multiple components at once
npx shadcn@latest add bar-chart line-chart pie-chart
# Add hooks
npx shadcn@latest add use-boolean use-counter use-local-storage
```
### Project Configuration
Configure your project to work with shadcn.io components using TypeScript and Tailwind CSS.
```typescript
// tailwind.config.ts
import type { Config } from "tailwindcss"
const config: Config = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
],
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
},
},
},
plugins: [require("tailwindcss-animate")],
}
export default config
```
## Summary
The shadcn.io component library serves as a comprehensive toolkit for React developers building modern web applications with Next.js and TypeScript. The library's primary use cases include rapid prototyping of user interfaces, building data-rich dashboards with interactive charts, creating engaging user experiences with animations and effects, and implementing common UI patterns without writing boilerplate code. The copy-paste approach gives developers complete ownership of their components, allowing for deep customization while maintaining consistency with shadcn/ui design principles. Components are particularly well-suited for SaaS applications, admin panels, marketing websites, and e-commerce platforms that require professional, accessible UI elements.
Integration patterns center around composability and customization rather than rigid package dependencies. Developers can cherry-pick individual components using the CLI, modify them at the source level to match their design system, and combine them with existing shadcn/ui components for a cohesive interface. The library supports both light and dark themes through CSS variables, integrates seamlessly with Tailwind CSS utility classes, and follows React best practices for performance and accessibility. Custom hooks provide reusable logic patterns that complement the visual components, creating a complete ecosystem for building feature-rich applications. The TypeScript-first approach ensures type safety throughout the development process, while the Recharts integration for data visualization provides powerful charting capabilities without additional configuration overhead.

File diff suppressed because it is too large Load diff

1
.cline/skills/shadcn-ui Symbolic link
View file

@ -0,0 +1 @@
/mnt/c/Users/Zenchant/codex/beadboard/.agents/skills/shadcn-ui/

File diff suppressed because it is too large Load diff

View file

@ -1,306 +0,0 @@
### shadcn/ui Chart Component - Installation
Source: https://ui.shadcn.com/docs/components/chart
The chart component in shadcn/ui is built on Recharts, providing direct access to all Recharts capabilities with consistent theming.
```bash
npx shadcn@latest add chart
```
--------------------------------
### shadcn/ui Chart Component - Basic Usage
Source: https://ui.shadcn.com/docs/components/chart
The ChartContainer wraps your Recharts component and accepts a config prop for theming. Requires `min-h-[value]` for responsiveness.
```tsx
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
]
export function BarChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - ChartConfig with Custom Colors
Source: https://ui.shadcn.com/docs/components/chart
You can define custom colors directly in the configuration using hex values or CSS variables.
```tsx
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
theme: {
light: "#2563eb",
dark: "#60a5fa",
},
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
```
--------------------------------
### shadcn/ui Chart Component - CSS Variables
Source: https://ui.shadcn.com/docs/components/chart
Add chart color variables to your globals.css for consistent theming.
```css
:root {
/* Chart colors */
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.546 0.198 38.228);
--chart-4: oklch(0.596 0.151 343.253);
--chart-5: oklch(0.546 0.158 49.157);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.698 0.141 24.311);
--chart-4: oklch(0.676 0.172 171.196);
--chart-5: oklch(0.578 0.192 302.85);
}
```
--------------------------------
### shadcn/ui Chart Component - Line Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a line chart with shadcn/ui charts component.
```tsx
import { Line, LineChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
price: {
label: "Price",
color: "var(--chart-1)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", price: 186 },
{ month: "February", price: 305 },
{ month: "March", price: 237 },
{ month: "April", price: 203 },
{ month: "May", price: 276 },
]
export function LineChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<LineChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} tickFormatter={(value) => `$${value}`} />
<Line
dataKey="price"
stroke="var(--color-price)"
strokeWidth={2}
dot={false}
/>
<ChartTooltip content={<ChartTooltipContent />} />
</LineChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Area Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating an area chart with gradient fill and legend.
```tsx
import { Area, AreaChart, XAxis, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
desktop: { label: "Desktop", color: "var(--chart-1)" },
mobile: { label: "Mobile", color: "var(--chart-2)" },
} satisfies import("@/components/ui/chart").ChartConfig
export function AreaChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<AreaChart data={chartData}>
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} />
<Area
dataKey="desktop"
fill="var(--color-desktop)"
stroke="var(--color-desktop)"
fillOpacity={0.3}
/>
<Area
dataKey="mobile"
fill="var(--color-mobile)"
stroke="var(--color-mobile)"
fillOpacity={0.3}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</AreaChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Pie Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a pie/donut chart with shadcn/ui.
```tsx
import { Pie, PieChart } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
chrome: { label: "Chrome", color: "var(--chart-1)" },
safari: { label: "Safari", color: "var(--chart-2)" },
firefox: { label: "Firefox", color: "var(--chart-3)" },
} satisfies import("@/components/ui/chart").ChartConfig
const pieData = [
{ browser: "Chrome", visitors: 275, fill: "var(--color-chrome)" },
{ browser: "Safari", visitors: 200, fill: "var(--color-safari)" },
{ browser: "Firefox", visitors: 187, fill: "var(--color-firefox)" },
]
export function PieChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<PieChart>
<Pie
data={pieData}
dataKey="visitors"
nameKey="browser"
cx="50%"
cy="50%"
outerRadius={80}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</PieChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui ChartTooltipContent Props
Source: https://ui.shadcn.com/docs/components/chart
The ChartTooltipContent component accepts these props for customizing tooltip behavior.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `labelKey` | string | "label" | Key for tooltip label |
| `nameKey` | string | "name" | Key for tooltip name |
| `indicator` | "dot" \| "line" \| "dashed" | "dot" | Indicator style |
| `hideLabel` | boolean | false | Hide label |
| `hideIndicator` | boolean | false | Hide indicator |
--------------------------------
### shadcn/ui Chart Component - Accessibility
Source: https://ui.shadcn.com/docs/components/chart
Enable keyboard navigation and screen reader support by adding the accessibilityLayer prop.
```tsx
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" />
<Bar dataKey="desktop" fill="var(--color-desktop)" />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
```
This adds:
- Keyboard arrow key navigation
- ARIA labels for chart elements
- Screen reader announcements for data values
--------------------------------
### shadcn/ui Chart Component - Recharts Dependencies
Source: https://ui.shadcn.com/docs/components/chart
The chart component requires the following Recharts dependencies to be installed.
```bash
pnpm add recharts
npm install recharts
yarn add recharts
```
Recharts provides the following chart types:
- Area, Bar, Line, Pie, Composed
- Radar, RadialBar, Scatter
- Funnel, Treemap

View file

@ -1,145 +0,0 @@
# shadcn/ui Learning Guide
This guide helps you learn shadcn/ui from basics to advanced patterns.
## Learning Path
### 1. Understanding the Philosophy
shadcn/ui is different from traditional component libraries:
- **Copy-paste components**: Components are copied into your project, not installed as packages
- **Full customization**: You own the code and can modify it freely
- **Built on Radix UI**: Provides accessibility primitives
- **Styled with Tailwind**: Uses utility classes for consistent styling
### 2. Core Concepts to Master
#### Class Variance Authority (CVA)
Most components use CVA for variant management:
```tsx
const buttonVariants = cva(
"base-classes",
{
variants: {
variant: {
default: "variant-classes",
destructive: "destructive-classes",
},
size: {
default: "size-classes",
sm: "small-classes",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
```
#### cn Utility Function
The `cn` function combines classes and resolves conflicts:
```tsx
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
```
### 3. Installation Checklist
- [ ] Initialize a new project (Next.js, Vite, or Remix)
- [ ] Install Tailwind CSS
- [ ] Run `npx shadcn@latest init`
- [ ] Configure CSS variables
- [ ] Install first component: `npx shadcn@latest add button`
### 4. Essential Components to Learn First
1. **Button** - Learn variants and sizes
2. **Input** - Form inputs with labels
3. **Card** - Container components
4. **Form** - Form handling with React Hook Form
5. **Dialog** - Modal windows
6. **Select** - Dropdown selections
7. **Toast** - Notifications
### 5. Common Patterns
#### Form Pattern
Every form follows this structure:
```tsx
1. Define Zod schema
2. Create form with useForm
3. Wrap with Form component
4. Add FormField for each input
5. Handle submission
```
#### Component Customization Pattern
To customize a component:
1. Copy component to your project
2. Modify the variants
3. Add new props if needed
4. Update types
### 6. Best Practices
- Always use TypeScript
- Follow the existing component structure
- Use semantic HTML when possible
- Test with screen readers for accessibility
- Keep components small and focused
### 7. Advanced Topics
- Creating custom components from scratch
- Building complex forms with validation
- Implementing dark mode
- Optimizing for performance
- Testing components
## Practice Exercises
### Exercise 1: Basic Setup
1. Create a new Next.js project
2. Set up shadcn/ui
3. Install and customize a Button component
4. Add a new variant "gradient"
### Exercise 2: Form Building
1. Create a contact form with:
- Name input (required)
- Email input (email validation)
- Message textarea (min length)
- Submit button with loading state
### Exercise 3: Component Combination
1. Build a settings page using:
- Card for layout
- Sheet for mobile menu
- Select for dropdowns
- Switch for toggles
- Toast for notifications
### Exercise 4: Custom Component
1. Create a custom Badge component
2. Support variants: default, secondary, destructive, outline
3. Support sizes: sm, default, lg
4. Add icon support
## Resources
- [Official Documentation](https://ui.shadcn.com)
- [GitHub Repository](https://github.com/shadcn/ui)
- [Examples Gallery](https://ui.shadcn.com/examples)
- [Radix UI Primitives](https://www.radix-ui.com/primitives)
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)

File diff suppressed because it is too large Load diff

View file

@ -1,586 +0,0 @@
# shadcn.io Component Library
shadcn.io is a comprehensive React UI component library built on shadcn/ui principles, providing developers with production-ready, composable components for modern web applications. The library serves as a centralized resource for React developers who need high-quality UI components with TypeScript support, ranging from basic interactive elements to advanced AI-powered integrations. Unlike traditional component libraries that require package installations, shadcn.io components are designed to be copied directly into your project, giving you full control and customization capabilities.
The library encompasses four major categories: composable UI components (terminal, dock, credit cards, QR codes, color pickers), chart components built with Recharts, animation components with Tailwind CSS integration, and custom React hooks for state management and lifecycle operations. Each component follows best practices for accessibility, performance, and developer experience, with comprehensive TypeScript definitions and Next.js compatibility. The platform emphasizes flexibility and customization, allowing developers to modify components at the source level rather than being constrained by package APIs.
## Core Components
### Terminal Component
Interactive terminal emulator with typing animations and command execution simulation for developer-focused interfaces.
```tsx
import { Terminal } from "@/components/ui/terminal"
export default function DemoTerminal() {
return (
npm install @repo/terminalInstalling dependencies...npm start
)
}
```
### Dock Component
macOS-style application dock with smooth magnification effects on hover, perfect for navigation menus.
```tsx
import { Dock, DockIcon } from "@/components/ui/dock"
import { Home, Settings, User, Mail } from "lucide-react"
export default function AppDock() {
return (
)
}
```
### Credit Card Component
Interactive 3D credit card component with flip animations for payment forms and card displays.
```tsx
import { CreditCard } from "@/components/ui/credit-card"
import { useState } from "react"
export default function PaymentForm() {
const [cardData, setCardData] = useState({
number: "4532 1234 5678 9010",
holder: "JOHN DOE",
expiry: "12/28",
cvv: "123"
})
return (
console.log("Card flipped:", flipped)}
/>
)
}
```
### Image Zoom Component
Zoomable image component with smooth modal transitions for image galleries and product displays.
```tsx
import { ImageZoom } from "@/components/ui/image-zoom"
export default function ProductGallery() {
return (
)
}
```
### QR Code Component
Generate and display customizable QR codes with styling options for links, contact information, and authentication.
```tsx
import { QRCode } from "@/components/ui/qr-code"
export default function ShareDialog() {
const shareUrl = "https://shadcn.io"
return (
Scan to visit shadcn.io
)
}
```
### Color Picker Component
Advanced color selection component supporting multiple color formats (HEX, RGB, HSL) with preview.
```tsx
import { ColorPicker } from "@/components/ui/color-picker"
import { useState } from "react"
export default function ThemeCustomizer() {
const [color, setColor] = useState("#3b82f6")
return (
Selected: {color}
)
}
```
## Chart Components
### Bar Chart Component
Clean bar chart component for data comparison and categorical analysis using Recharts.
```tsx
import { BarChart } from "@/components/ui/bar-chart"
export default function SalesChart() {
const data = [
{ month: "Jan", sales: 4000, revenue: 2400 },
{ month: "Feb", sales: 3000, revenue: 1398 },
{ month: "Mar", sales: 2000, revenue: 9800 },
{ month: "Apr", sales: 2780, revenue: 3908 },
{ month: "May", sales: 1890, revenue: 4800 },
{ month: "Jun", sales: 2390, revenue: 3800 }
]
return (
`$${value.toLocaleString()}`}
yAxisWidth={60}
/>
)
}
```
### Line Chart Component
Smooth line chart for visualizing trends and time-series data with multiple data series support.
```tsx
import { LineChart } from "@/components/ui/line-chart"
export default function MetricsChart() {
const data = [
{ date: "2024-01", users: 1200, sessions: 3400 },
{ date: "2024-02", users: 1800, sessions: 4200 },
{ date: "2024-03", users: 2400, sessions: 5800 },
{ date: "2024-04", users: 3100, sessions: 7200 },
{ date: "2024-05", users: 3800, sessions: 8900 }
]
return (
)
}
```
### Pie Chart Component
Donut chart component for displaying proportional data and percentage distributions.
```tsx
import { PieChart } from "@/components/ui/pie-chart"
export default function MarketShareChart() {
const data = [
{ name: "Product A", value: 400, fill: "#3b82f6" },
{ name: "Product B", value: 300, fill: "#10b981" },
{ name: "Product C", value: 300, fill: "#f59e0b" },
{ name: "Product D", value: 200, fill: "#ef4444" }
]
return (
`${entry.name}: ${entry.value}`}
/>
)
}
```
### Area Chart Component
Stacked area chart for visualizing volume changes over time with multiple data series.
```tsx
import { AreaChart } from "@/components/ui/area-chart"
export default function TrafficChart() {
const data = [
{ month: "Jan", mobile: 2000, desktop: 3000, tablet: 1000 },
{ month: "Feb", mobile: 2200, desktop: 3200, tablet: 1100 },
{ month: "Mar", mobile: 2800, desktop: 3800, tablet: 1300 },
{ month: "Apr", mobile: 3200, desktop: 4200, tablet: 1500 },
{ month: "May", mobile: 3800, desktop: 4800, tablet: 1800 }
]
return (
)
}
```
### Radar Chart Component
Multi-axis chart for comparing multiple variables across different categories simultaneously.
```tsx
import { RadarChart } from "@/components/ui/radar-chart"
export default function SkillsChart() {
const data = [
{ skill: "JavaScript", score: 85, industry: 75 },
{ skill: "TypeScript", score: 80, industry: 70 },
{ skill: "React", score: 90, industry: 80 },
{ skill: "Node.js", score: 75, industry: 72 },
{ skill: "CSS", score: 88, industry: 78 }
]
return (
)
}
```
### Mixed Chart Component
Combined bar and line chart for displaying multiple data types with different visualization methods.
```tsx
import { MixedChart } from "@/components/ui/mixed-chart"
export default function PerformanceChart() {
const data = [
{ month: "Jan", revenue: 4000, growth: 5.2 },
{ month: "Feb", revenue: 4200, growth: 5.0 },
{ month: "Mar", revenue: 4800, growth: 14.3 },
{ month: "Apr", revenue: 5200, growth: 8.3 },
{ month: "May", revenue: 5800, growth: 11.5 }
]
return (
)
}
```
## Animation Components
### Magnetic Effect Component
Magnetic hover effect that smoothly follows cursor movement for interactive buttons and cards.
```tsx
import { Magnetic } from "@/components/ui/magnetic"
export default function InteractiveButton() {
return (
Hover me
)
}
```
### Animated Cursor Component
Custom animated cursor with interactive effects and particle trails for immersive experiences.
```tsx
import { AnimatedCursor } from "@/components/ui/animated-cursor"
export default function Layout({ children }) {
return (
<>
{children}
)
}
```
### Apple Hello Effect Component
Recreation of Apple's iconic "hello" animation with multi-language text transitions.
```tsx
import { AppleHello } from "@/components/ui/apple-hello"
export default function WelcomeScreen() {
const greetings = [
{ text: "Hello", lang: "en" },
{ text: "Bonjour", lang: "fr" },
{ text: "こんにちは", lang: "ja" },
{ text: "Hola", lang: "es" },
{ text: "你好", lang: "zh" }
]
return (
)
}
```
### Liquid Button Component
Button with fluid liquid animation effect on hover for engaging call-to-action elements.
```tsx
import { LiquidButton } from "@/components/ui/liquid-button"
export default function CTASection() {
return (
console.log("CTA clicked")}
>
Get Started
)
}
```
### Rolling Text Component
Text animation that creates a rolling effect with smooth character transitions.
```tsx
import { RollingText } from "@/components/ui/rolling-text"
export default function AnimatedHeading() {
return (
)
}
```
### Shimmering Text Component
Text with animated shimmer effect for attention-grabbing headings and highlights.
```tsx
import { ShimmeringText } from "@/components/ui/shimmering-text"
export default function Hero() {
return (
)
}
```
## React Hooks
### useBoolean Hook
Enhanced boolean state management with toggle, enable, and disable methods for cleaner component logic.
```tsx
import { useBoolean } from "@/hooks/use-boolean"
export default function TogglePanel() {
const modal = useBoolean(false)
const loading = useBoolean(false)
const handleSubmit = async () => {
loading.setTrue()
try {
await submitForm()
modal.setFalse()
} finally {
loading.setFalse()
}
}
return (
<>
Toggle Modal
{modal.value && (
Status: {loading.value ? "Saving..." : "Ready"}
Submit
)}
)
}
```
### useCounter Hook
Counter hook with increment, decrement, reset, and set functionality for numeric state management.
```tsx
import { useCounter } from "@/hooks/use-counter"
export default function CartCounter() {
const quantity = useCounter(0, { min: 0, max: 99 })
return (
-
{quantity.value}
+
Reset
)
}
```
### useLocalStorage Hook
Persist state in browser localStorage with automatic serialization and deserialization.
```tsx
import { useLocalStorage } from "@/hooks/use-local-storage"
export default function UserPreferences() {
const [theme, setTheme] = useLocalStorage("theme", "light")
const [settings, setSettings] = useLocalStorage("settings", {
notifications: true,
emailUpdates: false
})
return (
setTheme(e.target.value)}>
LightDark setSettings({
...settings,
notifications: e.target.checked
})}
/>
Enable Notifications
)
}
```
### useDebounceValue Hook
Debounce values to prevent excessive updates and API calls during rapid user input.
```tsx
import { useDebounceValue } from "@/hooks/use-debounce-value"
import { useState, useEffect } from "react"
export default function SearchBox() {
const [search, setSearch] = useState("")
const debouncedSearch = useDebounceValue(search, 500)
const [results, setResults] = useState([])
const [apiCalls, setApiCalls] = useState(0)
useEffect(() => {
if (debouncedSearch) {
setApiCalls(prev => prev + 1)
fetch(`/api/search?q=${debouncedSearch}`)
.then(res => res.json())
.then(setResults)
}
}, [debouncedSearch])
return (
setSearch(e.target.value)}
placeholder="Search..."
/>
API calls: {apiCalls}
)
}
```
### useHover Hook
Track hover state on elements with customizable enter and leave delays for tooltip and preview functionality.
```tsx
import { useHover } from "@/hooks/use-hover"
import { useRef } from "react"
export default function ImagePreview() {
const hoverRef = useRef(null)
const isHovering = useHover(hoverRef, {
enterDelay: 200,
leaveDelay: 100
})
return (
![Preview](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/thumbnail.jpg)
{isHovering && (
![Full size](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/full-size.jpg)
)}
)
}
```
### useCountdown Hook
Countdown timer with play, pause, reset controls and completion callbacks for time-limited features.
```tsx
import { useCountdown } from "@/hooks/use-countdown"
export default function OTPTimer() {
const countdown = useCountdown({
initialSeconds: 60,
onComplete: () => alert("OTP expired! Request a new code.")
})
return (
{countdown.seconds}s
{!countdown.isRunning ? (
Start
) : (
Pause
)}
Reset
Status: {countdown.isComplete ? "Expired" : countdown.isRunning ? "Active" : "Paused"}
)
}
```
## Installation and Usage
### CLI Installation
Install components directly into your project using the shadcn CLI for instant integration.
```bash
# Initialize shadcn in your project
npx shadcn@latest init
# Add individual components
npx shadcn@latest add terminal
npx shadcn@latest add dock
npx shadcn@latest add credit-card
# Add multiple components at once
npx shadcn@latest add bar-chart line-chart pie-chart
# Add hooks
npx shadcn@latest add use-boolean use-counter use-local-storage
```
### Project Configuration
Configure your project to work with shadcn.io components using TypeScript and Tailwind CSS.
```typescript
// tailwind.config.ts
import type { Config } from "tailwindcss"
const config: Config = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
],
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
},
},
},
plugins: [require("tailwindcss-animate")],
}
export default config
```
## Summary
The shadcn.io component library serves as a comprehensive toolkit for React developers building modern web applications with Next.js and TypeScript. The library's primary use cases include rapid prototyping of user interfaces, building data-rich dashboards with interactive charts, creating engaging user experiences with animations and effects, and implementing common UI patterns without writing boilerplate code. The copy-paste approach gives developers complete ownership of their components, allowing for deep customization while maintaining consistency with shadcn/ui design principles. Components are particularly well-suited for SaaS applications, admin panels, marketing websites, and e-commerce platforms that require professional, accessible UI elements.
Integration patterns center around composability and customization rather than rigid package dependencies. Developers can cherry-pick individual components using the CLI, modify them at the source level to match their design system, and combine them with existing shadcn/ui components for a cohesive interface. The library supports both light and dark themes through CSS variables, integrates seamlessly with Tailwind CSS utility classes, and follows React best practices for performance and accessibility. Custom hooks provide reusable logic patterns that complement the visual components, creating a complete ecosystem for building feature-rich applications. The TypeScript-first approach ensures type safety throughout the development process, while the Recharts integration for data visualization provides powerful charting capabilities without additional configuration overhead.

File diff suppressed because it is too large Load diff

View file

@ -1 +1 @@
{}
{"user.email":"jordanlive121@gmail.com","user.name":"zenchant"}

View file

@ -1,6 +1,6 @@
{
"extends": [
"next/core-web-vitals",
"next/typescript"
]
}
{
"extends": [
"next/core-web-vitals",
"next/typescript"
]
}

View file

@ -1,152 +1,152 @@
---
name: code-custodian
description: |
Comprehensive code quality agent that finds and fixes issues across your codebase:
- Discovers untested functions and writes missing tests
- Runs test suite to verify coverage
- Auto-fixes linting and formatting issues
- Adds missing JSDoc/documentation
- Updates README with current API examples
- Identifies and fixes deprecated API usage
- Keeps ARCHITECTURE.md and CONTRIBUTING.md in sync
- Opens a single PR with all improvements
tools: Write, Read, LS, Glob, Grep, Bash(npm:*), Bash(git:*), Bash(gh:*)
color: blue
---
# Code Custodian
You are a comprehensive code quality and documentation steward. Your mission is to identify gaps in testing, documentation, and code quality—then fix them proactively. You work systematically and carefully, always verifying your changes don't break anything.
## Your Responsibilities
### 1. Test Coverage Analysis & Creation
When analyzing test coverage:
- Use `find` or `ls` to list all source files in `src/`, `lib/`, or `components/`
- For each file, check if a corresponding test file exists (look for `.test.ts`, `.spec.ts`, `.test.js`, etc.)
- Read uncovered files to understand what functions should be tested
- Identify critical functions: main exports, public APIs, business logic
- Write comprehensive Jest/Vitest tests for untested functions
- Include happy path tests
- Include edge cases and error scenarios
- Use meaningful test names describing the behavior
- Follow the existing test style in the repo
- Create test files in the appropriate `__tests__` or `tests/` directory matching source structure
- Run `npm test` or `npm run test` to verify all tests pass
- If tests fail, read the error, fix the test code, and re-run
### 2. Code Quality & Formatting
- Run `npm run lint` or `npx eslint . --fix` to auto-fix formatting
- Search for deprecated patterns (e.g., old API calls, outdated imports)
- Replace with current versions with explanations in commit messages
- Fix obvious issues: console.logs left in production code, dead code, unused imports
### 3. Documentation Updates
#### README.md
- Read current README
- Check if it accurately reflects current API/features
- Update feature list based on recent commits
- Refresh code examples to match latest version
- Add badges for test coverage, build status if missing
- Ensure setup/installation instructions are accurate
#### JSDoc/Comments
- Add missing JSDoc comments to exported functions
- Include @param, @returns, @throws where applicable
- Add brief descriptions for complex logic
#### ARCHITECTURE.md (if exists)
- Read the existing architecture doc
- After major refactors or new modules, update to reflect new components/modules added, changed data flows, new external integrations
#### CONTRIBUTING.md
- Verify test command instructions are correct
- Update with latest dev dependency versions
- Document common npm/pnpm/yarn commands for local development
- Add "golden path" for new contributors
### 4. Execution & PR Creation
When you've identified work:
1. Create branch: `git checkout -b chore/code-custodian-YYYY-MM-DD`
2. Make changes systematically:
- Write/update tests then verify they pass
- Fix linting then verify fixes applied
- Update docs then verify accuracy
- Commit with clear messages
3. Verify everything works:
- Run `npm test` - all tests pass
- Run `npm run lint` - no linting errors
- Review git diff to ensure quality
4. Open PR:
- Use `gh pr create` with detailed body
- List what was added/fixed in each category
- Explain any major decisions
- Note test results and coverage
## Workflow Overview
When invoked:
### Phase 1: ANALYSIS (5-10 min)
- Scan the codebase structure
- Identify untested files
- Check docs for staleness
- List all improvements needed
### Phase 2: TEST COVERAGE (varies)
- Write tests for untested functions
- Run test suite
- Fix any failing tests
### Phase 3: CODE QUALITY (5-10 min)
- Auto-fix linting
- Replace deprecated patterns
### Phase 4: DOCUMENTATION (10-15 min)
- Update README with current examples
- Add JSDoc comments
- Refresh ARCHITECTURE.md if needed
- Update CONTRIBUTING.md
### Phase 5: INTEGRATION & PR (5 min)
- Create branch and commit all changes
- Run full test suite one final time
- Open PR with detailed summary
## Best Practices
**Before making changes:**
- Always read existing code first to understand patterns
- Match the existing code style
- Check for test examples in the repo to replicate patterns
**When writing tests:**
- Use descriptive test names
- Test behavior, not implementation
- Include both success and failure scenarios
- Keep tests focused and independent
**When updating docs:**
- Keep examples short and runnable
- Use actual code from the repo where possible
- Test examples if they're code snippets
- Update dates/version numbers
**Safety first:**
- Always run tests before committing
- If tests fail, debug and fix before proceeding
- Don't make breaking changes without discussion
- When in doubt, add a comment explaining the change
## Communication
After each phase, explain what you found, what you fixed, any decisions made, status of test results, and link to the PR when created. If you encounter issues, describe the problem clearly with error messages and suggest solutions.
---
name: code-custodian
description: |
Comprehensive code quality agent that finds and fixes issues across your codebase:
- Discovers untested functions and writes missing tests
- Runs test suite to verify coverage
- Auto-fixes linting and formatting issues
- Adds missing JSDoc/documentation
- Updates README with current API examples
- Identifies and fixes deprecated API usage
- Keeps ARCHITECTURE.md and CONTRIBUTING.md in sync
- Opens a single PR with all improvements
tools: Write, Read, LS, Glob, Grep, Bash(npm:*), Bash(git:*), Bash(gh:*)
color: blue
---
# Code Custodian
You are a comprehensive code quality and documentation steward. Your mission is to identify gaps in testing, documentation, and code quality—then fix them proactively. You work systematically and carefully, always verifying your changes don't break anything.
## Your Responsibilities
### 1. Test Coverage Analysis & Creation
When analyzing test coverage:
- Use `find` or `ls` to list all source files in `src/`, `lib/`, or `components/`
- For each file, check if a corresponding test file exists (look for `.test.ts`, `.spec.ts`, `.test.js`, etc.)
- Read uncovered files to understand what functions should be tested
- Identify critical functions: main exports, public APIs, business logic
- Write comprehensive Jest/Vitest tests for untested functions
- Include happy path tests
- Include edge cases and error scenarios
- Use meaningful test names describing the behavior
- Follow the existing test style in the repo
- Create test files in the appropriate `__tests__` or `tests/` directory matching source structure
- Run `npm test` or `npm run test` to verify all tests pass
- If tests fail, read the error, fix the test code, and re-run
### 2. Code Quality & Formatting
- Run `npm run lint` or `npx eslint . --fix` to auto-fix formatting
- Search for deprecated patterns (e.g., old API calls, outdated imports)
- Replace with current versions with explanations in commit messages
- Fix obvious issues: console.logs left in production code, dead code, unused imports
### 3. Documentation Updates
#### README.md
- Read current README
- Check if it accurately reflects current API/features
- Update feature list based on recent commits
- Refresh code examples to match latest version
- Add badges for test coverage, build status if missing
- Ensure setup/installation instructions are accurate
#### JSDoc/Comments
- Add missing JSDoc comments to exported functions
- Include @param, @returns, @throws where applicable
- Add brief descriptions for complex logic
#### ARCHITECTURE.md (if exists)
- Read the existing architecture doc
- After major refactors or new modules, update to reflect new components/modules added, changed data flows, new external integrations
#### CONTRIBUTING.md
- Verify test command instructions are correct
- Update with latest dev dependency versions
- Document common npm/pnpm/yarn commands for local development
- Add "golden path" for new contributors
### 4. Execution & PR Creation
When you've identified work:
1. Create branch: `git checkout -b chore/code-custodian-YYYY-MM-DD`
2. Make changes systematically:
- Write/update tests then verify they pass
- Fix linting then verify fixes applied
- Update docs then verify accuracy
- Commit with clear messages
3. Verify everything works:
- Run `npm test` - all tests pass
- Run `npm run lint` - no linting errors
- Review git diff to ensure quality
4. Open PR:
- Use `gh pr create` with detailed body
- List what was added/fixed in each category
- Explain any major decisions
- Note test results and coverage
## Workflow Overview
When invoked:
### Phase 1: ANALYSIS (5-10 min)
- Scan the codebase structure
- Identify untested files
- Check docs for staleness
- List all improvements needed
### Phase 2: TEST COVERAGE (varies)
- Write tests for untested functions
- Run test suite
- Fix any failing tests
### Phase 3: CODE QUALITY (5-10 min)
- Auto-fix linting
- Replace deprecated patterns
### Phase 4: DOCUMENTATION (10-15 min)
- Update README with current examples
- Add JSDoc comments
- Refresh ARCHITECTURE.md if needed
- Update CONTRIBUTING.md
### Phase 5: INTEGRATION & PR (5 min)
- Create branch and commit all changes
- Run full test suite one final time
- Open PR with detailed summary
## Best Practices
**Before making changes:**
- Always read existing code first to understand patterns
- Match the existing code style
- Check for test examples in the repo to replicate patterns
**When writing tests:**
- Use descriptive test names
- Test behavior, not implementation
- Include both success and failure scenarios
- Keep tests focused and independent
**When updating docs:**
- Keep examples short and runnable
- Use actual code from the repo where possible
- Test examples if they're code snippets
- Update dates/version numbers
**Safety first:**
- Always run tests before committing
- If tests fail, debug and fix before proceeding
- Don't make breaking changes without discussion
- When in doubt, add a comment explaining the change
## Communication
After each phase, explain what you found, what you fixed, any decisions made, status of test results, and link to the PR when created. If you encounter issues, describe the problem clearly with error messages and suggest solutions.

42
.gitignore vendored
View file

@ -1,21 +1,21 @@
node_modules/
.next/
*.tsbuildinfo
.worktrees/
worktrees/
# bv (beads viewer) local config and caches
.bv/
# beads lock artifact
.beads/.bv.lock
.beads/.jsonl.lock
# local screenshot artifacts
artifacts/
# beads socket lock
.beads/bd.sock.startlock
# beadboard runtime artifacts
.beadboard/
node_modules/
.next/
*.tsbuildinfo
.worktrees/
worktrees/
# bv (beads viewer) local config and caches
.bv/
# beads lock artifact
.beads/.bv.lock
.beads/.jsonl.lock
# local screenshot artifacts
artifacts/
# beads socket lock
.beads/bd.sock.startlock
# beadboard runtime artifacts
.beadboard/

1
.openhands/skills/shadcn-ui Symbolic link
View file

@ -0,0 +1 @@
/mnt/c/Users/Zenchant/codex/beadboard/.agents/skills/shadcn-ui/

File diff suppressed because it is too large Load diff

View file

@ -1,306 +0,0 @@
### shadcn/ui Chart Component - Installation
Source: https://ui.shadcn.com/docs/components/chart
The chart component in shadcn/ui is built on Recharts, providing direct access to all Recharts capabilities with consistent theming.
```bash
npx shadcn@latest add chart
```
--------------------------------
### shadcn/ui Chart Component - Basic Usage
Source: https://ui.shadcn.com/docs/components/chart
The ChartContainer wraps your Recharts component and accepts a config prop for theming. Requires `min-h-[value]` for responsiveness.
```tsx
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
]
export function BarChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - ChartConfig with Custom Colors
Source: https://ui.shadcn.com/docs/components/chart
You can define custom colors directly in the configuration using hex values or CSS variables.
```tsx
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
theme: {
light: "#2563eb",
dark: "#60a5fa",
},
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies import("@/components/ui/chart").ChartConfig
```
--------------------------------
### shadcn/ui Chart Component - CSS Variables
Source: https://ui.shadcn.com/docs/components/chart
Add chart color variables to your globals.css for consistent theming.
```css
:root {
/* Chart colors */
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.546 0.198 38.228);
--chart-4: oklch(0.596 0.151 343.253);
--chart-5: oklch(0.546 0.158 49.157);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.698 0.141 24.311);
--chart-4: oklch(0.676 0.172 171.196);
--chart-5: oklch(0.578 0.192 302.85);
}
```
--------------------------------
### shadcn/ui Chart Component - Line Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a line chart with shadcn/ui charts component.
```tsx
import { Line, LineChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
const chartConfig = {
price: {
label: "Price",
color: "var(--chart-1)",
},
} satisfies import("@/components/ui/chart").ChartConfig
const chartData = [
{ month: "January", price: 186 },
{ month: "February", price: 305 },
{ month: "March", price: 237 },
{ month: "April", price: 203 },
{ month: "May", price: 276 },
]
export function LineChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<LineChart data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} tickFormatter={(value) => `$${value}`} />
<Line
dataKey="price"
stroke="var(--color-price)"
strokeWidth={2}
dot={false}
/>
<ChartTooltip content={<ChartTooltipContent />} />
</LineChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Area Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating an area chart with gradient fill and legend.
```tsx
import { Area, AreaChart, XAxis, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
desktop: { label: "Desktop", color: "var(--chart-1)" },
mobile: { label: "Mobile", color: "var(--chart-2)" },
} satisfies import("@/components/ui/chart").ChartConfig
export function AreaChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<AreaChart data={chartData}>
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} />
<Area
dataKey="desktop"
fill="var(--color-desktop)"
stroke="var(--color-desktop)"
fillOpacity={0.3}
/>
<Area
dataKey="mobile"
fill="var(--color-mobile)"
stroke="var(--color-mobile)"
fillOpacity={0.3}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</AreaChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui Chart Component - Pie Chart Example
Source: https://ui.shadcn.com/docs/components/chart
Creating a pie/donut chart with shadcn/ui.
```tsx
import { Pie, PieChart } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltipContent,
} from "@/components/ui/chart"
const chartConfig = {
chrome: { label: "Chrome", color: "var(--chart-1)" },
safari: { label: "Safari", color: "var(--chart-2)" },
firefox: { label: "Firefox", color: "var(--chart-3)" },
} satisfies import("@/components/ui/chart").ChartConfig
const pieData = [
{ browser: "Chrome", visitors: 275, fill: "var(--color-chrome)" },
{ browser: "Safari", visitors: 200, fill: "var(--color-safari)" },
{ browser: "Firefox", visitors: 187, fill: "var(--color-firefox)" },
]
export function PieChartDemo() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px]">
<PieChart>
<Pie
data={pieData}
dataKey="visitors"
nameKey="browser"
cx="50%"
cy="50%"
outerRadius={80}
/>
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
</PieChart>
</ChartContainer>
)
}
```
--------------------------------
### shadcn/ui ChartTooltipContent Props
Source: https://ui.shadcn.com/docs/components/chart
The ChartTooltipContent component accepts these props for customizing tooltip behavior.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `labelKey` | string | "label" | Key for tooltip label |
| `nameKey` | string | "name" | Key for tooltip name |
| `indicator` | "dot" \| "line" \| "dashed" | "dot" | Indicator style |
| `hideLabel` | boolean | false | Hide label |
| `hideIndicator` | boolean | false | Hide indicator |
--------------------------------
### shadcn/ui Chart Component - Accessibility
Source: https://ui.shadcn.com/docs/components/chart
Enable keyboard navigation and screen reader support by adding the accessibilityLayer prop.
```tsx
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" />
<Bar dataKey="desktop" fill="var(--color-desktop)" />
<ChartTooltip content={<ChartTooltipContent />} />
</BarChart>
```
This adds:
- Keyboard arrow key navigation
- ARIA labels for chart elements
- Screen reader announcements for data values
--------------------------------
### shadcn/ui Chart Component - Recharts Dependencies
Source: https://ui.shadcn.com/docs/components/chart
The chart component requires the following Recharts dependencies to be installed.
```bash
pnpm add recharts
npm install recharts
yarn add recharts
```
Recharts provides the following chart types:
- Area, Bar, Line, Pie, Composed
- Radar, RadialBar, Scatter
- Funnel, Treemap

View file

@ -1,145 +0,0 @@
# shadcn/ui Learning Guide
This guide helps you learn shadcn/ui from basics to advanced patterns.
## Learning Path
### 1. Understanding the Philosophy
shadcn/ui is different from traditional component libraries:
- **Copy-paste components**: Components are copied into your project, not installed as packages
- **Full customization**: You own the code and can modify it freely
- **Built on Radix UI**: Provides accessibility primitives
- **Styled with Tailwind**: Uses utility classes for consistent styling
### 2. Core Concepts to Master
#### Class Variance Authority (CVA)
Most components use CVA for variant management:
```tsx
const buttonVariants = cva(
"base-classes",
{
variants: {
variant: {
default: "variant-classes",
destructive: "destructive-classes",
},
size: {
default: "size-classes",
sm: "small-classes",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
```
#### cn Utility Function
The `cn` function combines classes and resolves conflicts:
```tsx
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
```
### 3. Installation Checklist
- [ ] Initialize a new project (Next.js, Vite, or Remix)
- [ ] Install Tailwind CSS
- [ ] Run `npx shadcn@latest init`
- [ ] Configure CSS variables
- [ ] Install first component: `npx shadcn@latest add button`
### 4. Essential Components to Learn First
1. **Button** - Learn variants and sizes
2. **Input** - Form inputs with labels
3. **Card** - Container components
4. **Form** - Form handling with React Hook Form
5. **Dialog** - Modal windows
6. **Select** - Dropdown selections
7. **Toast** - Notifications
### 5. Common Patterns
#### Form Pattern
Every form follows this structure:
```tsx
1. Define Zod schema
2. Create form with useForm
3. Wrap with Form component
4. Add FormField for each input
5. Handle submission
```
#### Component Customization Pattern
To customize a component:
1. Copy component to your project
2. Modify the variants
3. Add new props if needed
4. Update types
### 6. Best Practices
- Always use TypeScript
- Follow the existing component structure
- Use semantic HTML when possible
- Test with screen readers for accessibility
- Keep components small and focused
### 7. Advanced Topics
- Creating custom components from scratch
- Building complex forms with validation
- Implementing dark mode
- Optimizing for performance
- Testing components
## Practice Exercises
### Exercise 1: Basic Setup
1. Create a new Next.js project
2. Set up shadcn/ui
3. Install and customize a Button component
4. Add a new variant "gradient"
### Exercise 2: Form Building
1. Create a contact form with:
- Name input (required)
- Email input (email validation)
- Message textarea (min length)
- Submit button with loading state
### Exercise 3: Component Combination
1. Build a settings page using:
- Card for layout
- Sheet for mobile menu
- Select for dropdowns
- Switch for toggles
- Toast for notifications
### Exercise 4: Custom Component
1. Create a custom Badge component
2. Support variants: default, secondary, destructive, outline
3. Support sizes: sm, default, lg
4. Add icon support
## Resources
- [Official Documentation](https://ui.shadcn.com)
- [GitHub Repository](https://github.com/shadcn/ui)
- [Examples Gallery](https://ui.shadcn.com/examples)
- [Radix UI Primitives](https://www.radix-ui.com/primitives)
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)

File diff suppressed because it is too large Load diff

View file

@ -1,586 +0,0 @@
# shadcn.io Component Library
shadcn.io is a comprehensive React UI component library built on shadcn/ui principles, providing developers with production-ready, composable components for modern web applications. The library serves as a centralized resource for React developers who need high-quality UI components with TypeScript support, ranging from basic interactive elements to advanced AI-powered integrations. Unlike traditional component libraries that require package installations, shadcn.io components are designed to be copied directly into your project, giving you full control and customization capabilities.
The library encompasses four major categories: composable UI components (terminal, dock, credit cards, QR codes, color pickers), chart components built with Recharts, animation components with Tailwind CSS integration, and custom React hooks for state management and lifecycle operations. Each component follows best practices for accessibility, performance, and developer experience, with comprehensive TypeScript definitions and Next.js compatibility. The platform emphasizes flexibility and customization, allowing developers to modify components at the source level rather than being constrained by package APIs.
## Core Components
### Terminal Component
Interactive terminal emulator with typing animations and command execution simulation for developer-focused interfaces.
```tsx
import { Terminal } from "@/components/ui/terminal"
export default function DemoTerminal() {
return (
npm install @repo/terminalInstalling dependencies...npm start
)
}
```
### Dock Component
macOS-style application dock with smooth magnification effects on hover, perfect for navigation menus.
```tsx
import { Dock, DockIcon } from "@/components/ui/dock"
import { Home, Settings, User, Mail } from "lucide-react"
export default function AppDock() {
return (
)
}
```
### Credit Card Component
Interactive 3D credit card component with flip animations for payment forms and card displays.
```tsx
import { CreditCard } from "@/components/ui/credit-card"
import { useState } from "react"
export default function PaymentForm() {
const [cardData, setCardData] = useState({
number: "4532 1234 5678 9010",
holder: "JOHN DOE",
expiry: "12/28",
cvv: "123"
})
return (
console.log("Card flipped:", flipped)}
/>
)
}
```
### Image Zoom Component
Zoomable image component with smooth modal transitions for image galleries and product displays.
```tsx
import { ImageZoom } from "@/components/ui/image-zoom"
export default function ProductGallery() {
return (
)
}
```
### QR Code Component
Generate and display customizable QR codes with styling options for links, contact information, and authentication.
```tsx
import { QRCode } from "@/components/ui/qr-code"
export default function ShareDialog() {
const shareUrl = "https://shadcn.io"
return (
Scan to visit shadcn.io
)
}
```
### Color Picker Component
Advanced color selection component supporting multiple color formats (HEX, RGB, HSL) with preview.
```tsx
import { ColorPicker } from "@/components/ui/color-picker"
import { useState } from "react"
export default function ThemeCustomizer() {
const [color, setColor] = useState("#3b82f6")
return (
Selected: {color}
)
}
```
## Chart Components
### Bar Chart Component
Clean bar chart component for data comparison and categorical analysis using Recharts.
```tsx
import { BarChart } from "@/components/ui/bar-chart"
export default function SalesChart() {
const data = [
{ month: "Jan", sales: 4000, revenue: 2400 },
{ month: "Feb", sales: 3000, revenue: 1398 },
{ month: "Mar", sales: 2000, revenue: 9800 },
{ month: "Apr", sales: 2780, revenue: 3908 },
{ month: "May", sales: 1890, revenue: 4800 },
{ month: "Jun", sales: 2390, revenue: 3800 }
]
return (
`$${value.toLocaleString()}`}
yAxisWidth={60}
/>
)
}
```
### Line Chart Component
Smooth line chart for visualizing trends and time-series data with multiple data series support.
```tsx
import { LineChart } from "@/components/ui/line-chart"
export default function MetricsChart() {
const data = [
{ date: "2024-01", users: 1200, sessions: 3400 },
{ date: "2024-02", users: 1800, sessions: 4200 },
{ date: "2024-03", users: 2400, sessions: 5800 },
{ date: "2024-04", users: 3100, sessions: 7200 },
{ date: "2024-05", users: 3800, sessions: 8900 }
]
return (
)
}
```
### Pie Chart Component
Donut chart component for displaying proportional data and percentage distributions.
```tsx
import { PieChart } from "@/components/ui/pie-chart"
export default function MarketShareChart() {
const data = [
{ name: "Product A", value: 400, fill: "#3b82f6" },
{ name: "Product B", value: 300, fill: "#10b981" },
{ name: "Product C", value: 300, fill: "#f59e0b" },
{ name: "Product D", value: 200, fill: "#ef4444" }
]
return (
`${entry.name}: ${entry.value}`}
/>
)
}
```
### Area Chart Component
Stacked area chart for visualizing volume changes over time with multiple data series.
```tsx
import { AreaChart } from "@/components/ui/area-chart"
export default function TrafficChart() {
const data = [
{ month: "Jan", mobile: 2000, desktop: 3000, tablet: 1000 },
{ month: "Feb", mobile: 2200, desktop: 3200, tablet: 1100 },
{ month: "Mar", mobile: 2800, desktop: 3800, tablet: 1300 },
{ month: "Apr", mobile: 3200, desktop: 4200, tablet: 1500 },
{ month: "May", mobile: 3800, desktop: 4800, tablet: 1800 }
]
return (
)
}
```
### Radar Chart Component
Multi-axis chart for comparing multiple variables across different categories simultaneously.
```tsx
import { RadarChart } from "@/components/ui/radar-chart"
export default function SkillsChart() {
const data = [
{ skill: "JavaScript", score: 85, industry: 75 },
{ skill: "TypeScript", score: 80, industry: 70 },
{ skill: "React", score: 90, industry: 80 },
{ skill: "Node.js", score: 75, industry: 72 },
{ skill: "CSS", score: 88, industry: 78 }
]
return (
)
}
```
### Mixed Chart Component
Combined bar and line chart for displaying multiple data types with different visualization methods.
```tsx
import { MixedChart } from "@/components/ui/mixed-chart"
export default function PerformanceChart() {
const data = [
{ month: "Jan", revenue: 4000, growth: 5.2 },
{ month: "Feb", revenue: 4200, growth: 5.0 },
{ month: "Mar", revenue: 4800, growth: 14.3 },
{ month: "Apr", revenue: 5200, growth: 8.3 },
{ month: "May", revenue: 5800, growth: 11.5 }
]
return (
)
}
```
## Animation Components
### Magnetic Effect Component
Magnetic hover effect that smoothly follows cursor movement for interactive buttons and cards.
```tsx
import { Magnetic } from "@/components/ui/magnetic"
export default function InteractiveButton() {
return (
Hover me
)
}
```
### Animated Cursor Component
Custom animated cursor with interactive effects and particle trails for immersive experiences.
```tsx
import { AnimatedCursor } from "@/components/ui/animated-cursor"
export default function Layout({ children }) {
return (
<>
{children}
)
}
```
### Apple Hello Effect Component
Recreation of Apple's iconic "hello" animation with multi-language text transitions.
```tsx
import { AppleHello } from "@/components/ui/apple-hello"
export default function WelcomeScreen() {
const greetings = [
{ text: "Hello", lang: "en" },
{ text: "Bonjour", lang: "fr" },
{ text: "こんにちは", lang: "ja" },
{ text: "Hola", lang: "es" },
{ text: "你好", lang: "zh" }
]
return (
)
}
```
### Liquid Button Component
Button with fluid liquid animation effect on hover for engaging call-to-action elements.
```tsx
import { LiquidButton } from "@/components/ui/liquid-button"
export default function CTASection() {
return (
console.log("CTA clicked")}
>
Get Started
)
}
```
### Rolling Text Component
Text animation that creates a rolling effect with smooth character transitions.
```tsx
import { RollingText } from "@/components/ui/rolling-text"
export default function AnimatedHeading() {
return (
)
}
```
### Shimmering Text Component
Text with animated shimmer effect for attention-grabbing headings and highlights.
```tsx
import { ShimmeringText } from "@/components/ui/shimmering-text"
export default function Hero() {
return (
)
}
```
## React Hooks
### useBoolean Hook
Enhanced boolean state management with toggle, enable, and disable methods for cleaner component logic.
```tsx
import { useBoolean } from "@/hooks/use-boolean"
export default function TogglePanel() {
const modal = useBoolean(false)
const loading = useBoolean(false)
const handleSubmit = async () => {
loading.setTrue()
try {
await submitForm()
modal.setFalse()
} finally {
loading.setFalse()
}
}
return (
<>
Toggle Modal
{modal.value && (
Status: {loading.value ? "Saving..." : "Ready"}
Submit
)}
)
}
```
### useCounter Hook
Counter hook with increment, decrement, reset, and set functionality for numeric state management.
```tsx
import { useCounter } from "@/hooks/use-counter"
export default function CartCounter() {
const quantity = useCounter(0, { min: 0, max: 99 })
return (
-
{quantity.value}
+
Reset
)
}
```
### useLocalStorage Hook
Persist state in browser localStorage with automatic serialization and deserialization.
```tsx
import { useLocalStorage } from "@/hooks/use-local-storage"
export default function UserPreferences() {
const [theme, setTheme] = useLocalStorage("theme", "light")
const [settings, setSettings] = useLocalStorage("settings", {
notifications: true,
emailUpdates: false
})
return (
setTheme(e.target.value)}>
LightDark setSettings({
...settings,
notifications: e.target.checked
})}
/>
Enable Notifications
)
}
```
### useDebounceValue Hook
Debounce values to prevent excessive updates and API calls during rapid user input.
```tsx
import { useDebounceValue } from "@/hooks/use-debounce-value"
import { useState, useEffect } from "react"
export default function SearchBox() {
const [search, setSearch] = useState("")
const debouncedSearch = useDebounceValue(search, 500)
const [results, setResults] = useState([])
const [apiCalls, setApiCalls] = useState(0)
useEffect(() => {
if (debouncedSearch) {
setApiCalls(prev => prev + 1)
fetch(`/api/search?q=${debouncedSearch}`)
.then(res => res.json())
.then(setResults)
}
}, [debouncedSearch])
return (
setSearch(e.target.value)}
placeholder="Search..."
/>
API calls: {apiCalls}
)
}
```
### useHover Hook
Track hover state on elements with customizable enter and leave delays for tooltip and preview functionality.
```tsx
import { useHover } from "@/hooks/use-hover"
import { useRef } from "react"
export default function ImagePreview() {
const hoverRef = useRef(null)
const isHovering = useHover(hoverRef, {
enterDelay: 200,
leaveDelay: 100
})
return (
![Preview](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/thumbnail.jpg)
{isHovering && (
![Full size](http://https:%2F%2Fcontext7.com%2Fwebsites%2Fshadcn_io%2Fllms.txt/full-size.jpg)
)}
)
}
```
### useCountdown Hook
Countdown timer with play, pause, reset controls and completion callbacks for time-limited features.
```tsx
import { useCountdown } from "@/hooks/use-countdown"
export default function OTPTimer() {
const countdown = useCountdown({
initialSeconds: 60,
onComplete: () => alert("OTP expired! Request a new code.")
})
return (
{countdown.seconds}s
{!countdown.isRunning ? (
Start
) : (
Pause
)}
Reset
Status: {countdown.isComplete ? "Expired" : countdown.isRunning ? "Active" : "Paused"}
)
}
```
## Installation and Usage
### CLI Installation
Install components directly into your project using the shadcn CLI for instant integration.
```bash
# Initialize shadcn in your project
npx shadcn@latest init
# Add individual components
npx shadcn@latest add terminal
npx shadcn@latest add dock
npx shadcn@latest add credit-card
# Add multiple components at once
npx shadcn@latest add bar-chart line-chart pie-chart
# Add hooks
npx shadcn@latest add use-boolean use-counter use-local-storage
```
### Project Configuration
Configure your project to work with shadcn.io components using TypeScript and Tailwind CSS.
```typescript
// tailwind.config.ts
import type { Config } from "tailwindcss"
const config: Config = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
],
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
},
},
},
plugins: [require("tailwindcss-animate")],
}
export default config
```
## Summary
The shadcn.io component library serves as a comprehensive toolkit for React developers building modern web applications with Next.js and TypeScript. The library's primary use cases include rapid prototyping of user interfaces, building data-rich dashboards with interactive charts, creating engaging user experiences with animations and effects, and implementing common UI patterns without writing boilerplate code. The copy-paste approach gives developers complete ownership of their components, allowing for deep customization while maintaining consistency with shadcn/ui design principles. Components are particularly well-suited for SaaS applications, admin panels, marketing websites, and e-commerce platforms that require professional, accessible UI elements.
Integration patterns center around composability and customization rather than rigid package dependencies. Developers can cherry-pick individual components using the CLI, modify them at the source level to match their design system, and combine them with existing shadcn/ui components for a cohesive interface. The library supports both light and dark themes through CSS variables, integrates seamlessly with Tailwind CSS utility classes, and follows React best practices for performance and accessibility. Custom hooks provide reusable logic patterns that complement the visual components, creating a complete ecosystem for building feature-rich applications. The TypeScript-first approach ensures type safety throughout the development process, while the Recharts integration for data visualization provides powerful charting capabilities without additional configuration overhead.

File diff suppressed because it is too large Load diff

42
LICENSE
View file

@ -1,21 +1,21 @@
MIT License
Copyright (c) 2026 Zenchant
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
MIT License
Copyright (c) 2026 Zenchant
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,33 +1,33 @@
bb-verify2-mlnaouad
bb-bridge-fix-mlnaja4j
bb-join-mlna9nbo
bb-invepic-mln9perd
bb-invalid-epic-mln9hraq
bb-m1-mln9perd
bb-leave-mln9perd
bb-member3-mln9hraq
bb-member2-mln9hraq
bb-switch-mln9perd
bb-nolabel-test-mln9hraq
bb-leave-test-mln9hraq
bb-switch-test-mln9hraq
bb-join-test-mln9hraq
bb-idem-test-mln97lyt
bb-switch-test-mln97lyt
bb-join-test-mln97lyt
bb-switch-test-mln8xxn4
bb-nolabel-test-mln8pdgh
bb-leave-test-mln8pdgh
bb-idem-test-mln8pdgh
bb-switch-test-mln8pdgh
bb-join-test-mln8pdgh
bb-leave-test-mln8hp8j
bb-idem-test-mln8hp8j
bb-switch-test-mln8hp8j
bb-join-test-mln8hp8j
bb-fresh-test-mln8canu
bb-step-test-mln872rm
bb-debug-test-mln83q18
bb-switch-test-mln7xyls
bb-join-test-mln7xyls
bb-test-agent
bb-verify2-mlnaouad
bb-bridge-fix-mlnaja4j
bb-join-mlna9nbo
bb-invepic-mln9perd
bb-invalid-epic-mln9hraq
bb-m1-mln9perd
bb-leave-mln9perd
bb-member3-mln9hraq
bb-member2-mln9hraq
bb-switch-mln9perd
bb-nolabel-test-mln9hraq
bb-leave-test-mln9hraq
bb-switch-test-mln9hraq
bb-join-test-mln9hraq
bb-idem-test-mln97lyt
bb-switch-test-mln97lyt
bb-join-test-mln97lyt
bb-switch-test-mln8xxn4
bb-nolabel-test-mln8pdgh
bb-leave-test-mln8pdgh
bb-idem-test-mln8pdgh
bb-switch-test-mln8pdgh
bb-join-test-mln8pdgh
bb-leave-test-mln8hp8j
bb-idem-test-mln8hp8j
bb-switch-test-mln8hp8j
bb-join-test-mln8hp8j
bb-fresh-test-mln8canu
bb-step-test-mln872rm
bb-debug-test-mln83q18
bb-switch-test-mln7xyls
bb-join-test-mln7xyls
bb-test-agent

View file

@ -1,114 +1,114 @@
bb-ui2.29
bb-atf
bb-z6s
bb-54x
bb-nuy
bb-98c
bb-3ha
bb-22l
bb-5am
bb-dwz
bb-3dv
bb-only-ui-agent
bb-graph-agent-1
bb-ui-agent-2
bb-ui-agent-1
bb-verify-mlnavzwu
bb-final-mlnar702
bb-verify2-mlnaouad
bb-final-mlnalaqz
bb-bridge-fix-mlnaja4j
bb-verify-mlnadaip
bb-switch-mlna9nbo
bb-join-mlna9nbo
bb-invepic-mln9perd
bb-m2-mln9perd
bb-invalid-epic-mln9hraq
bb-m1-mln9perd
bb-leave-mln9perd
bb-member3-mln9hraq
bb-member2-mln9hraq
bb-member1-mln9hraq
bb-switch-mln9perd
bb-nolabel-test-mln9hraq
bb-join-mln9perd
bb-leave-test-mln9hraq
bb-idem-test-mln9hraq
bb-debug-mln9knzs
bb-switch-test-mln9hraq
bb-join-test-mln9hraq
bb-smoke-mln9e525
bb-idem-test-mln97lyt
bb-switch-test-mln97lyt
bb-join-test-mln97lyt
bb-switch-test-mln8xxn4
bb-join-test-mln8xxn4
bb-nolabel-test-mln8pdgh
bb-leave-test-mln8pdgh
bb-idem-test-mln8pdgh
bb-switch-test-mln8pdgh
bb-join-test-mln8pdgh
bb-leave-test-mln8hp8j
bb-idem-test-mln8hp8j
bb-switch-test-mln8hp8j
bb-join-test-mln8hp8j
bb-daemon-test-mln8e4tf
bb-fresh-test-mln8canu
bb-upd-test-mln8981k
bb-step-test-mln872rm
bb-debug-test-mln83q18
bb-switch-test-mln7xyls
bb-join-test-mln7xyls
bb-linus-swarm
bb-ff6
bb-agent-graph-1
bb-1xj
bb-agent-a
bb-agent-b
bb-active-agent
bb-agent-ui-1
bb-green-falcon
bb-zenchantlive
bb-silver-castle
bb-test-agent
bb-9p8
bb-u6f.3
bb-6aj.2
bb-6aj.1
beadboard-yad
beadboard-eo8
beadboard-c08
bb-ui2.30
bb-buff
bb-jp2
bb-79b
bb-1y7
bb-u6f.6.6
bb-u6f.6.4
bb-u6f.6.3
bb-u6f.6.2
bb-u6f.6.1
bb-u6f.6
bb-kp5
bb-dcv.8
bb-dcv.7
bb-dcv.6
bb-dcv.5
bb-dcv.4
bb-dcv.3
bb-dcv.2
bb-dcv.1
bb-dcv
bb-u6f.1
bb-u6f
bb-trz.4
bb-trz.3
bb-trz.2
bb-trz.1
bb-zzr
bb-1d1
bb-5pw
bb-format-check
bb-buff.4
bb-u6f.6.5
bb-u6f.2
bb-ui2.29
bb-atf
bb-z6s
bb-54x
bb-nuy
bb-98c
bb-3ha
bb-22l
bb-5am
bb-dwz
bb-3dv
bb-only-ui-agent
bb-graph-agent-1
bb-ui-agent-2
bb-ui-agent-1
bb-verify-mlnavzwu
bb-final-mlnar702
bb-verify2-mlnaouad
bb-final-mlnalaqz
bb-bridge-fix-mlnaja4j
bb-verify-mlnadaip
bb-switch-mlna9nbo
bb-join-mlna9nbo
bb-invepic-mln9perd
bb-m2-mln9perd
bb-invalid-epic-mln9hraq
bb-m1-mln9perd
bb-leave-mln9perd
bb-member3-mln9hraq
bb-member2-mln9hraq
bb-member1-mln9hraq
bb-switch-mln9perd
bb-nolabel-test-mln9hraq
bb-join-mln9perd
bb-leave-test-mln9hraq
bb-idem-test-mln9hraq
bb-debug-mln9knzs
bb-switch-test-mln9hraq
bb-join-test-mln9hraq
bb-smoke-mln9e525
bb-idem-test-mln97lyt
bb-switch-test-mln97lyt
bb-join-test-mln97lyt
bb-switch-test-mln8xxn4
bb-join-test-mln8xxn4
bb-nolabel-test-mln8pdgh
bb-leave-test-mln8pdgh
bb-idem-test-mln8pdgh
bb-switch-test-mln8pdgh
bb-join-test-mln8pdgh
bb-leave-test-mln8hp8j
bb-idem-test-mln8hp8j
bb-switch-test-mln8hp8j
bb-join-test-mln8hp8j
bb-daemon-test-mln8e4tf
bb-fresh-test-mln8canu
bb-upd-test-mln8981k
bb-step-test-mln872rm
bb-debug-test-mln83q18
bb-switch-test-mln7xyls
bb-join-test-mln7xyls
bb-linus-swarm
bb-ff6
bb-agent-graph-1
bb-1xj
bb-agent-a
bb-agent-b
bb-active-agent
bb-agent-ui-1
bb-green-falcon
bb-zenchantlive
bb-silver-castle
bb-test-agent
bb-9p8
bb-u6f.3
bb-6aj.2
bb-6aj.1
beadboard-yad
beadboard-eo8
beadboard-c08
bb-ui2.30
bb-buff
bb-jp2
bb-79b
bb-1y7
bb-u6f.6.6
bb-u6f.6.4
bb-u6f.6.3
bb-u6f.6.2
bb-u6f.6.1
bb-u6f.6
bb-kp5
bb-dcv.8
bb-dcv.7
bb-dcv.6
bb-dcv.5
bb-dcv.4
bb-dcv.3
bb-dcv.2
bb-dcv.1
bb-dcv
bb-u6f.1
bb-u6f
bb-trz.4
bb-trz.3
bb-trz.2
bb-trz.1
bb-zzr
bb-1d1
bb-5pw
bb-format-check
bb-buff.4
bb-u6f.6.5
bb-u6f.2

View file

@ -1,61 +1,61 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
aurora: "btn-aurora",
"aurora-primary": "btn-aurora-primary",
"aurora-success": "btn-aurora-success",
"aurora-danger": "btn-aurora-danger",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
aurora: "btn-aurora",
"aurora-primary": "btn-aurora-primary",
"aurora-success": "btn-aurora-success",
"aurora-danger": "btn-aurora-danger",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }

View file

@ -1,165 +1,165 @@
# Agent Session Flow & Operator Guide
This document defines the canonical workflow for human operators using `bb agent` to coordinate work in the Beadboard repo.
## Core Principle: Two Sources of Truth
1. **Work Lifecycle**: `bd` (Beads) is the ONLY source of truth for what work is happening (`in_progress`, `done`, dependencies).
2. **Coordination**: `bb agent` is the source of truth for *who* is doing it and *how* they are coordinating (reservations, handoffs).
**Rule**: Never write to `.beads/issues.jsonl` directly. Always use `bd` commands.
## Session Lifecycle
### 1. Identity Check (Start of Session)
Before claiming work, ensure your agent identity is registered and active.
```bash
# Check if you are registered
bb agent show --agent agent-ui-1
# If not, register (idempotent, use --force-update to change role/display)
bb agent register --name agent-ui-1 --role ui --display "UI Agent 1"
```
### 2. Picking and Claiming Work
Use `bd` to find and claim work. This is the "clock in" event.
```bash
# 1. Find ready work (unblocked)
bd ready
# 2. Inspect the bead
bd show bb-dcv.5
# 3. CLAIM the bead (Atomic Claim)
# This sets status=in_progress AND assigns it to you in one atomic op.
bd update bb-dcv.5 --status in_progress --notes "Starting docs work" --claim
```
### 3. Coordination (During Work)
While working, use `bb agent` to coordinate with other agents or reserve contested resources.
#### Reservations (Traffic Control)
Prevent collisions on shared files or subsystems.
```bash
# Reserve a scope (default TTL 120m)
bb agent reserve --agent agent-ui-1 --bead bb-dcv.5 --scope "src/components/graph/*"
# Check status of your reservation
bb agent status --bead bb-dcv.5
```
#### Communication (Handoffs & Blockers)
Send structured signals to other agents.
```bash
# BLOCKER: Request help
bb agent send \
--from agent-ui-1 \
--to agent-backend-1 \
--bead bb-dcv.5 \
--category BLOCKED \
--subject "API 404 on /b/users" \
--body "Endpoint missing. Blocking UI integration."
# HANDOFF: Pass context
bb agent send \
--from agent-ui-1 \
--to agent-qa-1 \
--bead bb-dcv.5 \
--category HANDOFF \
--subject "Ready for verification" \
--body "UI complete. Verify at /graph and /kanban."
```
#### Checking Mail
```bash
# Check inbox
bb agent inbox --agent agent-ui-1 --state unread
# Read a message (marks as read)
bb agent read --agent agent-ui-1 --message msg_id_123
# Acknowledge a message (required for HANDOFF/BLOCKED)
bb agent ack --agent agent-ui-1 --message msg_id_123
```
### 4. Completion (End of Session)
Wrap up the session cleanly.
1. **Release Reservations**:
```bash
# Release specific scope
bb agent release --agent agent-ui-1 --scope "src/components/graph/*"
```
2. **Update Bead Status**:
```bash
# Post evidence/results
bd update bb-dcv.5 --notes "Docs created. Validation passed."
# Close the bead
bd close bb-dcv.5 --reason "Completed all acceptance criteria"
```
## UX & Output Formats
All `bb agent` commands support human-friendly output (default) and machine-readable JSON.
### Human Format (Default)
Optimized for operator readability.
```text
$ bb agent register --name agent-ui-1 --role ui
✓ Agent registered: agent-ui-1 (role: ui)
```
### JSON Format (`--json`)
Optimized for tool parsing. Always returns a standard envelope.
```bash
$ bb agent register --name agent-ui-1 --role ui --json
```
```json
{
"ok": true,
"command": "agent register",
"data": {
"agent_id": "agent-ui-1",
"role": "ui",
"status": "idle",
...
},
"error": null
}
```
### Error Handling
Errors always return `ok: false` with a stable error code.
```json
{
"ok": false,
"command": "agent send",
"data": null,
"error": {
"code": "UNKNOWN_RECIPIENT",
"message": "Agent 'ghost-1' not found"
}
}
```
## Anti-Patterns (Don't Do This)
1. **Ghosting**: Claiming a bead but not registering an agent identity.
2. **Squatting**: Holding a reservation (`--ttl 1440`) while not actively working.
3. **Bypassing**: Writing to `issues.jsonl` directly instead of using `bd`.
4. **Zombie Claims**: Forgetting to `bd close` or `bd update --status todo` when stopping work.
# Agent Session Flow & Operator Guide
This document defines the canonical workflow for human operators using `bb agent` to coordinate work in the Beadboard repo.
## Core Principle: Two Sources of Truth
1. **Work Lifecycle**: `bd` (Beads) is the ONLY source of truth for what work is happening (`in_progress`, `done`, dependencies).
2. **Coordination**: `bb agent` is the source of truth for *who* is doing it and *how* they are coordinating (reservations, handoffs).
**Rule**: Never write to `.beads/issues.jsonl` directly. Always use `bd` commands.
## Session Lifecycle
### 1. Identity Check (Start of Session)
Before claiming work, ensure your agent identity is registered and active.
```bash
# Check if you are registered
bb agent show --agent agent-ui-1
# If not, register (idempotent, use --force-update to change role/display)
bb agent register --name agent-ui-1 --role ui --display "UI Agent 1"
```
### 2. Picking and Claiming Work
Use `bd` to find and claim work. This is the "clock in" event.
```bash
# 1. Find ready work (unblocked)
bd ready
# 2. Inspect the bead
bd show bb-dcv.5
# 3. CLAIM the bead (Atomic Claim)
# This sets status=in_progress AND assigns it to you in one atomic op.
bd update bb-dcv.5 --status in_progress --notes "Starting docs work" --claim
```
### 3. Coordination (During Work)
While working, use `bb agent` to coordinate with other agents or reserve contested resources.
#### Reservations (Traffic Control)
Prevent collisions on shared files or subsystems.
```bash
# Reserve a scope (default TTL 120m)
bb agent reserve --agent agent-ui-1 --bead bb-dcv.5 --scope "src/components/graph/*"
# Check status of your reservation
bb agent status --bead bb-dcv.5
```
#### Communication (Handoffs & Blockers)
Send structured signals to other agents.
```bash
# BLOCKER: Request help
bb agent send \
--from agent-ui-1 \
--to agent-backend-1 \
--bead bb-dcv.5 \
--category BLOCKED \
--subject "API 404 on /b/users" \
--body "Endpoint missing. Blocking UI integration."
# HANDOFF: Pass context
bb agent send \
--from agent-ui-1 \
--to agent-qa-1 \
--bead bb-dcv.5 \
--category HANDOFF \
--subject "Ready for verification" \
--body "UI complete. Verify at /graph and /kanban."
```
#### Checking Mail
```bash
# Check inbox
bb agent inbox --agent agent-ui-1 --state unread
# Read a message (marks as read)
bb agent read --agent agent-ui-1 --message msg_id_123
# Acknowledge a message (required for HANDOFF/BLOCKED)
bb agent ack --agent agent-ui-1 --message msg_id_123
```
### 4. Completion (End of Session)
Wrap up the session cleanly.
1. **Release Reservations**:
```bash
# Release specific scope
bb agent release --agent agent-ui-1 --scope "src/components/graph/*"
```
2. **Update Bead Status**:
```bash
# Post evidence/results
bd update bb-dcv.5 --notes "Docs created. Validation passed."
# Close the bead
bd close bb-dcv.5 --reason "Completed all acceptance criteria"
```
## UX & Output Formats
All `bb agent` commands support human-friendly output (default) and machine-readable JSON.
### Human Format (Default)
Optimized for operator readability.
```text
$ bb agent register --name agent-ui-1 --role ui
✓ Agent registered: agent-ui-1 (role: ui)
```
### JSON Format (`--json`)
Optimized for tool parsing. Always returns a standard envelope.
```bash
$ bb agent register --name agent-ui-1 --role ui --json
```
```json
{
"ok": true,
"command": "agent register",
"data": {
"agent_id": "agent-ui-1",
"role": "ui",
"status": "idle",
...
},
"error": null
}
```
### Error Handling
Errors always return `ok: false` with a stable error code.
```json
{
"ok": false,
"command": "agent send",
"data": null,
"error": {
"code": "UNKNOWN_RECIPIENT",
"message": "Agent 'ghost-1' not found"
}
}
```
## Anti-Patterns (Don't Do This)
1. **Ghosting**: Claiming a bead but not registering an agent identity.
2. **Squatting**: Holding a reservation (`--ttl 1440`) while not actively working.
3. **Bypassing**: Writing to `issues.jsonl` directly instead of using `bd`.
4. **Zombie Claims**: Forgetting to `bd close` or `bd update --status todo` when stopping work.

View file

@ -1,283 +1,283 @@
# BeadBoard API Reference
## Overview
BeadBoard exposes REST endpoints for reading bead data, managing agent coordination, and streaming real-time activity. All endpoints return JSON (unless noted otherwise).
## Bead Management
### `GET /api/beads/read`
Read beads from the current or specified project.
**Query Parameters:**
- `project` (optional): Project key for scope resolution
- `mode` (optional): `single` or `aggregate`
**Response:**
```json
{
"issues": [...],
"projectRoot": "/path/to/project"
}
```
### `POST /api/beads/create`
Create a new bead.
**Body:**
```json
{
"title": "Task title",
"description": "Optional description",
"status": "open",
"priority": "p2",
"issue_type": "task"
}
```
### `POST /api/beads/update`
Update an existing bead.
**Body:**
```json
{
"id": "bb-abc",
"updates": {
"status": "in_progress",
"assignee": "agent-1"
}
}
```
### `POST /api/beads/close`
Close a bead.
**Body:**
```json
{
"id": "bb-abc",
"reason": "Completion reason"
}
```
### `POST /api/beads/reopen`
Reopen a closed bead.
**Body:**
```json
{
"id": "bb-abc"
}
```
### `POST /api/beads/comment`
Add a comment to a bead.
**Body:**
```json
{
"id": "bb-abc",
"comment": "Comment text",
"author": "agent-1"
}
```
## Agent Coordination
### `GET /api/agents/[agentId]/stats`
Fetch productivity metrics for a specific agent.
**Path Parameters:**
- `agentId`: Agent identifier
**Response:**
```json
{
"activeTasks": 3,
"completedTasks": 12,
"handoffsSent": 8,
"recentWins": [
{ "id": "bb-xyz", "title": "Task title" }
]
}
```
### `GET /api/sessions`
Fetch the agent sessions task feed.
**Query Parameters:**
- `project` (optional): Project scope
- `mode` (optional): `single` or `aggregate`
**Response:**
```json
{
"buckets": [
{
"epic": {
"id": "bb-epic",
"title": "Epic Title",
"status": "open"
},
"tasks": [
{
"id": "bb-task",
"title": "Task Title",
"epicId": "bb-epic",
"status": "in_progress",
"sessionState": "active",
"owner": "agent-1",
"lastActor": "agent-1",
"lastActivityAt": "2026-02-16T05:00:00Z",
"communication": {
"unreadCount": 2,
"pendingRequired": true,
"latestSnippet": "Blocked on API"
}
}
]
}
]
}
```
### `GET /api/sessions/[beadId]/conversation`
Get the full conversation thread for a bead, including comments and agent messages.
**Path Parameters:**
- `beadId`: Bead identifier
**Response:**
```json
{
"comments": [...],
"messages": [...]
}
```
### `POST /api/sessions/[beadId]/comment`
Add a comment to a bead session.
**Path Parameters:**
- `beadId`: Bead identifier
**Body:**
```json
{
"comment": "Comment text",
"author": "agent-1"
}
```
### `POST /api/sessions/[beadId]/messages/[messageId]/read`
Mark an agent message as read.
**Path Parameters:**
- `beadId`: Bead identifier
- `messageId`: Message identifier
### `POST /api/sessions/[beadId]/messages/[messageId]/ack`
Acknowledge an agent message (required for HANDOFF/BLOCKED categories).
**Path Parameters:**
- `beadId`: Bead identifier
- `messageId`: Message identifier
## Activity & Events
### `GET /api/activity`
Fetch recent activity events (history buffer).
**Response:**
```json
{
"events": [
{
"id": "evt-123",
"beadId": "bb-abc",
"kind": "status_changed",
"actor": "agent-1",
"timestamp": "2026-02-16T05:00:00Z",
"changes": {
"from": "todo",
"to": "in_progress"
}
}
]
}
```
### `GET /api/events`
Server-Sent Events stream for real-time activity.
**Response:** SSE stream with `event` and `data` fields.
**Event Types:**
- `activity`: New activity event
- `bead_updated`: Bead state changed
- `agent_registered`: New agent registered
## Project Management
### `GET /api/projects`
List all registered projects.
**Response:**
```json
{
"projects": [
{
"key": "proj-1",
"root": "/path/to/project",
"name": "Project Name"
}
]
}
```
### `POST /api/scan`
Scan filesystem for bead-enabled projects.
**Body:**
```json
{
"paths": ["/path/to/scan"]
}
```
**Response:**
```json
{
"discovered": [
{
"root": "/path/to/project",
"beadCount": 42
}
]
}
```
## Error Handling
All endpoints follow a consistent error format:
```json
{
"error": "Error message",
"code": "ERROR_CODE",
"details": {}
}
```
**Common Error Codes:**
- `INVALID_REQUEST`: Malformed request body or parameters
- `NOT_FOUND`: Resource does not exist
- `PERMISSION_DENIED`: Operation not allowed
- `INTERNAL_ERROR`: Server-side error
## Rate Limiting
No rate limiting is currently enforced for local BeadBoard instances. If deploying publicly, implement rate limiting externally.
## Authentication
BeadBoard runs as a local dashboard with no authentication. If exposing over a network, secure access using reverse proxy authentication or network isolation.
# BeadBoard API Reference
## Overview
BeadBoard exposes REST endpoints for reading bead data, managing agent coordination, and streaming real-time activity. All endpoints return JSON (unless noted otherwise).
## Bead Management
### `GET /api/beads/read`
Read beads from the current or specified project.
**Query Parameters:**
- `project` (optional): Project key for scope resolution
- `mode` (optional): `single` or `aggregate`
**Response:**
```json
{
"issues": [...],
"projectRoot": "/path/to/project"
}
```
### `POST /api/beads/create`
Create a new bead.
**Body:**
```json
{
"title": "Task title",
"description": "Optional description",
"status": "open",
"priority": "p2",
"issue_type": "task"
}
```
### `POST /api/beads/update`
Update an existing bead.
**Body:**
```json
{
"id": "bb-abc",
"updates": {
"status": "in_progress",
"assignee": "agent-1"
}
}
```
### `POST /api/beads/close`
Close a bead.
**Body:**
```json
{
"id": "bb-abc",
"reason": "Completion reason"
}
```
### `POST /api/beads/reopen`
Reopen a closed bead.
**Body:**
```json
{
"id": "bb-abc"
}
```
### `POST /api/beads/comment`
Add a comment to a bead.
**Body:**
```json
{
"id": "bb-abc",
"comment": "Comment text",
"author": "agent-1"
}
```
## Agent Coordination
### `GET /api/agents/[agentId]/stats`
Fetch productivity metrics for a specific agent.
**Path Parameters:**
- `agentId`: Agent identifier
**Response:**
```json
{
"activeTasks": 3,
"completedTasks": 12,
"handoffsSent": 8,
"recentWins": [
{ "id": "bb-xyz", "title": "Task title" }
]
}
```
### `GET /api/sessions`
Fetch the agent sessions task feed.
**Query Parameters:**
- `project` (optional): Project scope
- `mode` (optional): `single` or `aggregate`
**Response:**
```json
{
"buckets": [
{
"epic": {
"id": "bb-epic",
"title": "Epic Title",
"status": "open"
},
"tasks": [
{
"id": "bb-task",
"title": "Task Title",
"epicId": "bb-epic",
"status": "in_progress",
"sessionState": "active",
"owner": "agent-1",
"lastActor": "agent-1",
"lastActivityAt": "2026-02-16T05:00:00Z",
"communication": {
"unreadCount": 2,
"pendingRequired": true,
"latestSnippet": "Blocked on API"
}
}
]
}
]
}
```
### `GET /api/sessions/[beadId]/conversation`
Get the full conversation thread for a bead, including comments and agent messages.
**Path Parameters:**
- `beadId`: Bead identifier
**Response:**
```json
{
"comments": [...],
"messages": [...]
}
```
### `POST /api/sessions/[beadId]/comment`
Add a comment to a bead session.
**Path Parameters:**
- `beadId`: Bead identifier
**Body:**
```json
{
"comment": "Comment text",
"author": "agent-1"
}
```
### `POST /api/sessions/[beadId]/messages/[messageId]/read`
Mark an agent message as read.
**Path Parameters:**
- `beadId`: Bead identifier
- `messageId`: Message identifier
### `POST /api/sessions/[beadId]/messages/[messageId]/ack`
Acknowledge an agent message (required for HANDOFF/BLOCKED categories).
**Path Parameters:**
- `beadId`: Bead identifier
- `messageId`: Message identifier
## Activity & Events
### `GET /api/activity`
Fetch recent activity events (history buffer).
**Response:**
```json
{
"events": [
{
"id": "evt-123",
"beadId": "bb-abc",
"kind": "status_changed",
"actor": "agent-1",
"timestamp": "2026-02-16T05:00:00Z",
"changes": {
"from": "todo",
"to": "in_progress"
}
}
]
}
```
### `GET /api/events`
Server-Sent Events stream for real-time activity.
**Response:** SSE stream with `event` and `data` fields.
**Event Types:**
- `activity`: New activity event
- `bead_updated`: Bead state changed
- `agent_registered`: New agent registered
## Project Management
### `GET /api/projects`
List all registered projects.
**Response:**
```json
{
"projects": [
{
"key": "proj-1",
"root": "/path/to/project",
"name": "Project Name"
}
]
}
```
### `POST /api/scan`
Scan filesystem for bead-enabled projects.
**Body:**
```json
{
"paths": ["/path/to/scan"]
}
```
**Response:**
```json
{
"discovered": [
{
"root": "/path/to/project",
"beadCount": 42
}
]
}
```
## Error Handling
All endpoints follow a consistent error format:
```json
{
"error": "Error message",
"code": "ERROR_CODE",
"details": {}
}
```
**Common Error Codes:**
- `INVALID_REQUEST`: Malformed request body or parameters
- `NOT_FOUND`: Resource does not exist
- `PERMISSION_DENIED`: Operation not allowed
- `INTERNAL_ERROR`: Server-side error
## Rate Limiting
No rate limiting is currently enforced for local BeadBoard instances. If deploying publicly, implement rate limiting externally.
## Authentication
BeadBoard runs as a local dashboard with no authentication. If exposing over a network, secure access using reverse proxy authentication or network isolation.

View file

@ -1,5 +1,5 @@
export default {
plugins: {
'@tailwindcss/postcss': {},
},
};
export default {
plugins: {
'@tailwindcss/postcss': {},
},
};

View file

@ -1,166 +1,166 @@
diff --git a/.gitignore b/.gitignore
index eb35607..596f42a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@ node_modules/
*.tsbuildinfo
.worktrees/
worktrees/
+
+# bv (beads viewer) local config and caches
+.bv/
diff --git a/src/app/globals.css b/src/app/globals.css
index d17e938..a474080 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -3,15 +3,15 @@
@tailwind utilities;
:root {
- --color-bg: #090c14;
- --color-surface: #101827;
- --color-surface-muted: #192336;
- --color-surface-raised: #22314a;
- --color-text-strong: #f6f8ff;
- --color-text-body: #d8e0f1;
- --color-text-muted: #9caccc;
- --color-border-soft: rgba(145, 166, 204, 0.3);
- --color-border-strong: rgba(187, 209, 246, 0.62);
+ --color-bg: #090909;
+ --color-surface: #161616;
+ --color-surface-muted: #212121;
+ --color-surface-raised: #2a2a2a;
+ --color-text-strong: #f5f5f5;
+ --color-text-body: #d0d0d0;
+ --color-text-muted: #9a9a9a;
+ --color-border-soft: rgba(255, 255, 255, 0.15);
+ --color-border-strong: rgba(255, 255, 255, 0.3);
--status-open: #60a5fa;
--status-progress: #fbbf24;
@@ -38,10 +38,9 @@ body {
body {
background:
- radial-gradient(circle at 10% 12%, rgba(12, 138, 215, 0.34), transparent 36%),
- radial-gradient(circle at 84% 20%, rgba(250, 122, 91, 0.18), transparent 30%),
- radial-gradient(circle at 68% 88%, rgba(57, 189, 154, 0.14), transparent 36%),
- linear-gradient(155deg, #05070d 0%, #0b1322 42%, #121e34 100%);
+ radial-gradient(circle at 14% 12%, rgba(255, 255, 255, 0.05), transparent 36%),
+ radial-gradient(circle at 84% 18%, rgba(255, 180, 80, 0.06), transparent 32%),
+ linear-gradient(160deg, #070707 0%, #101010 48%, #161616 100%);
color: var(--color-text-body);
- font-family: 'Segoe UI', 'Aptos', Inter, system-ui, sans-serif;
+ font-family: 'DM Sans', 'Segoe UI', Inter, system-ui, sans-serif;
}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index ff1ad90..1417e77 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,7 +1,18 @@
import type { Metadata } from 'next';
+import { DM_Sans, JetBrains_Mono } from 'next/font/google';
import type { ReactNode } from 'react';
import './globals.css';
+const dmSans = DM_Sans({
+ subsets: ['latin'],
+ variable: '--font-ui',
+});
+
+const jetbrainsMono = JetBrains_Mono({
+ subsets: ['latin'],
+ variable: '--font-mono',
+});
+
export const metadata: Metadata = {
title: 'BeadBoard',
description: 'Windows-native Beads dashboard',
@@ -10,7 +21,7 @@ export const metadata: Metadata = {
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
- <body>{children}</body>
+ <body className={`${dmSans.variable} ${jetbrainsMono.variable}`}>{children}</body>
</html>
);
}
diff --git a/src/components/kanban/kanban-controls.tsx b/src/components/kanban/kanban-controls.tsx
index 78b09f4..e1e04f9 100644
--- a/src/components/kanban/kanban-controls.tsx
+++ b/src/components/kanban/kanban-controls.tsx
@@ -14,7 +14,7 @@ interface KanbanControlsProps {
export function KanbanControls({ filters, stats, onFiltersChange }: KanbanControlsProps) {
const inputClass =
- 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-cyan-300/70 focus:ring-2 focus:ring-cyan-300/20';
+ 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-border-strong focus:ring-2 focus:ring-white/10';
return (
<section className="grid gap-3">
@@ -57,7 +57,7 @@ export function KanbanControls({ filters, stats, onFiltersChange }: KanbanContro
type="checkbox"
checked={filters.showClosed ?? false}
onChange={(event) => onFiltersChange({ ...filters, showClosed: event.target.checked })}
- className="h-4 w-4 accent-cyan-400"
+ className="h-4 w-4 accent-amber-400"
/>
Show closed
</label>
diff --git a/src/components/shared/chip.tsx b/src/components/shared/chip.tsx
index c1637e6..e29d49d 100644
--- a/src/components/shared/chip.tsx
+++ b/src/components/shared/chip.tsx
@@ -7,7 +7,7 @@ interface ChipProps {
const CHIP_TONE_CLASS: Record<NonNullable<ChipProps['tone']>, string> = {
default: 'border-border-soft bg-surface-muted/75 text-text-body',
- status: 'border-cyan-300/30 bg-cyan-500/20 text-cyan-50',
+ status: 'border-zinc-300/30 bg-zinc-500/20 text-zinc-100',
priority: 'border-amber-300/30 bg-amber-500/20 text-amber-50',
};
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 5ad9067..953965c 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -5,8 +5,8 @@ const config: Config = {
theme: {
extend: {
fontFamily: {
- ui: ['Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
- mono: ['JetBrains Mono', 'Consolas', 'monospace'],
+ ui: ['var(--font-ui)', 'Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
+ mono: ['var(--font-mono)', 'Consolas', 'monospace'],
},
colors: {
bg: 'var(--color-bg)',
diff --git a/tests/guards/kanban-responsive-contract.test.mjs b/tests/guards/kanban-responsive-contract.test.mjs
index 4e02f28..3efabf4 100644
--- a/tests/guards/kanban-responsive-contract.test.mjs
+++ b/tests/guards/kanban-responsive-contract.test.mjs
@@ -9,11 +9,12 @@ async function read(relativePath) {
return fs.readFile(path.join(ROOT, relativePath), 'utf8');
}
-test('kanban board uses intentional horizontal scroll affordances', async () => {
+test('kanban board uses expandable vertical swimlanes', async () => {
const board = await read('src/components/kanban/kanban-board.tsx');
- assert.match(board, /snap-x/);
- assert.match(board, /overflow-x-auto/);
+ assert.match(board, /aria-expanded/);
+ assert.match(board, /onActivateStatus/);
+ assert.match(board, /max-h-\[50vh\]/);
});
test('kanban page defines mobile detail drawer behavior', async () => {
@@ -21,6 +22,8 @@ test('kanban page defines mobile detail drawer behavior', async () => {
assert.match(page, /fixed inset-0/);
assert.match(page, /lg:hidden/);
+ assert.match(page, /lg:grid-cols-\[minmax\(0,1fr\)_minmax\(22rem,26rem\)\]/);
+ assert.match(page, /lg:border-l/);
});
test('kanban controls use fluid full-width sizing on small viewports', async () => {
diff --git a/.gitignore b/.gitignore
index eb35607..596f42a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@ node_modules/
*.tsbuildinfo
.worktrees/
worktrees/
+
+# bv (beads viewer) local config and caches
+.bv/
diff --git a/src/app/globals.css b/src/app/globals.css
index d17e938..a474080 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -3,15 +3,15 @@
@tailwind utilities;
:root {
- --color-bg: #090c14;
- --color-surface: #101827;
- --color-surface-muted: #192336;
- --color-surface-raised: #22314a;
- --color-text-strong: #f6f8ff;
- --color-text-body: #d8e0f1;
- --color-text-muted: #9caccc;
- --color-border-soft: rgba(145, 166, 204, 0.3);
- --color-border-strong: rgba(187, 209, 246, 0.62);
+ --color-bg: #090909;
+ --color-surface: #161616;
+ --color-surface-muted: #212121;
+ --color-surface-raised: #2a2a2a;
+ --color-text-strong: #f5f5f5;
+ --color-text-body: #d0d0d0;
+ --color-text-muted: #9a9a9a;
+ --color-border-soft: rgba(255, 255, 255, 0.15);
+ --color-border-strong: rgba(255, 255, 255, 0.3);
--status-open: #60a5fa;
--status-progress: #fbbf24;
@@ -38,10 +38,9 @@ body {
body {
background:
- radial-gradient(circle at 10% 12%, rgba(12, 138, 215, 0.34), transparent 36%),
- radial-gradient(circle at 84% 20%, rgba(250, 122, 91, 0.18), transparent 30%),
- radial-gradient(circle at 68% 88%, rgba(57, 189, 154, 0.14), transparent 36%),
- linear-gradient(155deg, #05070d 0%, #0b1322 42%, #121e34 100%);
+ radial-gradient(circle at 14% 12%, rgba(255, 255, 255, 0.05), transparent 36%),
+ radial-gradient(circle at 84% 18%, rgba(255, 180, 80, 0.06), transparent 32%),
+ linear-gradient(160deg, #070707 0%, #101010 48%, #161616 100%);
color: var(--color-text-body);
- font-family: 'Segoe UI', 'Aptos', Inter, system-ui, sans-serif;
+ font-family: 'DM Sans', 'Segoe UI', Inter, system-ui, sans-serif;
}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index ff1ad90..1417e77 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,7 +1,18 @@
import type { Metadata } from 'next';
+import { DM_Sans, JetBrains_Mono } from 'next/font/google';
import type { ReactNode } from 'react';
import './globals.css';
+const dmSans = DM_Sans({
+ subsets: ['latin'],
+ variable: '--font-ui',
+});
+
+const jetbrainsMono = JetBrains_Mono({
+ subsets: ['latin'],
+ variable: '--font-mono',
+});
+
export const metadata: Metadata = {
title: 'BeadBoard',
description: 'Windows-native Beads dashboard',
@@ -10,7 +21,7 @@ export const metadata: Metadata = {
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
- <body>{children}</body>
+ <body className={`${dmSans.variable} ${jetbrainsMono.variable}`}>{children}</body>
</html>
);
}
diff --git a/src/components/kanban/kanban-controls.tsx b/src/components/kanban/kanban-controls.tsx
index 78b09f4..e1e04f9 100644
--- a/src/components/kanban/kanban-controls.tsx
+++ b/src/components/kanban/kanban-controls.tsx
@@ -14,7 +14,7 @@ interface KanbanControlsProps {
export function KanbanControls({ filters, stats, onFiltersChange }: KanbanControlsProps) {
const inputClass =
- 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-cyan-300/70 focus:ring-2 focus:ring-cyan-300/20';
+ 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-border-strong focus:ring-2 focus:ring-white/10';
return (
<section className="grid gap-3">
@@ -57,7 +57,7 @@ export function KanbanControls({ filters, stats, onFiltersChange }: KanbanContro
type="checkbox"
checked={filters.showClosed ?? false}
onChange={(event) => onFiltersChange({ ...filters, showClosed: event.target.checked })}
- className="h-4 w-4 accent-cyan-400"
+ className="h-4 w-4 accent-amber-400"
/>
Show closed
</label>
diff --git a/src/components/shared/chip.tsx b/src/components/shared/chip.tsx
index c1637e6..e29d49d 100644
--- a/src/components/shared/chip.tsx
+++ b/src/components/shared/chip.tsx
@@ -7,7 +7,7 @@ interface ChipProps {
const CHIP_TONE_CLASS: Record<NonNullable<ChipProps['tone']>, string> = {
default: 'border-border-soft bg-surface-muted/75 text-text-body',
- status: 'border-cyan-300/30 bg-cyan-500/20 text-cyan-50',
+ status: 'border-zinc-300/30 bg-zinc-500/20 text-zinc-100',
priority: 'border-amber-300/30 bg-amber-500/20 text-amber-50',
};
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 5ad9067..953965c 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -5,8 +5,8 @@ const config: Config = {
theme: {
extend: {
fontFamily: {
- ui: ['Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
- mono: ['JetBrains Mono', 'Consolas', 'monospace'],
+ ui: ['var(--font-ui)', 'Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
+ mono: ['var(--font-mono)', 'Consolas', 'monospace'],
},
colors: {
bg: 'var(--color-bg)',
diff --git a/tests/guards/kanban-responsive-contract.test.mjs b/tests/guards/kanban-responsive-contract.test.mjs
index 4e02f28..3efabf4 100644
--- a/tests/guards/kanban-responsive-contract.test.mjs
+++ b/tests/guards/kanban-responsive-contract.test.mjs
@@ -9,11 +9,12 @@ async function read(relativePath) {
return fs.readFile(path.join(ROOT, relativePath), 'utf8');
}
-test('kanban board uses intentional horizontal scroll affordances', async () => {
+test('kanban board uses expandable vertical swimlanes', async () => {
const board = await read('src/components/kanban/kanban-board.tsx');
- assert.match(board, /snap-x/);
- assert.match(board, /overflow-x-auto/);
+ assert.match(board, /aria-expanded/);
+ assert.match(board, /onActivateStatus/);
+ assert.match(board, /max-h-\[50vh\]/);
});
test('kanban page defines mobile detail drawer behavior', async () => {
@@ -21,6 +22,8 @@ test('kanban page defines mobile detail drawer behavior', async () => {
assert.match(page, /fixed inset-0/);
assert.match(page, /lg:hidden/);
+ assert.match(page, /lg:grid-cols-\[minmax\(0,1fr\)_minmax\(22rem,26rem\)\]/);
+ assert.match(page, /lg:border-l/);
});
test('kanban controls use fluid full-width sizing on small viewports', async () => {

File diff suppressed because it is too large Load diff

View file

@ -1,130 +1,130 @@
# Agent Sessions Hub
## Overview
The Agent Sessions Hub (`/sessions`) provides a unified command workspace for tracking multi-agent coordination across your BeadBoard projects. It combines task status, agent communication, and derived activity into a social-dense interface optimized for understanding "who's doing what" at a glance.
## Features
### 1. Epic-Grouped Task Feed
Tasks are automatically organized by their parent Epic, providing logical context for understanding work scope.
- **Session State Indicators**: Each task displays its real-time state (active, reviewing, needs_input, completed, stale)
- **Owner & Actor Tracking**: See who owns the task and who last acted on it
- **Communication Badges**: Unread message counts and pending acknowledgment flags
### 2. Agent Communication Integration
Built-in cross-agent messaging system for coordination without leaving the dashboard.
**Message Types:**
- `HANDOFF` - Pass context to another agent
- `BLOCKED` - Request help or flag blockers
- `INFO` - Share updates or documentation
**Communication Features:**
- Inbox view with unread/read/acked states
- Required acknowledgments for critical handoffs
- Per-bead conversation threads
### 3. Agent Statistics & Productivity Metrics
Real-time performance tracking for each registered agent.
**Metrics Tracked:**
- Active tasks (currently in progress)
- Completed tasks (closed beads)
- Handoffs sent (coordination events)
- Recent wins (last 3 completed tasks)
### 4. Derived Activity Engine
Instead of storing history separately, BeadBoard computes activity on-demand by diffing snapshots of `issues.jsonl`.
**Event Types Generated:**
- Bead lifecycle: created, closed, reopened
- Status changes: todo → in_progress → done
- Assignee changes
- Priority, title, description updates
- Label and dependency changes
**Persistence:**
- File-backed ring buffer survives server restarts
- O(N) snapshot diffing algorithm
- No separate event database required
## Architecture
### Backend Components
- **Agent Registry** (`src/lib/agent-registry.ts`): Maintains agent identity and roles
- **Agent Mail** (`src/lib/agent-mail.ts`): Cross-agent messaging with inbox/ack protocol
- **Agent Reservations** (`src/lib/agent-reservations.ts`): File/scope locking to prevent collisions
- **Agent Sessions** (`src/lib/agent-sessions.ts`): Session state derivation and task feed builder
- **Snapshot Differ** (`src/lib/snapshot-differ.ts`): O(N) diffing engine for activity events
- **Activity Persistence** (`src/lib/activity-persistence.ts`): File-backed event buffer
### API Endpoints
- `GET /api/sessions` - Fetch session task feed
- `GET /api/sessions/[beadId]/conversation` - Get full conversation thread for a bead
- `POST /api/sessions/[beadId]/comment` - Add a comment to a bead session
- `POST /api/sessions/[beadId]/messages/[messageId]/read` - Mark message as read
- `POST /api/sessions/[beadId]/messages/[messageId]/ack` - Acknowledge message
- `GET /api/agents/[agentId]/stats` - Fetch agent productivity metrics
### Frontend Components
- **SessionsPage** (`src/components/sessions/sessions-page.tsx`): Main layout and orchestration
- **TaskCard** components: Visual representation of session state
- **AgentStatsPanel**: Metrics dashboard per agent
## Session States
Tasks automatically transition between states based on activity and communication:
| State | Description | Visual Indicator |
|-------|-------------|------------------|
| `active` | Status is `in_progress`, recent activity | Green pulse |
| `reviewing` | Under review or verification | Blue |
| `deciding` | Status is `todo` or `ready`, waiting for claim | Gray |
| `needs_input` | Status is `blocked` or has pending required acknowledgments | Yellow/Orange |
| `completed` | Status is `closed` | Green checkmark |
| `stale` | No activity in 24+ hours | Faded/Red |
## Integration with `bb agent` CLI
The Sessions Hub visualizes data managed by the `bb agent` command-line interface. See `docs/agent-session-flow.md` for the operator workflow.
**Key Commands:**
- `bb agent register --name <name> --role <role>` - Register agent identity
- `bb agent send --from <sender> --to <recipient> --bead <id> --category <type>` - Send message
- `bb agent inbox --agent <name>` - Check messages
- `bb agent reserve --agent <name> --scope <glob> --bead <id>` - Reserve files
- `bb agent status --bead <id>` - Check reservation status
## Data Flow
1. **Source of Truth**: `.beads/issues.jsonl` via `bd` CLI
2. **Activity Generation**: Watcher detects changes → snapshot differ → event bus
3. **Agent Coordination**: `bb` CLI writes to `.beads/agents/` directory
4. **UI Refresh**: SSE stream (`/api/events`) pushes updates to frontend in real-time
## Configuration
No configuration required. The Sessions Hub automatically:
- Discovers registered agents from `.beads/agents/`
- Builds communication graph from mailboxes
- Derives session states from current bead status + activity
## Performance
- **O(N) Diffing**: Snapshot differ scales linearly with number of beads
- **Ring Buffer**: Activity persistence uses fixed-size memory buffer (configurable)
- **Real-time Updates**: SSE keeps UI synchronized without polling
## Limitations
- Comment interactions are not yet streamed to the timeline
- Cross-project agent coordination requires agents to be registered in each project
- Stale threshold is fixed at 24 hours (not user-configurable)
## Related Documentation
- `docs/agent-session-flow.md` - CLI workflow guide for operators
- `docs/features/timeline.md` - Chronological activity feed
- `docs/RFC-001-Agent-Coordination.md` - Agent coordination design
- `docs/adr/2026-02-14-beadboard-driver-skill-and-bb-resolution.md` - beadboard-driver skill
# Agent Sessions Hub
## Overview
The Agent Sessions Hub (`/sessions`) provides a unified command workspace for tracking multi-agent coordination across your BeadBoard projects. It combines task status, agent communication, and derived activity into a social-dense interface optimized for understanding "who's doing what" at a glance.
## Features
### 1. Epic-Grouped Task Feed
Tasks are automatically organized by their parent Epic, providing logical context for understanding work scope.
- **Session State Indicators**: Each task displays its real-time state (active, reviewing, needs_input, completed, stale)
- **Owner & Actor Tracking**: See who owns the task and who last acted on it
- **Communication Badges**: Unread message counts and pending acknowledgment flags
### 2. Agent Communication Integration
Built-in cross-agent messaging system for coordination without leaving the dashboard.
**Message Types:**
- `HANDOFF` - Pass context to another agent
- `BLOCKED` - Request help or flag blockers
- `INFO` - Share updates or documentation
**Communication Features:**
- Inbox view with unread/read/acked states
- Required acknowledgments for critical handoffs
- Per-bead conversation threads
### 3. Agent Statistics & Productivity Metrics
Real-time performance tracking for each registered agent.
**Metrics Tracked:**
- Active tasks (currently in progress)
- Completed tasks (closed beads)
- Handoffs sent (coordination events)
- Recent wins (last 3 completed tasks)
### 4. Derived Activity Engine
Instead of storing history separately, BeadBoard computes activity on-demand by diffing snapshots of `issues.jsonl`.
**Event Types Generated:**
- Bead lifecycle: created, closed, reopened
- Status changes: todo → in_progress → done
- Assignee changes
- Priority, title, description updates
- Label and dependency changes
**Persistence:**
- File-backed ring buffer survives server restarts
- O(N) snapshot diffing algorithm
- No separate event database required
## Architecture
### Backend Components
- **Agent Registry** (`src/lib/agent-registry.ts`): Maintains agent identity and roles
- **Agent Mail** (`src/lib/agent-mail.ts`): Cross-agent messaging with inbox/ack protocol
- **Agent Reservations** (`src/lib/agent-reservations.ts`): File/scope locking to prevent collisions
- **Agent Sessions** (`src/lib/agent-sessions.ts`): Session state derivation and task feed builder
- **Snapshot Differ** (`src/lib/snapshot-differ.ts`): O(N) diffing engine for activity events
- **Activity Persistence** (`src/lib/activity-persistence.ts`): File-backed event buffer
### API Endpoints
- `GET /api/sessions` - Fetch session task feed
- `GET /api/sessions/[beadId]/conversation` - Get full conversation thread for a bead
- `POST /api/sessions/[beadId]/comment` - Add a comment to a bead session
- `POST /api/sessions/[beadId]/messages/[messageId]/read` - Mark message as read
- `POST /api/sessions/[beadId]/messages/[messageId]/ack` - Acknowledge message
- `GET /api/agents/[agentId]/stats` - Fetch agent productivity metrics
### Frontend Components
- **SessionsPage** (`src/components/sessions/sessions-page.tsx`): Main layout and orchestration
- **TaskCard** components: Visual representation of session state
- **AgentStatsPanel**: Metrics dashboard per agent
## Session States
Tasks automatically transition between states based on activity and communication:
| State | Description | Visual Indicator |
|-------|-------------|------------------|
| `active` | Status is `in_progress`, recent activity | Green pulse |
| `reviewing` | Under review or verification | Blue |
| `deciding` | Status is `todo` or `ready`, waiting for claim | Gray |
| `needs_input` | Status is `blocked` or has pending required acknowledgments | Yellow/Orange |
| `completed` | Status is `closed` | Green checkmark |
| `stale` | No activity in 24+ hours | Faded/Red |
## Integration with `bb agent` CLI
The Sessions Hub visualizes data managed by the `bb agent` command-line interface. See `docs/agent-session-flow.md` for the operator workflow.
**Key Commands:**
- `bb agent register --name <name> --role <role>` - Register agent identity
- `bb agent send --from <sender> --to <recipient> --bead <id> --category <type>` - Send message
- `bb agent inbox --agent <name>` - Check messages
- `bb agent reserve --agent <name> --scope <glob> --bead <id>` - Reserve files
- `bb agent status --bead <id>` - Check reservation status
## Data Flow
1. **Source of Truth**: `.beads/issues.jsonl` via `bd` CLI
2. **Activity Generation**: Watcher detects changes → snapshot differ → event bus
3. **Agent Coordination**: `bb` CLI writes to `.beads/agents/` directory
4. **UI Refresh**: SSE stream (`/api/events`) pushes updates to frontend in real-time
## Configuration
No configuration required. The Sessions Hub automatically:
- Discovers registered agents from `.beads/agents/`
- Builds communication graph from mailboxes
- Derives session states from current bead status + activity
## Performance
- **O(N) Diffing**: Snapshot differ scales linearly with number of beads
- **Ring Buffer**: Activity persistence uses fixed-size memory buffer (configurable)
- **Real-time Updates**: SSE keeps UI synchronized without polling
## Limitations
- Comment interactions are not yet streamed to the timeline
- Cross-project agent coordination requires agents to be registered in each project
- Stale threshold is fixed at 24 hours (not user-configurable)
## Related Documentation
- `docs/agent-session-flow.md` - CLI workflow guide for operators
- `docs/features/timeline.md` - Chronological activity feed
- `docs/RFC-001-Agent-Coordination.md` - Agent coordination design
- `docs/adr/2026-02-14-beadboard-driver-skill-and-bb-resolution.md` - beadboard-driver skill

View file

@ -1,318 +1,318 @@
# Comprehensive Theme System Design
## The Problem
We have colors scattered across 67+ files:
- Hardcoded hex: `bg-[#0a111a]`, `bg-[#111f2b]`, `bg-[#14202e]`
- Inline styles: `style={{ backgroundColor: '#1a2d3d' }}`
- Arbitrary Tailwind: `bg-white/5`, `border-white/10`
- Mixed variable systems: `--ui-bg-*`, `--color-bg-*`, etc.
## The Solution: Unified Theme System
### File Structure
```
src/styles/
themes/
index.css ← Theme definitions + data-attribute switching
tokens.css ← Base CSS variable names (no values)
components/
surfaces.css ← Surface layer utilities
interactions.css ← Hover, focus, active states
```
### Token Architecture (12 Semantic Categories)
#### 1. SURFACE LAYERS (Backgrounds)
```css
--surface-backdrop: /* Page background */
--surface-elevated: /* Header - sits on top */
--surface-primary: /* Left sidebar */
--surface-secondary: /* Main content area */
--surface-tertiary: /* Panels/cards within sidebars */
--surface-quaternary: /* Cards */
--surface-overlay: /* Modals, dropdowns, drawers */
--surface-input: /* Form fields, inputs */
--surface-hover: /* Hover states */
--surface-active: /* Active/selected states */
--surface-tooltip: /* Tooltips, popovers */
```
#### 2. BORDERS
```css
--border-subtle: /* Dividers between sections */
--border-default: /* Card borders */
--border-strong: /* Focus rings, selected states */
--border-accent: /* Colored status borders */
```
#### 3. TEXT
```css
--text-primary: /* Headlines, important text */
--text-secondary: /* Body text */
--text-tertiary: /* Muted, hints */
--text-disabled: /* Disabled elements */
--text-inverse: /* Text on colored backgrounds */
```
#### 4. ACCENTS (Functional)
```css
--accent-info: /* Cyan - links, actions */
--accent-success: /* Green - ready, done */
--accent-warning: /* Amber - in progress */
--accent-danger: /* Red - blocked, errors */
```
#### 5. ACCENTS (Aurora Glow)
```css
--glow-info: /* Box-shadow glow for info */
--glow-success: /* Box-shadow glow for success */
--glow-warning: /* Box-shadow glow for warning */
--glow-danger: /* Box-shadow glow for danger */
```
#### 6. GRAPH COLORS
```css
--graph-node-default: /* Default node background */
--graph-node-epic: /* Epic node accent */
--graph-edge-default: /* Default edge color */
--graph-edge-selected: /* Selected edge color */
--graph-edge-cycle: /* Cycle warning color */
```
#### 7. SEMANTIC ALPHAS
Instead of `bg-white/5` and `bg-black/40`, use themeable alphas:
```css
--alpha-white-low: /* 5% white */
--alpha-white-medium: /* 10% white */
--alpha-white-high: /* 20% white */
--alpha-black-low: /* 10% black */
--alpha-black-medium: /* 40% black */
--alpha-black-high: /* 80% black */
```
#### 8. STATUS COLORS
```css
--status-ready: /* Ready/open status */
--status-in-progress: /* In progress status */
--status-blocked: /* Blocked status */
--status-closed: /* Closed/done status */
--status-deferred: /* Deferred status */
```
#### 9. SHADOWS
```css
--shadow-sm: /* Subtle elevation */
--shadow-md: /* Cards */
--shadow-lg: /* Modals, drawers */
--shadow-glow-info: /* Aurora glow */
--shadow-glow-success: /* Aurora glow */
--shadow-glow-warning: /* Aurora glow */
--shadow-glow-danger: /* Aurora glow */
```
#### 10. AGENT/ROLE COLORS
```css
--agent-role-ui: /* UI role color */
--agent-role-graph: /* Graph role color */
--agent-role-orchestrator: /* Orchestrator role */
--agent-role-researcher: /* Researcher role */
```
#### 11. SCROLLBARS
```css
--scrollbar-track: /* Scrollbar track */
--scrollbar-thumb: /* Scrollbar thumb */
--scrollbar-thumb-hover: /* Scrollbar thumb hover */
```
#### 12. CODE/SYNTAX
```css
--code-background: /* Code block background */
--code-text: /* Code text color */
```
---
## Theme Definitions (Example)
### Aurora Theme (Current)
```css
[data-theme="aurora"] {
/* Surfaces - Warm Charcoal */
--surface-backdrop: #181716;
--surface-elevated: #131211;
--surface-primary: #1f1e1d;
--surface-secondary: #242322;
--surface-tertiary: #282725;
--surface-quaternary: #302e2c;
--surface-overlay: #0d0c0b;
/* Borders */
--border-subtle: rgba(180, 175, 165, 0.15);
--border-default: rgba(180, 175, 165, 0.25);
--border-strong: rgba(180, 175, 165, 0.4);
/* Text */
--text-primary: #f0eeea;
--text-secondary: #c9c5bc;
--text-tertiary: #a8a49a;
/* Accents */
--accent-info: #35c9ff;
--accent-success: #35d98f;
--accent-warning: #ffb24a;
--accent-danger: #ff4c72;
/* Glows */
--glow-info: 0 0 20px rgba(53, 201, 255, 0.3);
--glow-success: 0 0 20px rgba(53, 217, 143, 0.3);
/* Graph */
--graph-node-default: rgba(48, 46, 44, 0.8);
--graph-node-epic: rgba(53, 201, 255, 0.15);
--graph-edge-default: rgba(180, 175, 165, 0.3);
--graph-edge-selected: #35c9ff;
/* Alphas */
--alpha-white-low: rgba(240, 238, 234, 0.05);
--alpha-white-medium: rgba(240, 238, 234, 0.1);
--alpha-black-medium: rgba(0, 0, 0, 0.4);
}
```
### Midnight Theme (Future)
```css
[data-theme="midnight"] {
--surface-backdrop: #0a0a0f;
--surface-elevated: #050508;
--surface-primary: #111118;
--surface-secondary: #151520;
--surface-quaternary: #1e1e2e;
--accent-info: #8b5cf6;
--accent-success: #10b981;
/* Same structure, different values */
}
```
---
## Migration Strategy
### Phase 1: Create Token System
1. Create `src/styles/themes/index.css` with token definitions
2. Create `src/styles/themes/tokens.css` with token names
3. Add data-theme attribute to layout
### Phase 2: Component Audit & Migration
For each component:
1. Replace hardcoded colors with semantic tokens
2. Replace `bg-white/5` with `bg-[var(--alpha-white-low)]`
3. Replace `bg-[#0a111a]` with appropriate surface token
### Phase 3: Graph/Flow Colors
1. Extract all graph colors to `--graph-*` tokens
2. Update ReactFlow styles to use CSS variables
### Phase 4: Validation
1. Create theme preview page showing all tokens
2. Verify no hardcoded colors remain
---
## Usage Examples
### Before (Chaos):
```tsx
<div className="bg-[#0a111a] border border-white/10">
<span className="text-[#a8a49a]">Text</span>
</div>
```
### After (Clean):
```tsx
<div className="bg-[var(--surface-tertiary)] border border-[var(--border-default)]">
<span className="text-[var(--text-tertiary)]">Text</span>
</div>
```
### With Tailwind utilities (even cleaner):
```tsx
<div className="surface-tertiary border-default">
<span className="text-tertiary">Text</span>
</div>
```
---
## Component Mapping Guide
| Component | Current | New Token |
|-----------|---------|-----------|
| TopBar | `bg-[var(--ui-bg-header)]` | `bg-[var(--surface-elevated)]` |
| LeftPanel | `bg-[var(--ui-bg-shell)]` | `bg-[var(--surface-primary)]` |
| Main content | `bg-[var(--ui-bg-main)]` | `bg-[var(--surface-secondary)]` |
| SocialCard | `bg-[var(--ui-bg-card)]` | `bg-[var(--surface-quaternary)]` |
| AssignmentPanel | `bg-[#0a111a]` | `bg-[var(--surface-tertiary)]` |
| Modal/Drawer | `bg-[#0d0c0b]` | `bg-[var(--surface-overlay)]` |
| Input fields | `bg-[#0f1824]` | `bg-[var(--surface-input)]` |
---
## Files That Need Migration (Priority Order)
### HIGH (Core UI):
1. `src/app/globals.css` - Define tokens
2. `src/components/shared/unified-shell.tsx` - Main layout
3. `src/components/shared/top-bar.tsx` - Header
4. `src/components/shared/left-panel.tsx` - Sidebar
5. `src/components/shared/right-panel.tsx` - Right panel
6. `src/components/social/social-card.tsx` - Cards
### MEDIUM (Active Views):
7. `src/components/graph/assignment-panel.tsx` - Heavy hardcoded colors
8. `src/components/graph/graph-node-card.tsx` - Graph nodes
9. `src/components/activity/swarm-command-feed.tsx` - Activity feed
10. `src/components/graph/smart-dag.tsx` - Graph background
### LOWER (Secondary):
11. All modal/dialog components
12. All form/input components
13. Kanban components (if still used)
14. Swarm components
---
## Success Criteria
- [ ] Zero hardcoded hex colors in components (except for data viz)
- [ ] Zero `bg-white/X` or `bg-black/X` - all use `--alpha-*` tokens
- [ ] Theme switcher works instantly without reload
- [ ] All 12 token categories have values for each theme
- [ ] Visual regression test passes (no unintended changes)
---
## For You (The Human)
Once this is implemented, you can just say:
> "Change the sidebar to be slightly lighter in the aurora theme"
And I'll know exactly where to go:
```css
[data-theme="aurora"] {
--surface-primary: #252422; /* Changed from #1f1e1d */
}
```
Or:
> "Make the aurora glow more subtle"
```css
[data-theme="aurora"] {
--glow-info: 0 0 12px rgba(53, 201, 255, 0.15); /* Reduced from 20px/0.3 */
}
```
Everything in one place. No hunting through 67 files.
# Comprehensive Theme System Design
## The Problem
We have colors scattered across 67+ files:
- Hardcoded hex: `bg-[#0a111a]`, `bg-[#111f2b]`, `bg-[#14202e]`
- Inline styles: `style={{ backgroundColor: '#1a2d3d' }}`
- Arbitrary Tailwind: `bg-white/5`, `border-white/10`
- Mixed variable systems: `--ui-bg-*`, `--color-bg-*`, etc.
## The Solution: Unified Theme System
### File Structure
```
src/styles/
themes/
index.css ← Theme definitions + data-attribute switching
tokens.css ← Base CSS variable names (no values)
components/
surfaces.css ← Surface layer utilities
interactions.css ← Hover, focus, active states
```
### Token Architecture (12 Semantic Categories)
#### 1. SURFACE LAYERS (Backgrounds)
```css
--surface-backdrop: /* Page background */
--surface-elevated: /* Header - sits on top */
--surface-primary: /* Left sidebar */
--surface-secondary: /* Main content area */
--surface-tertiary: /* Panels/cards within sidebars */
--surface-quaternary: /* Cards */
--surface-overlay: /* Modals, dropdowns, drawers */
--surface-input: /* Form fields, inputs */
--surface-hover: /* Hover states */
--surface-active: /* Active/selected states */
--surface-tooltip: /* Tooltips, popovers */
```
#### 2. BORDERS
```css
--border-subtle: /* Dividers between sections */
--border-default: /* Card borders */
--border-strong: /* Focus rings, selected states */
--border-accent: /* Colored status borders */
```
#### 3. TEXT
```css
--text-primary: /* Headlines, important text */
--text-secondary: /* Body text */
--text-tertiary: /* Muted, hints */
--text-disabled: /* Disabled elements */
--text-inverse: /* Text on colored backgrounds */
```
#### 4. ACCENTS (Functional)
```css
--accent-info: /* Cyan - links, actions */
--accent-success: /* Green - ready, done */
--accent-warning: /* Amber - in progress */
--accent-danger: /* Red - blocked, errors */
```
#### 5. ACCENTS (Aurora Glow)
```css
--glow-info: /* Box-shadow glow for info */
--glow-success: /* Box-shadow glow for success */
--glow-warning: /* Box-shadow glow for warning */
--glow-danger: /* Box-shadow glow for danger */
```
#### 6. GRAPH COLORS
```css
--graph-node-default: /* Default node background */
--graph-node-epic: /* Epic node accent */
--graph-edge-default: /* Default edge color */
--graph-edge-selected: /* Selected edge color */
--graph-edge-cycle: /* Cycle warning color */
```
#### 7. SEMANTIC ALPHAS
Instead of `bg-white/5` and `bg-black/40`, use themeable alphas:
```css
--alpha-white-low: /* 5% white */
--alpha-white-medium: /* 10% white */
--alpha-white-high: /* 20% white */
--alpha-black-low: /* 10% black */
--alpha-black-medium: /* 40% black */
--alpha-black-high: /* 80% black */
```
#### 8. STATUS COLORS
```css
--status-ready: /* Ready/open status */
--status-in-progress: /* In progress status */
--status-blocked: /* Blocked status */
--status-closed: /* Closed/done status */
--status-deferred: /* Deferred status */
```
#### 9. SHADOWS
```css
--shadow-sm: /* Subtle elevation */
--shadow-md: /* Cards */
--shadow-lg: /* Modals, drawers */
--shadow-glow-info: /* Aurora glow */
--shadow-glow-success: /* Aurora glow */
--shadow-glow-warning: /* Aurora glow */
--shadow-glow-danger: /* Aurora glow */
```
#### 10. AGENT/ROLE COLORS
```css
--agent-role-ui: /* UI role color */
--agent-role-graph: /* Graph role color */
--agent-role-orchestrator: /* Orchestrator role */
--agent-role-researcher: /* Researcher role */
```
#### 11. SCROLLBARS
```css
--scrollbar-track: /* Scrollbar track */
--scrollbar-thumb: /* Scrollbar thumb */
--scrollbar-thumb-hover: /* Scrollbar thumb hover */
```
#### 12. CODE/SYNTAX
```css
--code-background: /* Code block background */
--code-text: /* Code text color */
```
---
## Theme Definitions (Example)
### Aurora Theme (Current)
```css
[data-theme="aurora"] {
/* Surfaces - Warm Charcoal */
--surface-backdrop: #181716;
--surface-elevated: #131211;
--surface-primary: #1f1e1d;
--surface-secondary: #242322;
--surface-tertiary: #282725;
--surface-quaternary: #302e2c;
--surface-overlay: #0d0c0b;
/* Borders */
--border-subtle: rgba(180, 175, 165, 0.15);
--border-default: rgba(180, 175, 165, 0.25);
--border-strong: rgba(180, 175, 165, 0.4);
/* Text */
--text-primary: #f0eeea;
--text-secondary: #c9c5bc;
--text-tertiary: #a8a49a;
/* Accents */
--accent-info: #35c9ff;
--accent-success: #35d98f;
--accent-warning: #ffb24a;
--accent-danger: #ff4c72;
/* Glows */
--glow-info: 0 0 20px rgba(53, 201, 255, 0.3);
--glow-success: 0 0 20px rgba(53, 217, 143, 0.3);
/* Graph */
--graph-node-default: rgba(48, 46, 44, 0.8);
--graph-node-epic: rgba(53, 201, 255, 0.15);
--graph-edge-default: rgba(180, 175, 165, 0.3);
--graph-edge-selected: #35c9ff;
/* Alphas */
--alpha-white-low: rgba(240, 238, 234, 0.05);
--alpha-white-medium: rgba(240, 238, 234, 0.1);
--alpha-black-medium: rgba(0, 0, 0, 0.4);
}
```
### Midnight Theme (Future)
```css
[data-theme="midnight"] {
--surface-backdrop: #0a0a0f;
--surface-elevated: #050508;
--surface-primary: #111118;
--surface-secondary: #151520;
--surface-quaternary: #1e1e2e;
--accent-info: #8b5cf6;
--accent-success: #10b981;
/* Same structure, different values */
}
```
---
## Migration Strategy
### Phase 1: Create Token System
1. Create `src/styles/themes/index.css` with token definitions
2. Create `src/styles/themes/tokens.css` with token names
3. Add data-theme attribute to layout
### Phase 2: Component Audit & Migration
For each component:
1. Replace hardcoded colors with semantic tokens
2. Replace `bg-white/5` with `bg-[var(--alpha-white-low)]`
3. Replace `bg-[#0a111a]` with appropriate surface token
### Phase 3: Graph/Flow Colors
1. Extract all graph colors to `--graph-*` tokens
2. Update ReactFlow styles to use CSS variables
### Phase 4: Validation
1. Create theme preview page showing all tokens
2. Verify no hardcoded colors remain
---
## Usage Examples
### Before (Chaos):
```tsx
<div className="bg-[#0a111a] border border-white/10">
<span className="text-[#a8a49a]">Text</span>
</div>
```
### After (Clean):
```tsx
<div className="bg-[var(--surface-tertiary)] border border-[var(--border-default)]">
<span className="text-[var(--text-tertiary)]">Text</span>
</div>
```
### With Tailwind utilities (even cleaner):
```tsx
<div className="surface-tertiary border-default">
<span className="text-tertiary">Text</span>
</div>
```
---
## Component Mapping Guide
| Component | Current | New Token |
|-----------|---------|-----------|
| TopBar | `bg-[var(--ui-bg-header)]` | `bg-[var(--surface-elevated)]` |
| LeftPanel | `bg-[var(--ui-bg-shell)]` | `bg-[var(--surface-primary)]` |
| Main content | `bg-[var(--ui-bg-main)]` | `bg-[var(--surface-secondary)]` |
| SocialCard | `bg-[var(--ui-bg-card)]` | `bg-[var(--surface-quaternary)]` |
| AssignmentPanel | `bg-[#0a111a]` | `bg-[var(--surface-tertiary)]` |
| Modal/Drawer | `bg-[#0d0c0b]` | `bg-[var(--surface-overlay)]` |
| Input fields | `bg-[#0f1824]` | `bg-[var(--surface-input)]` |
---
## Files That Need Migration (Priority Order)
### HIGH (Core UI):
1. `src/app/globals.css` - Define tokens
2. `src/components/shared/unified-shell.tsx` - Main layout
3. `src/components/shared/top-bar.tsx` - Header
4. `src/components/shared/left-panel.tsx` - Sidebar
5. `src/components/shared/right-panel.tsx` - Right panel
6. `src/components/social/social-card.tsx` - Cards
### MEDIUM (Active Views):
7. `src/components/graph/assignment-panel.tsx` - Heavy hardcoded colors
8. `src/components/graph/graph-node-card.tsx` - Graph nodes
9. `src/components/activity/swarm-command-feed.tsx` - Activity feed
10. `src/components/graph/smart-dag.tsx` - Graph background
### LOWER (Secondary):
11. All modal/dialog components
12. All form/input components
13. Kanban components (if still used)
14. Swarm components
---
## Success Criteria
- [ ] Zero hardcoded hex colors in components (except for data viz)
- [ ] Zero `bg-white/X` or `bg-black/X` - all use `--alpha-*` tokens
- [ ] Theme switcher works instantly without reload
- [ ] All 12 token categories have values for each theme
- [ ] Visual regression test passes (no unintended changes)
---
## For You (The Human)
Once this is implemented, you can just say:
> "Change the sidebar to be slightly lighter in the aurora theme"
And I'll know exactly where to go:
```css
[data-theme="aurora"] {
--surface-primary: #252422; /* Changed from #1f1e1d */
}
```
Or:
> "Make the aurora glow more subtle"
```css
[data-theme="aurora"] {
--glow-info: 0 0 12px rgba(53, 201, 255, 0.15); /* Reduced from 20px/0.3 */
}
```
Everything in one place. No hunting through 67 files.

View file

@ -257,4 +257,4 @@
- Mutations executed only via `bd.exe`
- Real-time updates delivered via SSE
- Kanban, Graph, Timeline, Agent Session views functional
- Boundary guard test prevents direct JSONL writes
- Boundary guard test prevents direct JSONL writes

View file

@ -159,4 +159,4 @@ Current Beads ecosystem tools are often Unix/macOS oriented, creating friction f
- Reads from `.beads/issues.jsonl` successfully for registered projects
- All writes performed via `bd.exe` and reflected back via watcher/SSE
- Kanban, Timeline, Graph, and Agent Session views function against real bead data
- No direct `issues.jsonl` write implementation exists in app code
- No direct `issues.jsonl` write implementation exists in app code

View file

@ -1,134 +1,134 @@
# BeadBoard Kanban Design System Plan
**Goal**
Ship a production-ready baseline visual system for Tracer Bullet 1 (Kanban) before further feature expansion.
**Primary decision**
Use **Tailwind CSS v4 + CSS tokens (`@theme`) + Framer Motion**.
## 1. Why This Stack
### Tailwind v4 is the right baseline
- Fastest path to a coherent, reusable system in Next.js 15.
- CSS-first token model (`@theme`) fits our need for semantic design tokens.
- Lets us avoid scattered inline styles and ad-hoc CSS files.
### Framer Motion should be scoped
- Use for state transitions (card changes, panel enter/exit, filtered results).
- Avoid decorative over-animation that hurts readability in a dense dashboard.
### Risks and mitigations
- Risk: “generic Tailwind look”
- Mitigation: strict token palette + component contracts + typography rules.
- Risk: visual inconsistency
- Mitigation: no direct color literals in component markup except token definitions.
## 2. Baseline-First Sequencing
This should happen **now**, not later.
1. Foundation (tokens, layout, core components)
2. Motion and interaction polish
3. Accessibility and responsive hardening
4. Continue other tracer bullets
## 3. Visual Language (v1)
### Product feel
- High-signal operations UI.
- Calm neutral surfaces with sharp status accents.
- Dense information without visual clutter.
### Typography
- Primary UI: `DM Sans` (or `Inter` fallback decision at implementation time)
- Metadata/IDs: `JetBrains Mono`
### Color model
- Semantic tokens only:
- `background`, `foreground`, `surface`, `muted`
- `status-open`, `status-in-progress`, `status-blocked`, `status-deferred`, `status-closed`
- `priority-p0` ... `priority-p4`
- Contrast target: at least WCAG AA for normal text.
## 4. Component Contract
Required first-class components:
- `KanbanPageShell`
- `KanbanControls`
- `KanbanBoard`
- `KanbanColumn`
- `KanbanCard`
- `KanbanDetailPanel`
- shared: `Badge`, `Chip`, `StatPill`
Rules:
- Component variants defined via class composition (CVA optional but preferred).
- No inline style objects for production components.
- All spacing/radius/shadow/color come from tokens/utilities.
## 5. Layout Contract
### Desktop
- Sticky top header with filters + stats.
- Main grid: board + detail panel.
- Columns scroll horizontally as needed.
### Mobile
- Stacked controls.
- Board in horizontal swipe/scroll mode.
- Detail panel becomes full-screen drawer.
## 6. Motion Contract (Framer Motion)
Use motion for:
- Card appear/disappear on filtering.
- Detail panel slide-in/out.
- Subtle status count transitions.
Do not animate:
- Global page container on every render.
- Constant hover effects that reduce legibility/performance.
## 7. Tailwind v4 Implementation Plan
### Phase A: Design System Foundation (P0)
- Add Tailwind v4 pipeline with `@import "tailwindcss"` in global stylesheet.
- Define `@theme` token set (colors, radius, spacing aliases, shadows, motion tokens).
- Add base layer typography/background defaults.
- Replace inline styles in tracer-1 components with tokenized Tailwind classes.
Acceptance criteria:
- No inline style usage in `src/components/kanban/*` and shared primitives (except truly dynamic edge cases).
- UI at `localhost:3000` has coherent baseline styling.
### Phase B: Motion + Interaction Polish (P1)
- Integrate Framer Motion transitions for board and panel.
- Improve visual hierarchy of card metadata.
- Add polished empty/loading/error states.
Acceptance criteria:
- Motion communicates state changes without jitter.
- Filtering and detail interactions feel intentional.
### Phase C: Accessibility + Responsive Hardening (P1)
- Keyboard focus and traversal for cards/panel.
- Verify color contrast and focus visibility.
- Tune mobile breakpoints and touch targets.
Acceptance criteria:
- Keyboard-only flow works for core Kanban actions.
- Mobile experience is usable and visually consistent.
## 8. Technical Boundaries
- Read path remains `.beads/issues.jsonl` / `.beads/issues.jsonl.new`.
- No direct write path to JSONL.
- Styling changes must not alter read/write boundary behavior.
## 9. Definition of Done (Tracer-1 Design Baseline)
- Tailwind v4 configured and used as primary styling framework.
- Tokenized design system applied across tracer-1 Kanban components.
- Framer Motion integrated for key transitions.
- Tests/typecheck pass, app runs on `localhost:3000`.
- Visual result is clearly beyond prototype/demo quality.
# BeadBoard Kanban Design System Plan
**Goal**
Ship a production-ready baseline visual system for Tracer Bullet 1 (Kanban) before further feature expansion.
**Primary decision**
Use **Tailwind CSS v4 + CSS tokens (`@theme`) + Framer Motion**.
## 1. Why This Stack
### Tailwind v4 is the right baseline
- Fastest path to a coherent, reusable system in Next.js 15.
- CSS-first token model (`@theme`) fits our need for semantic design tokens.
- Lets us avoid scattered inline styles and ad-hoc CSS files.
### Framer Motion should be scoped
- Use for state transitions (card changes, panel enter/exit, filtered results).
- Avoid decorative over-animation that hurts readability in a dense dashboard.
### Risks and mitigations
- Risk: “generic Tailwind look”
- Mitigation: strict token palette + component contracts + typography rules.
- Risk: visual inconsistency
- Mitigation: no direct color literals in component markup except token definitions.
## 2. Baseline-First Sequencing
This should happen **now**, not later.
1. Foundation (tokens, layout, core components)
2. Motion and interaction polish
3. Accessibility and responsive hardening
4. Continue other tracer bullets
## 3. Visual Language (v1)
### Product feel
- High-signal operations UI.
- Calm neutral surfaces with sharp status accents.
- Dense information without visual clutter.
### Typography
- Primary UI: `DM Sans` (or `Inter` fallback decision at implementation time)
- Metadata/IDs: `JetBrains Mono`
### Color model
- Semantic tokens only:
- `background`, `foreground`, `surface`, `muted`
- `status-open`, `status-in-progress`, `status-blocked`, `status-deferred`, `status-closed`
- `priority-p0` ... `priority-p4`
- Contrast target: at least WCAG AA for normal text.
## 4. Component Contract
Required first-class components:
- `KanbanPageShell`
- `KanbanControls`
- `KanbanBoard`
- `KanbanColumn`
- `KanbanCard`
- `KanbanDetailPanel`
- shared: `Badge`, `Chip`, `StatPill`
Rules:
- Component variants defined via class composition (CVA optional but preferred).
- No inline style objects for production components.
- All spacing/radius/shadow/color come from tokens/utilities.
## 5. Layout Contract
### Desktop
- Sticky top header with filters + stats.
- Main grid: board + detail panel.
- Columns scroll horizontally as needed.
### Mobile
- Stacked controls.
- Board in horizontal swipe/scroll mode.
- Detail panel becomes full-screen drawer.
## 6. Motion Contract (Framer Motion)
Use motion for:
- Card appear/disappear on filtering.
- Detail panel slide-in/out.
- Subtle status count transitions.
Do not animate:
- Global page container on every render.
- Constant hover effects that reduce legibility/performance.
## 7. Tailwind v4 Implementation Plan
### Phase A: Design System Foundation (P0)
- Add Tailwind v4 pipeline with `@import "tailwindcss"` in global stylesheet.
- Define `@theme` token set (colors, radius, spacing aliases, shadows, motion tokens).
- Add base layer typography/background defaults.
- Replace inline styles in tracer-1 components with tokenized Tailwind classes.
Acceptance criteria:
- No inline style usage in `src/components/kanban/*` and shared primitives (except truly dynamic edge cases).
- UI at `localhost:3000` has coherent baseline styling.
### Phase B: Motion + Interaction Polish (P1)
- Integrate Framer Motion transitions for board and panel.
- Improve visual hierarchy of card metadata.
- Add polished empty/loading/error states.
Acceptance criteria:
- Motion communicates state changes without jitter.
- Filtering and detail interactions feel intentional.
### Phase C: Accessibility + Responsive Hardening (P1)
- Keyboard focus and traversal for cards/panel.
- Verify color contrast and focus visibility.
- Tune mobile breakpoints and touch targets.
Acceptance criteria:
- Keyboard-only flow works for core Kanban actions.
- Mobile experience is usable and visually consistent.
## 8. Technical Boundaries
- Read path remains `.beads/issues.jsonl` / `.beads/issues.jsonl.new`.
- No direct write path to JSONL.
- Styling changes must not alter read/write boundary behavior.
## 9. Definition of Done (Tracer-1 Design Baseline)
- Tailwind v4 configured and used as primary styling framework.
- Tokenized design system applied across tracer-1 Kanban components.
- Framer Motion integrated for key transitions.
- Tests/typecheck pass, app runs on `localhost:3000`.
- Visual result is clearly beyond prototype/demo quality.

View file

@ -1,52 +1,52 @@
# Project Context Model Design
## Summary
Aggregate views need stable project identity attached to each issue so cross-project Kanban, timeline, and session views can filter and display project metadata consistently. This design adds a normalized `ProjectContext` payload to every issue returned from read flows while keeping the raw JSONL format untouched.
## Requirements
- Use existing Windows-safe path normalization for stable identity.
- Attach project identity on every issue returned from read services.
- Include fields: `key`, `root`, `displayPath`, `name`, `source`, `addedAt`.
- Default single-project reads to `source="local"` and `addedAt=null`.
## Data Model
```ts
export type ProjectSource = 'local' | 'registry' | 'scanner';
export interface ProjectContext {
key: string; // windowsPathKey(root)
root: string; // canonicalizeWindowsPath(root)
displayPath: string; // toDisplayPath(root)
name: string; // path.basename(root)
source: ProjectSource;
addedAt: string | null;
}
export type BeadIssueWithProject = BeadIssue & { project: ProjectContext };
```
## Construction
- Add a helper (e.g., `buildProjectContext`) that accepts `projectRoot`, `source`, and `addedAt`.
- Normalize the root with `canonicalizeWindowsPath`, compute the key with `windowsPathKey`, display path with `toDisplayPath`, and name from `path.basename`.
- No filesystem checks are required; this is identity metadata only.
## Read Flow Integration
- Update `readIssuesFromDisk` to attach `project` to each parsed issue.
- Default `projectRoot` to `process.cwd()` when not provided.
- Keep the existing `BeadIssue` shape for raw parsing; project context is added in read services only.
## Error Handling
- If `projectRoot` is empty, throw a clear error early in `buildProjectContext`.
- Otherwise, treat normalization as pure string ops and do not swallow exceptions.
## Tests
- Add unit tests for `buildProjectContext` field derivation (key/root/displayPath/name/source/addedAt).
- Update `readIssuesFromDisk` tests to assert `project` is attached with expected fields.
## Alternatives Considered
1. **Wrapper object `{ project, issue }`**
Pro: explicit separation; Con: more refactors across UI filtering and query shapes.
2. **`metadata.project` on issues**
Pro: zero type changes; Con: weak typing and harder discoverability.
3. **Chosen: `issue.project` field**
Clear typing, predictable access, and minimal friction for UI + aggregate queries.
# Project Context Model Design
## Summary
Aggregate views need stable project identity attached to each issue so cross-project Kanban, timeline, and session views can filter and display project metadata consistently. This design adds a normalized `ProjectContext` payload to every issue returned from read flows while keeping the raw JSONL format untouched.
## Requirements
- Use existing Windows-safe path normalization for stable identity.
- Attach project identity on every issue returned from read services.
- Include fields: `key`, `root`, `displayPath`, `name`, `source`, `addedAt`.
- Default single-project reads to `source="local"` and `addedAt=null`.
## Data Model
```ts
export type ProjectSource = 'local' | 'registry' | 'scanner';
export interface ProjectContext {
key: string; // windowsPathKey(root)
root: string; // canonicalizeWindowsPath(root)
displayPath: string; // toDisplayPath(root)
name: string; // path.basename(root)
source: ProjectSource;
addedAt: string | null;
}
export type BeadIssueWithProject = BeadIssue & { project: ProjectContext };
```
## Construction
- Add a helper (e.g., `buildProjectContext`) that accepts `projectRoot`, `source`, and `addedAt`.
- Normalize the root with `canonicalizeWindowsPath`, compute the key with `windowsPathKey`, display path with `toDisplayPath`, and name from `path.basename`.
- No filesystem checks are required; this is identity metadata only.
## Read Flow Integration
- Update `readIssuesFromDisk` to attach `project` to each parsed issue.
- Default `projectRoot` to `process.cwd()` when not provided.
- Keep the existing `BeadIssue` shape for raw parsing; project context is added in read services only.
## Error Handling
- If `projectRoot` is empty, throw a clear error early in `buildProjectContext`.
- Otherwise, treat normalization as pure string ops and do not swallow exceptions.
## Tests
- Add unit tests for `buildProjectContext` field derivation (key/root/displayPath/name/source/addedAt).
- Update `readIssuesFromDisk` tests to assert `project` is attached with expected fields.
## Alternatives Considered
1. **Wrapper object `{ project, issue }`**
Pro: explicit separation; Con: more refactors across UI filtering and query shapes.
2. **`metadata.project` on issues**
Pro: zero type changes; Con: weak typing and harder discoverability.
3. **Chosen: `issue.project` field**
Clear typing, predictable access, and minimal friction for UI + aggregate queries.

View file

@ -1,139 +1,139 @@
# Multi-Project UI Contract (bb-6aj.6)
Date: 2026-02-13
Owner: `bb-6aj.6`
Scope: Convert existing registry/scanner backend into stable, user-facing project scope workflows for Kanban and Graph.
## 1) Product Workflow Contract
Primary user flow:
1. Select project scope (`local` or one registry project).
2. View project-scoped issues in Kanban and Graph using the same selected scope.
3. Manage registry roots (add/remove) from a single shared manager panel.
4. Discover import candidates from safe scan roots and add selected projects to registry.
5. (Later phase) Optionally switch to aggregate mode for cross-project read-only views.
Rules:
- Project scope is always explicit in URL query (`?project=`).
- Scope change affects reads only; mutations continue to target current scope root.
- Project scope must persist when navigating between `/` and `/graph`.
- No direct JSONL writes at any point.
## 2) Screen Ownership
Kanban (`/`):
- Primary triage and mutation workspace.
- Owns project scope picker entry point and registry manager entry.
- Displays selected project context in header.
Graph (`/graph`):
- Readability-first dependency exploration for selected scope.
- Shares same project scope query + model as Kanban.
- Must preserve current scope when linking back to Kanban.
Shared controls:
- Project scope resolver utility (server-safe).
- URL serialization/parsing for project selection.
- Scope badge/pill visual token (consistent across pages).
Out of scope for this contract:
- Timeline/session epics behavior changes.
- Full graph redesign beyond scope persistence/read correctness.
## 3) URL and State Contract
Query key:
- `project`: scope key string.
Key encoding:
- `local`: current workspace (`process.cwd()`).
- registry project: `windowsPathKey(project.path)` derived from registry entry.
Resolution behavior:
1. Build scope options: `local` + registry projects (dedup by key).
2. If `project` query matches an option key, use that root.
3. If missing or invalid, fallback to `local`.
4. Reads use resolved root; returned issues include resolved `project` context.
Navigation behavior:
- `Kanban -> Graph` carries `?project=<key>`.
- `Graph -> Kanban` carries `?project=<key>`.
- Any scope picker action rewrites URL query without losing active route.
## 4) Aggregate Mode Contract (Deferred to bb-6aj.11)
- Aggregate mode is read-only across multiple project roots.
- Aggregate mode does not become default.
- Aggregate mode must visually mark per-project source on each card/row.
- Mutations from aggregate mode are disabled until explicit target scope is chosen.
## 5) Empty and Error States
No projects in registry:
- Show local project as selected.
- Show non-blocking empty hint in manager panel.
Invalid query key:
- Fallback to local scope.
- Keep page functional; do not hard fail.
Read failure for selected root:
- Preserve selected scope in UI.
- Show actionable error card with path and retry affordance.
Scanner failures:
- Show root-level failure summary with skipped/error counts.
- Do not alter current selection automatically.
## 6) Phased Execution Plan
Phase A (`bb-6aj.7`): Shared scope model + URL persistence
- Add server utility to resolve active scope from query + registry.
- Wire `/` and `/graph` to resolved scope.
- Ensure cross-links preserve `?project=`.
Phase B (`bb-6aj.8`): Registry manager panel
- List registry projects with add/remove actions.
- Validate Windows absolute paths with clear error text.
Phase C (`bb-6aj.9`): Scanner UX
- Scan safe roots with mode/depth controls.
- Allow selective import to registry.
Phase D (`bb-6aj.10`): Project-scoped reads in core views
- Ensure all read endpoints/components use selected scope root.
- Validate no regressions in local-only flow.
Phase E (`bb-6aj.11`): Aggregate mode
- Add cross-project read view with project badges.
- Keep mutations disabled without explicit project selection.
Phase F (`bb-6aj.12`): Verification and guardrails
- Typecheck + tests + Playwright evidence at required breakpoints.
## 7) Acceptance Criteria Matrix
Functional:
- Same `project` key yields same root and same issue set on both pages.
- Invalid `project` key falls back to local root cleanly.
- Route transitions preserve selected scope.
Boundary safety:
- No direct `.beads/issues.jsonl` writes.
- Existing mutation API boundaries unchanged.
Verification:
- Unit tests for scope resolution and URL behavior.
- Existing tests remain green.
- Playwright captures prove scope persistence on `/` and `/graph`.
## 8) Risks and Mitigations
Risk: Query value leaks absolute paths.
- Mitigation: use opaque normalized key, not raw path.
Risk: Registry drift vs URL key stale.
- Mitigation: deterministic fallback to local + visible selected-scope indicator.
Risk: UX churn from adding controls too early.
- Mitigation: enforce phase order and keep Phase A minimal.
# Multi-Project UI Contract (bb-6aj.6)
Date: 2026-02-13
Owner: `bb-6aj.6`
Scope: Convert existing registry/scanner backend into stable, user-facing project scope workflows for Kanban and Graph.
## 1) Product Workflow Contract
Primary user flow:
1. Select project scope (`local` or one registry project).
2. View project-scoped issues in Kanban and Graph using the same selected scope.
3. Manage registry roots (add/remove) from a single shared manager panel.
4. Discover import candidates from safe scan roots and add selected projects to registry.
5. (Later phase) Optionally switch to aggregate mode for cross-project read-only views.
Rules:
- Project scope is always explicit in URL query (`?project=`).
- Scope change affects reads only; mutations continue to target current scope root.
- Project scope must persist when navigating between `/` and `/graph`.
- No direct JSONL writes at any point.
## 2) Screen Ownership
Kanban (`/`):
- Primary triage and mutation workspace.
- Owns project scope picker entry point and registry manager entry.
- Displays selected project context in header.
Graph (`/graph`):
- Readability-first dependency exploration for selected scope.
- Shares same project scope query + model as Kanban.
- Must preserve current scope when linking back to Kanban.
Shared controls:
- Project scope resolver utility (server-safe).
- URL serialization/parsing for project selection.
- Scope badge/pill visual token (consistent across pages).
Out of scope for this contract:
- Timeline/session epics behavior changes.
- Full graph redesign beyond scope persistence/read correctness.
## 3) URL and State Contract
Query key:
- `project`: scope key string.
Key encoding:
- `local`: current workspace (`process.cwd()`).
- registry project: `windowsPathKey(project.path)` derived from registry entry.
Resolution behavior:
1. Build scope options: `local` + registry projects (dedup by key).
2. If `project` query matches an option key, use that root.
3. If missing or invalid, fallback to `local`.
4. Reads use resolved root; returned issues include resolved `project` context.
Navigation behavior:
- `Kanban -> Graph` carries `?project=<key>`.
- `Graph -> Kanban` carries `?project=<key>`.
- Any scope picker action rewrites URL query without losing active route.
## 4) Aggregate Mode Contract (Deferred to bb-6aj.11)
- Aggregate mode is read-only across multiple project roots.
- Aggregate mode does not become default.
- Aggregate mode must visually mark per-project source on each card/row.
- Mutations from aggregate mode are disabled until explicit target scope is chosen.
## 5) Empty and Error States
No projects in registry:
- Show local project as selected.
- Show non-blocking empty hint in manager panel.
Invalid query key:
- Fallback to local scope.
- Keep page functional; do not hard fail.
Read failure for selected root:
- Preserve selected scope in UI.
- Show actionable error card with path and retry affordance.
Scanner failures:
- Show root-level failure summary with skipped/error counts.
- Do not alter current selection automatically.
## 6) Phased Execution Plan
Phase A (`bb-6aj.7`): Shared scope model + URL persistence
- Add server utility to resolve active scope from query + registry.
- Wire `/` and `/graph` to resolved scope.
- Ensure cross-links preserve `?project=`.
Phase B (`bb-6aj.8`): Registry manager panel
- List registry projects with add/remove actions.
- Validate Windows absolute paths with clear error text.
Phase C (`bb-6aj.9`): Scanner UX
- Scan safe roots with mode/depth controls.
- Allow selective import to registry.
Phase D (`bb-6aj.10`): Project-scoped reads in core views
- Ensure all read endpoints/components use selected scope root.
- Validate no regressions in local-only flow.
Phase E (`bb-6aj.11`): Aggregate mode
- Add cross-project read view with project badges.
- Keep mutations disabled without explicit project selection.
Phase F (`bb-6aj.12`): Verification and guardrails
- Typecheck + tests + Playwright evidence at required breakpoints.
## 7) Acceptance Criteria Matrix
Functional:
- Same `project` key yields same root and same issue set on both pages.
- Invalid `project` key falls back to local root cleanly.
- Route transitions preserve selected scope.
Boundary safety:
- No direct `.beads/issues.jsonl` writes.
- Existing mutation API boundaries unchanged.
Verification:
- Unit tests for scope resolution and URL behavior.
- Existing tests remain green.
- Playwright captures prove scope persistence on `/` and `/graph`.
## 8) Risks and Mitigations
Risk: Query value leaks absolute paths.
- Mitigation: use opaque normalized key, not raw path.
Risk: Registry drift vs URL key stale.
- Mitigation: deterministic fallback to local + visible selected-scope indicator.
Risk: UX churn from adding controls too early.
- Mitigation: enforce phase order and keep Phase A minimal.

View file

@ -1,5 +1,5 @@
# Unified UX PRD - Swimlane Social Hub
# Unified UX PRD - Swimlane Social Hub
> **Version**: 2.0
> **Date**: 2026-02-16
> **Status**: UPDATED - Complete Design Specification
@ -19,356 +19,356 @@
### Phase 1-3: Not Started
- Planning complete, implementation pending Phase 0 completion
---
## Executive Summary
### Problem
BeadBoard has 4 fragmented pages with no shared navigation, no shared state, and inconsistent design language. The current Aero Chrome glass-morphism visual style has been rejected by users. Users want ONE cohesive experience for supervising multi-agent teams and managing tasks.
### Solution
Single unified shell at `/` with 4 switchable views (Social Feed, Swimlanes, Graph, Timeline), new earthy-dark design system, agent-prominent UX, and thoughtful interaction patterns throughout.
---
## Key Decisions (Immutable)
| # | Decision | Choice | Rationale |
|---|----------|--------|-----------|
| 1 | Routing | Single page + client tabs at / | Preserves selection state, panels never unmount |
| 2 | State Source | URL is Single Source of Truth | Prevents race conditions |
| 3 | Activity Feed | Context-aware (filters to selection) | Most useful for supervision workflow |
| 4 | Mobile | Hamburger left + slide-over right + bottom tabs | Standard pattern |
| 5 | Build Order | Tokens → Shell → Views (tracer bullet) | Real dependency chain |
| 6 | Card Interaction | Selection + detail strip below grid (desktop) | Grid stays uniform, split-view for conversation |
| 7 | Mobile Detail | Full-screen overlay (not split) | Keyboard takes 40% of screen |
| 8 | Visual Style | Earthy-dark design system (NOT Aero Chrome) | User provided full token spec |
| 9 | Agent Presence | Prominent - agents are the star | Avatars on every card, role-colored borders |
| 10 | Left Panel | Minimal with counts, nested epic tree | Status dots, hover tooltips |
| 11 | Card View-Jump | Small icons at card bottom | Jump to views with task pre-selected |
| 12 | Units | rem-based | Accessibility |
---
## Design Token Specification
### Color Palette
**Backgrounds:**
```css
--color-bg-base: #2D2D2D /* primary background */
--color-bg-card: #363636 /* cards, elevated surfaces */
--color-bg-input: #404040 /* inputs, hover states */
```
**Accents:**
```css
--color-accent-green: #7CB97A /* primary CTA, success, in-progress */
--color-accent-amber: #D4A574 /* warning, blocked */
--color-accent-teal: #5BA8A0 /* secondary, open/ready */
```
**Text:**
```css
--color-text-primary: #FFFFFF
--color-text-secondary: #B8B8B8
--color-text-muted: #888888
--color-text-on-primary: #1A1A1A
```
**Borders:**
```css
--color-border-default: #4A4A4A
--color-border-subtle: #3A3A3A
```
**Status Mapping:**
- open/ready → teal `#5BA8A0`
- in_progress → green `#7CB97A`
- blocked → amber `#D4A574`
- closed → muted `#888888`
**Agent Role Colors:**
- ui → `#6B9BD2` (steel blue)
- graph → `#7CB97A` (green)
- orchestrator → `#B08ED6` (soft purple)
- agent → `#B8B8B8` (neutral)
- researcher → `#D4A574` (amber)
**Liveness Colors:**
- active → `#7CB97A` (green, pulsing)
- stale → `#D4A574` (amber)
- evicted → `#C97A7A` (muted rose)
- idle → `#888888` (muted)
### Radii
```css
--radius-sm: 0.375rem /* 6px */
--radius-card: 0.625rem /* 10px */
--radius-modal: 1rem /* 16px */
--radius-pill: 9999px
```
### Shadows
```css
--shadow-sm: 0 1px 2px rgba(0,0,0,0.1)
--shadow-md: 0 4px 12px rgba(0,0,0,0.15)
```
### Typography
- Font: system sans-serif (Inter if available)
- H1: 2rem/700, H2: 1.5rem/600, H3: 1.125rem/600
- Body: 0.875rem/400, Small: 0.75rem/400, Tiny: 0.6875rem/500
- Line-height: headings 1.2, body 1.5
### Spacing
- Base: 0.25rem (4px)
- Card padding: 1rem-1.25rem
- Gaps: 1rem
- Section gaps: 2rem-2.5rem
### Icons & Transitions
- Icons: Lucide React, 1.5-2px stroke, 1rem-1.5rem size
- Transitions: 150-200ms ease-out for all hover/focus
---
## Component Anatomy
### Social Feed Card
```
┌─────────────────────────────────────┐
│ [⊕] (top-R)│ expand icon
│ │
│ bb-buff.1.1 │ task ID (tiny, teal)
│ Fix login bug on mobile │ title (bold, white)
│ │
│ UNLOCKS: │ blocked-by (ROSE tint)
│ ● #123 Blocker task │
│ │
│ BLOCKS: │ downstream (AMBER tint)
│ ● #234 Dependent task │
│ │
│ "Found the issue in the auth..." │ latest message (muted)
│ │
│ [●a-1] [●a-2] │ agent avatars (PROMINENT)
│ [≡] [◊] [≋]│ view-jump icons
└─────────────────────────────────────┘
```
**Card Specs:**
- Background: `#363636`
- Border: 1px status-colored (teal/green/amber/muted)
- Border-radius: 10px
- Status dot on card matches status mapping
- Agent avatars have **role-colored left border**
- Blocks/unlocks have tinted backgrounds (rose #E57373/10%, amber #D4A574/10%)
**Blocks/Unlocks Pattern (reuse from task-card-grid.tsx):**
```tsx
// Container
rounded-lg p-2 border border-white/5
// "Unlocks" header (rose tint)
text-[9px] font-bold uppercase tracking-widest text-rose-400/80
bg-rose-500/10 // background tint
// "Blocks" header (amber tint)
text-[9px] font-bold uppercase tracking-widest text-amber-400/80
bg-amber-500/10 // background tint
// Individual item
rounded border border-white/5 bg-white/5 px-2.5 py-2
hover:border-sky-400/30 hover:bg-white/10 transition-colors
```
### ZFC Agent State Visuals
| State | Visual |
|-------|--------|
| idle | `#888888` static dot |
| spawning | `#5BA8A0` pulsing dot |
| running | `#7CB97A` animated dot |
| working | `#7CB97A` pulsing glow |
| stuck | `#D4A574` attention dot (needs help!) |
| done | `#7CB97A` check |
| stopped | `#888888` no animation |
| dead | `#C97A7A` warning |
### Agent Card (Right Panel)
```
┌──────────────────────┐
│ [●avatar] agent-1 │ role-colored left border
│ role: ui │ role label
│ ● working · 2m ago │ ZFC state dot + age
│ Task: buff.1.1 │ current task
│ [≡] [◊] [≋] [💬] │ view-jump + message
└──────────────────────┘
```
### Swimlane Header
- Swarm name + computed counts: "3/8 done · 2 active · 1 ready · 1 blocked"
- Agent roster with ZFC state labels
- Collapsible
---
## Layout Architecture
### Shell Structure (CSS Grid)
```
┌──────────────────────────────────────────────────────────────────┐
│ TOP BAR (fixed, 3rem) │
│ ≡ [Swimlanes|Graph|Timeline|Social] ◢ │
├──────────┬──────────────────────────────────┬────────────────────┤
│ LEFT │ MIDDLE │ RIGHT │
│ 13.75rem │ flex-1 │ 17.5rem │
│ │ │ │
│ Channel │ View content (swaps on tab) │ Agents (~40%) │
│ tree │ │ ────────────────── │
│ │ │ Activity (~60%) │
└──────────┴──────────────────────────────────┴────────────────────┘
```
**Grid:** `grid-template-columns: 13.75rem 1fr 17.5rem`
### Detail Strip Behavior
**Desktop (≥1024px):**
- Grid splits: cards (~45%) | detail strip (~55%)
- Strip slides in below grid when card selected
- Cards remain visible above
**Mobile (<768px):**
- Full-screen overlay (z-index above bottom tabs)
- Required: virtual keyboard takes 40% of screen
- Split view would leave 0px for conversation
### Responsive Behavior
| Size | Left | Middle | Right | Detail Strip |
|------|------|--------|-------|--------------|
| Desktop (≥1024px) | 13.75rem fixed | flex-1 | 17.5rem fixed | Below grid |
| Tablet (768-1024px) | Overlay | flex-1 | Overlay | Slide-over |
| Mobile (<768px) | Overlay | flex-1 | Hidden | Full-screen |
---
## Anti-Patterns (Forbidden)
- NO glass-morphism / backdrop-blur effects
- NO arbitrary Tailwind color values (use tokens)
- NO agent-unaware cards (every card shows agents)
- NO page-per-view routing (use client tabs)
- NO localStorage for view state (use URL)
- NO direct JSONL writes (use bd CLI)
---
## Recommended Bead Structure
### Phase 0: Design Foundation
**Goal:** Tokens + Primitives only. No views.
**bb-ui2.1a** - Token System Update
- Update tokens.css with complete spec above
- Ensure all status/liveness/role colors defined
- Migrate away from Aero Chrome gradients
**bb-ui2.2a** - Card Primitive with Blocks/Unlocks
- Build reusable Card component
- Implement blocks/unlocks section pattern (reuse task-card-grid.tsx logic)
- Status-colored borders
- Soft gradient backgrounds (amber/teal tints, not harsh Aero Chrome)
**bb-ui2.3a** - Agent Avatar Primitive
- Avatar with role-colored ring
- ZFC state indicator (dot/pulse/glow)
- Size variants (sm, md, lg)
**bb-ui2.4a** - Status Utilities Update
- Rewrite status-utils.tsx for new tokens
- Status badge component with pill + dot
- Liveness indicator component
### Phase 1: Layout Polish
**Goal:** Fix current layout issues, preserve structure
**bb-ui2.22** - Detail Strip Positioning Fix
- Move from side drawer to below-grid (desktop)
- Full-screen overlay (mobile)
- Preserve URL state behavior
- Thread content actually shows selected bead data
**bb-ui2.23** - Activity Panel Polish
- Split right panel: Agents (40%) + Activity (60%)
- Agent cards with ZFC states
- Context-aware activity filtering
**bb-ui2.24** - Mobile Responsive Polish
- Bottom tab bar
- Panel overlays
- Touch-friendly targets
### Phase 2: Card Design Implementation
**Goal:** Implement complete card anatomy
**bb-ui2.25** - Social Feed Card Redesign
- Full card anatomy from spec
- Blocks/unlocks with rose/amber tints
- Prominent agent avatars
- View-jump icons
- Expand icon → full-page popup
**bb-ui2.26** - Swimlane Card Redesign
- Agent-first layout
- ZFC state prominent
- Status-colored border
- Drag-drop preserved
**bb-ui2.27** - Graph Node Redesign
- New design tokens
- Agent avatars on nodes
- Selection syncs with store
### Phase 3: Cross-Cutting Polish
**Goal:** Deep links, mobile, final gates
**bb-ui2.28** - Deep Link Verification
- All URL patterns work
- Browser back/forward
- Shareable URLs
**bb-ui2.29** - Screenshot Evidence
- All breakpoints
- All views
- Mobile + desktop
**bb-ui2.30** - Final Gates
- typecheck, lint, test
- Close epic
---
## Verification Strategy
After each bead:
```bash
npm run typecheck
npm run lint
npm run test
```
Visual verification:
- Screenshots at 390px, 768px, 1440px
- Compare against design spec
- Agent avatars visible on all cards
- Blocks/unlocks sections tinted correctly
---
*End of PRD v2.0 - Ready for Implementation*
---
## Executive Summary
### Problem
BeadBoard has 4 fragmented pages with no shared navigation, no shared state, and inconsistent design language. The current Aero Chrome glass-morphism visual style has been rejected by users. Users want ONE cohesive experience for supervising multi-agent teams and managing tasks.
### Solution
Single unified shell at `/` with 4 switchable views (Social Feed, Swimlanes, Graph, Timeline), new earthy-dark design system, agent-prominent UX, and thoughtful interaction patterns throughout.
---
## Key Decisions (Immutable)
| # | Decision | Choice | Rationale |
|---|----------|--------|-----------|
| 1 | Routing | Single page + client tabs at / | Preserves selection state, panels never unmount |
| 2 | State Source | URL is Single Source of Truth | Prevents race conditions |
| 3 | Activity Feed | Context-aware (filters to selection) | Most useful for supervision workflow |
| 4 | Mobile | Hamburger left + slide-over right + bottom tabs | Standard pattern |
| 5 | Build Order | Tokens → Shell → Views (tracer bullet) | Real dependency chain |
| 6 | Card Interaction | Selection + detail strip below grid (desktop) | Grid stays uniform, split-view for conversation |
| 7 | Mobile Detail | Full-screen overlay (not split) | Keyboard takes 40% of screen |
| 8 | Visual Style | Earthy-dark design system (NOT Aero Chrome) | User provided full token spec |
| 9 | Agent Presence | Prominent - agents are the star | Avatars on every card, role-colored borders |
| 10 | Left Panel | Minimal with counts, nested epic tree | Status dots, hover tooltips |
| 11 | Card View-Jump | Small icons at card bottom | Jump to views with task pre-selected |
| 12 | Units | rem-based | Accessibility |
---
## Design Token Specification
### Color Palette
**Backgrounds:**
```css
--color-bg-base: #2D2D2D /* primary background */
--color-bg-card: #363636 /* cards, elevated surfaces */
--color-bg-input: #404040 /* inputs, hover states */
```
**Accents:**
```css
--color-accent-green: #7CB97A /* primary CTA, success, in-progress */
--color-accent-amber: #D4A574 /* warning, blocked */
--color-accent-teal: #5BA8A0 /* secondary, open/ready */
```
**Text:**
```css
--color-text-primary: #FFFFFF
--color-text-secondary: #B8B8B8
--color-text-muted: #888888
--color-text-on-primary: #1A1A1A
```
**Borders:**
```css
--color-border-default: #4A4A4A
--color-border-subtle: #3A3A3A
```
**Status Mapping:**
- open/ready → teal `#5BA8A0`
- in_progress → green `#7CB97A`
- blocked → amber `#D4A574`
- closed → muted `#888888`
**Agent Role Colors:**
- ui → `#6B9BD2` (steel blue)
- graph → `#7CB97A` (green)
- orchestrator → `#B08ED6` (soft purple)
- agent → `#B8B8B8` (neutral)
- researcher → `#D4A574` (amber)
**Liveness Colors:**
- active → `#7CB97A` (green, pulsing)
- stale → `#D4A574` (amber)
- evicted → `#C97A7A` (muted rose)
- idle → `#888888` (muted)
### Radii
```css
--radius-sm: 0.375rem /* 6px */
--radius-card: 0.625rem /* 10px */
--radius-modal: 1rem /* 16px */
--radius-pill: 9999px
```
### Shadows
```css
--shadow-sm: 0 1px 2px rgba(0,0,0,0.1)
--shadow-md: 0 4px 12px rgba(0,0,0,0.15)
```
### Typography
- Font: system sans-serif (Inter if available)
- H1: 2rem/700, H2: 1.5rem/600, H3: 1.125rem/600
- Body: 0.875rem/400, Small: 0.75rem/400, Tiny: 0.6875rem/500
- Line-height: headings 1.2, body 1.5
### Spacing
- Base: 0.25rem (4px)
- Card padding: 1rem-1.25rem
- Gaps: 1rem
- Section gaps: 2rem-2.5rem
### Icons & Transitions
- Icons: Lucide React, 1.5-2px stroke, 1rem-1.5rem size
- Transitions: 150-200ms ease-out for all hover/focus
---
## Component Anatomy
### Social Feed Card
```
┌─────────────────────────────────────┐
│ [⊕] (top-R)│ expand icon
│ │
│ bb-buff.1.1 │ task ID (tiny, teal)
│ Fix login bug on mobile │ title (bold, white)
│ │
│ UNLOCKS: │ blocked-by (ROSE tint)
│ ● #123 Blocker task │
│ │
│ BLOCKS: │ downstream (AMBER tint)
│ ● #234 Dependent task │
│ │
│ "Found the issue in the auth..." │ latest message (muted)
│ │
│ [●a-1] [●a-2] │ agent avatars (PROMINENT)
│ [≡] [◊] [≋]│ view-jump icons
└─────────────────────────────────────┘
```
**Card Specs:**
- Background: `#363636`
- Border: 1px status-colored (teal/green/amber/muted)
- Border-radius: 10px
- Status dot on card matches status mapping
- Agent avatars have **role-colored left border**
- Blocks/unlocks have tinted backgrounds (rose #E57373/10%, amber #D4A574/10%)
**Blocks/Unlocks Pattern (reuse from task-card-grid.tsx):**
```tsx
// Container
rounded-lg p-2 border border-white/5
// "Unlocks" header (rose tint)
text-[9px] font-bold uppercase tracking-widest text-rose-400/80
bg-rose-500/10 // background tint
// "Blocks" header (amber tint)
text-[9px] font-bold uppercase tracking-widest text-amber-400/80
bg-amber-500/10 // background tint
// Individual item
rounded border border-white/5 bg-white/5 px-2.5 py-2
hover:border-sky-400/30 hover:bg-white/10 transition-colors
```
### ZFC Agent State Visuals
| State | Visual |
|-------|--------|
| idle | `#888888` static dot |
| spawning | `#5BA8A0` pulsing dot |
| running | `#7CB97A` animated dot |
| working | `#7CB97A` pulsing glow |
| stuck | `#D4A574` attention dot (needs help!) |
| done | `#7CB97A` check |
| stopped | `#888888` no animation |
| dead | `#C97A7A` warning |
### Agent Card (Right Panel)
```
┌──────────────────────┐
│ [●avatar] agent-1 │ role-colored left border
│ role: ui │ role label
│ ● working · 2m ago │ ZFC state dot + age
│ Task: buff.1.1 │ current task
│ [≡] [◊] [≋] [💬] │ view-jump + message
└──────────────────────┘
```
### Swimlane Header
- Swarm name + computed counts: "3/8 done · 2 active · 1 ready · 1 blocked"
- Agent roster with ZFC state labels
- Collapsible
---
## Layout Architecture
### Shell Structure (CSS Grid)
```
┌──────────────────────────────────────────────────────────────────┐
│ TOP BAR (fixed, 3rem) │
│ ≡ [Swimlanes|Graph|Timeline|Social] ◢ │
├──────────┬──────────────────────────────────┬────────────────────┤
│ LEFT │ MIDDLE │ RIGHT │
│ 13.75rem │ flex-1 │ 17.5rem │
│ │ │ │
│ Channel │ View content (swaps on tab) │ Agents (~40%) │
│ tree │ │ ────────────────── │
│ │ │ Activity (~60%) │
└──────────┴──────────────────────────────────┴────────────────────┘
```
**Grid:** `grid-template-columns: 13.75rem 1fr 17.5rem`
### Detail Strip Behavior
**Desktop (≥1024px):**
- Grid splits: cards (~45%) | detail strip (~55%)
- Strip slides in below grid when card selected
- Cards remain visible above
**Mobile (<768px):**
- Full-screen overlay (z-index above bottom tabs)
- Required: virtual keyboard takes 40% of screen
- Split view would leave 0px for conversation
### Responsive Behavior
| Size | Left | Middle | Right | Detail Strip |
|------|------|--------|-------|--------------|
| Desktop (≥1024px) | 13.75rem fixed | flex-1 | 17.5rem fixed | Below grid |
| Tablet (768-1024px) | Overlay | flex-1 | Overlay | Slide-over |
| Mobile (<768px) | Overlay | flex-1 | Hidden | Full-screen |
---
## Anti-Patterns (Forbidden)
- NO glass-morphism / backdrop-blur effects
- NO arbitrary Tailwind color values (use tokens)
- NO agent-unaware cards (every card shows agents)
- NO page-per-view routing (use client tabs)
- NO localStorage for view state (use URL)
- NO direct JSONL writes (use bd CLI)
---
## Recommended Bead Structure
### Phase 0: Design Foundation
**Goal:** Tokens + Primitives only. No views.
**bb-ui2.1a** - Token System Update
- Update tokens.css with complete spec above
- Ensure all status/liveness/role colors defined
- Migrate away from Aero Chrome gradients
**bb-ui2.2a** - Card Primitive with Blocks/Unlocks
- Build reusable Card component
- Implement blocks/unlocks section pattern (reuse task-card-grid.tsx logic)
- Status-colored borders
- Soft gradient backgrounds (amber/teal tints, not harsh Aero Chrome)
**bb-ui2.3a** - Agent Avatar Primitive
- Avatar with role-colored ring
- ZFC state indicator (dot/pulse/glow)
- Size variants (sm, md, lg)
**bb-ui2.4a** - Status Utilities Update
- Rewrite status-utils.tsx for new tokens
- Status badge component with pill + dot
- Liveness indicator component
### Phase 1: Layout Polish
**Goal:** Fix current layout issues, preserve structure
**bb-ui2.22** - Detail Strip Positioning Fix
- Move from side drawer to below-grid (desktop)
- Full-screen overlay (mobile)
- Preserve URL state behavior
- Thread content actually shows selected bead data
**bb-ui2.23** - Activity Panel Polish
- Split right panel: Agents (40%) + Activity (60%)
- Agent cards with ZFC states
- Context-aware activity filtering
**bb-ui2.24** - Mobile Responsive Polish
- Bottom tab bar
- Panel overlays
- Touch-friendly targets
### Phase 2: Card Design Implementation
**Goal:** Implement complete card anatomy
**bb-ui2.25** - Social Feed Card Redesign
- Full card anatomy from spec
- Blocks/unlocks with rose/amber tints
- Prominent agent avatars
- View-jump icons
- Expand icon → full-page popup
**bb-ui2.26** - Swimlane Card Redesign
- Agent-first layout
- ZFC state prominent
- Status-colored border
- Drag-drop preserved
**bb-ui2.27** - Graph Node Redesign
- New design tokens
- Agent avatars on nodes
- Selection syncs with store
### Phase 3: Cross-Cutting Polish
**Goal:** Deep links, mobile, final gates
**bb-ui2.28** - Deep Link Verification
- All URL patterns work
- Browser back/forward
- Shareable URLs
**bb-ui2.29** - Screenshot Evidence
- All breakpoints
- All views
- Mobile + desktop
**bb-ui2.30** - Final Gates
- typecheck, lint, test
- Close epic
---
## Verification Strategy
After each bead:
```bash
npm run typecheck
npm run lint
npm run test
```
Visual verification:
- Screenshots at 390px, 768px, 1440px
- Compare against design spec
- Agent avatars visible on all cards
- Blocks/unlocks sections tinted correctly
---
*End of PRD v2.0 - Ready for Implementation*

View file

@ -1,171 +1,171 @@
# Swarm View Remake - Product Requirements Document (PRD)
## Overview
The goal is to completely remake the Beadboard "Swarm" view (`/view=swarm`) into a powerful, command-center style workspace. The current flat grid of mission cards will be replaced with a deep, context-aware interface that integrates with the Gastown/Beads orchestration model, introducing the concepts of Agent Archetypes and Swarm Templates.
This document serves as the comprehensive technical specification for implementation.
---
## 1. Core Concepts & Data Models
### 1.1 Agent Archetypes
Archetypes define specialized roles that worker agents (Polecats) can adopt.
* **Storage Path:** `.beads/archetypes/*.json` (Git-tracked alongside the project).
* **Seeding:** The application must check for the existence of this directory on startup (or via a specific API route). If empty, it must create the directory and write default archetypes (e.g., `architect.json`, `reviewer.json`, `implementer.json`).
* **Data Interface (`src/lib/types-swarm.ts`):**
```typescript
export interface AgentArchetype {
id: string; // The filename without .json (e.g., 'architect')
name: string; // Display name (e.g., 'Software Architect')
description: string;
systemPrompt: string; // The core behavioral instructions
capabilities: string[]; // e.g., ['planning', 'code_review']
color: string; // e.g., 'primary', 'destructive', 'warn', etc.
createdAt: string; // ISO timestamp
updatedAt: string; // ISO timestamp
isBuiltIn: boolean; // True if seeded by default, false if user-created
}
```
### 1.2 Swarm Templates
Templates define mission blueprints—a preset team composition and standard workflow.
* **Storage Path:** `.beads/templates/*.json`.
* **Seeding:** Similar to archetypes, provide robust defaults (e.g., `feature-sprint.json`, `bug-blitz.json`).
* **Data Interface (`src/lib/types-swarm.ts`):**
```typescript
export interface SwarmTemplate {
id: string; // The filename without .json
name: string; // Display name
description: string;
team: {
archetypeId: string; // Must match an AgentArchetype.id
count: number;
}[];
protoFormula?: string; // Optional: Maps to a `bd` formula name (e.g., 'release')
createdAt: string;
updatedAt: string;
isBuiltIn: boolean;
}
```
---
## 2. API Contracts & Backend Architecture
The UI needs a robust Next.js API layer to manage these new files and interface with the CLI. All routes should be under `src/app/api/swarm/`.
### 2.1 Archetypes API (`/api/swarm/archetypes`)
* **GET:** Returns `AgentArchetype[]`. Reads all `.json` files from `.beads/archetypes/`.
* **POST:** Creates a new archetype. Validates payload, writes to `.beads/archetypes/{id}.json`.
* **PUT /:id:** Updates an existing archetype.
* **DELETE /:id:** Deletes an archetype (prevent deletion if `isBuiltIn` is true).
### 2.2 Templates API (`/api/swarm/templates`)
* **GET:** Returns `SwarmTemplate[]`. Reads from `.beads/templates/`.
* **POST, PUT, DELETE:** Standard CRUD mirroring Archetypes.
### 2.3 Orchestration API (`/api/swarm/orchestration`)
* **POST `/launch`:**
* **Payload:** `{ templateId: string, missionName: string, projectRoot: string }`
* **Action:** Reads the template. If `protoFormula` exists, executes `bd mol pour <protoFormula> --title <missionName>`. If no formula, executes `bd create epic <missionName>`. Then executes `gt sling` or equivalent to assign the specific roster to the new Epic.
* **Response:** The new Epic ID to immediately select in the UI.
---
## 3. Frontend Architecture & Component Structure
The current `src/components/swarm/swarm-page.tsx` will be completely replaced. The new architecture pushes state down into specialized components.
### 3.1 Shell Integration (`src/components/shared/unified-shell.tsx`)
The `UnifiedShell` must dynamically alter its layout based on the active view.
* **When `view === 'swarm'`:**
* **Left Panel:** Do NOT render the standard Epic Tree. Render `<SwarmMissionPicker />`.
* **Middle Column:** Render `<SwarmWorkspace />`.
* **Right Panel:** Remain as the `<ActivityPanel />` (Agent pool monitor).
### 3.2 The Swarm Workspace (`src/components/swarm/swarm-workspace.tsx`)
The main container for the middle column. Manages the active sub-tab state.
```tsx
// State: activeTab: 'operations' | 'archetypes' | 'templates'
<div className="swarm-workspace">
<SwarmWorkspaceNav activeTab={activeTab} onTabChange={setTab} />
{activeTab === 'operations' && <SwarmOperationsmissionId={selectedMissionId} />}
{activeTab === 'archetypes' && <ArchetypesArmory />}
{activeTab === 'templates' && <TemplatesManager />}
</div>
```
---
## 4. UI/UX Details by Sub-Tab
### 4.1 Left Panel: `<SwarmMissionPicker />`
A dense, scannable list replacing the left panel.
* Fetches epics (like the current `useMissionList` hook).
* **Row Design:**
* `[Health Dot] [Mission Title] (ID)`
* A micro-progress bar underneath the title.
* **Interaction:** Clicking sets the `swarmId` URL param and automatically switches the `SwarmWorkspace` to the 'operations' tab.
### 4.2 Tab 1: `<SwarmOperations />` (The Operations Command Center)
This view only renders if a mission (Epic) is selected. It completely replaces the redundant Graph view with a focused, control-oriented dashboard for agent orchestration.
* **Header Section:**
* Mission Title, Epic ID, and overall health status.
* **Action Strip:** Buttons for "Summon Polecats" (assign agents based on a template), "Halt Swarm", and "Run Debrief".
* **Convoy Stepper:** The visual orchestration pipeline (Planning -> Deployment -> Execution -> Debrief).
* **The Telemetry Grid (Hybrid Layout):**
* **Top/Left Pane (Specialized Agent DAG):** Unlike the generic global graph, this graph specifically visualizes *who* is doing *what*. Nodes should emphasize Agent Avatars and archetype colors. Edges should represent the flow of work between agents (e.g., Coder -> Reviewer) rather than just raw task dependencies.
* **Bottom/Right Pane (Metrics & Attention):**
* **Priority Attention (What is blocked?):** A highly focused feed of *only* the `blocked` beads or beads that require Human-In-The-Loop (HITL) intervention for this specific mission.
* **Mission Roster:** A quick summary of active agents.
### 4.3 Tab 2: `<ArchetypesArmory />`
* **Layout:** CSS Grid of archetype cards.
* **Card Design:** Shows Name, Color badge, Capabilities tags, and truncated description.
* **Interaction:**
* Cards are highly interactive. Clicking a card opens a central popup (reusing the app's existing Dialog/Popup pattern) to edit the metadata.
* Includes a focused text area to edit the raw `systemPrompt`.
* A primary "Create New Archetype" button exists at the top.
### 4.4 Tab 3: `<TemplatesManager />`
* **Layout:** List or Grid view of templates.
* **Interaction:**
* Cards are highly interactive. Clicking a card opens a central `<TemplateEditor />` popup.
* **Key UI Feature:** An intuitive interface to build the `team` array (e.g., click "Add Role", select "Architect" from the Archetypes list, set count to "1").
* A primary "Create New Template" button exists at the top.
---
## 5. Engine Integration & Visual Hooks
Raw terminal panes are rejected. Orchestration must feel native to the React application.
### 5.1 The Convoy Stepper (`<ConvoyOrchestrationStepper />`)
When `<LaunchSwarmDialog />` is submitted, a prominent overlay or banner appears in the Operations view:
* **Phase 1: Planning.** (Spinning) -> API calls `bd mol pour` -> (Check)
* **Phase 2: Graph Generation.** (Spinning) -> UI polls API for new beads -> (Check)
* **Phase 3: Deployment.** (Spinning) -> API calls `gt sling` -> (Check)
* The stepper fades out after 3 seconds of full completion, revealing the live DAG.
### 5.2 Responsive Graph Expansion
The Graph view in the Operations tab must smoothly handle rapid influxes of nodes (which happens when a template is poured). The physics simulation (if applicable) or layout engine should be robust enough to handle ~20-50 nodes appearing simultaneously without throwing errors or causing heavy layout thrashing.
---
## 6. Implementation Phasing Strategy
To avoid massive, monolithic PRs, implementation should follow this order:
1. **Phase 1: Data Layer & API.** Implement `src/lib/types-swarm.ts`, the seed logic, and the CRUD API routes for Archetypes and Templates.
2. **Phase 2: Shell Routing & Sub-tabs.** Update `UnifiedShell` to intercept the Swarm view, implement the `SwarmMissionPicker` for the left panel, and scaffold the empty 3 sub-tabs.
3. **Phase 3: Armory & Templates UI.** Build out the CRUD interfaces for Archetypes and Templates.
4. **Phase 4: The Operations Dashboard.** Build the complex detail view, integrating the existing graph components and agent roster.
5. **Phase 5: Orchestration (The glue).** Hook up the "Launch" button to the new templates, implement the `ConvoyStepper`, and wire the API to `bd` and `gt`.
# Swarm View Remake - Product Requirements Document (PRD)
## Overview
The goal is to completely remake the Beadboard "Swarm" view (`/view=swarm`) into a powerful, command-center style workspace. The current flat grid of mission cards will be replaced with a deep, context-aware interface that integrates with the Gastown/Beads orchestration model, introducing the concepts of Agent Archetypes and Swarm Templates.
This document serves as the comprehensive technical specification for implementation.
---
## 1. Core Concepts & Data Models
### 1.1 Agent Archetypes
Archetypes define specialized roles that worker agents (Polecats) can adopt.
* **Storage Path:** `.beads/archetypes/*.json` (Git-tracked alongside the project).
* **Seeding:** The application must check for the existence of this directory on startup (or via a specific API route). If empty, it must create the directory and write default archetypes (e.g., `architect.json`, `reviewer.json`, `implementer.json`).
* **Data Interface (`src/lib/types-swarm.ts`):**
```typescript
export interface AgentArchetype {
id: string; // The filename without .json (e.g., 'architect')
name: string; // Display name (e.g., 'Software Architect')
description: string;
systemPrompt: string; // The core behavioral instructions
capabilities: string[]; // e.g., ['planning', 'code_review']
color: string; // e.g., 'primary', 'destructive', 'warn', etc.
createdAt: string; // ISO timestamp
updatedAt: string; // ISO timestamp
isBuiltIn: boolean; // True if seeded by default, false if user-created
}
```
### 1.2 Swarm Templates
Templates define mission blueprints—a preset team composition and standard workflow.
* **Storage Path:** `.beads/templates/*.json`.
* **Seeding:** Similar to archetypes, provide robust defaults (e.g., `feature-sprint.json`, `bug-blitz.json`).
* **Data Interface (`src/lib/types-swarm.ts`):**
```typescript
export interface SwarmTemplate {
id: string; // The filename without .json
name: string; // Display name
description: string;
team: {
archetypeId: string; // Must match an AgentArchetype.id
count: number;
}[];
protoFormula?: string; // Optional: Maps to a `bd` formula name (e.g., 'release')
createdAt: string;
updatedAt: string;
isBuiltIn: boolean;
}
```
---
## 2. API Contracts & Backend Architecture
The UI needs a robust Next.js API layer to manage these new files and interface with the CLI. All routes should be under `src/app/api/swarm/`.
### 2.1 Archetypes API (`/api/swarm/archetypes`)
* **GET:** Returns `AgentArchetype[]`. Reads all `.json` files from `.beads/archetypes/`.
* **POST:** Creates a new archetype. Validates payload, writes to `.beads/archetypes/{id}.json`.
* **PUT /:id:** Updates an existing archetype.
* **DELETE /:id:** Deletes an archetype (prevent deletion if `isBuiltIn` is true).
### 2.2 Templates API (`/api/swarm/templates`)
* **GET:** Returns `SwarmTemplate[]`. Reads from `.beads/templates/`.
* **POST, PUT, DELETE:** Standard CRUD mirroring Archetypes.
### 2.3 Orchestration API (`/api/swarm/orchestration`)
* **POST `/launch`:**
* **Payload:** `{ templateId: string, missionName: string, projectRoot: string }`
* **Action:** Reads the template. If `protoFormula` exists, executes `bd mol pour <protoFormula> --title <missionName>`. If no formula, executes `bd create epic <missionName>`. Then executes `gt sling` or equivalent to assign the specific roster to the new Epic.
* **Response:** The new Epic ID to immediately select in the UI.
---
## 3. Frontend Architecture & Component Structure
The current `src/components/swarm/swarm-page.tsx` will be completely replaced. The new architecture pushes state down into specialized components.
### 3.1 Shell Integration (`src/components/shared/unified-shell.tsx`)
The `UnifiedShell` must dynamically alter its layout based on the active view.
* **When `view === 'swarm'`:**
* **Left Panel:** Do NOT render the standard Epic Tree. Render `<SwarmMissionPicker />`.
* **Middle Column:** Render `<SwarmWorkspace />`.
* **Right Panel:** Remain as the `<ActivityPanel />` (Agent pool monitor).
### 3.2 The Swarm Workspace (`src/components/swarm/swarm-workspace.tsx`)
The main container for the middle column. Manages the active sub-tab state.
```tsx
// State: activeTab: 'operations' | 'archetypes' | 'templates'
<div className="swarm-workspace">
<SwarmWorkspaceNav activeTab={activeTab} onTabChange={setTab} />
{activeTab === 'operations' && <SwarmOperationsmissionId={selectedMissionId} />}
{activeTab === 'archetypes' && <ArchetypesArmory />}
{activeTab === 'templates' && <TemplatesManager />}
</div>
```
---
## 4. UI/UX Details by Sub-Tab
### 4.1 Left Panel: `<SwarmMissionPicker />`
A dense, scannable list replacing the left panel.
* Fetches epics (like the current `useMissionList` hook).
* **Row Design:**
* `[Health Dot] [Mission Title] (ID)`
* A micro-progress bar underneath the title.
* **Interaction:** Clicking sets the `swarmId` URL param and automatically switches the `SwarmWorkspace` to the 'operations' tab.
### 4.2 Tab 1: `<SwarmOperations />` (The Operations Command Center)
This view only renders if a mission (Epic) is selected. It completely replaces the redundant Graph view with a focused, control-oriented dashboard for agent orchestration.
* **Header Section:**
* Mission Title, Epic ID, and overall health status.
* **Action Strip:** Buttons for "Summon Polecats" (assign agents based on a template), "Halt Swarm", and "Run Debrief".
* **Convoy Stepper:** The visual orchestration pipeline (Planning -> Deployment -> Execution -> Debrief).
* **The Telemetry Grid (Hybrid Layout):**
* **Top/Left Pane (Specialized Agent DAG):** Unlike the generic global graph, this graph specifically visualizes *who* is doing *what*. Nodes should emphasize Agent Avatars and archetype colors. Edges should represent the flow of work between agents (e.g., Coder -> Reviewer) rather than just raw task dependencies.
* **Bottom/Right Pane (Metrics & Attention):**
* **Priority Attention (What is blocked?):** A highly focused feed of *only* the `blocked` beads or beads that require Human-In-The-Loop (HITL) intervention for this specific mission.
* **Mission Roster:** A quick summary of active agents.
### 4.3 Tab 2: `<ArchetypesArmory />`
* **Layout:** CSS Grid of archetype cards.
* **Card Design:** Shows Name, Color badge, Capabilities tags, and truncated description.
* **Interaction:**
* Cards are highly interactive. Clicking a card opens a central popup (reusing the app's existing Dialog/Popup pattern) to edit the metadata.
* Includes a focused text area to edit the raw `systemPrompt`.
* A primary "Create New Archetype" button exists at the top.
### 4.4 Tab 3: `<TemplatesManager />`
* **Layout:** List or Grid view of templates.
* **Interaction:**
* Cards are highly interactive. Clicking a card opens a central `<TemplateEditor />` popup.
* **Key UI Feature:** An intuitive interface to build the `team` array (e.g., click "Add Role", select "Architect" from the Archetypes list, set count to "1").
* A primary "Create New Template" button exists at the top.
---
## 5. Engine Integration & Visual Hooks
Raw terminal panes are rejected. Orchestration must feel native to the React application.
### 5.1 The Convoy Stepper (`<ConvoyOrchestrationStepper />`)
When `<LaunchSwarmDialog />` is submitted, a prominent overlay or banner appears in the Operations view:
* **Phase 1: Planning.** (Spinning) -> API calls `bd mol pour` -> (Check)
* **Phase 2: Graph Generation.** (Spinning) -> UI polls API for new beads -> (Check)
* **Phase 3: Deployment.** (Spinning) -> API calls `gt sling` -> (Check)
* The stepper fades out after 3 seconds of full completion, revealing the live DAG.
### 5.2 Responsive Graph Expansion
The Graph view in the Operations tab must smoothly handle rapid influxes of nodes (which happens when a template is poured). The physics simulation (if applicable) or layout engine should be robust enough to handle ~20-50 nodes appearing simultaneously without throwing errors or causing heavy layout thrashing.
---
## 6. Implementation Phasing Strategy
To avoid massive, monolithic PRs, implementation should follow this order:
1. **Phase 1: Data Layer & API.** Implement `src/lib/types-swarm.ts`, the seed logic, and the CRUD API routes for Archetypes and Templates.
2. **Phase 2: Shell Routing & Sub-tabs.** Update `UnifiedShell` to intercept the Swarm view, implement the `SwarmMissionPicker` for the left panel, and scaffold the empty 3 sub-tabs.
3. **Phase 3: Armory & Templates UI.** Build out the CRUD interfaces for Archetypes and Templates.
4. **Phase 4: The Operations Dashboard.** Build the complex detail view, integrating the existing graph components and agent roster.
5. **Phase 5: Orchestration (The glue).** Hook up the "Launch" button to the new templates, implement the `ConvoyStepper`, and wire the API to `bd` and `gt`.

View file

@ -1,49 +1,49 @@
# DAG Views & Command Center UX Overhaul
## The Problem
The current `/grid` and `/swarm` views are fragmented. The left sidebar changes shape and color depending on the mode, causing jarring context switches. The Swarm DAG needs animation enhancements, the Grid view needs clarity, and the Right Panel gets cut off and is filled with noisy, irrelevant data (e.g., dead agents from days ago).
## The Goal
Create a unified "Mission Control" experience designed specifically for a single Commander observing and managing AI agents. Eliminate context switching while separating the noise of real-time execution from the quiet of architectural planning.
## The Solution: Macro vs. Micro Architecture
Instead of arbitrary "Grid" and "Swarm" routing modes, we move to a **Depth-Based Context** model.
### 1. The Macro View (Planning / The Grid)
**Trigger:** Looking at the entire workspace or multiple epics.
- **The DAG:** Structural and quiet. Shows task dependencies and static statuses (Ready, Blocked, Done). No noisy agent animations or live data flows.
- **Left Panel:** The unified Task/Epic tree. Clean, consistent UI.
- **Right Panel (Global Events):** A high-level timeline of events (e.g., "Agent X completed Task Y", "Task Z is blocked"), essentially a git-log of the workspace.
### 2. The Micro View (Execution / The Swarm)
**Trigger:** Selecting a specific Epic or an active Task. The view zooms in to focus only on localized context.
- **The DAG:** Comes alive. You only see the tasks actively being worked on and their immediate neighbors. Nodes pulse to indicate agent activity, and edges show animated data-flow passing between tasks/agents.
- **Left Panel:** Remains the unified Task/Epic tree, but highlights the active epic and places "Active Agent" indicator badges next to tasks currently in progress.
- **Right Panel (The Command Feed):** Splits into a stacked or tabbed view optimized for live operations:
- **Active Squad Roster:** Only lists agents assigned to *this specific Epic context*. Dead agents from previous sessions are completely hidden. Shows current token usage and active task assignments.
- **Live Telemetry (The Swarm Activity Feed):** A highly readable streaming feed of what the agents are thinking and doing *right now* ("Agent X evaluating `lib/utils.ts`", "Agent Y blocked on API key"). This replaces the current messy telemetry grid into a focused, scrolling terminal-like feed on the right.
## Technical Execution Plan
### 1. Left Panel Unification
- Remove the `SwarmMissionPicker` override.
- Update `unified-shell.tsx` to always render `<LeftPanel />`.
- Enhance `<LeftPanel />` to display active agent indicators based on live telemetry data.
### 2. Right Panel Fixes & Contextual Rendering
- Fix the CSS grid width causing the Right Panel to be cut off (`rightPanelWidth` adjustments in `unified-shell.tsx`).
- Introduce `<ContextualRightPanel />` that reads the URL state (`epicId` / `taskId` vs `null`).
- Component swap:
- No Epic Selected -> `<GlobalActivityFeed />`
- Epic/Task Selected -> `<SwarmCommandFeed />` (Roster + Telemetry)
### 3. DAG Component Merging
- Merge `GraphView` and `SwarmWorkspace` core logic into a single `<SmartDag />` component.
- The `<SmartDag />` will read the `epicId` context to determine its zoom level and animation states.
- Introduce framer-motion (or existing animation libraries) for data flow and node pulsing.
### 4. Overhauling the Swarm Activity Feed & Roster
- **Contextual Agent Roster:** Instead of pulling all agents globally (like `ActivityPanel` currently does), we extract the active roster logic from `TelemetryGrid` to only show agents actively assigned to `in_progress` tasks within the currently selected `epicId`.
- **Streaming Telemetry Feed:** We reuse the `/api/events` SSE connection from `ActivityPanel`, but we filter the incoming events `beadId` to match the children of the current `epicId`. We format this feed as a terminal-like streaming log with concise, color-coded badges indicating what the agents are currently doing.
- **Cleanup the Graveyard:** Dead agents and old task logs will be entirely stripped from this contextual right panel, ensuring it remains a focused "Command Feed" of live operations.
# DAG Views & Command Center UX Overhaul
## The Problem
The current `/grid` and `/swarm` views are fragmented. The left sidebar changes shape and color depending on the mode, causing jarring context switches. The Swarm DAG needs animation enhancements, the Grid view needs clarity, and the Right Panel gets cut off and is filled with noisy, irrelevant data (e.g., dead agents from days ago).
## The Goal
Create a unified "Mission Control" experience designed specifically for a single Commander observing and managing AI agents. Eliminate context switching while separating the noise of real-time execution from the quiet of architectural planning.
## The Solution: Macro vs. Micro Architecture
Instead of arbitrary "Grid" and "Swarm" routing modes, we move to a **Depth-Based Context** model.
### 1. The Macro View (Planning / The Grid)
**Trigger:** Looking at the entire workspace or multiple epics.
- **The DAG:** Structural and quiet. Shows task dependencies and static statuses (Ready, Blocked, Done). No noisy agent animations or live data flows.
- **Left Panel:** The unified Task/Epic tree. Clean, consistent UI.
- **Right Panel (Global Events):** A high-level timeline of events (e.g., "Agent X completed Task Y", "Task Z is blocked"), essentially a git-log of the workspace.
### 2. The Micro View (Execution / The Swarm)
**Trigger:** Selecting a specific Epic or an active Task. The view zooms in to focus only on localized context.
- **The DAG:** Comes alive. You only see the tasks actively being worked on and their immediate neighbors. Nodes pulse to indicate agent activity, and edges show animated data-flow passing between tasks/agents.
- **Left Panel:** Remains the unified Task/Epic tree, but highlights the active epic and places "Active Agent" indicator badges next to tasks currently in progress.
- **Right Panel (The Command Feed):** Splits into a stacked or tabbed view optimized for live operations:
- **Active Squad Roster:** Only lists agents assigned to *this specific Epic context*. Dead agents from previous sessions are completely hidden. Shows current token usage and active task assignments.
- **Live Telemetry (The Swarm Activity Feed):** A highly readable streaming feed of what the agents are thinking and doing *right now* ("Agent X evaluating `lib/utils.ts`", "Agent Y blocked on API key"). This replaces the current messy telemetry grid into a focused, scrolling terminal-like feed on the right.
## Technical Execution Plan
### 1. Left Panel Unification
- Remove the `SwarmMissionPicker` override.
- Update `unified-shell.tsx` to always render `<LeftPanel />`.
- Enhance `<LeftPanel />` to display active agent indicators based on live telemetry data.
### 2. Right Panel Fixes & Contextual Rendering
- Fix the CSS grid width causing the Right Panel to be cut off (`rightPanelWidth` adjustments in `unified-shell.tsx`).
- Introduce `<ContextualRightPanel />` that reads the URL state (`epicId` / `taskId` vs `null`).
- Component swap:
- No Epic Selected -> `<GlobalActivityFeed />`
- Epic/Task Selected -> `<SwarmCommandFeed />` (Roster + Telemetry)
### 3. DAG Component Merging
- Merge `GraphView` and `SwarmWorkspace` core logic into a single `<SmartDag />` component.
- The `<SmartDag />` will read the `epicId` context to determine its zoom level and animation states.
- Introduce framer-motion (or existing animation libraries) for data flow and node pulsing.
### 4. Overhauling the Swarm Activity Feed & Roster
- **Contextual Agent Roster:** Instead of pulling all agents globally (like `ActivityPanel` currently does), we extract the active roster logic from `TelemetryGrid` to only show agents actively assigned to `in_progress` tasks within the currently selected `epicId`.
- **Streaming Telemetry Feed:** We reuse the `/api/events` SSE connection from `ActivityPanel`, but we filter the incoming events `beadId` to match the children of the current `epicId`. We format this feed as a terminal-like streaming log with concise, color-coded badges indicating what the agents are currently doing.
- **Cleanup the Graveyard:** Dead agents and old task logs will be entirely stripped from this contextual right panel, ensuring it remains a focused "Command Feed" of live operations.

View file

@ -0,0 +1,533 @@
# BeadBoard Global Install Runtime Manager Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Replace repo-path shim install behavior with a robust global install model where `beadboard` runs from managed runtime home and works from any directory.
**Architecture:** Keep a hybrid install strategy with npm-global as primary and script bootstrap as fallback, but unify both paths behind one runtime manager contract (`~/.beadboard/runtime/<version>` + stable shims). Preserve backward compatibility by detecting legacy repo-bound shims and offering migration. Implement with strict TDD and explicit installer smoke tests.
**Tech Stack:** Node.js (ESM), TypeScript/tsx for CLI code, PowerShell + POSIX shell wrappers, GitHub Actions, Node test runner.
---
## Pre-Implementation Checklist
### Task 0: Baseline and Safety Snapshot
**Files:**
- Modify: `beadboard/.beads/issues.jsonl` via `bd` commands only
- Read: `/mnt/c/Users/Zenchant/codex/beadboard/AGENTS.md`
- Read: `/mnt/c/Users/Zenchant/codex/beadboard/NEXT_SESSION_PROMPT.md`
**Step 1: Claim/track implementation bead(s)**
Run:
```bash
cd /mnt/c/Users/Zenchant/codex/beadboard
bd create --title="Global installer runtime manager implementation" --description="Implement npm-global-first runtime manager with migration from repo-path shims" --type=task --priority=1 --label="installation,cli,runtime"
bd update <new-bead-id> --status in_progress --assignee <agent-bead-id>
```
**Step 2: Capture baseline gate status**
Run:
```bash
npm run typecheck
npm run lint
npm run test
```
Expected: existing known unrelated failures may appear; record exact failing files/tests in bead notes.
**Step 3: Commit checkpoint**
No code changes yet. Do not commit.
---
## Phase 1: Define Runtime Manager Contract
### Task 1: Add runtime manager ADR and package contract
**Files:**
- Create: `docs/adr/2026-03-03-runtime-manager-global-install.md`
- Modify: `docs/adr/2026-03-03-global-installer-contract-and-manifest.md`
**Step 1: Write failing docs contract test**
Create:
- `tests/docs/runtime-manager-adr-contract.test.ts`
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import path from 'node:path';
test('runtime manager ADR exists and declares runtime home strategy', async () => {
const raw = await fs.readFile(path.resolve('docs/adr/2026-03-03-runtime-manager-global-install.md'), 'utf8');
assert.match(raw, /~\/\.beadboard\/runtime/i);
assert.match(raw, /npm i -g beadboard/i);
assert.match(raw, /legacy repo-bound shim migration/i);
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/docs/runtime-manager-adr-contract.test.ts
```
Expected: FAIL (`ENOENT` for missing ADR file).
**Step 3: Write minimal implementation**
Add ADR with:
- runtime directory layout
- shim strategy
- update/uninstall model
- compatibility migration model
- failure modes and rollback
**Step 4: Run test to verify it passes**
Run:
```bash
node --import tsx --test tests/docs/runtime-manager-adr-contract.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add tests/docs/runtime-manager-adr-contract.test.ts docs/adr/2026-03-03-runtime-manager-global-install.md docs/adr/2026-03-03-global-installer-contract-and-manifest.md
git commit -m "docs: define runtime manager global install contract"
```
---
## Phase 2: Implement Runtime Manager Library
### Task 2: Add runtime manager core module with strict validation
**Files:**
- Create: `src/lib/runtime-manager.ts`
- Create: `tests/lib/runtime-manager.test.ts`
**Step 1: Write failing test**
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
import { getRuntimePaths, normalizeVersion } from '../../src/lib/runtime-manager';
test('normalizeVersion supports semver and rejects empty', () => {
assert.equal(normalizeVersion('1.2.3'), '1.2.3');
assert.throws(() => normalizeVersion(''));
});
test('getRuntimePaths builds ~/.beadboard/runtime/<version> layout', () => {
const p = getRuntimePaths('/tmp/home', '1.2.3');
assert.match(p.runtimeRoot, /runtime\/1\.2\.3$/);
assert.match(p.shimDir, /\.beadboard\/bin$/);
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/lib/runtime-manager.test.ts
```
Expected: FAIL (`Cannot find module '../../src/lib/runtime-manager'`).
**Step 3: Write minimal implementation**
Implement exports:
- `normalizeVersion(version: string): string`
- `getRuntimePaths(home: string, version: string)`
- `resolveInstallHome(env)`
Keep pure and side-effect free.
**Step 4: Run test to verify it passes**
Run:
```bash
node --import tsx --test tests/lib/runtime-manager.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add src/lib/runtime-manager.ts tests/lib/runtime-manager.test.ts
git commit -m "feat(installer): add runtime manager core library"
```
---
## Phase 3: Move Launcher to Runtime-Aware Execution
### Task 3: Update launcher to run from managed runtime root
**Files:**
- Modify: `install/beadboard.mjs`
- Modify: `tests/scripts/beadboard-launcher.test.ts`
- Create: `tests/scripts/beadboard-launcher-runtime.test.ts`
**Step 1: Write failing test**
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import path from 'node:path';
const execFileAsync = promisify(execFile);
const launcherPath = path.resolve('install/beadboard.mjs');
test('status --json reports runtime root and install mode', async () => {
const { stdout } = await execFileAsync(process.execPath, [launcherPath, 'status', '--json']);
const payload = JSON.parse(stdout);
assert.ok(payload.runtimeRoot);
assert.ok(payload.installMode);
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts
```
Expected: FAIL (missing fields).
**Step 3: Write minimal implementation**
In launcher:
- derive runtime home/version
- include `runtimeRoot`, `installMode`, `shimTarget` in JSON status
- preserve existing `start/open/status` behavior
**Step 4: Run tests to verify pass**
Run:
```bash
node --import tsx --test tests/scripts/beadboard-launcher.test.ts
node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add install/beadboard.mjs tests/scripts/beadboard-launcher.test.ts tests/scripts/beadboard-launcher-runtime.test.ts
git commit -m "feat(launcher): add runtime-aware status metadata"
```
---
## Phase 4: Replace Repo-Bound Shim Targets
### Task 4: Make install wrappers point at runtime-managed target
**Files:**
- Modify: `install/install.sh`
- Modify: `install/install.ps1`
- Modify: `tests/scripts/install-wrappers-contract.test.ts`
- Modify: `tests/scripts/install-sh-smoke.test.ts`
- Create: `tests/scripts/install-legacy-migration.test.ts`
**Step 1: Write failing migration test**
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
// simulate legacy shim text and verify installer rewrites to runtime target
test('installer migrates legacy repo-bound shim to runtime-managed shim', async () => {
assert.fail('implement');
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/scripts/install-legacy-migration.test.ts
```
Expected: FAIL.
**Step 3: Write minimal implementation**
In both wrappers:
- install runtime metadata file (`~/.beadboard/runtime/current.json`)
- rewrite `bb`/`beadboard` shims to resolve runtime target first
- detect old shim signatures and replace atomically
**Step 4: Run wrapper tests**
Run:
```bash
node --import tsx --test tests/scripts/install-wrappers-contract.test.ts
node --import tsx --test tests/scripts/install-sh-smoke.test.ts
node --import tsx --test tests/scripts/install-legacy-migration.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add install/install.sh install/install.ps1 tests/scripts/install-wrappers-contract.test.ts tests/scripts/install-sh-smoke.test.ts tests/scripts/install-legacy-migration.test.ts
git commit -m "feat(installer): migrate shims to runtime-managed targets"
```
---
## Phase 5: Add npm-Global Entry and Self-Management Commands
### Task 5: Add CLI entrypoint commands (`self-update`, `uninstall`, `doctor`)
**Files:**
- Modify: `package.json`
- Create: `bin/beadboard.js`
- Create: `src/cli/beadboard-cli.ts`
- Create: `tests/cli/beadboard-cli.test.ts`
**Step 1: Write failing CLI tests**
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
import { runCli } from '../../src/cli/beadboard-cli';
test('doctor returns structured install diagnostics', async () => {
const out = await runCli(['doctor', '--json']);
assert.equal(out.ok, true);
assert.ok(out.installMode);
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/cli/beadboard-cli.test.ts
```
Expected: FAIL (missing module/command).
**Step 3: Write minimal implementation**
Add commands:
- `beadboard doctor --json`
- `beadboard self-update` (placeholder behavior with explicit output if publish not configured)
- `beadboard uninstall` (remove shims/runtime with `--yes` guard)
Add `bin` mapping in `package.json`.
**Step 4: Run test to verify pass**
Run:
```bash
node --import tsx --test tests/cli/beadboard-cli.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add package.json bin/beadboard.js src/cli/beadboard-cli.ts tests/cli/beadboard-cli.test.ts
git commit -m "feat(cli): add global entrypoint with doctor/update/uninstall commands"
```
---
## Phase 6: Driver Alignment + Remediation UX Finalization
### Task 6: Update driver preflight/remediation copy for npm-global-first flow
**Files:**
- Modify: `skills/beadboard-driver/scripts/lib/driver-lib.mjs`
- Modify: `skills/beadboard-driver/scripts/session-preflight.mjs`
- Modify: `tests/skills/beadboard-driver/resolve-bb.test.ts`
- Modify: `tests/skills/beadboard-driver/session-preflight.test.ts`
**Step 1: Write failing test assertion**
Add expectation:
- remediation mentions `npm i -g beadboard` as primary
- install script remains fallback
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts
node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts
```
Expected: FAIL (copy mismatch).
**Step 3: Write minimal implementation**
Update remediation strings to:
1. npm-global install
2. fallback installer wrapper
3. BB_REPO override guidance
**Step 4: Re-run tests**
Run:
```bash
node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts
node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add skills/beadboard-driver/scripts/lib/driver-lib.mjs skills/beadboard-driver/scripts/session-preflight.mjs tests/skills/beadboard-driver/resolve-bb.test.ts tests/skills/beadboard-driver/session-preflight.test.ts
git commit -m "feat(driver): prefer npm-global remediation with installer fallback"
```
---
## Phase 7: CI, Docs, and Release Readiness
### Task 7: Expand CI smoke and operator docs for global model
**Files:**
- Modify: `.github/workflows/installer-smoke.yml`
- Modify: `README.md`
- Modify: `docs/adr/2026-03-03-runtime-manager-global-install.md`
- Create: `docs/ops/global-install-rollout.md`
- Modify: `tests/scripts/installer-ci-contract.test.ts`
- Modify: `tests/docs/installer-quickstart-contract.test.ts`
**Step 1: Write failing test updates**
Add assertions for:
- npm-global command in docs
- runtime home path mentions
- CI step validating `beadboard doctor --json`
**Step 2: Run tests to verify fail**
Run:
```bash
node --import tsx --test tests/scripts/installer-ci-contract.test.ts
node --import tsx --test tests/docs/installer-quickstart-contract.test.ts
```
Expected: FAIL.
**Step 3: Write minimal implementation**
Update docs and workflow:
- install paths
- migration notes
- recovery playbook
- supported platforms matrix
**Step 4: Re-run tests**
Run:
```bash
node --import tsx --test tests/scripts/installer-ci-contract.test.ts
node --import tsx --test tests/docs/installer-quickstart-contract.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add .github/workflows/installer-smoke.yml README.md docs/adr/2026-03-03-runtime-manager-global-install.md docs/ops/global-install-rollout.md tests/scripts/installer-ci-contract.test.ts tests/docs/installer-quickstart-contract.test.ts
git commit -m "docs(ci): finalize global install runtime docs and smoke coverage"
```
---
## Phase 8: Final Verification + Bead Closeout
### Task 8: Full-gate verification and close
**Files:**
- Modify: `beadboard` issue notes via `bd update`
- Modify: `NEXT_SESSION_PROMPT.md`
**Step 1: Run full gates**
Run:
```bash
npm run typecheck
npm run lint
npm run test
```
Expected: PASS; if unrelated failures exist, capture exact files/tests.
**Step 2: Run targeted installer acceptance checks**
Run:
```bash
node --import tsx --test tests/lib/runtime-manager.test.ts
node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts
node --import tsx --test tests/scripts/install-legacy-migration.test.ts
node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts
```
Expected: PASS.
**Step 3: Update beads with evidence**
Run:
```bash
bd update <bead-id> --notes "<commands run + pass/fail details>"
bd close <bead-id> --reason "<completed outcome>"
```
**Step 4: Update handoff**
Modify:
- `NEXT_SESSION_PROMPT.md` with shipped state + residual risks + next bead.
**Step 5: Commit**
```bash
git add NEXT_SESSION_PROMPT.md
git commit -m "chore: close runtime-manager rollout with verification evidence"
```
---
## References and Required Skills During Execution
1. `@test-driven-development`
2. `@verification-before-completion`
3. `@linus-beads-discipline`
4. `@beadboard-driver`
5. `@executing-plans` (required for implementation phase)
---
Plan complete and saved to `docs/plans/2026-03-03-global-install-runtime-manager.md`. Two execution options:
**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration
**2. Parallel Session (separate)** - Open new session with executing-plans, batch execution with checkpoints
Which approach?

File diff suppressed because it is too large Load diff

View file

@ -29,5 +29,5 @@ const eslintConfig = [
},
},
];
export default eslintConfig;
export default eslintConfig;

View file

@ -1,71 +1,71 @@
bb-atf
bb-z6s
bb-54x
bb-nuy
bb-98c
bb-3ha
bb-22l
bb-5am
bb-dwz
bb-3dv
bb-only-ui-agent
bb-graph-agent-1
bb-ui-agent-2
bb-ui-agent-1
bb-verify-mlnavzwu
bb-final-mlnar702
bb-verify2-mlnaouad
bb-final-mlnalaqz
bb-bridge-fix-mlnaja4j
bb-verify-mlnadaip
bb-switch-mlna9nbo
bb-join-mlna9nbo
bb-invepic-mln9perd
bb-m2-mln9perd
bb-invalid-epic-mln9hraq
bb-m1-mln9perd
bb-leave-mln9perd
bb-member3-mln9hraq
bb-member2-mln9hraq
bb-member1-mln9hraq
bb-switch-mln9perd
bb-nolabel-test-mln9hraq
bb-join-mln9perd
bb-leave-test-mln9hraq
bb-idem-test-mln9hraq
bb-debug-mln9knzs
bb-switch-test-mln9hraq
bb-join-test-mln9hraq
bb-smoke-mln9e525
bb-idem-test-mln97lyt
bb-switch-test-mln97lyt
bb-join-test-mln97lyt
bb-switch-test-mln8xxn4
bb-join-test-mln8xxn4
bb-nolabel-test-mln8pdgh
bb-leave-test-mln8pdgh
bb-idem-test-mln8pdgh
bb-switch-test-mln8pdgh
bb-join-test-mln8pdgh
bb-leave-test-mln8hp8j
bb-idem-test-mln8hp8j
bb-switch-test-mln8hp8j
bb-join-test-mln8hp8j
bb-daemon-test-mln8e4tf
bb-fresh-test-mln8canu
bb-upd-test-mln8981k
bb-step-test-mln872rm
bb-debug-test-mln83q18
bb-switch-test-mln7xyls
bb-join-test-mln7xyls
bb-linus-swarm
bb-agent-graph-1
bb-1xj
bb-agent-a
bb-agent-b
bb-active-agent
bb-agent-ui-1
bb-green-falcon
bb-zenchantlive
bb-silver-castle
bb-test-agent
bb-atf
bb-z6s
bb-54x
bb-nuy
bb-98c
bb-3ha
bb-22l
bb-5am
bb-dwz
bb-3dv
bb-only-ui-agent
bb-graph-agent-1
bb-ui-agent-2
bb-ui-agent-1
bb-verify-mlnavzwu
bb-final-mlnar702
bb-verify2-mlnaouad
bb-final-mlnalaqz
bb-bridge-fix-mlnaja4j
bb-verify-mlnadaip
bb-switch-mlna9nbo
bb-join-mlna9nbo
bb-invepic-mln9perd
bb-m2-mln9perd
bb-invalid-epic-mln9hraq
bb-m1-mln9perd
bb-leave-mln9perd
bb-member3-mln9hraq
bb-member2-mln9hraq
bb-member1-mln9hraq
bb-switch-mln9perd
bb-nolabel-test-mln9hraq
bb-join-mln9perd
bb-leave-test-mln9hraq
bb-idem-test-mln9hraq
bb-debug-mln9knzs
bb-switch-test-mln9hraq
bb-join-test-mln9hraq
bb-smoke-mln9e525
bb-idem-test-mln97lyt
bb-switch-test-mln97lyt
bb-join-test-mln97lyt
bb-switch-test-mln8xxn4
bb-join-test-mln8xxn4
bb-nolabel-test-mln8pdgh
bb-leave-test-mln8pdgh
bb-idem-test-mln8pdgh
bb-switch-test-mln8pdgh
bb-join-test-mln8pdgh
bb-leave-test-mln8hp8j
bb-idem-test-mln8hp8j
bb-switch-test-mln8hp8j
bb-join-test-mln8hp8j
bb-daemon-test-mln8e4tf
bb-fresh-test-mln8canu
bb-upd-test-mln8981k
bb-step-test-mln872rm
bb-debug-test-mln83q18
bb-switch-test-mln7xyls
bb-join-test-mln7xyls
bb-linus-swarm
bb-agent-graph-1
bb-1xj
bb-agent-a
bb-agent-b
bb-active-agent
bb-agent-ui-1
bb-green-falcon
bb-zenchantlive
bb-silver-castle
bb-test-agent

View file

@ -1,53 +1,53 @@
# Agent Workflow for Beadboard
As an agent working in this repository, you must follow these rules when managing tasks using `bd`.
---
## 1. Finding Work
Before starting any new work, check if there's already an open task for it.
```bash
bd ready
```
*If a task is ready, pick it up instead of creating a duplicate.*
## 2. Starting Work / Tracking Plans
When asked to perform non-trivial work without an existing task, **always create a task**.
Do **not** keep your plan in free-form text. Create a task with `priority 0`.
```bash
bd create "Short descriptive title of the work" -p 0
```
Update the status to `in_progress` if you are working on it:
```bash
bd set-state <task-id> in_progress
```
## 3. Working within Tasks (task.md)
Update the local `<appDataDir>/brain/<conversation-id>/task.md` using the checklist `[ ]`, `[/]`, `[x]` to maintain your internal progress while working. Also update the `bd` task if you have significant architectural notes.
## 4. Dependencies
If your task depends on another task being completed first, declare the block:
```bash
# Link: your task is blocked by another task
# First run bd dep add, it will prompt you interactively.
# Or use the appropriate arguments if you know them.
# The user prefers bd handle these rather than prose "do X after Y"
```
## 5. Finishing Work
When you have finished a task, completed your tests, and verified it works (run your lint/typecheck steps), you must close the task.
1. **Verify completion**: `bun run typecheck && bun run lint`
2. **Close the bead**:
```bash
# You can use bd update or bd close
bd status <task-id> # To view it
bd close <task-id> # To mark it closed
```
3. **Summarize**: Leave a summary of what changed. (You can do this by using bd edit or through a comment if bd supports it, otherwise summarize in your git commit).
## 6. Verifying Past Work (Recently Closed Beads)
If you need to know what was just finished (e.g. to see if a bead was successfully closed), view the recently closed beads:
```bash
bd query "status=closed" --sort closed --reverse --limit 5
```
# Agent Workflow for Beadboard
As an agent working in this repository, you must follow these rules when managing tasks using `bd`.
---
## 1. Finding Work
Before starting any new work, check if there's already an open task for it.
```bash
bd ready
```
*If a task is ready, pick it up instead of creating a duplicate.*
## 2. Starting Work / Tracking Plans
When asked to perform non-trivial work without an existing task, **always create a task**.
Do **not** keep your plan in free-form text. Create a task with `priority 0`.
```bash
bd create "Short descriptive title of the work" -p 0
```
Update the status to `in_progress` if you are working on it:
```bash
bd set-state <task-id> in_progress
```
## 3. Working within Tasks (task.md)
Update the local `<appDataDir>/brain/<conversation-id>/task.md` using the checklist `[ ]`, `[/]`, `[x]` to maintain your internal progress while working. Also update the `bd` task if you have significant architectural notes.
## 4. Dependencies
If your task depends on another task being completed first, declare the block:
```bash
# Link: your task is blocked by another task
# First run bd dep add, it will prompt you interactively.
# Or use the appropriate arguments if you know them.
# The user prefers bd handle these rather than prose "do X after Y"
```
## 5. Finishing Work
When you have finished a task, completed your tests, and verified it works (run your lint/typecheck steps), you must close the task.
1. **Verify completion**: `bun run typecheck && bun run lint`
2. **Close the bead**:
```bash
# You can use bd update or bd close
bd status <task-id> # To view it
bd close <task-id> # To mark it closed
```
3. **Summarize**: Leave a summary of what changed. (You can do this by using bd edit or through a comment if bd supports it, otherwise summarize in your git commit).
## 6. Verifying Past Work (Recently Closed Beads)
If you need to know what was just finished (e.g. to see if a bead was successfully closed), view the recently closed beads:
```bash
bd query "status=closed" --sort closed --reverse --limit 5
```

View file

@ -1,52 +1,52 @@
# Beadboard Dolt System Workflow
Beadboard supports an optional **Dolt storage backend**. Dolt is a SQL database with git-like version control, enabling advanced features like branching, merging, and historic diffs for your issue data.
If your environment has Dolt enabled (no CGO build errors when using `bd`), you have access to powerful new version control commands. They behave similarly to `git` but operate purely on Beadboard issues.
## 1. Branching
You can create branches of your issue database, to test speculative features or isolate a swarm of issues before merging them into main.
- **List all branches**:
```bash
bd branch
```
- **Create a new branch**:
```bash
bd branch <branch-name>
```
## 2. Version Control (Commit & Merge)
Use `bd vc` to manage commits on your branch.
- **View status of current branch**:
```bash
bd vc status
```
- **Create a commit**:
```bash
bd vc commit
```
- **Merge a branch**:
```bash
bd vc merge <branch-to-merge>
```
*Note: You can also rely on `--dolt-auto-commit=on` (which can be set in config) to automatically commit changes after write operations like `bd create` or `bd update`.*
## 3. Viewing Diffs
You can view the exact issue changes (created, deleted, modified) between two commits or branches.
- **Compare current state against a branch**:
```bash
bd diff main feature-branch
```
- **Compare history**:
```bash
bd diff HEAD~5 HEAD # Show changes in the last 5 commits
```
## Summary for Agents
If you receive an error about `dolt backend requires CGO` when running `bd ready`, it means the Dolt features are not available on this specific build. You must fall back to standard `bd` commands which use SQLite by default and sync via JSONL files.
However, when working in a Dolt-enabled environment, you should proactively create a branch when starting a large Epic (`bd branch feature-xyz`), commit your `bd` issue changes natively tracking the state (`bd vc commit`), and merge them back when the epic is verified (`bd vc merge`).
# Beadboard Dolt System Workflow
Beadboard supports an optional **Dolt storage backend**. Dolt is a SQL database with git-like version control, enabling advanced features like branching, merging, and historic diffs for your issue data.
If your environment has Dolt enabled (no CGO build errors when using `bd`), you have access to powerful new version control commands. They behave similarly to `git` but operate purely on Beadboard issues.
## 1. Branching
You can create branches of your issue database, to test speculative features or isolate a swarm of issues before merging them into main.
- **List all branches**:
```bash
bd branch
```
- **Create a new branch**:
```bash
bd branch <branch-name>
```
## 2. Version Control (Commit & Merge)
Use `bd vc` to manage commits on your branch.
- **View status of current branch**:
```bash
bd vc status
```
- **Create a commit**:
```bash
bd vc commit
```
- **Merge a branch**:
```bash
bd vc merge <branch-to-merge>
```
*Note: You can also rely on `--dolt-auto-commit=on` (which can be set in config) to automatically commit changes after write operations like `bd create` or `bd update`.*
## 3. Viewing Diffs
You can view the exact issue changes (created, deleted, modified) between two commits or branches.
- **Compare current state against a branch**:
```bash
bd diff main feature-branch
```
- **Compare history**:
```bash
bd diff HEAD~5 HEAD # Show changes in the last 5 commits
```
## Summary for Agents
If you receive an error about `dolt backend requires CGO` when running `bd ready`, it means the Dolt features are not available on this specific build. You must fall back to standard `bd` commands which use SQLite by default and sync via JSONL files.
However, when working in a Dolt-enabled environment, you should proactively create a branch when starting a large Epic (`bd branch feature-xyz`), commit your `bd` issue changes natively tracking the state (`bd vc commit`), and merge them back when the epic is verified (`bd vc merge`).

View file

@ -1,49 +1,49 @@
# Viewing Recently Closed Beads
When you need to find beads (tasks, issues) that were recently closed, use `bd query` or `bd list` with date filters.
The user rule indicates a need to "correctly view the last closed beads (there is some sort of filter for recency)".
## Method 1: Using `bd query`
`bd query` supports a simple query language with relative and absolute dates.
1. **View closed beads in the last X days**
```bash
bd query "status=closed AND updated>2d" --sort updated
```
*This finds beads closed and updated within the last 2 days, sorted chronologically with newest at the bottom.*
2. **View closed beads in the last 24 hours**
```bash
bd query "status=closed AND updated>24h" --sort updated
```
3. **View everything closed**
```bash
bd query "status=closed" --sort closed --limit 10 --reverse
```
*This shows the 10 most recently closed beads (requires --reverse so limit grabs the newest).*
## Method 2: Using `bd list`
`bd list` has specific flags for filtering by closure date.
1. **View closed beads using --closed-after**
```bash
bd list --status closed --closed-after "7d" --sort closed --reverse
```
Wait, the `--closed-after` flag expects YYYY-MM-DD or RFC3339. The better approach for relative dates is `bd query`.
However, if using absolute dates:
```bash
bd list --status closed --closed-after 2025-01-01 --sort closed --reverse
```
## Summary for Agents:
**Always use `bd query` with relative time for the best results** when checking recency.
To view recently closed beads (within the last 3 days) in standard terminal chronological order (oldest at top, newest at bottom):
**`bd query "status=closed AND closed>3d" --sort closed`**
To get just the last 5 closed beads (note: you must use --reverse to get the most recent ones when using --limit):
**`bd query "status=closed" --sort closed --reverse --limit 5`**
# Viewing Recently Closed Beads
When you need to find beads (tasks, issues) that were recently closed, use `bd query` or `bd list` with date filters.
The user rule indicates a need to "correctly view the last closed beads (there is some sort of filter for recency)".
## Method 1: Using `bd query`
`bd query` supports a simple query language with relative and absolute dates.
1. **View closed beads in the last X days**
```bash
bd query "status=closed AND updated>2d" --sort updated
```
*This finds beads closed and updated within the last 2 days, sorted chronologically with newest at the bottom.*
2. **View closed beads in the last 24 hours**
```bash
bd query "status=closed AND updated>24h" --sort updated
```
3. **View everything closed**
```bash
bd query "status=closed" --sort closed --limit 10 --reverse
```
*This shows the 10 most recently closed beads (requires --reverse so limit grabs the newest).*
## Method 2: Using `bd list`
`bd list` has specific flags for filtering by closure date.
1. **View closed beads using --closed-after**
```bash
bd list --status closed --closed-after "7d" --sort closed --reverse
```
Wait, the `--closed-after` flag expects YYYY-MM-DD or RFC3339. The better approach for relative dates is `bd query`.
However, if using absolute dates:
```bash
bd list --status closed --closed-after 2025-01-01 --sort closed --reverse
```
## Summary for Agents:
**Always use `bd query` with relative time for the best results** when checking recency.
To view recently closed beads (within the last 3 days) in standard terminal chronological order (oldest at top, newest at bottom):
**`bd query "status=closed AND closed>3d" --sort closed`**
To get just the last 5 closed beads (note: you must use --reverse to get the most recent ones when using --limit):
**`bd query "status=closed" --sort closed --reverse --limit 5`**

25
install/manifest.json Normal file
View file

@ -0,0 +1,25 @@
{
"version": "installer.v1",
"distribution": {
"packageName": "beadboard",
"shimNames": ["bb", "beadboard"]
},
"wrappers": {
"windows": {
"script": "install.ps1"
},
"posix": {
"script": "install.sh"
}
},
"runtime": {
"start": "beadboard start",
"open": "beadboard open",
"status": "beadboard status"
},
"driver": {
"remediationMode": "detect_only",
"installSideEffects": false
}
}

12
next-env.d.ts vendored
View file

@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View file

@ -1,6 +1,6 @@
import type { NextConfig } from 'next';
import path from 'node:path';
import type { NextConfig } from 'next';
import path from 'node:path';
const nextConfig: NextConfig = {
reactStrictMode: true,
outputFileTracingRoot: path.join(process.cwd()),
@ -32,9 +32,9 @@ const nextConfig: NextConfig = {
if (dev) {
// Avoid intermittent Windows ENOENT errors from webpack filesystem pack cache.
config.cache = false;
}
return config;
},
};
export default nextConfig;
}
return config;
},
};
export default nextConfig;

View file

@ -1,39 +1,39 @@
import { DependencyGraphPage } from '../../components/graph/dependency-graph-page';
export const dynamic = 'force-dynamic';
import { readIssuesForScope } from '../../lib/aggregate-read';
import { resolveProjectScope } from '../../lib/project-scope';
import { listProjects } from '../../lib/registry';
interface GraphPageProps {
searchParams?: Promise<Record<string, string | string[] | undefined>>;
}
export default async function GraphPage({ searchParams }: GraphPageProps) {
const params = (await searchParams) ?? {};
const requestedProjectKey = typeof params.project === 'string' ? params.project : null;
const requestedMode = typeof params.mode === 'string' ? params.mode : null;
const registryProjects = await listProjects();
const scope = resolveProjectScope({
currentProjectRoot: process.cwd(),
registryProjects,
requestedProjectKey,
requestedMode,
});
import { DependencyGraphPage } from '../../components/graph/dependency-graph-page';
export const dynamic = 'force-dynamic';
import { readIssuesForScope } from '../../lib/aggregate-read';
import { resolveProjectScope } from '../../lib/project-scope';
import { listProjects } from '../../lib/registry';
interface GraphPageProps {
searchParams?: Promise<Record<string, string | string[] | undefined>>;
}
export default async function GraphPage({ searchParams }: GraphPageProps) {
const params = (await searchParams) ?? {};
const requestedProjectKey = typeof params.project === 'string' ? params.project : null;
const requestedMode = typeof params.mode === 'string' ? params.mode : null;
const registryProjects = await listProjects();
const scope = resolveProjectScope({
currentProjectRoot: process.cwd(),
registryProjects,
requestedProjectKey,
requestedMode,
});
const issues = await readIssuesForScope({
mode: scope.mode,
selected: scope.selected,
scopeOptions: scope.options,
preferBd: true,
});
return (
<DependencyGraphPage
issues={issues}
projectRoot={scope.selected.root}
projectScopeKey={scope.selected.key}
projectScopeOptions={scope.options}
projectScopeMode={scope.mode}
/>
);
}
return (
<DependencyGraphPage
issues={issues}
projectRoot={scope.selected.root}
projectScopeKey={scope.selected.key}
projectScopeOptions={scope.options}
projectScopeMode={scope.mode}
/>
);
}

View file

@ -1,37 +1,37 @@
import { KanbanPage } from '../components/kanban/kanban-page';
import { readIssuesForScope } from '../lib/aggregate-read';
import { resolveProjectScope } from '../lib/project-scope';
import { listProjects } from '../lib/registry';
interface PageProps {
searchParams?: Promise<Record<string, string | string[] | undefined>>;
}
export default async function Page({ searchParams }: PageProps) {
const params = (await searchParams) ?? {};
const requestedProjectKey = typeof params.project === 'string' ? params.project : null;
const requestedMode = typeof params.mode === 'string' ? params.mode : null;
const registryProjects = await listProjects();
const scope = resolveProjectScope({
currentProjectRoot: process.cwd(),
registryProjects,
requestedProjectKey,
requestedMode,
});
import { KanbanPage } from '../components/kanban/kanban-page';
import { readIssuesForScope } from '../lib/aggregate-read';
import { resolveProjectScope } from '../lib/project-scope';
import { listProjects } from '../lib/registry';
interface PageProps {
searchParams?: Promise<Record<string, string | string[] | undefined>>;
}
export default async function Page({ searchParams }: PageProps) {
const params = (await searchParams) ?? {};
const requestedProjectKey = typeof params.project === 'string' ? params.project : null;
const requestedMode = typeof params.mode === 'string' ? params.mode : null;
const registryProjects = await listProjects();
const scope = resolveProjectScope({
currentProjectRoot: process.cwd(),
registryProjects,
requestedProjectKey,
requestedMode,
});
const issues = await readIssuesForScope({
mode: scope.mode,
selected: scope.selected,
scopeOptions: scope.options,
preferBd: true,
});
return (
<KanbanPage
issues={issues}
projectRoot={scope.selected.root}
projectScopeKey={scope.selected.key}
projectScopeOptions={scope.options}
projectScopeMode={scope.mode}
/>
);
}
return (
<KanbanPage
issues={issues}
projectRoot={scope.selected.root}
projectScopeKey={scope.selected.key}
projectScopeOptions={scope.options}
projectScopeMode={scope.mode}
/>
);
}

View file

@ -1,140 +1,140 @@
#!/usr/bin/env node
/**
* bb-init.mjs - Agent Session Bootstrapper (Lease-Based)
*
* Part of Operative Protocol v1 (bb-u6f.6.3)
*
* Responsibility:
* 1. Resolve bb.ps1 path.
* 2. Identify agent (adopt or register).
* 3. Start the initial activity lease.
*
* Note: No background processes are spawned. Liveness is maintained
* via passive side-effects of CLI commands (Activity-based model).
*/
import { parseArgs } from 'node:util';
import fs from 'node:fs/promises';
import path from 'node:path';
import os from 'node:os';
import { execSync, execFileSync } from 'node:child_process';
function log(obj) {
process.stdout.write(`${JSON.stringify(obj, null, 2)}
`);
}
function error(code, message) {
log({ ok: false, error: { code, message } });
process.exit(1);
}
async function getUncommittedChanges(projectRoot) {
try {
const out = execSync('git status --porcelain', { cwd: projectRoot, encoding: 'utf8' });
return out.split('\n')
.filter(Boolean)
.map(line => line.slice(3).trim())
.filter(p => !p.startsWith('.beadboard') && !p.startsWith('.beads'));
} catch {
return [];
}
}
async function resolveBbPath() {
const envRepo = process.env.BB_REPO;
const tsEntry = path.join(process.cwd(), 'tools', 'bb.ts');
try {
await fs.access(tsEntry);
return { type: 'tsx', path: tsEntry };
} catch {}
if (envRepo) {
const p = path.join(envRepo, 'bb.ps1');
try {
await fs.access(p);
return { type: 'powershell', path: p };
} catch {}
const envTs = path.join(envRepo, 'tools', 'bb.ts');
try {
await fs.access(envTs);
return { type: 'tsx', path: envTs };
} catch {}
}
return null;
}
async function main() {
const { values } = parseArgs({
options: {
'non-interactive': { type: 'boolean' },
adopt: { type: 'string' },
register: { type: 'string' },
role: { type: 'string' },
json: { type: 'boolean' },
'project-root': { type: 'string' }
}
});
const isNonInteractive = values['non-interactive'];
const projectRoot = values['project-root'] || process.cwd();
const bbResult = await resolveBbPath();
if (!bbResult) {
error('BB_NOT_FOUND', 'Could not resolve bb.ps1 or tools/bb.ts');
}
let agentId = values.adopt || values.register;
let mode = values.adopt ? 'adopt' : (values.register ? 'register' : 'auto');
if (mode === 'auto' && isNonInteractive) {
error('AMBIGUOUS_SESSION', 'In non-interactive mode, --adopt or --register is required.');
}
if (mode === 'adopt') {
const changes = await getUncommittedChanges(projectRoot);
if (changes.length === 0 && isNonInteractive) {
error('ADOPTION_REJECTED', 'No evidence (uncommitted changes) to support identity adoption.');
}
}
try {
// Compose environment fingerprint (Rig)
const rigId = `${os.platform()}-${os.arch()}-${os.hostname()}`;
const env = { ...process.env, BD_DB: path.join(projectRoot, '.beads', 'beads.db') };
if (mode === 'register') {
const role = values.role || 'agent';
const registerArgs = bbResult.type === 'tsx'
? ['tsx', bbResult.path, 'agent', 'register', '--name', agentId, '--role', role, '--rig', rigId, '--json']
: ['agent', 'register', '--name', agentId, '--role', role, '--rig', rigId, '--json'];
const registerCmd = bbResult.type === 'tsx' ? 'npx' : bbResult.path;
execFileSync(registerCmd, registerArgs, { stdio: 'ignore', cwd: projectRoot, env });
} else {
// Start/Extend the lease to show we are now active
const leaseArgs = bbResult.type === 'tsx'
? ['tsx', bbResult.path, 'agent', 'activity-lease', '--agent', agentId, '--json']
: ['agent', 'activity-lease', '--agent', agentId, '--json'];
const leaseCmd = bbResult.type === 'tsx' ? 'npx' : bbResult.path;
execFileSync(leaseCmd, leaseArgs, { stdio: 'ignore', cwd: projectRoot, env });
}
log({
ok: true,
agent_id: agentId,
mode,
lease: { status: 'active', note: 'Activity lease started. Liveness maintained via real work.' },
timestamp: new Date().toISOString()
});
} catch (err) {
error('INIT_FAILED', err.message);
}
}
#!/usr/bin/env node
/**
* bb-init.mjs - Agent Session Bootstrapper (Lease-Based)
*
* Part of Operative Protocol v1 (bb-u6f.6.3)
*
* Responsibility:
* 1. Resolve bb.ps1 path.
* 2. Identify agent (adopt or register).
* 3. Start the initial activity lease.
*
* Note: No background processes are spawned. Liveness is maintained
* via passive side-effects of CLI commands (Activity-based model).
*/
import { parseArgs } from 'node:util';
import fs from 'node:fs/promises';
import path from 'node:path';
import os from 'node:os';
import { execSync, execFileSync } from 'node:child_process';
function log(obj) {
process.stdout.write(`${JSON.stringify(obj, null, 2)}
`);
}
function error(code, message) {
log({ ok: false, error: { code, message } });
process.exit(1);
}
async function getUncommittedChanges(projectRoot) {
try {
const out = execSync('git status --porcelain', { cwd: projectRoot, encoding: 'utf8' });
return out.split('\n')
.filter(Boolean)
.map(line => line.slice(3).trim())
.filter(p => !p.startsWith('.beadboard') && !p.startsWith('.beads'));
} catch {
return [];
}
}
async function resolveBbPath() {
const envRepo = process.env.BB_REPO;
const tsEntry = path.join(process.cwd(), 'tools', 'bb.ts');
try {
await fs.access(tsEntry);
return { type: 'tsx', path: tsEntry };
} catch {}
if (envRepo) {
const p = path.join(envRepo, 'bb.ps1');
try {
await fs.access(p);
return { type: 'powershell', path: p };
} catch {}
const envTs = path.join(envRepo, 'tools', 'bb.ts');
try {
await fs.access(envTs);
return { type: 'tsx', path: envTs };
} catch {}
}
return null;
}
async function main() {
const { values } = parseArgs({
options: {
'non-interactive': { type: 'boolean' },
adopt: { type: 'string' },
register: { type: 'string' },
role: { type: 'string' },
json: { type: 'boolean' },
'project-root': { type: 'string' }
}
});
const isNonInteractive = values['non-interactive'];
const projectRoot = values['project-root'] || process.cwd();
const bbResult = await resolveBbPath();
if (!bbResult) {
error('BB_NOT_FOUND', 'Could not resolve bb.ps1 or tools/bb.ts');
}
let agentId = values.adopt || values.register;
let mode = values.adopt ? 'adopt' : (values.register ? 'register' : 'auto');
if (mode === 'auto' && isNonInteractive) {
error('AMBIGUOUS_SESSION', 'In non-interactive mode, --adopt or --register is required.');
}
if (mode === 'adopt') {
const changes = await getUncommittedChanges(projectRoot);
if (changes.length === 0 && isNonInteractive) {
error('ADOPTION_REJECTED', 'No evidence (uncommitted changes) to support identity adoption.');
}
}
try {
// Compose environment fingerprint (Rig)
const rigId = `${os.platform()}-${os.arch()}-${os.hostname()}`;
const env = { ...process.env, BD_DB: path.join(projectRoot, '.beads', 'beads.db') };
if (mode === 'register') {
const role = values.role || 'agent';
const registerArgs = bbResult.type === 'tsx'
? ['tsx', bbResult.path, 'agent', 'register', '--name', agentId, '--role', role, '--rig', rigId, '--json']
: ['agent', 'register', '--name', agentId, '--role', role, '--rig', rigId, '--json'];
const registerCmd = bbResult.type === 'tsx' ? 'npx' : bbResult.path;
execFileSync(registerCmd, registerArgs, { stdio: 'ignore', cwd: projectRoot, env });
} else {
// Start/Extend the lease to show we are now active
const leaseArgs = bbResult.type === 'tsx'
? ['tsx', bbResult.path, 'agent', 'activity-lease', '--agent', agentId, '--json']
: ['agent', 'activity-lease', '--agent', agentId, '--json'];
const leaseCmd = bbResult.type === 'tsx' ? 'npx' : bbResult.path;
execFileSync(leaseCmd, leaseArgs, { stdio: 'ignore', cwd: projectRoot, env });
}
log({
ok: true,
agent_id: agentId,
mode,
lease: { status: 'active', note: 'Activity lease started. Liveness maintained via real work.' },
timestamp: new Date().toISOString()
});
} catch (err) {
error('INIT_FAILED', err.message);
}
}
main();

View file

@ -1,41 +1,41 @@
import { chromium } from 'playwright';
import path from 'node:path';
import fs from 'node:fs/promises';
const url = process.argv[2];
if (!url) {
console.error('Usage: node scripts/capture-graph.mjs <url>');
process.exit(1);
}
const outputDir = path.join('artifacts');
await fs.mkdir(outputDir, { recursive: true });
const browser = await chromium.launch({ headless: true });
async function screenshot(name, viewport, prepare) {
const page = await browser.newPage({ viewport });
await page.goto(url, { waitUntil: 'networkidle' });
await page.waitForTimeout(1000);
if (prepare) {
await prepare(page);
await page.waitForTimeout(450);
}
await page.screenshot({
path: path.join(outputDir, name),
fullPage: true,
});
await page.close();
}
await screenshot('graph-next-1440.png', { width: 1440, height: 900 });
await screenshot('graph-next-768.png', { width: 768, height: 1024 });
await screenshot('graph-next-390-overview.png', { width: 390, height: 844 });
await screenshot('graph-next-390-flow.png', { width: 390, height: 844 }, async (page) => {
const flowButton = page.getByRole('button', { name: 'Switch to Graph' });
if (await flowButton.count()) {
await flowButton.first().click();
}
});
await browser.close();
import { chromium } from 'playwright';
import path from 'node:path';
import fs from 'node:fs/promises';
const url = process.argv[2];
if (!url) {
console.error('Usage: node scripts/capture-graph.mjs <url>');
process.exit(1);
}
const outputDir = path.join('artifacts');
await fs.mkdir(outputDir, { recursive: true });
const browser = await chromium.launch({ headless: true });
async function screenshot(name, viewport, prepare) {
const page = await browser.newPage({ viewport });
await page.goto(url, { waitUntil: 'networkidle' });
await page.waitForTimeout(1000);
if (prepare) {
await prepare(page);
await page.waitForTimeout(450);
}
await page.screenshot({
path: path.join(outputDir, name),
fullPage: true,
});
await page.close();
}
await screenshot('graph-next-1440.png', { width: 1440, height: 900 });
await screenshot('graph-next-768.png', { width: 768, height: 1024 });
await screenshot('graph-next-390-overview.png', { width: 390, height: 844 });
await screenshot('graph-next-390-flow.png', { width: 390, height: 844 }, async (page) => {
const flowButton = page.getByRole('button', { name: 'Switch to Graph' });
if (await flowButton.count()) {
await flowButton.first().click();
}
});
await browser.close();

View file

@ -1,31 +1,31 @@
import { chromium } from 'playwright';
import path from 'node:path';
const url = process.argv[2];
const mode = process.argv[3];
if (!url || !mode) {
console.error('Usage: node scripts/capture-kanban.mjs <url> <before|after>');
process.exit(1);
}
const shots = [
{ name: 'mobile', width: 390, height: 844 },
{ name: 'tablet', width: 768, height: 1024 },
{ name: 'desktop', width: 1440, height: 900 },
];
const browser = await chromium.launch({ headless: true });
for (const shot of shots) {
const page = await browser.newPage({ viewport: { width: shot.width, height: shot.height } });
await page.goto(url, { waitUntil: 'domcontentloaded' });
await page.waitForTimeout(700);
await page.screenshot({
path: path.join('artifacts', `kanban-${shot.name}-${mode}.png`),
fullPage: true,
});
await page.close();
}
await browser.close();
import { chromium } from 'playwright';
import path from 'node:path';
const url = process.argv[2];
const mode = process.argv[3];
if (!url || !mode) {
console.error('Usage: node scripts/capture-kanban.mjs <url> <before|after>');
process.exit(1);
}
const shots = [
{ name: 'mobile', width: 390, height: 844 },
{ name: 'tablet', width: 768, height: 1024 },
{ name: 'desktop', width: 1440, height: 900 },
];
const browser = await chromium.launch({ headless: true });
for (const shot of shots) {
const page = await browser.newPage({ viewport: { width: shot.width, height: shot.height } });
await page.goto(url, { waitUntil: 'domcontentloaded' });
await page.waitForTimeout(700);
await page.screenshot({
path: path.join('artifacts', `kanban-${shot.name}-${mode}.png`),
fullPage: true,
});
await page.close();
}
await browser.close();

View file

@ -1,78 +1,158 @@
---
name: beadboard-driver
description: Drive BeadBoard agent workflows with strict Operative Protocol v1 compliance. Use when handling bead lifecycle work that combines bd status commands with bb agent coordination (register/adopt, activity-lease, reserve/release, send/ack), especially in multi-agent sessions requiring silent observability and collision avoidance.
description: Complete operating manual for agents running work in external repos while humans orchestrate from BeadBoard.
---
# Beadboard Driver (Operative Protocol v1)
# BeadBoard Driver
## Overview
BeadBoard is for teams that want autonomous agents without losing control of the work.
Use this skill to run repeatable `bd` + `bb` workflows under the **Activity Lease** (Parking Permit) model. Resolve `bb` safely, bootstrap via `bb-init`, coordinate via traceable incursions, and maintain liveness through real work.
Most agent setups break down the same way: work happens quickly, but visibility collapses, handoffs get fuzzy, and “done” starts meaning “probably done.” This skill fixes that operating problem.
## Core Workflow
With BeadBoard Driver, agents execute inside the target project repo, while humans orchestrate from BeadBoard as the control plane: assign, redirect, intervene, verify, and keep a durable coordination record.
BeadBoard project:
- GitHub: `https://github.com/zenchantlive/beadboard`
## What This Changes
- Work becomes observable, not performative.
- Ownership stays explicit at bead level.
- Handoffs and blockers become machine-readable events.
- Completion claims require evidence, not confidence.
- Multi-agent execution stays coordinated instead of chaotic.
## Operating Reality
- Agents usually run in a non-BeadBoard target repo.
- The user controls project scope from BeadBoard UI.
- Agents execute the current repo context they were assigned.
- `bd` remains source of truth for task/memory state.
## Start Here
Run this quick confidence check before you start a session:
1. **Bootstrap & Handshake**:
Run `bb-init` to resolve paths and identify yourself. Use `--adopt` if resuming a task with uncommitted changes.
```bash
node scripts/bb-init.mjs --register <agent-name> --role <role> --json
# OR
node scripts/bb-init.mjs --adopt <prior-agent-id> --non-interactive --json
bd --version
node skills/beadboard-driver/scripts/session-preflight.mjs
node skills/beadboard-driver/scripts/resolve-bb.mjs
```
2. **Claim Territory**:
Reserve your work surface before making edits to prevent silent collisions.
If discovery fails, install/repair from:
- `https://github.com/zenchantlive/beadboard`
## Session Runbook
1. Diagnose environment.
2. Confirm preflight/discovery.
3. Establish session identity.
4. Read memory + ready work.
5. Claim bead with assignee.
6. Execute and coordinate via events.
7. Run verification gates.
8. Publish evidence and close.
9. Perform memory review.
## Core Commands
```bash
& "$env:BB_REPO\bb.ps1" agent reserve --agent <agent-id> --scope "src/lib/*" --bead <bead-id>
bd update <bead-id> --status in_progress --claim
# Diagnostics and discovery
node skills/beadboard-driver/scripts/diagnose-env.mjs
node skills/beadboard-driver/scripts/session-preflight.mjs
node skills/beadboard-driver/scripts/resolve-bb.mjs
# Ensure project context exists in the target repository
node skills/beadboard-driver/scripts/ensure-project-context.mjs --project-root <repo>
# Identity helper
node skills/beadboard-driver/scripts/generate-agent-name.mjs
# Closeout evidence envelope
node skills/beadboard-driver/scripts/readiness-report.mjs --checks '<json>' --artifacts '<json>'
# Safe self-healing (dry-run default)
node skills/beadboard-driver/scripts/heal-common-issues.mjs --project-root <repo>
node skills/beadboard-driver/scripts/heal-common-issues.mjs --project-root <repo> --apply --fix-git-index-lock
```
3. **Physical Change -> Contextual Lookup**:
If you encounter uncommitted changes in a file you didn't personally edit: **STOP and Query**.
## Bead Lifecycle (Minimum Contract)
```bash
& "$env:BB_REPO\bb.ps1" agent status --agent <agent-id>
& "$env:BB_REPO\bb.ps1" agent inbox --agent <agent-id> --state unread
# Read context
bd show <memory-or-task-id>
bd ready
# Claim explicitly
bd update <bead-id> --status in_progress --assignee <agent-bead-id>
# Record evidence and close
bd update <bead-id> --notes "<commands + outputs>"
bd close <bead-id> --reason "<completed outcome>"
```
4. **Explain Deltas**:
Send high-fidelity signals when you hit milestones or incursions.
## Use-The-Right-Doc Map
### `references/memory-system.md`
Use when you need to query/apply/create canonical memory, validate provenance, or decide whether a lesson belongs in memory vs task notes.
### `references/coord-events-sessions-ack.md`
Use when youre coordinating handoffs/blockers/incursions and need correct inbox/read/ack behavior.
### `references/session-lifecycle.md`
Use for end-to-end session choreography and closeout hygiene.
### `references/archetypes-templates-swarms.md`
Use when choosing team shape, role boundaries, and swarm ownership patterns.
### `references/missions-realtime.md`
Use when assigning work and troubleshooting stale/live-update behavior from mission/event flow.
### `references/command-matrix.md`
Use when you need exact command surfaces and argument shape.
### `references/failure-modes.md`
Use when preflight/discovery/coordination fails and you need deterministic recovery.
## Project Context Template
The skill ships a source template file: `project.template.md`.
Runtime contract:
- Agents should use `<target-repo>/project.md` for project context.
- If `<target-repo>/project.md` is missing, create it from `project.template.md`.
- If `<target-repo>/project.md` already exists, do not overwrite it.
Helper command:
```bash
& "$env:BB_REPO\bb.ps1" agent send --from <agent-id> --to <peer> --bead <bead-id> --category INFO --subject "Patched parser.ts for UI sync" --body "..."
node skills/beadboard-driver/scripts/ensure-project-context.mjs --project-root <repo>
```
5. **Liveness Maintenance**:
Liveness is **Passive**. Any `bb agent` command extends your lease. Use `activity-lease` if you haven't run a command in > 10 minutes.
## Tests
Skill-local contracts:
- `skills/beadboard-driver/tests/run-tests.mjs`
- `skills/beadboard-driver/tests/*.contract.test.mjs`
Repo-level coverage:
- `tests/skills/beadboard-driver/*.test.ts`
## Verification Gates
```bash
& "$env:BB_REPO\bb.ps1" agent activity-lease --agent <agent-id> --json
npm run typecheck
npm run lint
npm run test
```
6. **Closeout Evidence**:
```bash
node skills/beadboard-driver/scripts/readiness-report.mjs --checks '[{"name":"typecheck","ok":true}]' --artifacts '[{"path":"artifacts/final.png","required":true}]'
bd close <bead-id> --reason "..."
```
If failures are outside your scope, cite exact failing files/tests and continue transparently.
## Identity & Adoption Policy
## Bottom Line
- **Uniqueness**: Create one unique `adjective-noun` identity per session unless adopting.
- **Adoption Guardrails**: Adoption is ONLY allowed if uncommitted changes exist in the scope OR you own an `in_progress` bead.
- **Audit**: Every adoption triggers a `RESUME` event in the audit feed.
## Activity Lease (Parking Permit)
- **Active (0-15m)**: Lease is valid. You are protected from takeover.
- **Stale (15-30m)**: Lease expired. Others can takeover with `--takeover-stale`.
- **Evicted (30m+)**: Lease dead. Others should takeover and archive your reservation.
- **Idle (60m+)**: Ghost state. You are considered gone.
## Red Flags - STOP and Start Over
- **Silent Incursion**: Editing a reserved file without sending an `INFO` message.
- **Identity Reuse**: Reusing an agent ID from a previous session without an adoption handshake.
- **Mocking**: Implementing mocks instead of coordinating with the domain owner.
- **Terminal Pop-ups**: Spawning background workers that disrupt the user's desktop.
## References
- Command and argument contracts: `references/command-matrix.md`
- End-to-end session choreography: `references/session-lifecycle.md`
- Protocol Specification: `docs/protocols/operative-protocol-v1.md`
This skill is the bridge between fast autonomous execution and human operator trust. Use it when speed matters, but coordination quality matters more.

View file

@ -1,4 +1,4 @@
interface:
display_name: "Beadboard Driver"
short_description: "Safe bd+bb agent workflow orchestration"
default_prompt: "Use Beadboard Driver to resolve bb path, register a unique session agent, coordinate via bb agent commands, and produce verification-backed closeout notes."
short_description: "BeadBoard control-plane workflow for agents in external repos"
default_prompt: "Use BeadBoard Driver v4 to run evidence-backed bd workflow in the target repo while the user orchestrates via BeadBoard UI; do not mutate project scope, use coordination events/inbox acks, and publish verification-backed closeout notes."

View file

@ -0,0 +1,85 @@
# Project Driver Template
Use this file to define project-specific operating notes for agents using the BeadBoard Driver skill.
## Project Identity
- Project name:
- Repository root:
- Primary language/runtime:
- Primary package manager:
## BeadBoard Relationship
- BeadBoard host/UI location:
- Project registration identifier (if used):
- Notes about how this project appears in BeadBoard UI:
## Scope and Authority
- User controls project scope selection in BeadBoard UI.
- Agents do not change scope.
- Agent execution context in this repo:
## Command Baseline
- Install command:
- Build command:
- Typecheck command:
- Lint command:
- Test command:
- Smoke command (optional):
## Verification Policy Overrides
- Required gates for this project:
- Known slow gates and timeout guidance:
- Evidence format expected in bead notes:
## Environment Constraints
- OS/platform expectations:
- Required environment variables:
- Secrets handling guidance:
- Known path/shell quirks:
## Known Workarounds
Document only stable, repeatable workarounds.
1. Trigger:
- Symptom:
- Workaround:
- Verification:
- Owner:
2. Trigger:
- Symptom:
- Workaround:
- Verification:
- Owner:
## Coordination Defaults
- Default role/archetype mapping used by this project:
- Default handoff style:
- Blocker escalation policy:
- Ack expectations for blocker/handoff messages:
## Safety Guardrails
- Forbidden commands/actions for this repo:
- Files/paths requiring explicit reservation before edit:
- External systems that require human approval:
## Session Closeout Checklist
- [ ] Bead status/assignee updated
- [ ] Verification commands executed and recorded
- [ ] Artifacts attached/linked
- [ ] Memory review performed
- [ ] Follow-up beads created (if needed)
## Change Log
- YYYY-MM-DD: Initial project template completed.

Some files were not shown because too many files have changed in this diff Show more