UNPKG

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
--- 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