Skip to content

Commit 5e0c4f0

Browse files
committed
Complete init-skills pass: solid, svelte, vue MFE skill scaffolds
Prior commit's init-skills run was interrupted after 3 of 6 MFEs. This commit adds the remaining three — symmetric with the first batch, each MFE gets its own .claude/skills/, .agents/skills/, and .mcp.json pointing at its own annotask server port (4220/4230/4240).
1 parent b929fbb commit 5e0c4f0

15 files changed

Lines changed: 2190 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../.claude/skills/annotask-apply
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../.claude/skills/annotask-init

playgrounds/stress-test/apps/mfe-solid-component-lab/.claude/skills/annotask-apply/SKILL.md

Lines changed: 453 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
# annotask-init
2+
3+
Initialize Annotask for this project by scanning the codebase and generating `.annotask/design-spec.json`.
4+
5+
## When to use
6+
7+
Use this skill when the user says any of:
8+
- "initialize Annotask" / "init Annotask"
9+
- "set up Annotask" / "configure Annotask"
10+
- "scan my project for Annotask"
11+
- `/annotask-init`
12+
13+
## What it does
14+
15+
Scans the project to detect the framework, design tokens (colors, typography, spacing, borders), icon library, and component library. Writes `.annotask/design-spec.json` which Annotask reads to populate the Theme page with editable design tokens.
16+
17+
## Output schema
18+
19+
Every token uses this shape:
20+
21+
```json
22+
{
23+
"role": "primary",
24+
"value": "#3b82f6",
25+
"cssVar": "--color-primary",
26+
"source": "var(--color-primary)",
27+
"sourceFile": "src/assets/main.css",
28+
"sourceLine": 12
29+
}
30+
```
31+
32+
- `role` — semantic name (see vocabularies below)
33+
- `value` — resolved value (hex color, font string, size, etc.)
34+
- `cssVar` — the CSS custom property name, if backed by one. Omit if not a CSS variable.
35+
- `source` — human-readable provenance: `var(--x)`, `tailwind.config:colors.primary`, `@theme:--color-primary`
36+
- `sourceFile` — relative path to the file where the value is defined
37+
- `sourceLine` — line number in that file
38+
39+
## Steps
40+
41+
### 1. Detect framework
42+
43+
Check `package.json` dependencies:
44+
- `vue` → name "vue", read version
45+
- `react` / `react-dom` → name "react"
46+
- `svelte` → name "svelte"
47+
- `solid-js` → name "solid"
48+
49+
Check for styling:
50+
- `tailwindcss` in devDependencies or dependencies → add "tailwind" to styling array
51+
- Look for `<style scoped>` in `.vue` files → add "scoped-css"
52+
- Look for CSS module imports (`.module.css`) → add "css-modules"
53+
54+
### 2. Scan colors
55+
56+
**Find color sources:**
57+
58+
1. **CSS variables**: Search for `:root` declarations across CSS files and Vue `<style>` blocks. Extract `--variable-name: value` pairs.
59+
60+
2. **Tailwind v4** (version >= 4): Search for `@theme` blocks in CSS files. Extract custom properties defined within them.
61+
62+
3. **Tailwind v3** (version < 4): Read `tailwind.config.js`, `tailwind.config.ts`, or `tailwind.config.mjs`. Extract `theme.extend.colors`. Convert to flat key-value pairs.
63+
64+
**Classify into semantic roles using this fixed vocabulary:**
65+
66+
| Role | Match heuristics (in variable/key name) |
67+
|------|----------------------------------------|
68+
| `primary` | primary, brand |
69+
| `secondary` | secondary |
70+
| `accent` | accent |
71+
| `background` | bg, background |
72+
| `surface` | surface, card |
73+
| `text` | text, foreground, fg (but not text-muted) |
74+
| `text-muted` | text-muted, muted, subtle |
75+
| `border` | border, divider, separator |
76+
| `danger` | danger, error, destructive, red |
77+
| `warning` | warning, amber, yellow (semantic) |
78+
| `success` | success, green (semantic) |
79+
| `info` | info, blue (semantic) |
80+
81+
If a variable doesn't match any heuristic, use a descriptive role name derived from the variable name (e.g., `--sidebar-bg` → role `sidebar-bg`).
82+
83+
**Limits**: Maximum 30 color tokens. Prioritize semantic roles first, then most-used custom colors.
84+
85+
### 3. Scan typography
86+
87+
**Font families**: Search for:
88+
- CSS variables containing `font`, `family` in `:root` or `@theme`
89+
- `fontFamily` in Tailwind config
90+
- Direct `font-family` declarations on `body`, `html`, `h1`-`h6` elements
91+
92+
Classify as:
93+
- `heading` — used on h1-h6 or named heading/display
94+
- `body` — used on body/html or named sans/body/base
95+
- `mono` — monospace, code, named mono
96+
97+
**Font scale**: Search for:
98+
- CSS variables containing `font-size`, `text-` size names
99+
- `fontSize` in Tailwind config
100+
- `@theme` size definitions
101+
102+
Use roles: `xs`, `sm`, `base`, `lg`, `xl`, `2xl`, `3xl`, `4xl` (match by name or by ascending size order).
103+
104+
**Weights**: Scan component files for `font-weight` values and Tailwind weight classes (`font-bold`, `font-semibold`, etc.). List unique weights as strings: `["400", "500", "600", "700"]`.
105+
106+
### 4. Scan spacing
107+
108+
Search for:
109+
- CSS variables containing `space`, `gap`, `margin`, `padding`, `size`
110+
- `spacing` in Tailwind config
111+
- `@theme` spacing definitions
112+
113+
Use roles: `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `4xl` (match by name or ascending size).
114+
115+
**Limits**: Maximum 12 spacing tokens.
116+
117+
### 5. Scan border radius
118+
119+
Search for:
120+
- CSS variables containing `radius`, `rounded`
121+
- `borderRadius` in Tailwind config
122+
- `@theme` radius definitions
123+
124+
Use roles: `sm`, `md`, `lg`, `xl`, `full` (match by name or ascending size).
125+
126+
### 6. Scan breakpoints
127+
128+
Detect responsive breakpoints from whatever styling system the project uses. Output as a flat object mapping name → min-width value.
129+
130+
**Sources (check in order):**
131+
132+
1. **Tailwind v4** (>= 4): Look in CSS files for `@theme` blocks defining `--breakpoint-*` custom properties, or `@custom-media` rules.
133+
134+
2. **Tailwind v3** (< 4): Read `tailwind.config.{js,ts,mjs}`. Extract `theme.screens` or `theme.extend.screens`. Default Tailwind screens: `{ "sm": "640px", "md": "768px", "lg": "1024px", "xl": "1280px", "2xl": "1536px" }` — use these as fallback if Tailwind is detected but no custom screens are defined.
135+
136+
3. **Bootstrap**: Check for `bootstrap` in package.json. Default Bootstrap breakpoints: `{ "sm": "576px", "md": "768px", "lg": "992px", "xl": "1200px", "xxl": "1400px" }`.
137+
138+
4. **CSS custom properties**: Search `:root` for variables containing `breakpoint`, `screen`, `bp` in the name (e.g., `--bp-mobile: 480px`).
139+
140+
5. **CSS `@media` patterns**: Scan `.css`, `.scss`, `.vue` files for `@media` queries with `min-width` or `max-width`. Extract the 3–6 most common breakpoint values and assign roles by ascending size: `sm`, `md`, `lg`, `xl`, `2xl`.
141+
142+
**Output example:**
143+
```json
144+
"breakpoints": {
145+
"sm": "640px",
146+
"md": "768px",
147+
"lg": "1024px",
148+
"xl": "1280px",
149+
"2xl": "1536px"
150+
}
151+
```
152+
153+
If no breakpoints are detected, omit the `breakpoints` field (don't include an empty object).
154+
155+
### 7. Detect icon library
156+
157+
Check `package.json` dependencies for:
158+
159+
| Package | Library name |
160+
|---------|-------------|
161+
| `lucide-vue-next` or `lucide-react` | lucide |
162+
| `@heroicons/vue` or `@heroicons/react` | heroicons |
163+
| `@fortawesome/vue-fontawesome` or `@fortawesome/react-fontawesome` | fontawesome |
164+
| `@phosphor-icons/vue` or `@phosphor-icons/react` | phosphor |
165+
| `@tabler/icons-vue` or `@tabler/icons-react` | tabler |
166+
167+
Read the version from package.json.
168+
169+
### 8. Detect component library
170+
171+
Check `package.json` dependencies for:
172+
173+
| Package | Library name |
174+
|---------|-------------|
175+
| `primevue` | PrimeVue |
176+
| `vuetify` | Vuetify |
177+
| `element-plus` | Element Plus |
178+
| `@headlessui/vue` | Headless UI |
179+
| `radix-vue` | Radix Vue |
180+
| `naive-ui` | Naive UI |
181+
| `@shadcn/ui` or `shadcn-vue` | shadcn/ui |
182+
183+
If found, scan `src/` for import statements to find used components:
184+
```bash
185+
grep -rh "from '${package}" --include='*.vue' --include='*.ts' --include='*.js' src/ | sort -u
186+
```
187+
188+
Extract component names from the imports. Read the version from package.json.
189+
190+
### 9. Write design spec
191+
192+
Create `.annotask/design-spec.json`:
193+
194+
```json
195+
{
196+
"version": "1.0",
197+
"framework": {
198+
"name": "vue",
199+
"version": "3.5.0",
200+
"styling": ["tailwind", "scoped-css"]
201+
},
202+
"colors": [
203+
{ "role": "primary", "value": "#3b82f6", "cssVar": "--color-primary", "source": "var(--color-primary)", "sourceFile": "src/assets/main.css", "sourceLine": 5 },
204+
{ "role": "background", "value": "#0b1120", "cssVar": "--bg", "source": "var(--bg)", "sourceFile": "src/assets/main.css", "sourceLine": 3 }
205+
],
206+
"typography": {
207+
"families": [
208+
{ "role": "body", "value": "Inter, sans-serif", "cssVar": "--font-sans", "source": "var(--font-sans)", "sourceFile": "src/assets/main.css", "sourceLine": 10 }
209+
],
210+
"scale": [
211+
{ "role": "base", "value": "1rem", "cssVar": "--text-base", "source": "var(--text-base)", "sourceFile": "src/assets/main.css", "sourceLine": 15 }
212+
],
213+
"weights": ["400", "500", "600", "700"]
214+
},
215+
"spacing": [
216+
{ "role": "sm", "value": "8px", "cssVar": "--space-sm", "source": "var(--space-sm)", "sourceFile": "src/assets/main.css", "sourceLine": 20 }
217+
],
218+
"borders": {
219+
"radius": [
220+
{ "role": "md", "value": "8px", "cssVar": "--radius-md", "source": "var(--radius-md)", "sourceFile": "src/assets/main.css", "sourceLine": 25 }
221+
]
222+
},
223+
"breakpoints": {
224+
"sm": "640px",
225+
"md": "768px",
226+
"lg": "1024px",
227+
"xl": "1280px",
228+
"2xl": "1536px"
229+
},
230+
"icons": {
231+
"library": "lucide",
232+
"version": "0.300.0"
233+
},
234+
"components": {
235+
"library": "PrimeVue",
236+
"version": "4.5.4",
237+
"used": ["DataTable", "Column", "InputText", "Tag", "Button"]
238+
}
239+
}
240+
```
241+
242+
### 10. Clean up old config
243+
244+
If `.annotask/config.json` exists, delete it — it's been replaced by `design-spec.json`.
245+
246+
### 11. Update .gitignore
247+
248+
Check if `.gitignore` contains `.annotask/`. If not, append:
249+
```
250+
# Annotask (generated)
251+
.annotask/
252+
```
253+
254+
### 12. Report to user
255+
256+
Tell the user:
257+
- What was detected (framework, number of color/typography/spacing tokens, libraries)
258+
- That they can open the **Theme** page in Annotask to view and edit tokens
259+
- That they can re-run `/annotask-init` to rescan
260+
261+
## Notes
262+
263+
- This skill is idempotent — re-running overwrites the design spec with fresh data
264+
- The design spec is gitignored because it's generated and may vary per developer
265+
- If detection fails for any section, use empty defaults (empty array, null) rather than omitting the field
266+
- All top-level fields are required — use empty values for missing data
267+
- When a token has a CSS variable backing, always populate the `cssVar` field — this enables live preview in the Theme page
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"mcpServers": {
3+
"annotask": {
4+
"type": "http",
5+
"url": "http://127.0.0.1:4240/__annotask/mcp"
6+
}
7+
}
8+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../.claude/skills/annotask-apply
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../.claude/skills/annotask-init

0 commit comments

Comments
 (0)