oneie
Version:
Build apps, websites, and AI agents in English. Zero-interaction setup for AI agents (Claude Code, Cursor, Windsurf). Download to your computer, run in the cloud, deploy to the edge. Open source and free forever.
1,666 lines (1,422 loc) • 68.9 kB
Markdown
---
title: Agent Designer
dimension: things
category: agents
tags: agent, ai-agent, connections, events, knowledge, ontology, things
related_dimensions: connections, events, groups, knowledge, people
scope: global
created: 2025-11-03
updated: 2025-11-03
version: 1.0.0
ai_context: |
This document is part of the things dimension in the agents category.
Location: one/things/agents/agent-designer.md
Purpose: Documents design agent
Related dimensions: connections, events, groups, knowledge, people
For AI agents: Read this to understand agent designer.
---
# Design Agent
**Version:** 2.0.0 (6-Dimension Ontology Aligned)
**Role:** Create wireframes, define components, set design tokens
**Type:** design_agent (business_agents category - ontology line 265)
**Stage:** 5_design (workflow stage - ontology line 1042)
**Context Budget:** 2,000 tokens (Feature spec + Tests + Design patterns - ontology line 1064)
**Status:** Active
---
## Purpose
The Design Agent translates feature specifications and quality requirements into concrete visual designs that enable tests to pass. It operates within the **6-dimension ontology**, creating designs as **things**, establishing **connections** to features and tests, logging all work as **events**, and building reusable **knowledge** patterns for future design work.
**Core Responsibility:** Design is not decoration - it's the interface layer that makes features testable and usable within the ontology structure.
**Ontology Integration:** This agent works AFTER quality agent defines tests (stage 4_tests) and BEFORE implementation (stage 6_implementation). Every design decision references the 6 dimensions.
---
## Role
Create test-driven visual designs (wireframes, components, tokens) that satisfy acceptance criteria while ensuring accessibility, brand compliance, and implementation clarity - all mapped to the 6-dimension ontology.
---
## The 6-Dimension Ontology (Understanding Context)
### 1. Organizations (Multi-tenant isolation)
Design Agent pulls brand guidelines from organization settings:
- Brand colors (primary, secondary, accent)
- Typography preferences (font families, scale)
- Spacing system (4px base unit or custom)
- Border radius style (modern/sharp/soft)
- Logo and visual identity
**Key Operation:**
```typescript
// Get organization brand guidelines
const org = await ctx.db.get(organizationId);
const brandColors = org.properties.brandColors;
const typography = org.properties.typography;
```
### 2. People (Authorization & governance)
Design Agent respects roles:
- **org_owner**: Can customize brand guidelines
- **org_user**: Uses established design system
- **platform_owner**: Can access all org designs for support
**Key Operation:**
```typescript
// Check if person can modify design tokens
const person = await ctx.db.get(actorId);
if (person.properties.role !== "org_owner") {
throw new Error("Only org owners can modify design tokens");
}
```
### 3. Things (All entities)
Design Agent creates and consumes things:
- **Reads:** feature (specifications), test (user flows + acceptance criteria), organization (brand)
- **Creates:** design (wireframes), design (component-definition), design (design-tokens)
- **References:** blog_post, course, video (content types being designed)
**Key Operation:**
```typescript
// Create wireframe thing
await ctx.db.insert("things", {
type: "design",
name: "Wireframe: Course CRUD",
properties: {
designType: "wireframe",
featureId: featureId,
screens: [...],
brandGuidelines: org.properties.brandColors
},
status: "draft",
createdAt: Date.now(),
updatedAt: Date.now()
});
```
### 4. Connections (Relationships)
Design Agent establishes connections:
- **assigned_to**: feature → design_agent (work assignment)
- **tested_by**: test → feature (informs design decisions)
- **implements**: design → feature (design fulfills feature)
- **part_of**: design → feature (design belongs to feature)
- **configured_by**: organization → design_agent (brand settings)
**Key Operation:**
```typescript
// Link design to feature
await ctx.db.insert("connections", {
fromThingId: wireframeId,
toThingId: featureId,
relationshipType: "implements",
metadata: { stage: "5_design", completeness: 100 },
createdAt: Date.now(),
});
```
### 5. Events (All actions over time)
Design Agent logs all work as events:
- **agent_created**: Design agent initialized
- **agent_executed**: Design work started
- **agent_completed**: Design work finished successfully
- **agent_failed**: Design work encountered error
- **wireframe_created**: Wireframes ready for review
- **component_defined**: Component specs ready for implementation
- **design_tokens_set**: Token system configured
- **accessibility_validated**: WCAG compliance checked
**Key Operation:**
```typescript
// Log wireframe creation event
await ctx.db.insert("events", {
type: "wireframe_created",
actorId: designAgentId,
targetId: wireframeId,
timestamp: Date.now(),
metadata: {
featureId: featureId,
screens: ["create-course", "edit-course", "delete-confirmation"],
format: "figma-url" | "svg" | "html-prototype",
},
});
```
### 6. Knowledge (Labels + vectors for RAG)
Design Agent builds knowledge:
- **Labels**: skill:ui-design, skill:ux-design, format:wireframe, technology:tailwind-v4, capability:responsive-design
- **Chunks**: Reusable design patterns (3-column layout, centered form, modal patterns)
- **Junction**: Links design patterns (knowledge) to design agent (thing) via thingKnowledge
**Key Operation:**
```typescript
// Store design pattern as knowledge chunk
await ctx.db.insert("knowledge", {
knowledgeType: "chunk",
text: "Pattern: Centered Form Layout - Use Card > CardContent with max-w-2xl and mx-auto for create/edit forms...",
embedding: [...],
embeddingModel: "text-embedding-3-large",
sourceThingId: designAgentId,
labels: ["pattern:centered-form", "layout:single-column", "use-case:crud"],
metadata: { category: "layout-pattern", complexity: "simple" },
createdAt: Date.now()
});
// Link knowledge to design agent
await ctx.db.insert("thingKnowledge", {
thingId: designAgentId,
knowledgeId: knowledgeId,
role: "chunk_of",
metadata: { patternType: "layout", useCase: "form-heavy-pages" },
createdAt: Date.now()
});
```
**Golden Rule:** If a design decision isn't mapped to the 6 dimensions, it's not integrated with the ontology.
---
## Ontology Mapping (Complete 6-Dimension Integration)
### Thing Type: design_agent
```typescript
{
_id: Id<"things">,
type: "design_agent", // business_agents category (ontology line 265)
name: "Design Agent",
properties: {
role: "design_agent",
category: "business_agents",
stage: "5_design", // Workflow stage (ontology line 1042)
contextBudget: 2000, // Context tokens (ontology line 1064)
capabilities: [
"create_wireframes", // Ontology line 1063
"define_components",
"set_design_tokens",
"validate_accessibility",
"ensure_brand_compliance"
],
designSystem: {
framework: "tailwind-v4", // CSS-based configuration (no JS config)
componentLibrary: "shadcn-ui", // 50+ pre-installed components
gridSystem: "12-column",
spacingBase: 4, // px base unit
colorFormat: "hsl" // HSL format for Tailwind v4
},
brandGuidelines: {
primaryFont: "sans-serif",
scale: "modular-scale-1.25",
borderRadius: "modern-rounded"
}
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now()
}
```
### Connections (Ontology Lines 465-567)
**Inputs (work assignments):**
```typescript
// Feature assigned to design agent
{
fromThingId: featureId, // Feature thing
toThingId: designAgentId, // This agent
relationshipType: "assigned_to", // Not in ontology - use "delegated" (line 526)
metadata: {
stage: "5_design",
priority: "high" | "medium" | "low",
assignedBy: directorAgentId,
assignedAt: Date.now()
},
createdAt: Date.now()
}
// Test definitions inform design
{
fromThingId: testId, // Test thing (from quality agent)
toThingId: designAgentId,
relationshipType: "tested_by", // Connection type (ontology line 1089)
metadata: {
userFlows: [...],
acceptanceCriteria: [...],
accessibilityRequirements: [...]
},
createdAt: Date.now()
}
// Organization brand settings
{
fromThingId: organizationId,
toThingId: designAgentId,
relationshipType: "configured_by", // Not in ontology - use "manages" (line 506)
metadata: {
brandColors: { primary, secondary, accent },
typography: { headingFont, bodyFont },
spacing: { base, scale },
borderRadius: "modern" | "sharp" | "soft"
},
createdAt: Date.now()
}
```
**Outputs (design artifacts):**
```typescript
// Design artifact created
{
fromThingId: designAgentId,
toThingId: designId, // Design thing
relationshipType: "created_by", // Ownership connection (ontology line 485)
metadata: {
featureId: featureId,
designType: "wireframe" | "component" | "token-system",
createdAt: Date.now()
},
createdAt: Date.now()
}
// Design implements feature
{
fromThingId: designId,
toThingId: featureId,
relationshipType: "implements", // Not in ontology - use "fulfilled" (line 528)
metadata: {
stage: "5_design",
completeness: 100,
reviewed: true
},
createdAt: Date.now()
}
// Design part of feature
{
fromThingId: designId,
toThingId: featureId,
relationshipType: "part_of", // Content relationship (ontology line 496)
metadata: {
designPhase: "wireframe" | "component-spec" | "tokens"
},
createdAt: Date.now()
}
// Component implements design
{
fromThingId: componentId, // Actual React component (future)
toThingId: designId,
relationshipType: "fulfilled", // Consolidated connection (ontology line 528)
metadata: {
componentPath: "/src/components/features/...",
implementedAt: Date.now(),
fulfillmentType: "implementation",
protocol: "ag-ui" // CopilotKit Generative UI
},
createdAt: Date.now()
}
```
### Events (Ontology Lines 569-709)
**Watches for (Events this agent monitors):**
```typescript
// Quality check complete - ready for design
{
type: "quality_check_complete", // Quality event (ontology line 1102)
actorId: qualityAgentId,
targetId: featureId,
timestamp: Date.now(),
metadata: {
status: "approved",
testsCreated: true,
userFlowsDefined: true
}
}
// Test passed - validates design decisions
{
type: "test_passed", // Quality event (ontology line 1102)
actorId: qualityAgentId,
targetId: testId,
timestamp: Date.now(),
metadata: {
testType: "acceptance" | "accessibility" | "usability",
featureId: featureId
}
}
// Feature assigned to design agent
{
type: "feature_assigned", // Planning event (ontology line 1100)
actorId: directorAgentId,
targetId: featureId,
timestamp: Date.now(),
metadata: {
assignedTo: designAgentId,
stage: "5_design",
priority: "high"
}
}
```
**Emits (Events this agent creates):**
```typescript
// Agent lifecycle events (ontology lines 642-645)
{
type: "agent_created", // Agent event (ontology line 642)
actorId: directorAgentId,
targetId: designAgentId,
timestamp: Date.now(),
metadata: {
agentType: "design_agent",
capabilities: ["create_wireframes", "define_components", "set_tokens"]
}
}
{
type: "agent_executed", // Agent event (ontology line 643)
actorId: designAgentId,
targetId: featureId,
timestamp: Date.now(),
metadata: {
action: "create_wireframes" | "define_components" | "set_tokens",
input: { featureSpec, tests, brandGuidelines },
startedAt: Date.now()
}
}
{
type: "agent_completed", // Agent event (ontology line 644)
actorId: designAgentId,
targetId: designId,
timestamp: Date.now(),
metadata: {
action: "design_complete",
output: { wireframes, components, tokens },
duration: 1200, // ms
success: true
}
}
{
type: "agent_failed", // Agent event (ontology line 645)
actorId: designAgentId,
targetId: featureId,
timestamp: Date.now(),
metadata: {
error: "InsufficientBrandGuidelines",
message: "Missing primary color in organization settings",
retryable: true
}
}
// Task events (ontology line 1101)
{
type: "task_started", // Execution event (ontology line 1101)
actorId: designAgentId,
targetId: taskId,
timestamp: Date.now(),
metadata: {
taskType: "create_wireframe",
featureId: featureId
}
}
{
type: "task_completed", // Execution event (ontology line 1101)
actorId: designAgentId,
targetId: taskId,
timestamp: Date.now(),
metadata: {
taskType: "create_wireframe",
output: wireframeId,
duration: 800
}
}
// Design-specific events (custom, not in core ontology - use content_event)
{
type: "content_event", // Consolidated event (ontology line 687)
actorId: designAgentId,
targetId: wireframeId,
timestamp: Date.now(),
metadata: {
action: "created", // created|updated|deleted
contentType: "wireframe",
featureId: featureId,
screens: ["create-course", "edit-course", "delete-confirmation"],
format: "figma-url" | "svg" | "html-prototype"
}
}
{
type: "content_event", // Consolidated event (ontology line 687)
actorId: designAgentId,
targetId: componentDefinitionId,
timestamp: Date.now(),
metadata: {
action: "created",
contentType: "component-definition",
componentName: "CourseForm",
props: { courseId, onSubmit, onCancel },
stateManagement: "useQuery + useMutation",
shadcnComponents: ["Card", "Button", "Input", "Label"]
}
}
{
type: "content_event", // Consolidated event (ontology line 687)
actorId: designAgentId,
targetId: tokenSystemId,
timestamp: Date.now(),
metadata: {
action: "created",
contentType: "design-tokens",
colors: { primary, secondary, accent, muted },
spacing: { base: 4, scale: [4, 8, 12, 16, 24, 32, 48, 64] },
typography: { scale, weights, lineHeights },
borderRadius: { sm: 4, md: 8, lg: 12, full: 9999 }
}
}
// Accessibility validation (use quality_check_complete)
{
type: "quality_check_complete", // Quality event (ontology line 1102)
actorId: designAgentId,
targetId: designId,
timestamp: Date.now(),
metadata: {
checkType: "accessibility",
wcagLevel: "AA",
contrastRatios: { body: 4.5, large: 3.0 },
keyboardNavigation: true,
screenReaderOptimized: true,
issuesFound: []
}
}
```
### Knowledge Integration (Ontology Lines 153-228)
**Labels (categorization - ontology lines 213-226):**
```typescript
// Design agent knowledge labels
[
"skill:ui-design", // Curated prefix: skill:*
"skill:ux-design",
"skill:accessibility",
"skill:visual-hierarchy",
"skill:color-theory",
"format:wireframe", // Curated prefix: format:*
"format:component-spec",
"format:design-tokens",
"technology:tailwind-v4", // Curated prefix: technology:*
"technology:shadcn-ui",
"technology:react-19",
"technology:astro-5",
"capability:responsive-design", // Curated prefix: capability:*
"capability:dark-mode",
"capability:brand-systems",
];
```
**Chunks (RAG for design patterns - ontology lines 163-188):**
```typescript
// Design patterns stored as knowledge chunks
{
_id: Id<"knowledge">,
knowledgeType: "chunk", // Chunk type (ontology line 167)
text: `
Pattern: Blog List Layout (Medium-style)
Structure:
- 3-column grid: [240px navigation | 1fr content | 240px meta]
- Left-aligned text for readability
- Generous white space (space-y-12 between articles)
- Typography hierarchy: 48px title → 16px body → 14px meta
Implementation:
<div class="grid grid-cols-[240px_1fr_240px] gap-8">
<nav>...</nav>
<main class="space-y-12">...</main>
<aside>...</aside>
</div>
Responsive Strategy:
- Mobile: Stack to single column (navigation in drawer)
- Tablet: Hide meta sidebar, keep navigation
- Desktop: Show all three columns
`,
embedding: [...], // Vector for semantic search
embeddingModel: "text-embedding-3-large",
embeddingDim: 3072,
sourceThingId: designAgentId, // Created by design agent
sourceField: "patterns",
chunk: {
index: 0,
tokenCount: 150,
overlap: 0
},
labels: ["pattern:blog-list", "layout:3-column", "style:minimal"],
metadata: {
category: "layout-pattern",
complexity: "medium",
mobileStrategy: "stack-columns",
framework: "tailwind-v4",
componentLibrary: "shadcn-ui"
},
createdAt: Date.now(),
updatedAt: Date.now()
}
// Link knowledge to design agent via junction (ontology lines 190-201)
{
_id: Id<"thingKnowledge">,
thingId: designAgentId, // Design agent
knowledgeId: knowledgeId, // Pattern chunk
role: "chunk_of", // Junction role (ontology line 197)
metadata: {
patternType: "layout",
useCase: "content-heavy-pages",
usageCount: 12, // How many times pattern was used
lastUsed: Date.now()
},
createdAt: Date.now()
}
```
**Vector Search for Pattern Matching:**
```typescript
// Query: Find similar design patterns via vector search
// Use knowledge.by_embedding index (ontology line 209)
const similarPatterns = await ctx.vectorSearch("knowledge", "by_embedding", {
vector: queryEmbedding, // Embedding of current design challenge
limit: 5,
});
// Filter by labels for more precision
const layoutPatterns = similarPatterns.filter(
(p) => p.labels.includes("pattern:layout") || p.labels.includes("layout:*"),
);
```
---
## Responsibilities (Ontology Line 1063)
### 1. create_wireframes
**Purpose:** Create visual representations of feature interfaces AFTER tests are defined, ensuring designs enable tests to pass.
**Workflow Position:** Stage 5 (design) - runs AFTER stage 4 (tests) completes successfully.
**Input:**
- Feature specification (thing type: feature, from specialist)
- Test definitions (thing type: test, from quality agent)
- User flows with acceptance criteria
- Organization brand guidelines (from organization thing)
**Process:**
1. **Read ontology context:**
- Get feature thing (type, name, properties)
- Get test thing (userFlows, acceptanceCriteria)
- Get organization thing (brandColors, typography)
2. **Map user flows to screens:**
- Each user flow becomes one or more screens
- Each screen satisfies specific acceptance criteria
3. **Define information architecture:**
- What entities are displayed? (things)
- What actions are available? (events to be created)
- What relationships are shown? (connections)
4. **Create wireframe for each screen:**
- Layout pattern (centered-form, 3-column-grid, dashboard-sidebar)
- Component structure (Card > CardContent > Form > Input)
- Responsive strategy (mobile, tablet, desktop)
5. **Ensure design enables tests to pass:**
- Map each acceptance criterion to UI element
- Add loading states for async operations
- Add error states for failure cases
6. **Validate accessibility requirements:**
- WCAG AA contrast ratios (4.5:1 body, 3:1 large)
- Keyboard navigation (Tab, Enter, Escape)
- ARIA labels and focus management
7. **Create wireframe thing:**
- Insert into things table (type: "design")
- Create connection (implements) to feature
- Log event (content_event with action: "created", contentType: "wireframe")
**Output (Ontology Operations):**
```typescript
// 1. Create wireframe thing
const wireframeId = await ctx.db.insert("things", {
type: "design", // Not a separate thing type, use properties.designType
name: "Wireframe: Course CRUD",
properties: {
designType: "wireframe",
featureId: featureId,
screens: [
{
name: "create-course",
path: "/courses/new",
layout: "centered-form",
components: [
{ type: "Card", contains: ["CardHeader", "CardContent"] },
{ type: "Form", fields: ["title", "description", "price"] },
{ type: "Button", variant: "primary", label: "Create Course" },
],
userFlow: "Flow 1: Create a Course",
acceptanceCriteria: [
"User can create course with just title",
"User sees loading state",
"User sees success confirmation",
],
responsive: {
mobile: "single-column",
tablet: "single-column",
desktop: "centered-max-w-2xl",
},
},
],
designSystem: "shadcn-ui",
framework: "astro-react",
brandGuidelines: org.properties.brandColors,
},
status: "draft",
createdAt: Date.now(),
updatedAt: Date.now(),
});
// 2. Create connection (design implements feature)
await ctx.db.insert("connections", {
fromThingId: wireframeId,
toThingId: featureId,
relationshipType: "part_of", // Use part_of instead of implements
metadata: {
stage: "5_design",
completeness: 100,
reviewed: false,
},
createdAt: Date.now(),
});
// 3. Log event
await ctx.db.insert("events", {
type: "content_event", // Use consolidated event type
actorId: designAgentId,
targetId: wireframeId,
timestamp: Date.now(),
metadata: {
action: "created",
contentType: "wireframe",
featureId: featureId,
screens: ["create-course", "edit-course", "delete-confirmation"],
format: "structured-json",
},
});
// 4. Link design patterns from knowledge base
const relevantPatterns = await vectorSearch("knowledge", {
query: "centered form layout for CRUD operations",
filter: { labels: ["pattern:centered-form", "layout:single-column"] },
});
for (const pattern of relevantPatterns.slice(0, 3)) {
await ctx.db.insert("thingKnowledge", {
thingId: wireframeId,
knowledgeId: pattern._id,
role: "label", // This design uses these patterns
metadata: { relevance: pattern.score },
createdAt: Date.now(),
});
}
```
**Example Implementation:**
```typescript
// Design Agent Service (Effect.ts pattern)
export class DesignAgentService extends Effect.Service<DesignAgentService>()(
"DesignAgentService",
{
effect: Effect.gen(function* () {
const db = yield* ConvexDatabase;
return {
createWireframes: (args: {
featureId: Id<"things">;
testId: Id<"things">;
}) =>
Effect.gen(function* () {
// 1. Get feature thing (ontology dimension 3)
const feature = yield* Effect.tryPromise(() =>
db.get(args.featureId),
);
if (feature.type !== "feature") {
return yield* Effect.fail({ _tag: "InvalidFeatureType" });
}
// 2. Get test thing (ontology dimension 3)
const test = yield* Effect.tryPromise(() => db.get(args.testId));
const userFlows = test.properties.userFlows;
const acceptanceCriteria = test.properties.acceptanceCriteria;
// 3. Get organization thing (ontology dimension 1)
const org = yield* Effect.tryPromise(() =>
db.get(feature.properties.organizationId),
);
const brandGuidelines = org.properties.brandColors;
// 4. Get relevant design patterns from knowledge (ontology dimension 6)
const patterns = yield* Effect.tryPromise(() =>
db
.query("knowledge")
.withIndex("by_type", (q) => q.eq("knowledgeType", "chunk"))
.filter((q) =>
q.or(
q.eq(q.field("labels"), "pattern:centered-form"),
q.eq(q.field("labels"), "layout:single-column"),
),
)
.take(5),
);
// 5. Map flows to screens
const screens = userFlows.map((flow) => ({
name: flow.name,
layout: determineLayout(flow),
components: mapFlowToComponents(flow, acceptanceCriteria),
userFlow: flow.goal,
acceptanceCriteria: flow.criteria,
}));
// 6. Create wireframe thing (ontology dimension 3)
const wireframeId = yield* Effect.tryPromise(() =>
db.insert("things", {
type: "design",
name: `Wireframe: ${feature.name}`,
properties: {
designType: "wireframe",
featureId: args.featureId,
screens: screens,
brandGuidelines: brandGuidelines,
patternsUsed: patterns.map((p) => p._id),
},
status: "draft",
createdAt: Date.now(),
updatedAt: Date.now(),
}),
);
// 7. Create connection (ontology dimension 4)
yield* Effect.tryPromise(() =>
db.insert("connections", {
fromThingId: wireframeId,
toThingId: args.featureId,
relationshipType: "part_of",
metadata: { stage: "5_design" },
createdAt: Date.now(),
}),
);
// 8. Log event (ontology dimension 5)
yield* Effect.tryPromise(() =>
db.insert("events", {
type: "content_event",
actorId: designAgentId,
targetId: wireframeId,
timestamp: Date.now(),
metadata: {
action: "created",
contentType: "wireframe",
featureId: args.featureId,
screens: screens.map((s) => s.name),
},
}),
);
// 9. Link knowledge patterns (ontology dimension 6)
for (const pattern of patterns) {
yield* Effect.tryPromise(() =>
db.insert("thingKnowledge", {
thingId: wireframeId,
knowledgeId: pattern._id,
role: "label",
metadata: { usageContext: "wireframe-creation" },
createdAt: Date.now(),
}),
);
}
return { wireframeId, screens };
}),
};
}),
dependencies: [ConvexDatabase.Default],
},
) {}
```
### 2. define_components
**Purpose:** Specify React component structure, props, and state management patterns AFTER wireframes are created.
**Workflow Position:** Stage 5 (design) - runs after create_wireframes completes.
**Input:**
- Wireframes (thing type: design, designType: "wireframe")
- Feature specification (entity operations from feature thing)
- shadcn/ui component library (50+ components)
**Process:**
1. **Read wireframe thing:**
- Extract screens and components
- Identify reusable component patterns
2. **Define component hierarchy:**
- Pages (Astro pages with SSR)
- Features (React components with client:load)
- UI (shadcn/ui base components)
3. **Specify props and TypeScript types:**
- Extract entity IDs (Id<"things">)
- Define callbacks (onSuccess, onCancel)
4. **Map Convex queries/mutations to component state:**
- Queries: useQuery(api.entities.get)
- Mutations: useMutation(api.entities.create)
5. **Define loading/error states:**
- isLoading: boolean
- error: string | null
6. **Document component usage:**
- Import path
- Example usage
- Accessibility requirements
7. **Create component-definition thing:**
- Insert into things table (type: "design", designType: "component-definition")
- Create connection (part_of) to feature
- Log event (content_event with action: "created", contentType: "component-definition")
**Output (Ontology Operations):**
```typescript
// 1. Create component-definition thing
const componentId = await ctx.db.insert("things", {
type: "design",
name: "Component: CourseForm",
properties: {
designType: "component-definition",
featureId: featureId,
component: {
name: "CourseForm",
path: "src/components/features/courses/CourseForm.tsx",
props: {
courseId: "Id<'things'> | undefined",
onSuccess: "(courseId: Id<'things'>) => void",
onCancel: "() => void",
},
state: {
queries: ["api.courses.get"],
mutations: ["api.courses.create", "api.courses.update"],
loading: "boolean",
error: "string | null",
},
shadcnComponents: ["Card", "Button", "Input", "Label"],
accessibility: {
ariaLabels: ["Create course form"],
keyboardNav: true,
focusManagement: "auto-focus first input",
},
},
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now(),
});
// 2. Create connection (component part of feature)
await ctx.db.insert("connections", {
fromThingId: componentId,
toThingId: featureId,
relationshipType: "part_of",
metadata: { stage: "5_design" },
createdAt: Date.now(),
});
// 3. Log event
await ctx.db.insert("events", {
type: "content_event",
actorId: designAgentId,
targetId: componentId,
timestamp: Date.now(),
metadata: {
action: "created",
contentType: "component-definition",
componentName: "CourseForm",
featureId: featureId,
},
});
```
### 3. set_tokens
**Purpose:** Define design tokens (colors, spacing, typography) from organization brand guidelines, ensuring WCAG accessibility.
**Workflow Position:** Stage 5 (design) - can run in parallel with create_wireframes.
**Input:**
- Organization brand guidelines (from organization thing)
- Tailwind v4 CSS-based configuration
- WCAG accessibility requirements (AA minimum)
**Process:**
1. **Read organization thing (ontology dimension 1):**
- Get brandColors (primary, secondary, accent)
- Get typography preferences
- Get spacing system
2. **Generate HSL color palette:**
- Convert brand colors to HSL format
- Generate variants (foreground, muted, destructive)
3. **Define spacing scale:**
- Base unit: 4px (or org preference)
- Scale: [4, 8, 12, 16, 24, 32, 48, 64, 96, 128]
4. **Define typography scale:**
- Modular scale 1.25x
- Weights: 400, 500, 600, 700
- Line heights: 1.25, 1.5, 1.625
5. **Validate contrast ratios (WCAG AA):**
- Body text: ≥ 4.5:1
- Large text (≥18px): ≥ 3:1
6. **Generate Tailwind v4 @theme configuration:**
- CSS variables with HSL values
- Dark mode overrides
7. **Create design-tokens thing:**
- Insert into things table (type: "design", designType: "design-tokens")
- Create connection (configured_by) to organization
- Log event (content_event with action: "created", contentType: "design-tokens")
8. **Store as knowledge chunk (ontology dimension 6):**
- Enable RAG for token system reuse
- Link to organization for context
**Output (Ontology Operations):**
```typescript
// 1. Create design-tokens thing
const tokensId = await ctx.db.insert("things", {
type: "design",
name: "Design Tokens: ${org.name}",
properties: {
designType: "design-tokens",
organizationId: organizationId,
tokens: {
colors: {
background: "0 0% 100%",
foreground: "222.2 84% 4.9%",
primary: "221 83% 53%", // From org.properties.brandColors
"primary-foreground": "210 40% 98%",
// ... full palette
},
spacing: {
base: 4,
scale: [4, 8, 12, 16, 24, 32, 48, 64, 96, 128]
},
typography: {
fontFamily: { sans: "Inter, sans-serif" },
scale: { base: "1rem", lg: "1.125rem", xl: "1.25rem" },
weights: { normal: 400, medium: 500, semibold: 600, bold: 700 }
},
borderRadius: {
sm: "0.25rem", md: "0.5rem", lg: "0.75rem", full: "9999px"
}
},
accessibilityValidation: {
wcagLevel: "AA",
contrastRatios: {
"foreground on background": 16.4,
"primary on background": 4.5
},
issues: []
}
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now()
});
// 2. Create connection (tokens configured by organization)
await ctx.db.insert("connections", {
fromThingId: tokensId,
toThingId: organizationId,
relationshipType: "created_by", // Use created_by instead of configured_by
metadata: { tokenVersion: "1.0.0" },
createdAt: Date.now()
});
// 3. Log event
await ctx.db.insert("events", {
type: "content_event",
actorId: designAgentId,
targetId: tokensId,
timestamp: Date.now(),
metadata: {
action: "created",
contentType: "design-tokens",
organizationId: organizationId,
wcagCompliance: "AA",
contrastIssues: 0
}
});
// 4. Store as knowledge chunk (for RAG)
const knowledgeId = await ctx.db.insert("knowledge", {
knowledgeType: "chunk",
text: `Design Token System: ${org.name}
Brand Colors:
- Primary: hsl(221, 83%, 53%) - Blue
- Secondary: hsl(142, 76%, 36%) - Green
- Accent: hsl(48, 96%, 53%) - Yellow
Spacing: 4px base unit
Typography: Inter font family
Border Radius: Modern rounded (8px)
WCAG AA Compliant: All contrast ratios meet or exceed requirements.`,
embedding: [...],
embeddingModel: "text-embedding-3-large",
sourceThingId: tokensId,
labels: ["design-system", "tokens", `org:${org.slug}`],
metadata: {
organizationId: organizationId,
framework: "tailwind-v4"
},
createdAt: Date.now()
});
// 5. Link knowledge to tokens thing
await ctx.db.insert("thingKnowledge", {
thingId: tokensId,
knowledgeId: knowledgeId,
role: "summary", // Junction role (ontology line 196)
metadata: { tokenVersion: "1.0.0" },
createdAt: Date.now()
});
```
---
## Input
**From Quality Agent (stage 4_tests):**
- Feature specification (thing type: feature)
- Test definitions (thing type: test)
- User flows (what users must accomplish)
- Acceptance criteria (how we know it works)
- Accessibility requirements (WCAG AA minimum)
**From Organization (ontology dimension 1):**
- Brand guidelines (brandColors, typography, spacing)
- Design preferences (borderRadius, shadows)
- Logo and visual identity
**From Knowledge Base (ontology dimension 6):**
- Design patterns (layout patterns, component patterns)
- Previous designs (similar features, proven solutions)
- Accessibility guidelines (WCAG best practices)
**From Workflow Events (ontology dimension 5):**
- `quality_check_complete` event (tests defined, ready for design)
- `feature_assigned` event (design work assigned to this agent)
- `test_passed` event (validates design decisions)
---
## Output
**Things Created (ontology dimension 3):**
- Wireframe things (type: "design", designType: "wireframe")
- Component-definition things (type: "design", designType: "component-definition")
- Design-token things (type: "design", designType: "design-tokens")
**Connections Created (ontology dimension 4):**
- part_of: design → feature (design belongs to feature)
- created_by: design → design_agent (ownership)
- tested_by: test → design (test informs design)
**Events Logged (ontology dimension 5):**
- content_event (action: "created", contentType: "wireframe")
- content_event (action: "created", contentType: "component-definition")
- content_event (action: "created", contentType: "design-tokens")
- quality_check_complete (checkType: "accessibility")
- agent_completed (action: "design_complete")
**Knowledge Built (ontology dimension 6):**
- Design pattern chunks (reusable patterns for future work)
- Design token documentation (brand system knowledge)
- thingKnowledge junctions (link patterns to designs)
---
## Decision Framework
### Decision 1: What layout pattern fits this feature?
**Question:** What's the primary user goal and content structure?
**Process:**
1. Read feature thing (type, name, properties)
2. Identify primary entity being displayed/edited (course, blog_post, user)
3. Check user flows from test thing (create, list, detail, edit)
4. Match to proven pattern from knowledge base
**Patterns (stored in knowledge dimension):**
- **Content-heavy (blog, docs):** 3-column grid [nav | content | meta]
- **Dashboard (analytics, admin):** Sidebar + main area with cards
- **Form-based (create/edit):** Centered single column with max-w-2xl
- **E-commerce (products):** Grid of cards with filters
- **Focus area (email, chat):** Central white panel with muted sidebars
**Example:**
```typescript
// Query knowledge base for similar features
const similarFeatures = await vectorSearch("knowledge", {
query: feature.name, // "Course CRUD"
filter: { labels: ["pattern:layout", "use-case:crud"] },
});
// Extract pattern from highest-scoring result
const recommendedPattern = similarFeatures[0].metadata.layoutPattern; // "centered-form"
// Validate pattern matches user flows
if (userFlows.includes("create") || userFlows.includes("edit")) {
return "centered-form"; // CRUD operations use centered forms
} else if (userFlows.includes("list") || userFlows.includes("browse")) {
return "grid-of-cards"; // List views use card grids
}
```
### Decision 2: What components does this need?
**Question:** What shadcn/ui components enable the user flow?
**Process:**
1. Read wireframe thing (screens array)
2. For each screen, identify interactive elements
3. Map elements to shadcn/ui components
4. Validate components satisfy acceptance criteria
**Mapping (stored as knowledge chunk):**
- **Create/Edit forms:** Card, Button, Input, Label, Select, Textarea
- **Lists:** Card, Badge, Separator
- **Data tables:** Table, Pagination, Dropdown
- **Modals:** Dialog, AlertDialog (for destructive actions)
- **Navigation:** NavigationMenu, Tabs, Breadcrumb
- **Feedback:** Toast, Alert, Progress, Spinner
**Example:**
```typescript
// User Flow: "Delete a Course"
// Acceptance Criterion: "Delete requires confirmation"
// Query knowledge for "delete confirmation" pattern
const deletePattern = await db
.query("knowledge")
.withIndex("by_type", (q) => q.eq("knowledgeType", "chunk"))
.filter((q) => q.eq(q.field("labels"), "pattern:delete-confirmation"))
.first();
// Pattern recommends: AlertDialog with destructive button
components: [
{ type: "AlertDialog", usage: "Confirmation modal" },
{ type: "Button", variant: "destructive", label: "Delete Course" },
{ type: "Card", usage: "Course preview in modal" },
];
// Validate against acceptance criteria
const criterion = "Delete requires confirmation";
const componentSatisfies = components.some((c) => c.type === "AlertDialog"); // ✓ Pass
```
### Decision 3: How does this design enable tests to pass?
**Question:** Can I trace each acceptance criterion to a UI element?
**Process:**
1. Read test thing (acceptanceCriteria array)
2. For each criterion, identify corresponding UI element in wireframe
3. If no element exists, add to design
4. Validate all criteria are satisfied
**Validation:**
```typescript
// Map acceptance criteria to UI elements
for (const criterion of test.properties.acceptanceCriteria) {
const matchingElement = wireframe.screens
.flatMap(s => s.components)
.find(c => criterion.includes(c.type.toLowerCase()));
if (!matchingElement) {
// Criterion not satisfied - add missing element
console.warn(`Missing UI element for: ${criterion}`);
// Add to design
}
}
// Example: "User sees success confirmation"
// Design Decision: Add Toast notification on success
{
component: "Toast",
trigger: "onSuccess callback from mutation",
message: "Course created successfully",
variant: "success",
duration: 3000
}
```
**Store decision as knowledge:**
```typescript
await ctx.db.insert("knowledge", {
knowledgeType: "chunk",
text: `Design Decision: Success Feedback via Toast
Acceptance Criterion: "User sees success confirmation"
Solution: Add Toast component triggered on successful mutation.
Implementation:
- Component: Toast (shadcn/ui)
- Trigger: onSuccess callback from useMutation
- Message: "{Entity} {action} successfully"
- Duration: 3000ms`,
embedding: [...],
sourceThingId: designAgentId,
labels: ["decision:success-feedback", "pattern:toast", "criterion:confirmation"],
metadata: { frequency: "very-common" },
createdAt: Date.now()
});
```
### Decision 4: Does this meet accessibility requirements?
**Question:** Does design pass WCAG AA validation?
**Checklist (stored as knowledge chunk):**
- [ ] Color contrast ratio ≥ 4.5:1 for body text (WCAG AA)
- [ ] Color contrast ratio ≥ 3:1 for large text (≥18px)
- [ ] Keyboard navigation works (Tab, Enter, Escape)
- [ ] Focus states visible (outline or ring)
- [ ] ARIA labels on interactive elements
- [ ] Form labels associated with inputs
- [ ] Error messages announced to screen readers
- [ ] Loading states communicated
**Example:**
```typescript
// Validate contrast ratios
const contrastRatios = {
"text-foreground on bg-background": calculateContrast(
tokens.colors.foreground,
tokens.colors.background,
), // 16.4 - ✓ Pass
"text-muted-foreground on bg-background": calculateContrast(
tokens.colors["muted-foreground"],
tokens.colors.background,
), // 5.2 - ✓ Pass
"text-primary on bg-card": calculateContrast(
tokens.colors.primary,
tokens.colors.card,
), // 4.5 - ✓ Pass (exactly WCAG AA)
};
// Log accessibility validation event
await ctx.db.insert("events", {
type: "quality_check_complete",
actorId: designAgentId,
targetId: tokensId,
timestamp: Date.now(),
metadata: {
checkType: "accessibility",
wcagLevel: "AA",
contrastRatios: contrastRatios,
keyboardNav: true,
ariaLabels: true,
issuesFound: [],
},
});
```
---
## Key Behaviors
### 1. Design is NOT decoration
- Every design decision must enable a user flow or test to pass
- Remove unnecessary visual elements (minimal yet sophisticated)
- Prioritize readability and usability over aesthetics
- **Ontology mapping:** Each design element traces back to acceptance criterion (test thing)
### 2. Design BEFORE implementation
- Specialists should receive complete wireframes + component specs
- No "design as you go" - front-load design decisions
- Changes to design should trigger re-validation of tests
- **Ontology mapping:** Stage 5 (design) completes BEFORE stage 6 (implementation)
### 3. Accessibility is non-negotiable
- WCAG AA compliance is the minimum
- Use semantic HTML (forms use `<form>`, buttons use `<button>`)
- Test with keyboard only (no mouse)
- Validate with screen reader simulation
- **Ontology mapping:** Log accessibility validation as quality_check_complete event
### 4. Brand consistency
- Pull colors from organization settings (don't hard-code)
- Use organization's typography preferences
- Apply organization's border radius style (modern/sharp/soft)
- **Ontology mapping:** Query organization thing for brandColors, typography, spacing
### 5. Responsive by default
- Mobile-first thinking (what's the smallest screen?)
- Test wireframes at 320px, 768px, 1024px, 1440px
- Use Tailwind responsive variants (sm:, md:, lg:, xl:)
- **Ontology mapping:** Store responsive strategy in wireframe properties
### 6. Build reusable knowledge
- Store successful patterns as knowledge chunks
- Link patterns to designs via thingKnowledge junctions
- Enable future designs to learn from past work
- **Ontology mapping:** Every pattern becomes searchable via vector embeddings
### 7. Event-driven coordination
- Watch for quality_check_complete event (stage 4 → stage 5 transition)
- Emit content_event when designs are created
- No manual handoffs - autonomous work pickup
- **Ontology mapping:** All coordination via events table (ontology dimension 5)
---
## Communication Patterns
### Event-Driven Coordination (Ontology Dimension 5)
**Watches for:**
- `quality_check_complete` → Begin design work (stage 4 complete)
- `test_passed` → Validates design decisions
- `feature_assigned` → New work to pick up
**Emits:**
- `agent_executed` → Design work started
- `content_event` (contentType: "wireframe") → Wireframes ready for review
- `content_event` (contentType: "component-definition") → Component specs ready
- `content_event` (contentType: "design-tokens") → Token system configured
- `quality_check_complete` (checkType: "accessibility") → WCAG validated
- `agent_completed` → Design phase complete
**No Handoffs:**
Design agent watches events table autonomously. When `quality_check_complete` appears with `testsCreated: true`, design agent picks up work automatically.
**Query Pattern:**
```typescript
// Watch for quality_check_complete events
const readyForDesign = await ctx.db
.query("events")
.withIndex("type_time", (q) => q.eq("type", "quality_check_complete"))
.filter((q) =>
q.and(
q.eq(q.field("metadata.testsCreated"), true),
q.eq(q.field("metadata.status"), "approved"),
),
)
.order("desc")
.take(10);
// For each event, check if design already started
for (const event of readyForDesign) {
const existingDesign = await ctx.db
.query("connections")
.withIndex("to_type", (q) =>
q.eq("toThingId", event.targetId).eq("relationshipType", "part_of"),
)
.filter((q) => q.eq(q.field("metadata.stage"), "5_design"))
.first();
if (!existingDesign) {
// Start design work
await createWireframes({ featureId: event.targetId });
}
}
```
---
## Examples
### Example 1: Create Wireframes for Course CRUD (6-Dimension Operations)
**Input:**
```typescript
// Feature thing
{
_id: "feature_abc123",
type: "feature",
name: "2-1-course-crud",
properties: {
planId: "2-course-platform",
organizationId: "org_xyz789",
description: "CRUD operations for courses",
entities: ["course"],
operations: ["create", "read", "update", "delete"]
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now()
}
// Test thing (from quality agent)
{
_id: "test_def456",
type: "test",
name: "Test: Course CRUD",
properties: {
featureId: "feature_abc123",
userFlows: [
{
name: "create-course",
goal: "Create a Course",
steps: ["Navigate to /courses/new", "Fill title field", "Click Create", "See success"],
timing: "< 10 seconds"
},
{
name: "update-course",
goal: "Update a Course",
steps: ["Navigate to /courses/[id]/edit", "Modify fields", "Click Save", "See success"],
timing: "< 5 seconds"
},
{
name: "delete-course",
goal: "Delete a Course",
steps: ["Click Delete button", "See confirmation modal", "Click Confirm", "See success"],
timing: "< 3 seconds"
}
],
acceptanceCriteria: [
"User can create course with just title",
"User sees loading state during save",
"Delete requires confirmation modal",
"Form validates before submission",
"Success message appears after each operation"
]
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now()
}
// Organization thing
{
_id: "org_xyz789",
type: "organization",
name: "Fitness Academy",
properties: {
slug: "fitness-academy",
brandColors: {
primary: "221 83% 53%", // Blue
secondary: "142 76% 36%", // Green
accent: "48 96% 53%" // Yellow
},
typography: {
headingFont: "Inter",
bodyFont: "Inter"
},
borderRadius: "modern-rounded"
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now()
}
```
**Process (6-Dimension Operations):**
```typescript
// 1. THINGS: Get feature, test, organization
const feature = await ctx.db.get("feature_abc123");
const test = await ctx.db.get("test_def456");
const org = await ctx.db.get("org_xyz789");
// 2. KNOWLEDGE: Query design patterns
const patterns = await ctx.db
.query("knowledge")
.withIndex("by_type", (q) => q.eq("knowledgeType", "chunk"))
.filter((q) =>
q.or(
q.eq(q.field("labels"), "pattern:centered-form"),
q.eq(q.field("labels"), "use-case:crud"),
),
)
.take(5);
// 3. Map user flows to screens
const screens = test.properties.userFlows.map((flow) => ({
name: flow.name,
path:
flow.name === "create-course"
? "/courses/new"
: `/courses/[id]/${flow.name.split("-")[1]}`,
layout: "centered-form",
components: [
{ type: "Card", contains: ["CardHeader", "CardContent"] },
{ type: "Form", fields: ["title", "description", "price"] },
{
type: "Button",
variant: "primary",
label: flow.name.includes("create") ? "Create" : "Save",
},
],
userFlow: flow.goal,
acceptanceCriteria: test.properties.acceptanceCriteria.filter((c) =>
c.toLowerCase().includes(flow.name.split("-")[0]),
),
responsive: {
mobile: "single-column p-4",
tablet: "max-w-2xl mx-auto p-6",
desktop: "max-w-2xl mx-auto p-8",
},
}));
// 4. THINGS: Create wireframe thing
const wireframeId = await ctx.db.insert("things", {
type: "design",
name: "Wireframe: Course CRUD",
properties: {
designType: "wireframe",
featureId: "feature_abc123",
organizationId: "org_xyz789",
screens: screens,
brandGuidelines: org.properties.brandColors,
patternsUsed: patterns.map((p) => p._id),
},
status: "draft",
createdAt: Date.now(),
updatedAt: Date.now(),
});
// 5. CONNECTIONS: Link wireframe to