stitch-kit 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +139 -0
- package/CHANGELOG.md +86 -0
- package/README.md +167 -0
- package/agents/stitch-kit.md +93 -0
- package/bin/stitch-kit.mjs +430 -0
- package/docs/architecture.md +118 -0
- package/docs/color-prompt-guide.md +119 -0
- package/docs/mcp-naming-convention.md +64 -0
- package/docs/mcp-schemas/README.md +130 -0
- package/docs/mcp-schemas/apply_design_system.json +36 -0
- package/docs/mcp-schemas/create_design_system.json +78 -0
- package/docs/mcp-schemas/create_project.json +290 -0
- package/docs/mcp-schemas/delete_project.json +20 -0
- package/docs/mcp-schemas/edit_screens.json +46 -0
- package/docs/mcp-schemas/generate_screen_from_text.json +242 -0
- package/docs/mcp-schemas/generate_variants.json +77 -0
- package/docs/mcp-schemas/get_project.json +137 -0
- package/docs/mcp-schemas/get_screen.json +92 -0
- package/docs/mcp-schemas/list_design_systems.json +32 -0
- package/docs/mcp-schemas/list_projects.json +136 -0
- package/docs/mcp-schemas/list_screens.json +56 -0
- package/docs/mcp-schemas/update_design_system.json +32 -0
- package/docs/mcp-schemas/upload_screens_from_images.json +52 -0
- package/docs/prd-to-stitch-workflow.md +137 -0
- package/docs/skills-index.md +108 -0
- package/docs/tailwind-reference.md +207 -0
- package/package.json +41 -0
- package/skills/stitch-a11y/SKILL.md +428 -0
- package/skills/stitch-a11y/resources/audit-checklist.md +102 -0
- package/skills/stitch-animate/SKILL.md +371 -0
- package/skills/stitch-animate/resources/animation-patterns.md +248 -0
- package/skills/stitch-design-md/SKILL.md +215 -0
- package/skills/stitch-design-md/examples/DESIGN.md +54 -0
- package/skills/stitch-design-md/examples/usage.md +67 -0
- package/skills/stitch-design-md/scripts/fetch-stitch.sh +35 -0
- package/skills/stitch-design-system/SKILL.md +314 -0
- package/skills/stitch-design-system/resources/tokens-template.css +237 -0
- package/skills/stitch-html-components/SKILL.md +344 -0
- package/skills/stitch-html-components/resources/architecture-checklist.md +74 -0
- package/skills/stitch-html-components/scripts/fetch-stitch.sh +45 -0
- package/skills/stitch-loop/SKILL.md +183 -0
- package/skills/stitch-loop/examples/SITE.md +39 -0
- package/skills/stitch-loop/examples/next-prompt.md +24 -0
- package/skills/stitch-loop/examples/usage.md +77 -0
- package/skills/stitch-mcp-apply-design-system/SKILL.md +82 -0
- package/skills/stitch-mcp-create-design-system/SKILL.md +117 -0
- package/skills/stitch-mcp-create-project/SKILL.md +77 -0
- package/skills/stitch-mcp-delete-project/SKILL.md +62 -0
- package/skills/stitch-mcp-edit-screens/SKILL.md +121 -0
- package/skills/stitch-mcp-generate-screen-from-text/SKILL.md +102 -0
- package/skills/stitch-mcp-generate-screen-from-text/examples/desktop.md +53 -0
- package/skills/stitch-mcp-generate-screen-from-text/examples/mobile.md +71 -0
- package/skills/stitch-mcp-generate-variants/SKILL.md +124 -0
- package/skills/stitch-mcp-get-project/SKILL.md +67 -0
- package/skills/stitch-mcp-get-screen/SKILL.md +117 -0
- package/skills/stitch-mcp-get-screen/scripts/fetch-stitch.sh +35 -0
- package/skills/stitch-mcp-list-design-systems/SKILL.md +84 -0
- package/skills/stitch-mcp-list-projects/SKILL.md +77 -0
- package/skills/stitch-mcp-list-screens/SKILL.md +69 -0
- package/skills/stitch-mcp-update-design-system/SKILL.md +82 -0
- package/skills/stitch-mcp-upload-screens-from-images/SKILL.md +95 -0
- package/skills/stitch-mcp-upload-screens-from-images/scripts/encode-image.sh +43 -0
- package/skills/stitch-nextjs-components/SKILL.md +181 -0
- package/skills/stitch-nextjs-components/resources/architecture-checklist.md +65 -0
- package/skills/stitch-nextjs-components/resources/component-template.tsx +101 -0
- package/skills/stitch-nextjs-components/scripts/fetch-stitch.sh +45 -0
- package/skills/stitch-orchestrator/SKILL.md +337 -0
- package/skills/stitch-orchestrator/examples/workflow.md +173 -0
- package/skills/stitch-react-components/SKILL.md +236 -0
- package/skills/stitch-react-components/references/tailwind-to-react.md +117 -0
- package/skills/stitch-react-components/resources/architecture-checklist.md +34 -0
- package/skills/stitch-react-components/resources/component-template.tsx +35 -0
- package/skills/stitch-react-components/scripts/fetch-stitch.sh +35 -0
- package/skills/stitch-react-native-components/SKILL.md +333 -0
- package/skills/stitch-react-native-components/resources/architecture-checklist.md +74 -0
- package/skills/stitch-react-native-components/resources/component-template.tsx +104 -0
- package/skills/stitch-react-native-components/scripts/fetch-stitch.sh +45 -0
- package/skills/stitch-remotion/SKILL.md +280 -0
- package/skills/stitch-setup/SKILL.md +183 -0
- package/skills/stitch-shadcn-ui/SKILL.md +255 -0
- package/skills/stitch-skill-creator/SKILL.md +257 -0
- package/skills/stitch-skill-creator/references/output-patterns.md +71 -0
- package/skills/stitch-skill-creator/scripts/init_stitch_skill.py +229 -0
- package/skills/stitch-svelte-components/SKILL.md +282 -0
- package/skills/stitch-svelte-components/resources/architecture-checklist.md +62 -0
- package/skills/stitch-svelte-components/resources/component-template.svelte +193 -0
- package/skills/stitch-svelte-components/scripts/fetch-stitch.sh +36 -0
- package/skills/stitch-swiftui-components/SKILL.md +424 -0
- package/skills/stitch-swiftui-components/resources/architecture-checklist.md +83 -0
- package/skills/stitch-swiftui-components/resources/component-template.swift +131 -0
- package/skills/stitch-swiftui-components/resources/layout-mapping.md +155 -0
- package/skills/stitch-swiftui-components/scripts/fetch-stitch.sh +45 -0
- package/skills/stitch-ued-guide/SKILL.md +124 -0
- package/skills/stitch-ui-design-spec-generator/SKILL.md +115 -0
- package/skills/stitch-ui-design-spec-generator/examples/usage.md +79 -0
- package/skills/stitch-ui-design-variants/SKILL.md +127 -0
- package/skills/stitch-ui-prompt-architect/SKILL.md +196 -0
- package/skills/stitch-ui-prompt-architect/references/KEYWORDS.md +170 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stitch-mcp-list-screens
|
|
3
|
+
description: Lists all screens in a Stitch project. Use this after generate_screen_from_text to find the screenId of the newly generated screen, then call stitch-mcp-get-screen to retrieve it.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- "stitch*:*"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Stitch MCP — List Screens
|
|
9
|
+
|
|
10
|
+
Lists all screens contained within a specific Stitch project. You typically call this right after `generate_screen_from_text` to find the `screenId` of the screen that was just created.
|
|
11
|
+
|
|
12
|
+
## Critical prerequisite
|
|
13
|
+
|
|
14
|
+
**Only use this skill when the user explicitly mentions "Stitch".**
|
|
15
|
+
|
|
16
|
+
## When to use
|
|
17
|
+
|
|
18
|
+
- Immediately after `generate_screen_from_text` — to find the new screen's ID
|
|
19
|
+
- User wants to browse all screens in a project
|
|
20
|
+
- You need a `screenId` to call `get_screen`
|
|
21
|
+
- Checking what screens already exist before generating a new one
|
|
22
|
+
|
|
23
|
+
## Call the MCP tool
|
|
24
|
+
|
|
25
|
+
**Important: Use the `projects/ID` format — not the numeric ID alone.**
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"name": "list_screens",
|
|
30
|
+
"arguments": {
|
|
31
|
+
"projectId": "projects/3780309359108792857"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
✅ "projects/3780309359108792857"
|
|
38
|
+
❌ "3780309359108792857"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Output schema
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"screens": [
|
|
46
|
+
{
|
|
47
|
+
"name": "projects/3780309359108792857/screens/88805abc123def456",
|
|
48
|
+
"title": "Login Screen",
|
|
49
|
+
"screenshot": {
|
|
50
|
+
"downloadUrl": "https://storage.googleapis.com/..."
|
|
51
|
+
},
|
|
52
|
+
"deviceType": "MOBILE"
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## After listing
|
|
59
|
+
|
|
60
|
+
1. Identify the target screen (usually the most recently generated — last in the list)
|
|
61
|
+
2. Extract the numeric `screenId` from the `name` field:
|
|
62
|
+
- `"projects/3780309359108792857/screens/88805abc123def456"` → screenId = `"88805abc123def456"`
|
|
63
|
+
3. Call `stitch-mcp-get-screen` with the numeric `projectId` and `screenId`
|
|
64
|
+
|
|
65
|
+
## ID format reminder
|
|
66
|
+
|
|
67
|
+
For the next call (`get_screen`), you need the **numeric IDs** for both project and screen:
|
|
68
|
+
- `projectId` → `3780309359108792857` (strip `projects/` prefix)
|
|
69
|
+
- `screenId` → `88805abc123def456` (strip `projects/.../screens/` prefix)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stitch-mcp-update-design-system
|
|
3
|
+
description: Updates an existing Stitch Design System's theme, tokens, or guidelines. Requires the asset name from create or list operations.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- "stitch*:*"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Stitch MCP — Update Design System
|
|
9
|
+
|
|
10
|
+
Updates an existing Stitch Design System. Use this to modify theme properties, design tokens, or style guidelines without creating a new design system.
|
|
11
|
+
|
|
12
|
+
## Critical prerequisite
|
|
13
|
+
|
|
14
|
+
**Only use this skill when the user explicitly mentions "Stitch".**
|
|
15
|
+
|
|
16
|
+
You must have the design system's asset `name` before calling this. If you don't have one:
|
|
17
|
+
- List existing design systems via `stitch-mcp-list-design-systems`
|
|
18
|
+
- Or use the `name` returned from `stitch-mcp-create-design-system`
|
|
19
|
+
|
|
20
|
+
## When to use
|
|
21
|
+
|
|
22
|
+
- User wants to modify colors, fonts, or roundness of an existing design system
|
|
23
|
+
- After reviewing a design system and wanting to adjust specific properties
|
|
24
|
+
- Updating design tokens after a brand refresh
|
|
25
|
+
|
|
26
|
+
## Call the MCP tool
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"name": "update_design_system",
|
|
31
|
+
"arguments": {
|
|
32
|
+
"designSystem": {
|
|
33
|
+
"name": "assets/ds_abc123",
|
|
34
|
+
"displayName": "SaaS Dashboard Theme v2",
|
|
35
|
+
"theme": {
|
|
36
|
+
"colorMode": "DARK",
|
|
37
|
+
"font": "GEIST",
|
|
38
|
+
"roundness": "ROUND_TWELVE",
|
|
39
|
+
"saturation": 2,
|
|
40
|
+
"customColor": "#818CF8",
|
|
41
|
+
"backgroundLight": "#F9FAFB",
|
|
42
|
+
"backgroundDark": "#09090B"
|
|
43
|
+
},
|
|
44
|
+
"designTokens": "--color-primary: #818CF8;\n--color-bg: #09090B;",
|
|
45
|
+
"styleGuidelines": "Dark mode first. Geist font. Subtle indigo accent."
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Parameter reference
|
|
52
|
+
|
|
53
|
+
### `designSystem` — required, Asset wrapper
|
|
54
|
+
|
|
55
|
+
The object must include the `name` field (asset identifier) plus any fields you want to update:
|
|
56
|
+
|
|
57
|
+
| Field | Type | Required | Description |
|
|
58
|
+
|-------|------|----------|-------------|
|
|
59
|
+
| `name` | string | **Yes** | Asset name from create or list (e.g., `assets/ds_abc123`) |
|
|
60
|
+
| `displayName` | string | No | Updated human-readable name |
|
|
61
|
+
| `theme` | DesignTheme | No | Updated visual configuration (see `stitch-mcp-create-design-system` for full reference) |
|
|
62
|
+
| `designTokens` | string | No | Updated CSS custom properties |
|
|
63
|
+
| `styleGuidelines` | string | No | Updated design rules |
|
|
64
|
+
|
|
65
|
+
**Note:** This is a full replacement, not a merge. Include all theme fields you want to keep, not just the ones you're changing.
|
|
66
|
+
|
|
67
|
+
## Output
|
|
68
|
+
|
|
69
|
+
Returns the updated Asset object:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"name": "assets/ds_abc123",
|
|
74
|
+
"displayName": "SaaS Dashboard Theme v2",
|
|
75
|
+
"designSystem": { ... }
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## After updating
|
|
80
|
+
|
|
81
|
+
- Offer: "Re-apply this updated design system to existing screens?" → `stitch-mcp-apply-design-system`
|
|
82
|
+
- Screens generated before the update won't automatically reflect changes — they need to be re-applied
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stitch-mcp-upload-screens-from-images
|
|
3
|
+
description: Uploads screenshots or mockup images into a Stitch project as new screens. Enables the "redesign from screenshot" workflow — import existing UI and then edit or convert.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- "stitch*:*"
|
|
6
|
+
- "Bash"
|
|
7
|
+
- "Read"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Stitch MCP — Upload Screens from Images
|
|
11
|
+
|
|
12
|
+
Uploads one or more images (screenshots, mockups, wireframes) into a Stitch project as new screens. This is the entry point for the "redesign existing UI" workflow — import what you have, then use `edit_screens` to iterate or convert directly to code.
|
|
13
|
+
|
|
14
|
+
## Critical prerequisite
|
|
15
|
+
|
|
16
|
+
**Only use this skill when the user explicitly mentions "Stitch".**
|
|
17
|
+
|
|
18
|
+
You must have a `projectId` before calling this. If you don't have one:
|
|
19
|
+
- Create a new project via `stitch-mcp-create-project`
|
|
20
|
+
- Or find an existing project via `stitch-mcp-list-projects`
|
|
21
|
+
|
|
22
|
+
## When to use
|
|
23
|
+
|
|
24
|
+
- User provides a screenshot and wants to redesign it in Stitch
|
|
25
|
+
- User wants to import existing mockups into Stitch for editing
|
|
26
|
+
- The orchestrator classifies intent as "Upload screenshot"
|
|
27
|
+
- User says "import this design", "upload this image", or "redesign this screen"
|
|
28
|
+
|
|
29
|
+
## Step 1: Encode the image to base64
|
|
30
|
+
|
|
31
|
+
Use the helper script to convert a local image file to base64:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bash scripts/encode-image.sh "path/to/screenshot.png"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The script outputs raw base64 to stdout. Capture it for the API call.
|
|
38
|
+
|
|
39
|
+
Supported formats and their MIME types:
|
|
40
|
+
| Extension | MIME type |
|
|
41
|
+
|-----------|----------|
|
|
42
|
+
| `.png` | `image/png` |
|
|
43
|
+
| `.jpg`, `.jpeg` | `image/jpeg` |
|
|
44
|
+
| `.webp` | `image/webp` |
|
|
45
|
+
| `.gif` | `image/gif` |
|
|
46
|
+
|
|
47
|
+
## Step 2: Call the MCP tool
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"name": "upload_screens_from_images",
|
|
52
|
+
"arguments": {
|
|
53
|
+
"projectId": "3780309359108792857",
|
|
54
|
+
"images": [
|
|
55
|
+
{
|
|
56
|
+
"fileContentBase64": "[base64-encoded-image-data]",
|
|
57
|
+
"mimeType": "image/png"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `projectId` — numeric ID only, no prefix
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
✅ "3780309359108792857"
|
|
68
|
+
❌ "projects/3780309359108792857"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### `images` — array of image objects
|
|
72
|
+
|
|
73
|
+
Each image needs:
|
|
74
|
+
| Field | Type | Description |
|
|
75
|
+
|-------|------|-------------|
|
|
76
|
+
| `fileContentBase64` | string | Base64-encoded image data (no `data:` prefix) |
|
|
77
|
+
| `mimeType` | string | MIME type matching the image format |
|
|
78
|
+
|
|
79
|
+
You can upload multiple images in a single call — each becomes a separate screen.
|
|
80
|
+
|
|
81
|
+
## Output
|
|
82
|
+
|
|
83
|
+
Returns session info similar to `generate_screen_from_text`. The uploaded images appear as new screens in the project.
|
|
84
|
+
|
|
85
|
+
## After uploading
|
|
86
|
+
|
|
87
|
+
1. Call `stitch-mcp-list-screens` to find the new screen IDs
|
|
88
|
+
2. Offer the user:
|
|
89
|
+
- "Edit this screen (change colors, layout, content)?" → `stitch-mcp-edit-screens`
|
|
90
|
+
- "Convert directly to code?" → `stitch-mcp-get-screen` → framework conversion
|
|
91
|
+
- "Generate variants based on this design?" → `stitch-mcp-generate-variants`
|
|
92
|
+
|
|
93
|
+
## References
|
|
94
|
+
|
|
95
|
+
- `scripts/encode-image.sh` — Base64 encoding helper
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# encode-image.sh — Encodes an image file to base64 for the Stitch upload API.
|
|
3
|
+
#
|
|
4
|
+
# Usage: bash encode-image.sh "path/to/image.png"
|
|
5
|
+
# Output: Raw base64 string to stdout (no wrapping, no data: prefix)
|
|
6
|
+
#
|
|
7
|
+
# Supports: PNG, JPG, JPEG, WebP, GIF
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
if [[ $# -lt 1 ]]; then
|
|
12
|
+
echo "Usage: bash encode-image.sh <image-path>" >&2
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
IMAGE_PATH="$1"
|
|
17
|
+
|
|
18
|
+
# Validate the file exists
|
|
19
|
+
if [[ ! -f "$IMAGE_PATH" ]]; then
|
|
20
|
+
echo "Error: File not found: $IMAGE_PATH" >&2
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Validate the file is an image by extension
|
|
25
|
+
EXT="${IMAGE_PATH##*.}"
|
|
26
|
+
EXT_LOWER=$(echo "$EXT" | tr '[:upper:]' '[:lower:]')
|
|
27
|
+
|
|
28
|
+
case "$EXT_LOWER" in
|
|
29
|
+
png|jpg|jpeg|webp|gif)
|
|
30
|
+
;;
|
|
31
|
+
*)
|
|
32
|
+
echo "Error: Unsupported image format: .$EXT_LOWER (expected png, jpg, jpeg, webp, or gif)" >&2
|
|
33
|
+
exit 1
|
|
34
|
+
;;
|
|
35
|
+
esac
|
|
36
|
+
|
|
37
|
+
# Encode to base64 — macOS and Linux compatible
|
|
38
|
+
# macOS base64 doesn't support --wrap, uses -b 0 instead
|
|
39
|
+
if base64 --wrap=0 "$IMAGE_PATH" 2>/dev/null; then
|
|
40
|
+
: # Linux: --wrap=0 disables line wrapping
|
|
41
|
+
else
|
|
42
|
+
base64 -i "$IMAGE_PATH" # macOS: no wrapping by default with -i
|
|
43
|
+
fi
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stitch-nextjs-components
|
|
3
|
+
description: Converts Stitch designs into production-ready Next.js 15 App Router components — Server vs Client split, dark mode via CSS variables, TypeScript strict, ARIA, and responsive mobile-first layout.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- "stitch*:*"
|
|
6
|
+
- "Bash"
|
|
7
|
+
- "Read"
|
|
8
|
+
- "Write"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Stitch → Next.js 15 App Router Components
|
|
12
|
+
|
|
13
|
+
You are a senior Next.js engineer. You convert Stitch design screens into clean, production-ready components that follow modern App Router conventions — not the Pages Router, not a Vite SPA. Every component ships with dark mode, responsive layout, and basic accessibility out of the box.
|
|
14
|
+
|
|
15
|
+
## When to use this skill
|
|
16
|
+
|
|
17
|
+
Use this skill (not `react-components`) when:
|
|
18
|
+
- The target project uses **Next.js 13+** with the **App Router** (`app/` directory)
|
|
19
|
+
- The user mentions `next.js`, `app router`, `server components`, `server actions`, or `next-themes`
|
|
20
|
+
- You see `app/layout.tsx`, `app/page.tsx`, or a `next.config.*` file in the project
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
|
|
24
|
+
- Access to the Stitch MCP server
|
|
25
|
+
- A Stitch project with at least one generated screen
|
|
26
|
+
- Target project has `next-themes` installed for dark mode (or user approves adding it)
|
|
27
|
+
|
|
28
|
+
## Step 1: Retrieve the Stitch design
|
|
29
|
+
|
|
30
|
+
1. **Namespace discovery** — Run `list_tools` to find the Stitch MCP prefix (e.g., `stitch:`). Use this prefix for all subsequent calls.
|
|
31
|
+
2. **Fetch screen metadata** — Call `[prefix]:get_screen` with the `projectId` and `screenId`.
|
|
32
|
+
3. **Download HTML** — GCS URLs need a reliable downloader:
|
|
33
|
+
```bash
|
|
34
|
+
bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html"
|
|
35
|
+
```
|
|
36
|
+
4. **Visual audit** — Check `screenshot.downloadUrl` to understand layout intent before writing code.
|
|
37
|
+
|
|
38
|
+
## Step 2: Decide Server Component vs Client Component
|
|
39
|
+
|
|
40
|
+
Apply this decision tree **per component**, not per file:
|
|
41
|
+
|
|
42
|
+
| Has... | Use |
|
|
43
|
+
|--------|-----|
|
|
44
|
+
| `onClick`, `onChange`, `useState`, `useEffect`, animations | `'use client'` |
|
|
45
|
+
| Only renders data, no interactivity | Server Component (no directive needed) |
|
|
46
|
+
| Wraps a Client Component library | `'use client'` |
|
|
47
|
+
| Form with Server Action | Server Component + `<form action={serverAction}>` |
|
|
48
|
+
|
|
49
|
+
**Default to Server Components.** Only add `'use client'` when required. This is the single most impactful App Router pattern.
|
|
50
|
+
|
|
51
|
+
## Step 3: Component architecture
|
|
52
|
+
|
|
53
|
+
### File structure
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
app/
|
|
57
|
+
├── [route]/
|
|
58
|
+
│ ├── page.tsx ← Server Component (route entry)
|
|
59
|
+
│ └── components/
|
|
60
|
+
│ ├── [Name].tsx ← Logic-heavy Client Component
|
|
61
|
+
│ ├── [Name].module.css ← Scoped styles (optional)
|
|
62
|
+
│ └── index.ts ← Re-exports
|
|
63
|
+
src/
|
|
64
|
+
├── components/
|
|
65
|
+
│ └── ui/ ← Reusable primitives
|
|
66
|
+
├── data/
|
|
67
|
+
│ └── mockData.ts ← Static content decoupled from components
|
|
68
|
+
└── types/
|
|
69
|
+
└── index.ts ← Shared TypeScript types
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Rules
|
|
73
|
+
|
|
74
|
+
- **Props contract**: Every component has a `Readonly<ComponentNameProps>` interface at the top of the file.
|
|
75
|
+
- **Data decoupling**: All static text, image URLs, and list data goes in `src/data/mockData.ts`. Components receive data via props.
|
|
76
|
+
- **No hardcoded colors**: Use CSS custom property classes (`bg-[var(--color-primary)]`) or semantic Tailwind tokens. Never use arbitrary hex in JSX.
|
|
77
|
+
- **No inline styles**: Exceptions only for truly dynamic values (e.g., width from JS calculation).
|
|
78
|
+
|
|
79
|
+
## Step 4: Dark mode with CSS variables
|
|
80
|
+
|
|
81
|
+
This project uses a CSS variable approach that works with `next-themes`. Extract colors from the Stitch design and map them to semantic tokens.
|
|
82
|
+
|
|
83
|
+
In `app/globals.css`:
|
|
84
|
+
```css
|
|
85
|
+
:root {
|
|
86
|
+
--color-background: #ffffff;
|
|
87
|
+
--color-surface: #f4f4f5;
|
|
88
|
+
--color-primary: /* dominant action color from Stitch design */;
|
|
89
|
+
--color-primary-foreground: #ffffff;
|
|
90
|
+
--color-text: #09090b;
|
|
91
|
+
--color-text-muted: #71717a;
|
|
92
|
+
--color-border: #e4e4e7;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.dark {
|
|
96
|
+
--color-background: #09090b;
|
|
97
|
+
--color-surface: #18181b;
|
|
98
|
+
--color-primary: /* same hue, lighter shade for dark bg */;
|
|
99
|
+
--color-primary-foreground: #09090b;
|
|
100
|
+
--color-text: #fafafa;
|
|
101
|
+
--color-text-muted: #a1a1aa;
|
|
102
|
+
--color-border: #27272a;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
In `app/layout.tsx`, wrap with `ThemeProvider` from `next-themes`:
|
|
107
|
+
```tsx
|
|
108
|
+
import { ThemeProvider } from 'next-themes'
|
|
109
|
+
|
|
110
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
111
|
+
return (
|
|
112
|
+
<html lang="en" suppressHydrationWarning>
|
|
113
|
+
<body>
|
|
114
|
+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
|
115
|
+
{children}
|
|
116
|
+
</ThemeProvider>
|
|
117
|
+
</body>
|
|
118
|
+
</html>
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Step 5: Responsive layout
|
|
124
|
+
|
|
125
|
+
All components must work at `sm` (640px), `md` (768px), `lg` (1024px), and `xl` (1280px) breakpoints.
|
|
126
|
+
|
|
127
|
+
Apply these patterns from the Stitch design:
|
|
128
|
+
- **Navigation**: `hidden md:flex` for desktop nav, `flex md:hidden` for mobile hamburger
|
|
129
|
+
- **Grid**: `grid-cols-1 sm:grid-cols-2 lg:grid-cols-3` — start single column
|
|
130
|
+
- **Typography**: `text-2xl md:text-4xl` — scale up on larger screens
|
|
131
|
+
- **Padding**: `px-4 md:px-8 lg:px-16` — breathe more at wider widths
|
|
132
|
+
- **Images**: Always use `next/image` with `sizes` attribute to avoid CLS
|
|
133
|
+
|
|
134
|
+
## Step 6: Accessibility baseline
|
|
135
|
+
|
|
136
|
+
Every component must include these without being asked:
|
|
137
|
+
|
|
138
|
+
- **Semantic HTML**: `<nav>`, `<main>`, `<section>`, `<article>`, `<header>`, `<footer>` — never a `<div>` when a semantic element fits.
|
|
139
|
+
- **Interactive elements**: Buttons use `<button>`, not `<div onClick>`. Links use `<a>` or `next/link`.
|
|
140
|
+
- **Images**: `<Image>` always has a descriptive `alt` attribute. Decorative images get `alt=""`.
|
|
141
|
+
- **ARIA labels**: Icon-only buttons get `aria-label`. Landmark regions get `aria-label` when there are multiples.
|
|
142
|
+
- **Focus ring**: Never `outline-none` without a custom `focus-visible:ring-*` replacement.
|
|
143
|
+
- **Color contrast**: Don't use muted text on muted backgrounds — check the ratio mentally.
|
|
144
|
+
|
|
145
|
+
If the design has complex interactivity (modals, dropdowns, tabs), use the `stitch-a11y` skill for a full audit.
|
|
146
|
+
|
|
147
|
+
## Step 7: Execution steps
|
|
148
|
+
|
|
149
|
+
1. **Environment check** — If `node_modules` is missing, run `npm install`.
|
|
150
|
+
2. **Data layer** — Create `src/data/mockData.ts` from design content.
|
|
151
|
+
3. **Component drafting** — Use `resources/component-template.tsx` as the starting point. Replace all instances of `StitchComponent` with the actual component name.
|
|
152
|
+
4. **Dark mode tokens** — Add CSS variable declarations to `app/globals.css`. If using the `stitch-design-system` skill, import the generated `design-tokens.css` instead.
|
|
153
|
+
5. **Application wiring** — Update `app/page.tsx` or the relevant route page to import and render the new components.
|
|
154
|
+
6. **Quality check** — Run through `resources/architecture-checklist.md` before declaring done.
|
|
155
|
+
7. **Dev verification** — Run `npm run dev` and check both light and dark modes.
|
|
156
|
+
|
|
157
|
+
## Step 8: Animation (optional)
|
|
158
|
+
|
|
159
|
+
If the Stitch design contains clear motion intent (hover states, transitions, reveals), use the `stitch-animate` skill after components are built. Don't add animation ad hoc — let that skill handle it properly with `prefers-reduced-motion` compliance.
|
|
160
|
+
|
|
161
|
+
## Troubleshooting
|
|
162
|
+
|
|
163
|
+
| Issue | Fix |
|
|
164
|
+
|-------|-----|
|
|
165
|
+
| `fetch` fails on GCS URL | Always quote the URL in bash: `bash scripts/fetch-stitch.sh "$URL" out.html` |
|
|
166
|
+
| Hydration mismatch on dark mode | Add `suppressHydrationWarning` to `<html>` tag |
|
|
167
|
+
| `next-themes` not found | `npm install next-themes` |
|
|
168
|
+
| Server Component using hooks | Move component to its own file with `'use client'` directive |
|
|
169
|
+
| CSS variable not applying in dark | Ensure `.dark` class is on `<html>`, not `<body>` |
|
|
170
|
+
|
|
171
|
+
## Integration with other skills
|
|
172
|
+
|
|
173
|
+
- **stitch-design-system** — Run first to generate `design-tokens.css`. Import in `globals.css`.
|
|
174
|
+
- **stitch-animate** — Run after to add motion to the generated components.
|
|
175
|
+
- **stitch-a11y** — Run after if design has modals, dropdowns, or complex interactions.
|
|
176
|
+
|
|
177
|
+
## References
|
|
178
|
+
|
|
179
|
+
- `resources/component-template.tsx` — Production-ready component boilerplate
|
|
180
|
+
- `resources/architecture-checklist.md` — Pre-ship quality checklist
|
|
181
|
+
- `scripts/fetch-stitch.sh` — Reliable GCS HTML downloader
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Next.js Components — Architecture Checklist
|
|
2
|
+
|
|
3
|
+
Run through this checklist before marking the task complete.
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
- [ ] Components are in separate files — no single-file spaghetti
|
|
8
|
+
- [ ] Static content is in `src/data/mockData.ts`, not hardcoded in JSX
|
|
9
|
+
- [ ] Shared TypeScript types are in `src/types/index.ts`
|
|
10
|
+
- [ ] Each component file has a `Readonly<ComponentNameProps>` interface
|
|
11
|
+
- [ ] Custom hooks (if any) are in `src/hooks/`
|
|
12
|
+
|
|
13
|
+
## App Router correctness
|
|
14
|
+
|
|
15
|
+
- [ ] Pages are in `app/[route]/page.tsx`, not `pages/`
|
|
16
|
+
- [ ] Interactive components have `'use client'` at the top
|
|
17
|
+
- [ ] Non-interactive components do NOT have `'use client'`
|
|
18
|
+
- [ ] No `useState` / `useEffect` in Server Components
|
|
19
|
+
- [ ] `next/image` used for all images (never `<img>`)
|
|
20
|
+
- [ ] `next/link` used for all internal navigation (never `<a>`)
|
|
21
|
+
|
|
22
|
+
## TypeScript
|
|
23
|
+
|
|
24
|
+
- [ ] No `any` types
|
|
25
|
+
- [ ] All function parameters are typed
|
|
26
|
+
- [ ] All component props use `Readonly<>`
|
|
27
|
+
- [ ] No `@ts-ignore` or `@ts-expect-error` without a comment explaining why
|
|
28
|
+
|
|
29
|
+
## Styling — CSS variables
|
|
30
|
+
|
|
31
|
+
- [ ] No hardcoded hex colors in JSX or CSS
|
|
32
|
+
- [ ] All colors reference `var(--color-*)` tokens
|
|
33
|
+
- [ ] Dark mode works — toggle `.dark` class on `<html>` and verify visually
|
|
34
|
+
- [ ] `design-tokens.css` is imported in `globals.css`
|
|
35
|
+
|
|
36
|
+
## Responsive
|
|
37
|
+
|
|
38
|
+
- [ ] Layout works at 320px (small mobile) — no horizontal overflow
|
|
39
|
+
- [ ] Layout works at 768px (tablet)
|
|
40
|
+
- [ ] Layout works at 1280px (desktop)
|
|
41
|
+
- [ ] Navigation collapses appropriately on mobile
|
|
42
|
+
- [ ] All images have correct `sizes` attribute for responsive loading
|
|
43
|
+
|
|
44
|
+
## Accessibility baseline
|
|
45
|
+
|
|
46
|
+
- [ ] Semantic HTML: `<nav>`, `<main>`, `<section>`, `<article>` where appropriate
|
|
47
|
+
- [ ] `<main id="main-content">` exists on every page
|
|
48
|
+
- [ ] Skip navigation link is first element in `app/layout.tsx`
|
|
49
|
+
- [ ] All interactive elements are `<button>` or `<a>`, not `<div>`
|
|
50
|
+
- [ ] All images have descriptive `alt` text (or `alt=""` for decorative)
|
|
51
|
+
- [ ] Icon-only buttons have `aria-label`
|
|
52
|
+
- [ ] No `outline-none` without a visible `focus-visible:ring-*` replacement
|
|
53
|
+
|
|
54
|
+
## Dark mode
|
|
55
|
+
|
|
56
|
+
- [ ] `ThemeProvider` is wrapping `{children}` in `app/layout.tsx`
|
|
57
|
+
- [ ] `suppressHydrationWarning` is on the `<html>` tag
|
|
58
|
+
- [ ] Both light and dark modes look correct (test by toggling class)
|
|
59
|
+
- [ ] No elements that "disappear" in dark mode (white on white, etc.)
|
|
60
|
+
|
|
61
|
+
## Performance
|
|
62
|
+
|
|
63
|
+
- [ ] No `console.log` statements left in production code
|
|
64
|
+
- [ ] Images use `next/image` with `width` and `height` (or `fill` + `sizes`)
|
|
65
|
+
- [ ] Heavy dependencies are dynamically imported if not needed on initial load
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StitchComponent
|
|
3
|
+
*
|
|
4
|
+
* Generated from Stitch design via stitch-nextjs-components skill.
|
|
5
|
+
* Replace "StitchComponent" with the actual component name throughout.
|
|
6
|
+
*
|
|
7
|
+
* Pattern: Server Component by default.
|
|
8
|
+
* Add 'use client' only if this component uses hooks, onClick, or browser APIs.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Uncomment if this component needs interactivity:
|
|
12
|
+
// 'use client'
|
|
13
|
+
|
|
14
|
+
import type { ReactNode } from 'react'
|
|
15
|
+
|
|
16
|
+
// ------------------------------------------------------------
|
|
17
|
+
// Types
|
|
18
|
+
// ------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Props for StitchComponent.
|
|
22
|
+
* All data comes through props — never imported directly.
|
|
23
|
+
* Use Readonly<> to prevent accidental mutation.
|
|
24
|
+
*/
|
|
25
|
+
interface StitchComponentProps {
|
|
26
|
+
/** Primary content to display */
|
|
27
|
+
title: string
|
|
28
|
+
/** Supporting description text */
|
|
29
|
+
description?: string
|
|
30
|
+
/** Nested content — use for compound components */
|
|
31
|
+
children?: ReactNode
|
|
32
|
+
/** Callback for primary action — triggers 'use client' if needed */
|
|
33
|
+
// onAction?: () => void
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ------------------------------------------------------------
|
|
37
|
+
// Component
|
|
38
|
+
// ------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* StitchComponent — [describe what this component does in one sentence]
|
|
42
|
+
*
|
|
43
|
+
* @param props - {@link StitchComponentProps}
|
|
44
|
+
*/
|
|
45
|
+
export function StitchComponent({
|
|
46
|
+
title,
|
|
47
|
+
description,
|
|
48
|
+
children,
|
|
49
|
+
}: Readonly<StitchComponentProps>) {
|
|
50
|
+
return (
|
|
51
|
+
<section
|
|
52
|
+
// Semantic landmark — adjust to article, aside, div, etc. as appropriate
|
|
53
|
+
aria-labelledby="stitch-component-title"
|
|
54
|
+
className="
|
|
55
|
+
/* Layout */
|
|
56
|
+
flex flex-col gap-4
|
|
57
|
+
/* Spacing */
|
|
58
|
+
p-6 md:p-8
|
|
59
|
+
/* Colors — always use CSS variable classes, never arbitrary hex */
|
|
60
|
+
bg-[var(--color-surface)]
|
|
61
|
+
text-[var(--color-text)]
|
|
62
|
+
/* Geometry */
|
|
63
|
+
rounded-[var(--radius-lg)]
|
|
64
|
+
border border-[var(--color-border)]
|
|
65
|
+
/* Shadow */
|
|
66
|
+
shadow-sm
|
|
67
|
+
/* Responsive */
|
|
68
|
+
w-full max-w-2xl
|
|
69
|
+
"
|
|
70
|
+
>
|
|
71
|
+
{/* Heading — maintain hierarchy (h1 → h2 → h3, never skip) */}
|
|
72
|
+
<h2
|
|
73
|
+
id="stitch-component-title"
|
|
74
|
+
className="
|
|
75
|
+
text-2xl font-bold
|
|
76
|
+
text-[var(--color-text)]
|
|
77
|
+
font-[var(--font-sans)]
|
|
78
|
+
"
|
|
79
|
+
>
|
|
80
|
+
{title}
|
|
81
|
+
</h2>
|
|
82
|
+
|
|
83
|
+
{/* Description — optional, use text-muted for supporting copy */}
|
|
84
|
+
{description && (
|
|
85
|
+
<p className="text-[var(--color-text-muted)] text-base leading-relaxed">
|
|
86
|
+
{description}
|
|
87
|
+
</p>
|
|
88
|
+
)}
|
|
89
|
+
|
|
90
|
+
{/* Slot for nested content */}
|
|
91
|
+
{children && (
|
|
92
|
+
<div className="flex flex-col gap-3">
|
|
93
|
+
{children}
|
|
94
|
+
</div>
|
|
95
|
+
)}
|
|
96
|
+
</section>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Default export for page-level components. Named export for UI primitives.
|
|
101
|
+
export default StitchComponent
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# fetch-stitch.sh
|
|
3
|
+
# Reliably downloads Stitch HTML from Google Cloud Storage URLs.
|
|
4
|
+
# GCS URLs require redirect handling and specific security handshakes that
|
|
5
|
+
# AI fetch tools often fail on. This script handles both.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# bash scripts/fetch-stitch.sh "<url>" "<output-path>"
|
|
9
|
+
#
|
|
10
|
+
# Example:
|
|
11
|
+
# bash scripts/fetch-stitch.sh "$htmlCode_downloadUrl" "temp/source.html"
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
URL="${1:?Usage: fetch-stitch.sh <url> <output-path>}"
|
|
16
|
+
OUTPUT="${2:?Usage: fetch-stitch.sh <url> <output-path>}"
|
|
17
|
+
|
|
18
|
+
# Create output directory if it doesn't exist
|
|
19
|
+
mkdir -p "$(dirname "$OUTPUT")"
|
|
20
|
+
|
|
21
|
+
# Use curl with:
|
|
22
|
+
# -L : follow redirects (GCS uses multiple redirect hops)
|
|
23
|
+
# -A : set User-Agent to avoid bot blocking
|
|
24
|
+
# --compressed : handle gzip responses
|
|
25
|
+
# --retry 3 : retry on transient failures
|
|
26
|
+
# --retry-delay 1 : wait 1s between retries
|
|
27
|
+
# --max-time 30 : don't hang forever
|
|
28
|
+
curl -L \
|
|
29
|
+
-A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
|
|
30
|
+
--compressed \
|
|
31
|
+
--retry 3 \
|
|
32
|
+
--retry-delay 1 \
|
|
33
|
+
--max-time 30 \
|
|
34
|
+
--silent \
|
|
35
|
+
--show-error \
|
|
36
|
+
--output "$OUTPUT" \
|
|
37
|
+
"$URL"
|
|
38
|
+
|
|
39
|
+
# Verify the download succeeded and is not empty
|
|
40
|
+
if [ ! -s "$OUTPUT" ]; then
|
|
41
|
+
echo "Error: Downloaded file is empty. URL may be expired or invalid." >&2
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
echo "Downloaded to: $OUTPUT ($(wc -c < "$OUTPUT") bytes)"
|