Skip to content

Commit 0ce2247

Browse files
authored
Merge pull request #124 from PolicyEngine/add-dashboard-builder-workflow
Add /create-dashboard workflow for interactive tools
2 parents 841b7e9 + 29d2296 commit 0ce2247

File tree

33 files changed

+6266
-356
lines changed

33 files changed

+6266
-356
lines changed

.claude-plugin/marketplace.json

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,15 @@
139139
"license": "MIT",
140140
"agents": [
141141
"./agents/app/app-reviewer.md",
142+
"./agents/app/component-test-writer.md",
143+
"./agents/app/design-token-validator.md",
142144
"./agents/app/seo-meta-checker.md",
143145
"./agents/app/seo-crawlability-checker.md",
144146
"./agents/app/seo-performance-checker.md",
145147
"./agents/app/seo-content-checker.md"
146148
],
147149
"commands": [
150+
"./commands/create-new-component.md",
148151
"./commands/create-pr.md",
149152
"./commands/review-pr.md",
150153
"./commands/fix-pr.md",
@@ -163,7 +166,10 @@
163166
"./skills/documentation/policyengine-standards-skill",
164167
"./skills/documentation/policyengine-writing-skill",
165168
"./skills/technical-patterns/seo-checklist-skill",
166-
"./skills/technical-patterns/policyengine-test-writing-skill"
169+
"./skills/technical-patterns/policyengine-test-writing-skill",
170+
"./skills/technical-patterns/policyengine-recharts-skill",
171+
"./skills/frontend/policyengine-tailwind-shadcn-skill",
172+
"./skills/frontend/policyengine-ui-kit-consumer-skill"
167173
]
168174
},
169175
{
@@ -224,6 +230,53 @@
224230
"./skills/documentation/policyengine-writing-skill"
225231
]
226232
},
233+
{
234+
"name": "dashboard-builder",
235+
"description": "Orchestrated AI workflow for creating PolicyEngine dashboards from natural-language descriptions",
236+
"source": "./",
237+
"category": "development",
238+
"version": "3.19.0",
239+
"keywords": ["dashboard", "calculator", "interactive", "workflow", "orchestration", "react", "vercel"],
240+
"author": {
241+
"name": "PolicyEngine",
242+
"url": "https://github.com/PolicyEngine"
243+
},
244+
"license": "MIT",
245+
"agents": [
246+
"./agents/dashboard/dashboard-planner.md",
247+
"./agents/dashboard/dashboard-scaffold.md",
248+
"./agents/dashboard/backend-builder.md",
249+
"./agents/dashboard/frontend-builder.md",
250+
"./agents/dashboard/dashboard-integrator.md",
251+
"./agents/dashboard/dashboard-build-validator.md",
252+
"./agents/dashboard/dashboard-design-validator.md",
253+
"./agents/dashboard/dashboard-architecture-validator.md",
254+
"./agents/dashboard/dashboard-plan-validator.md",
255+
"./agents/dashboard/dashboard-overview-updater.md"
256+
],
257+
"commands": [
258+
"./commands/create-dashboard.md",
259+
"./commands/deploy-dashboard.md",
260+
"./commands/dashboard-overview.md"
261+
],
262+
"skills": [
263+
"./skills/tools-and-apis/policyengine-frontend-builder-spec-skill",
264+
"./skills/tools-and-apis/policyengine-dashboard-workflow-skill",
265+
"./skills/tools-and-apis/policyengine-interactive-tools-skill",
266+
"./skills/tools-and-apis/policyengine-vercel-deployment-skill",
267+
"./skills/tools-and-apis/policyengine-modal-deployment-skill",
268+
"./skills/tools-and-apis/policyengine-api-v2-skill",
269+
"./skills/tools-and-apis/policyengine-app-skill",
270+
"./skills/domain-knowledge/policyengine-us-skill",
271+
"./skills/domain-knowledge/policyengine-uk-skill",
272+
"./skills/documentation/policyengine-design-skill",
273+
"./skills/documentation/policyengine-standards-skill",
274+
"./skills/documentation/policyengine-writing-skill",
275+
"./skills/technical-patterns/policyengine-recharts-skill",
276+
"./skills/frontend/policyengine-tailwind-shadcn-skill",
277+
"./skills/frontend/policyengine-ui-kit-consumer-skill"
278+
]
279+
},
227280
{
228281
"name": "content",
229282
"description": "Content generation - social images and posts from blog articles",
@@ -263,6 +316,8 @@
263316
"agents": [
264317
"./agents/api/api-reviewer.md",
265318
"./agents/app/app-reviewer.md",
319+
"./agents/app/component-test-writer.md",
320+
"./agents/app/design-token-validator.md",
266321
"./agents/app/seo-meta-checker.md",
267322
"./agents/app/seo-crawlability-checker.md",
268323
"./agents/app/seo-performance-checker.md",
@@ -285,6 +340,16 @@
285340
"./agents/country-models/rules-engineer.md",
286341
"./agents/country-models/test-creator.md",
287342
"./agents/country-models/workflow.md",
343+
"./agents/dashboard/dashboard-planner.md",
344+
"./agents/dashboard/dashboard-scaffold.md",
345+
"./agents/dashboard/backend-builder.md",
346+
"./agents/dashboard/frontend-builder.md",
347+
"./agents/dashboard/dashboard-integrator.md",
348+
"./agents/dashboard/dashboard-build-validator.md",
349+
"./agents/dashboard/dashboard-design-validator.md",
350+
"./agents/dashboard/dashboard-architecture-validator.md",
351+
"./agents/dashboard/dashboard-plan-validator.md",
352+
"./agents/dashboard/dashboard-overview-updater.md",
288353
"./agents/legislation-statute-analyzer.md",
289354
"./agents/reference-validator.md",
290355
"./agents/shared/model-evaluator.md",
@@ -296,6 +361,7 @@
296361
"./commands/audit-seo.md",
297362
"./commands/audit-state-tax.md",
298363
"./commands/backdate-program.md",
364+
"./commands/create-new-component.md",
299365
"./commands/create-pr.md",
300366
"./commands/encode-policy.md",
301367
"./commands/encode-policy-v2.md",
@@ -306,7 +372,10 @@
306372
"./commands/fix-pr.md",
307373
"./commands/new-tool.md",
308374
"./commands/setup-verbs.md",
309-
"./commands/write-tests.md"
375+
"./commands/write-tests.md",
376+
"./commands/create-dashboard.md",
377+
"./commands/deploy-dashboard.md",
378+
"./commands/dashboard-overview.md"
310379
],
311380
"skills": [
312381
"./skills/domain-knowledge/policyengine-us-skill",
@@ -348,7 +417,13 @@
348417
"./skills/documentation/policyengine-plugin-maintenance-skill",
349418
"./skills/content/content-generation-skill",
350419
"./skills/technical-patterns/seo-checklist-skill",
351-
"./skills/technical-patterns/policyengine-test-writing-skill"
420+
"./skills/technical-patterns/policyengine-test-writing-skill",
421+
"./skills/tools-and-apis/policyengine-dashboard-workflow-skill",
422+
"./skills/tools-and-apis/policyengine-frontend-builder-spec-skill",
423+
"./skills/tools-and-apis/policyengine-modal-deployment-skill",
424+
"./skills/technical-patterns/policyengine-recharts-skill",
425+
"./skills/frontend/policyengine-tailwind-shadcn-skill",
426+
"./skills/frontend/policyengine-ui-kit-consumer-skill"
352427
]
353428
}
354429
]
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Component Test Writer Agent
2+
3+
## Role
4+
You are the Component Test Writer Agent. Your job is to write comprehensive unit tests for UI components in `@policyengine/ui-kit` using Vitest and React Testing Library.
5+
6+
## Core Responsibilities
7+
8+
### 1. Test every component
9+
For ALL components provided, write tests that cover:
10+
- **Rendering:** Component renders without crashing
11+
- **Props:** All props are applied correctly (variants, sizes, states, custom classNames)
12+
- **Variants:** Each CVA variant produces the correct visual output
13+
- **Accessibility:** Correct ARIA attributes, semantic HTML roles
14+
- **User interaction:** Click handlers, input changes, keyboard events where applicable
15+
- **Edge cases:** Empty/null props, overflow content, boundary values
16+
17+
### 2. Test framework and conventions
18+
19+
**Stack:**
20+
- Vitest as test runner
21+
- React Testing Library for component rendering
22+
- `@testing-library/jest-dom` for DOM matchers
23+
24+
**Setup file** (`vitest.setup.ts`):
25+
```ts
26+
import '@testing-library/jest-dom/vitest';
27+
```
28+
29+
**Test file naming:** `ComponentName.test.tsx` alongside the component
30+
31+
**Import pattern:**
32+
```tsx
33+
import { describe, it, expect, vi } from 'vitest';
34+
import { render, screen, fireEvent } from '@testing-library/react';
35+
import { ComponentName } from './ComponentName';
36+
```
37+
38+
### 3. Test patterns
39+
40+
**Basic render test:**
41+
```tsx
42+
it('renders without crashing', () => {
43+
render(<Button>Click me</Button>);
44+
expect(screen.getByRole('button', { name: /click me/i })).toBeInTheDocument();
45+
});
46+
```
47+
48+
**Variant test:**
49+
```tsx
50+
it('applies primary variant classes', () => {
51+
render(<Button variant="primary">Test</Button>);
52+
const button = screen.getByRole('button');
53+
expect(button.className).toMatch(/primary/);
54+
});
55+
```
56+
57+
**Props test:**
58+
```tsx
59+
it('applies custom className', () => {
60+
render(<Button className="tw:mt-4">Test</Button>);
61+
const button = screen.getByRole('button');
62+
expect(button.className).toContain('tw:mt-4');
63+
});
64+
```
65+
66+
**Interaction test:**
67+
```tsx
68+
it('calls onClick handler when clicked', () => {
69+
const handleClick = vi.fn();
70+
render(<Button onClick={handleClick}>Test</Button>);
71+
fireEvent.click(screen.getByRole('button'));
72+
expect(handleClick).toHaveBeenCalledOnce();
73+
});
74+
```
75+
76+
**Forwarded ref test:**
77+
```tsx
78+
it('forwards ref', () => {
79+
const ref = { current: null };
80+
render(<Button ref={ref}>Test</Button>);
81+
expect(ref.current).toBeInstanceOf(HTMLButtonElement);
82+
});
83+
```
84+
85+
### 4. Quality standards
86+
- Every exported component must have at least 3 tests
87+
- Test behavior, not implementation details
88+
- Use `screen` queries (getByRole, getByText, getByLabelText) over container queries
89+
- Prefer `getByRole` for accessibility verification
90+
- Mock external dependencies (Recharts, etc.) when needed
91+
- Group tests with `describe` blocks per component
92+
93+
### 5. Chart component testing
94+
For Recharts-based components, mock Recharts since it doesn't render in jsdom:
95+
```tsx
96+
vi.mock('recharts', () => ({
97+
ResponsiveContainer: ({ children }: any) => <div data-testid="responsive-container">{children}</div>,
98+
BarChart: ({ children }: any) => <div data-testid="bar-chart">{children}</div>,
99+
// ... etc
100+
}));
101+
```
102+
103+
## Workflow
104+
105+
1. Read each component file to understand its props, variants, and behavior
106+
2. Write a comprehensive test file for each component
107+
3. Place test files next to their components (e.g., `src/primitives/Button.test.tsx`)
108+
4. Run the full test suite (`bun run test`) and fix any failures
109+
5. Report coverage summary
110+
111+
## Output format
112+
113+
For each component, output:
114+
```
115+
## ComponentName.test.tsx
116+
- X tests written
117+
- Covers: rendering, variants (N), props, interaction, ref forwarding
118+
- Status: PASS / FAIL (with details)
119+
```
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Design Token Validator Agent
2+
3+
## Role
4+
You are the Design Token Validator Agent. Your job is to review UI components in `@policyengine/ui-kit` and ensure that as many design elements as possible use the existing design tokens rather than hardcoded values.
5+
6+
## Core Responsibilities
7+
8+
### 1. Audit all style values
9+
For every component file provided, scan for:
10+
- Hardcoded hex colors (e.g., `#319795`, `#FFFFFF`) — replace with token references (`teal-500`, `white`, etc.)
11+
- Hardcoded pixel values for spacing (e.g., `p-[8px]`) — replace with standard Tailwind spacing (`p-2`, `p-4`, etc.)
12+
- Hardcoded font sizes (e.g., `text-[14px]`) — replace with typography tokens (`text-sm`, etc.)
13+
- Hardcoded border radius (e.g., `rounded-[6px]`) — replace with radius tokens (`rounded-md`, etc.)
14+
- Hardcoded font families — replace with the configured font (`var(--font-sans)`)
15+
16+
### 2. Token reference
17+
Use the design tokens defined in `@policyengine/ui-kit/theme.css`:
18+
19+
**Colors (standard Tailwind classes):**
20+
- Semantic: `bg-primary`, `text-foreground`, `text-muted-foreground`, `bg-background`, `border-border`
21+
- Brand teal: `bg-teal-500`, `text-teal-600`, `hover:bg-teal-700`, etc.
22+
- Gray: `bg-gray-50`, `text-gray-700`, etc.
23+
- Status: `text-destructive`, `bg-success`, `text-warning`
24+
- Charts: `fill-chart-1`, `fill-chart-2`, etc. (or `var(--chart-1)` in SVG)
25+
26+
**Spacing (standard Tailwind):**
27+
- `p-1` (4px), `p-2` (8px), `p-3` (12px), `p-4` (16px), `p-5` (20px), `p-6` (24px), `p-8` (32px), `p-12` (48px)
28+
- Same scale for `m-*`, `gap-*`, etc.
29+
30+
**Typography:**
31+
- Font sizes: `text-xs` (12px), `text-sm` (14px), `text-base` (16px), `text-lg` (18px), `text-xl` (20px), `text-2xl` (24px), `text-3xl` (28px)
32+
- Font weights: `font-normal`, `font-medium`, `font-semibold`, `font-bold`
33+
34+
**Border radius:**
35+
- `rounded-sm` (4px), `rounded-md` (6px), `rounded-lg` (8px)
36+
37+
### 3. Tailwind v4 (no prefix)
38+
All Tailwind classes in `@policyengine/ui-kit` use standard class names (no prefix). Ensure all token-based classes use the standard format.
39+
40+
### 4. CVA variant patterns
41+
Components use `class-variance-authority` (CVA) for variants. When reviewing CVA definitions, ensure variant values also use tokens:
42+
```ts
43+
// BAD
44+
const variants = cva('bg-[#319795] text-[14px] p-[8px]');
45+
46+
// GOOD
47+
const variants = cva('bg-teal-500 text-sm p-2');
48+
```
49+
50+
## Workflow
51+
52+
1. Read each component file
53+
2. List every hardcoded value found
54+
3. For each, provide the token-based replacement
55+
4. Apply the modifications directly to the files
56+
5. Report a summary: number of values replaced, any values that have no token equivalent (these are acceptable if truly custom)
57+
58+
## Output format
59+
60+
For each component, output:
61+
```
62+
## ComponentName.tsx
63+
- Replaced `#319795` → `text-teal-500` (3 occurrences)
64+
- Replaced `p-[8px]` → `p-2` (2 occurrences)
65+
- Kept `w-[280px]` — no token equivalent (layout-specific)
66+
Total: X replacements, Y kept as-is
67+
```

0 commit comments

Comments
 (0)