Frontend-Design AgentSkill
Overview
frontend-design is the sixth step in the SSDAM execution pipeline (after backend-design, optional). It transforms architectural and backend specifications into a complete frontend design specification covering pages, components, state management, API integration, and routing.
This skill produces a single output document (frontend-design.TSK-NNN.md) that drives the final implementation step (frontend-implementation).
Skill Chain Context
task-spec.TSK-NNN.yaml
+ architecture-design.TSK-NNN.md (required)
+ backend-design.TSK-NNN.md (optional — provides API specs)
↓
[frontend-design] ← YOU ARE HERE
↓
.ssdam/{id}/output/design/frontend-design.TSK-NNN.md
↓
[frontend-implementation]
Trigger and I/O
| Aspect |
Details |
| Trigger |
/frontend-design <task-spec-path> |
| Input |
task-spec.TSK-NNN.yaml + architecture-design.TSK-NNN.md (req.) + backend-design.TSK-NNN.md (opt.) |
| Output |
.ssdam/{id}/output/design/frontend-design.TSK-NNN.md |
| Tech Stack |
Svelte 5, TypeScript, TailwindCSS, Vite, SvelteKit (varies by task-spec.tech_stack) |
Execution Procedure
Step 1: Load Inputs
Parse task-spec.TSK-NNN.yaml:
- Extract
purpose.scope_included (features/views requiring frontend)
- Extract
purpose.scope_excluded (out-of-scope frontend features)
- Read
execution_plan.tech_stack to determine frontend framework (default: Svelte 5)
- Extract
requirement_ids and output_contract (acceptance criteria)
Read architecture-design.TSK-NNN.md:
- Extract
domain_entities (data model overview)
- Extract
api_contract_overview (high-level API structure)
- Extract
module_boundaries (system partitioning)
- Note any user roles and permission levels
If backend-design.TSK-NNN.md exists:
- Read
api_endpoints section (precise endpoints, methods, paths)
- Read
schemas section (TypeScript interfaces for request/response types)
- Use these details for precise API integration plan (override api_contract_overview if conflicting)
Error handling:
- If
architecture-design.TSK-NNN.md not found: Stop and instruct user to run /architecture-design first.
- If no frontend scope in
scope_included: Warn that this task has no frontend work — skip frontend chain entirely.
Step 2: Identify Pages and Routes
For each item in scope_included that involves user interface:
Page identification: List each distinct page or view.
- Page name: descriptive (e.g., "Library", "UploadManagement", "Marketplace")
- Route: SvelteKit route pattern (e.g.,
/, /uploads, /marketplace/[id])
- Purpose: one-sentence description of what the page does
- Accessed by: which user role(s) can access this page (from architecture-design)
- Layout: which layout wrapper component (e.g., "AppLayout", "AuthLayout", "BlankLayout")
Verify all UI-related scope_included items are represented by at least one page.
Step 3: Design Component Tree
For each page identified in Step 2:
Page component: Create a top-level page component.
- File:
src/routes/{route}/+page.svelte
- Responsibility: page-level layout, data loading orchestration, page-specific state
Layout components: Identify shared UI (header, sidebar, footer, navigation).
- Shared across pages →
src/lib/components/layout/ (e.g., AppHeader.svelte, AppSidebar.svelte)
- One layout per page category (e.g., "AppLayout" for authenticated pages, "AuthLayout" for login/signup)
Feature components: Components specific to a feature or page.
- File:
src/lib/components/features/{FeatureName}/
- Examples:
MediaGrid.svelte, FileUploadModal.svelte, FilterPanel.svelte
- Responsibility: handle a discrete feature or interaction
Atomic components: Reusable, primitive components.
- File:
src/lib/components/atomic/ (e.g., Button.svelte, TextField.svelte, Modal.svelte)
- Responsibility: single, focused UI pattern (no business logic)
For each component, define:
| Attribute |
Format |
Example |
| Component name |
PascalCase |
MediaGrid, FileUploadModal |
| File path |
Relative to project_root |
src/lib/components/features/MediaGallery/Grid.svelte |
| Category |
page | layout | feature | atomic |
feature |
| Props |
List with types |
items: MediaFile[], selectedId: string | null |
| Events |
Custom events dispatched |
on:select={...} → { detail: { id: string } } |
| Stores used |
List of stores read/written |
mediaFilesStore, authStore |
Step 4: Design State Management
For each piece of shared state (data needed across multiple components):
Store identification: One store per domain concept.
- Examples:
authStore, mediaFilesStore, purchasesStore, uiStateStore
- Do NOT create one massive global store — partition by domain.
For each store, define:
| Attribute |
Format |
Example |
| Store name |
camelCase |
mediaFilesStore |
| Store file |
src/lib/stores/{storeName}.ts |
src/lib/stores/mediaFiles.ts |
| State interface |
TypeScript interface |
interface MediaFilesState { items: MediaFile[]; loading: boolean } |
| Initial state |
Concrete values |
{ items: [], loading: false, error: null } |
| Actions/methods |
Named operations |
fetchFiles(), uploadFile(file), deleteFile(id) |
| Derived stores |
Computed values |
selectedCount$ = derived(...) |
Step 5: Design API Integration
For each API call the frontend needs to make:
Endpoint mapping: Match each component action to a backend endpoint.
- Method: GET, POST, PUT, DELETE, PATCH
- Path: e.g.,
/api/media/files, /api/uploads/{id}
- Source: from
backend-design.api_endpoints if available, else from architecture-design.api_contract_overview
Trigger identification: Which user action initiates each call.
- Example: "Click 'Upload' button" →
POST /api/uploads
- Example: "Page load on /library" →
GET /api/media/files
- Example: "Delete media" →
DELETE /api/media/files/{id}
Component/store responsibility: Which component/store makes the call.
- Prefer stores for shared data (mediaFilesStore.fetchFiles())
- Prefer components for isolated actions
TypeScript types: For each endpoint, define request and response types.
- Request interface (if body is required):
CreateUploadRequest { filename: string; mimetype: string }
- Response interface:
MediaFile { id: string; filename: string; size: number; uploadedAt: Date }
- Match field names exactly with backend schemas (from backend-design)
Loading and error handling:
- Every API call must update a loading state before fetch, unset in finally block
- Every API call must catch errors and update error state
- Components displaying results show loading spinner, error message, or success state
Group into API client module:
Step 6: UI/UX Decisions
For each significant interaction identified in Steps 2-5:
Interaction pattern: Name the interaction (e.g., "double-click to open detail", "drag-to-reorder", "search-to-filter")
Component responsible: Which component handles it.
Behavior: What happens in response.
- Example: "Double-click media → open detail modal"
- Example: "Type in search field → filter list in real-time"
- Example: "Click upload → show file picker"
State changes: Which store(s) update, and how.
- Example:
mediaFilesStore.setSelectedId(id) → detail modal becomes visible
Step 7: Define File Structure
List all files and directories to be created in project_root/:
| Directory/File |
Description |
Example |
src/routes/ |
SvelteKit page routes |
src/routes/+page.svelte, src/routes/library/+page.svelte |
src/lib/components/ |
Reusable components |
src/lib/components/MediaGrid.svelte |
src/lib/components/layout/ |
Layout wrappers |
src/lib/components/layout/AppLayout.svelte |
src/lib/components/atomic/ |
Primitive components |
src/lib/components/atomic/Button.svelte |
src/lib/stores/ |
Svelte stores |
src/lib/stores/mediaFiles.ts |
src/lib/api/ |
API client functions |
src/lib/api/mediaFiles.ts |
src/lib/types/ |
TypeScript interfaces |
src/lib/types/media.ts, src/lib/types/auth.ts |
tests/ |
Component and store tests |
tests/components/MediaGrid.test.ts |
Step 8: Test Strategy and Write Output
Define testing approach:
- Test runner: Vitest + Svelte Testing Library
- Per-component testing: component renders, props work, events dispatch, stores integrate
- Store testing: actions update state correctly, derived values compute
- API client testing: functions call correct endpoints, handle errors, transform responses
Write output document .ssdam/{id}/output/design/frontend-design.TSK-NNN.md:
- Follow structure in
references/output.template.yaml
- Include all pages, components, stores, API integrations, file structure, test strategy
- Self-validation: verify all scope_included UI items are addressed
Post-Execution
On successful completion:
✓ frontend-design.TSK-NNN.md written.
- N pages defined
- N components defined
- N stores defined
- N API endpoints integrated
Next: run /frontend-implementation <task-spec-path>
Error Handling
| Error |
Action |
architecture-design.TSK-NNN.md not found |
Stop. Instruct user: "Run /architecture-design first." |
No frontend scope in task-spec.scope_included |
Warn: "This task has no frontend work — skipping frontend chain." Do not produce a document. |
backend-design.TSK-NNN.md not found |
Proceed using api_contract_overview from architecture-design as fallback. Document the fallback. |
| Incomplete pages/components |
Return error: "Step 3: [list missing components needed for scope_included]" |
| Missing API integration for a page action |
Return error: "Step 5: [page/action] has no API endpoint defined." |
References
- input.template.yaml: Template for parsing task-spec, architecture-design, backend-design
- output.template.yaml: Schema for the output frontend-design.TSK-NNN.md document
- rules.md: Mandatory conventions (naming, store design, component structure, etc.)
Compatibility Notes
- Framework detection: Read
task-spec.execution_plan.tech_stack.frontend to determine framework (Svelte 5, React, Vue, etc.). This skill is optimized for Svelte 5 but abstracts patterns for other frameworks.
- TypeScript: All interface definitions must match backend schemas exactly (same field names, compatible types).
- Styling: TailwindCSS is the default CSS framework. Adjust if task-spec specifies otherwise.
1---2name: frontend-design3description: Frontend-Design AgentSkill4---56# Frontend-Design AgentSkill78## Overview910**frontend-design** is the sixth step in the SSDAM execution pipeline (after backend-design, optional). It transforms architectural and backend specifications into a complete frontend design specification covering pages, components, state management, API integration, and routing.1112This skill produces a single output document (frontend-design.TSK-NNN.md) that drives the final implementation step (frontend-implementation).1314## Skill Chain Context1516```17task-spec.TSK-NNN.yaml18 + architecture-design.TSK-NNN.md (required)19 + backend-design.TSK-NNN.md (optional — provides API specs)20 ↓21[frontend-design] ← YOU ARE HERE22 ↓23.ssdam/{id}/output/design/frontend-design.TSK-NNN.md24 ↓25[frontend-implementation]26```2728## Trigger and I/O2930| Aspect | Details |31|--------|---------|32| **Trigger** | `/frontend-design <task-spec-path>` |33| **Input** | `task-spec.TSK-NNN.yaml` + `architecture-design.TSK-NNN.md` (req.) + `backend-design.TSK-NNN.md` (opt.) |34| **Output** | `.ssdam/{id}/output/design/frontend-design.TSK-NNN.md` |35| **Tech Stack** | Svelte 5, TypeScript, TailwindCSS, Vite, SvelteKit (varies by task-spec.tech_stack) |3637## Execution Procedure3839### Step 1: Load Inputs40411. Parse `task-spec.TSK-NNN.yaml`:42 - Extract `purpose.scope_included` (features/views requiring frontend)43 - Extract `purpose.scope_excluded` (out-of-scope frontend features)44 - Read `execution_plan.tech_stack` to determine frontend framework (default: Svelte 5)45 - Extract `requirement_ids` and `output_contract` (acceptance criteria)46472. Read `architecture-design.TSK-NNN.md`:48 - Extract `domain_entities` (data model overview)49 - Extract `api_contract_overview` (high-level API structure)50 - Extract `module_boundaries` (system partitioning)51 - Note any user roles and permission levels52533. If `backend-design.TSK-NNN.md` exists:54 - Read `api_endpoints` section (precise endpoints, methods, paths)55 - Read `schemas` section (TypeScript interfaces for request/response types)56 - Use these details for precise API integration plan (override api_contract_overview if conflicting)5758**Error handling:**59- If `architecture-design.TSK-NNN.md` not found: Stop and instruct user to run `/architecture-design` first.60- If no frontend scope in `scope_included`: Warn that this task has no frontend work — skip frontend chain entirely.6162### Step 2: Identify Pages and Routes6364For each item in `scope_included` that involves user interface:65661. **Page identification:** List each distinct page or view.67 - Page name: descriptive (e.g., "Library", "UploadManagement", "Marketplace")68 - Route: SvelteKit route pattern (e.g., `/`, `/uploads`, `/marketplace/[id]`)69 - Purpose: one-sentence description of what the page does70 - Accessed by: which user role(s) can access this page (from architecture-design)71 - Layout: which layout wrapper component (e.g., "AppLayout", "AuthLayout", "BlankLayout")72732. Verify all UI-related scope_included items are represented by at least one page.7475### Step 3: Design Component Tree7677For each page identified in Step 2:78791. **Page component:** Create a top-level page component.80 - File: `src/routes/{route}/+page.svelte`81 - Responsibility: page-level layout, data loading orchestration, page-specific state82832. **Layout components:** Identify shared UI (header, sidebar, footer, navigation).84 - Shared across pages → `src/lib/components/layout/` (e.g., `AppHeader.svelte`, `AppSidebar.svelte`)85 - One layout per page category (e.g., "AppLayout" for authenticated pages, "AuthLayout" for login/signup)86873. **Feature components:** Components specific to a feature or page.88 - File: `src/lib/components/features/{FeatureName}/`89 - Examples: `MediaGrid.svelte`, `FileUploadModal.svelte`, `FilterPanel.svelte`90 - Responsibility: handle a discrete feature or interaction91924. **Atomic components:** Reusable, primitive components.93 - File: `src/lib/components/atomic/` (e.g., `Button.svelte`, `TextField.svelte`, `Modal.svelte`)94 - Responsibility: single, focused UI pattern (no business logic)9596**For each component, define:**9798| Attribute | Format | Example |99|-----------|--------|---------|100| Component name | PascalCase | `MediaGrid`, `FileUploadModal` |101| File path | Relative to project_root | `src/lib/components/features/MediaGallery/Grid.svelte` |102| Category | page \| layout \| feature \| atomic | `feature` |103| Props | List with types | `items: MediaFile[]`, `selectedId: string \| null` |104| Events | Custom events dispatched | `on:select={...}` → `{ detail: { id: string } }` |105| Stores used | List of stores read/written | `mediaFilesStore`, `authStore` |106107### Step 4: Design State Management108109For each piece of shared state (data needed across multiple components):1101111. **Store identification:** One store per domain concept.112 - Examples: `authStore`, `mediaFilesStore`, `purchasesStore`, `uiStateStore`113 - Do NOT create one massive global store — partition by domain.1141152. **For each store, define:**116117| Attribute | Format | Example |118|-----------|--------|---------|119| Store name | camelCase | `mediaFilesStore` |120| Store file | `src/lib/stores/{storeName}.ts` | `src/lib/stores/mediaFiles.ts` |121| State interface | TypeScript interface | `interface MediaFilesState { items: MediaFile[]; loading: boolean }` |122| Initial state | Concrete values | `{ items: [], loading: false, error: null }` |123| Actions/methods | Named operations | `fetchFiles()`, `uploadFile(file)`, `deleteFile(id)` |124| Derived stores | Computed values | `selectedCount$ = derived(...)` |125126### Step 5: Design API Integration127128For each API call the frontend needs to make:1291301. **Endpoint mapping:** Match each component action to a backend endpoint.131 - Method: GET, POST, PUT, DELETE, PATCH132 - Path: e.g., `/api/media/files`, `/api/uploads/{id}`133 - Source: from `backend-design.api_endpoints` if available, else from `architecture-design.api_contract_overview`1341352. **Trigger identification:** Which user action initiates each call.136 - Example: "Click 'Upload' button" → `POST /api/uploads`137 - Example: "Page load on /library" → `GET /api/media/files`138 - Example: "Delete media" → `DELETE /api/media/files/{id}`1391403. **Component/store responsibility:** Which component/store makes the call.141 - Prefer stores for shared data (mediaFilesStore.fetchFiles())142 - Prefer components for isolated actions1431444. **TypeScript types:** For each endpoint, define request and response types.145 - Request interface (if body is required): `CreateUploadRequest { filename: string; mimetype: string }`146 - Response interface: `MediaFile { id: string; filename: string; size: number; uploadedAt: Date }`147 - Match field names exactly with backend schemas (from backend-design)1481495. **Loading and error handling:**150 - Every API call must update a loading state before fetch, unset in finally block151 - Every API call must catch errors and update error state152 - Components displaying results show loading spinner, error message, or success state1531546. **Group into API client module:**155 - File: `src/lib/api/{domain}.ts` (e.g., `src/lib/api/mediaFiles.ts`)156 - Export async functions (not methods on a class)157 - Examples:158 ```typescript159 export async function fetchMediaFiles(): Promise<MediaFile[]> { ... }160 export async function uploadFile(file: File): Promise<MediaFile> { ... }161 ```162163### Step 6: UI/UX Decisions164165For each significant interaction identified in Steps 2-5:1661671. **Interaction pattern:** Name the interaction (e.g., "double-click to open detail", "drag-to-reorder", "search-to-filter")1681692. **Component responsible:** Which component handles it.1701713. **Behavior:** What happens in response.172 - Example: "Double-click media → open detail modal"173 - Example: "Type in search field → filter list in real-time"174 - Example: "Click upload → show file picker"1751764. **State changes:** Which store(s) update, and how.177 - Example: `mediaFilesStore.setSelectedId(id)` → detail modal becomes visible178179### Step 7: Define File Structure180181List all files and directories to be created in `project_root/`:182183| Directory/File | Description | Example |184|----------------|-------------|---------|185| `src/routes/` | SvelteKit page routes | `src/routes/+page.svelte`, `src/routes/library/+page.svelte` |186| `src/lib/components/` | Reusable components | `src/lib/components/MediaGrid.svelte` |187| `src/lib/components/layout/` | Layout wrappers | `src/lib/components/layout/AppLayout.svelte` |188| `src/lib/components/atomic/` | Primitive components | `src/lib/components/atomic/Button.svelte` |189| `src/lib/stores/` | Svelte stores | `src/lib/stores/mediaFiles.ts` |190| `src/lib/api/` | API client functions | `src/lib/api/mediaFiles.ts` |191| `src/lib/types/` | TypeScript interfaces | `src/lib/types/media.ts`, `src/lib/types/auth.ts` |192| `tests/` | Component and store tests | `tests/components/MediaGrid.test.ts` |193194### Step 8: Test Strategy and Write Output1951961. **Define testing approach:**197 - Test runner: Vitest + Svelte Testing Library198 - Per-component testing: component renders, props work, events dispatch, stores integrate199 - Store testing: actions update state correctly, derived values compute200 - API client testing: functions call correct endpoints, handle errors, transform responses2012022. **Write output document** `.ssdam/{id}/output/design/frontend-design.TSK-NNN.md`:203 - Follow structure in `references/output.template.yaml`204 - Include all pages, components, stores, API integrations, file structure, test strategy205 - Self-validation: verify all scope_included UI items are addressed206207## Post-Execution208209On successful completion:210211```212✓ frontend-design.TSK-NNN.md written.213 - N pages defined214 - N components defined215 - N stores defined216 - N API endpoints integrated217218Next: run /frontend-implementation <task-spec-path>219```220221## Error Handling222223| Error | Action |224|-------|--------|225| `architecture-design.TSK-NNN.md` not found | Stop. Instruct user: "Run /architecture-design first." |226| No frontend scope in `task-spec.scope_included` | Warn: "This task has no frontend work — skipping frontend chain." Do not produce a document. |227| `backend-design.TSK-NNN.md` not found | Proceed using `api_contract_overview` from architecture-design as fallback. Document the fallback. |228| Incomplete pages/components | Return error: "Step 3: [list missing components needed for scope_included]" |229| Missing API integration for a page action | Return error: "Step 5: [page/action] has no API endpoint defined." |230231## References232233- **input.template.yaml**: Template for parsing task-spec, architecture-design, backend-design234- **output.template.yaml**: Schema for the output frontend-design.TSK-NNN.md document235- **rules.md**: Mandatory conventions (naming, store design, component structure, etc.)236237## Compatibility Notes238239- **Framework detection:** Read `task-spec.execution_plan.tech_stack.frontend` to determine framework (Svelte 5, React, Vue, etc.). This skill is optimized for Svelte 5 but abstracts patterns for other frameworks.240- **TypeScript:** All interface definitions must match backend schemas exactly (same field names, compatible types).241- **Styling:** TailwindCSS is the default CSS framework. Adjust if task-spec specifies otherwise.