bps-kit 1.0.18 → 1.1.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/bin/cli.js +156 -28
- package/bin/convert_to_vscode.js +3 -0
- package/package.json +2 -2
- package/templates/VAULT_INDEX.md +5 -4
- package/templates/agents-template/agents/frontend-specialist.md +1 -1
- package/templates/agents-template/agents/site-builder.md +177 -0
- package/templates/agents-template/rules/GEMINI.md +5 -2
- package/templates/agents-template/workflows/build-site.md +122 -0
- package/templates/skills_extra/stitch-loop/README.md +54 -0
- package/templates/skills_extra/stitch-loop/SKILL.md +263 -0
- package/templates/skills_extra/stitch-loop/examples/SITE.md +73 -0
- package/templates/skills_extra/stitch-loop/examples/next-prompt.md +25 -0
- package/templates/skills_extra/stitch-loop/resources/baton-schema.md +61 -0
- package/templates/skills_extra/stitch-loop/resources/site-template.md +104 -0
- package/templates/skills_normal/design-md/README.md +34 -0
- package/templates/skills_normal/design-md/SKILL.md +172 -0
- package/templates/skills_normal/design-md/examples/DESIGN.md +154 -0
- package/templates/skills_normal/enhance-prompt/README.md +34 -0
- package/templates/skills_normal/enhance-prompt/SKILL.md +204 -0
- package/templates/skills_normal/enhance-prompt/references/KEYWORDS.md +114 -0
- package/templates/skills_normal/react-components/README.md +36 -0
- package/templates/skills_normal/react-components/SKILL.md +47 -0
- package/templates/skills_normal/react-components/examples/gold-standard-card.tsx +80 -0
- package/templates/skills_normal/react-components/package-lock.json +231 -0
- package/templates/skills_normal/react-components/package.json +16 -0
- package/templates/skills_normal/react-components/resources/architecture-checklist.md +15 -0
- package/templates/skills_normal/react-components/resources/component-template.tsx +37 -0
- package/templates/skills_normal/react-components/resources/stitch-api-reference.md +14 -0
- package/templates/skills_normal/react-components/resources/style-guide.json +27 -0
- package/templates/skills_normal/react-components/scripts/fetch-stitch.sh +30 -0
- package/templates/skills_normal/react-components/scripts/validate.js +70 -0
- package/templates/vault/remotion/README.md +105 -0
- package/templates/vault/remotion/examples/WalkthroughComposition.tsx +78 -0
- package/templates/vault/remotion/examples/screens.json +56 -0
- package/templates/vault/remotion/resources/composition-checklist.md +124 -0
- package/templates/vault/remotion/resources/screen-slide-template.tsx +123 -0
- package/templates/vault/remotion/scripts/download-stitch-asset.sh +38 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "stitch-to-react-pro",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "stitch-to-react-pro",
|
|
9
|
+
"version": "1.0.0",
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@swc/core": "^1.3.100"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18.0.0"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"node_modules/@swc/core": {
|
|
18
|
+
"version": "1.15.8",
|
|
19
|
+
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.8.tgz",
|
|
20
|
+
"integrity": "sha512-T8keoJjXaSUoVBCIjgL6wAnhADIb09GOELzKg10CjNg+vLX48P93SME6jTfte9MZIm5m+Il57H3rTSk/0kzDUw==",
|
|
21
|
+
"hasInstallScript": true,
|
|
22
|
+
"license": "Apache-2.0",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@swc/counter": "^0.1.3",
|
|
25
|
+
"@swc/types": "^0.1.25"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=10"
|
|
29
|
+
},
|
|
30
|
+
"funding": {
|
|
31
|
+
"type": "opencollective",
|
|
32
|
+
"url": "https://opencollective.com/swc"
|
|
33
|
+
},
|
|
34
|
+
"optionalDependencies": {
|
|
35
|
+
"@swc/core-darwin-arm64": "1.15.8",
|
|
36
|
+
"@swc/core-darwin-x64": "1.15.8",
|
|
37
|
+
"@swc/core-linux-arm-gnueabihf": "1.15.8",
|
|
38
|
+
"@swc/core-linux-arm64-gnu": "1.15.8",
|
|
39
|
+
"@swc/core-linux-arm64-musl": "1.15.8",
|
|
40
|
+
"@swc/core-linux-x64-gnu": "1.15.8",
|
|
41
|
+
"@swc/core-linux-x64-musl": "1.15.8",
|
|
42
|
+
"@swc/core-win32-arm64-msvc": "1.15.8",
|
|
43
|
+
"@swc/core-win32-ia32-msvc": "1.15.8",
|
|
44
|
+
"@swc/core-win32-x64-msvc": "1.15.8"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@swc/helpers": ">=0.5.17"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"@swc/helpers": {
|
|
51
|
+
"optional": true
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"node_modules/@swc/core-darwin-arm64": {
|
|
56
|
+
"version": "1.15.8",
|
|
57
|
+
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.8.tgz",
|
|
58
|
+
"integrity": "sha512-M9cK5GwyWWRkRGwwCbREuj6r8jKdES/haCZ3Xckgkl8MUQJZA3XB7IXXK1IXRNeLjg6m7cnoMICpXv1v1hlJOg==",
|
|
59
|
+
"cpu": [
|
|
60
|
+
"arm64"
|
|
61
|
+
],
|
|
62
|
+
"license": "Apache-2.0 AND MIT",
|
|
63
|
+
"optional": true,
|
|
64
|
+
"os": [
|
|
65
|
+
"darwin"
|
|
66
|
+
],
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=10"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"node_modules/@swc/core-darwin-x64": {
|
|
72
|
+
"version": "1.15.8",
|
|
73
|
+
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.8.tgz",
|
|
74
|
+
"integrity": "sha512-j47DasuOvXl80sKJHSi2X25l44CMc3VDhlJwA7oewC1nV1VsSzwX+KOwE5tLnfORvVJJyeiXgJORNYg4jeIjYQ==",
|
|
75
|
+
"cpu": [
|
|
76
|
+
"x64"
|
|
77
|
+
],
|
|
78
|
+
"license": "Apache-2.0 AND MIT",
|
|
79
|
+
"optional": true,
|
|
80
|
+
"os": [
|
|
81
|
+
"darwin"
|
|
82
|
+
],
|
|
83
|
+
"engines": {
|
|
84
|
+
"node": ">=10"
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
|
88
|
+
"version": "1.15.8",
|
|
89
|
+
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.8.tgz",
|
|
90
|
+
"integrity": "sha512-siAzDENu2rUbwr9+fayWa26r5A9fol1iORG53HWxQL1J8ym4k7xt9eME0dMPXlYZDytK5r9sW8zEA10F2U3Xwg==",
|
|
91
|
+
"cpu": [
|
|
92
|
+
"arm"
|
|
93
|
+
],
|
|
94
|
+
"license": "Apache-2.0",
|
|
95
|
+
"optional": true,
|
|
96
|
+
"os": [
|
|
97
|
+
"linux"
|
|
98
|
+
],
|
|
99
|
+
"engines": {
|
|
100
|
+
"node": ">=10"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"node_modules/@swc/core-linux-arm64-gnu": {
|
|
104
|
+
"version": "1.15.8",
|
|
105
|
+
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.8.tgz",
|
|
106
|
+
"integrity": "sha512-o+1y5u6k2FfPYbTRUPvurwzNt5qd0NTumCTFscCNuBksycloXY16J8L+SMW5QRX59n4Hp9EmFa3vpvNHRVv1+Q==",
|
|
107
|
+
"cpu": [
|
|
108
|
+
"arm64"
|
|
109
|
+
],
|
|
110
|
+
"license": "Apache-2.0 AND MIT",
|
|
111
|
+
"optional": true,
|
|
112
|
+
"os": [
|
|
113
|
+
"linux"
|
|
114
|
+
],
|
|
115
|
+
"engines": {
|
|
116
|
+
"node": ">=10"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"node_modules/@swc/core-linux-arm64-musl": {
|
|
120
|
+
"version": "1.15.8",
|
|
121
|
+
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.8.tgz",
|
|
122
|
+
"integrity": "sha512-koiCqL09EwOP1S2RShCI7NbsQuG6r2brTqUYE7pV7kZm9O17wZ0LSz22m6gVibpwEnw8jI3IE1yYsQTVpluALw==",
|
|
123
|
+
"cpu": [
|
|
124
|
+
"arm64"
|
|
125
|
+
],
|
|
126
|
+
"license": "Apache-2.0 AND MIT",
|
|
127
|
+
"optional": true,
|
|
128
|
+
"os": [
|
|
129
|
+
"linux"
|
|
130
|
+
],
|
|
131
|
+
"engines": {
|
|
132
|
+
"node": ">=10"
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"node_modules/@swc/core-linux-x64-gnu": {
|
|
136
|
+
"version": "1.15.8",
|
|
137
|
+
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.8.tgz",
|
|
138
|
+
"integrity": "sha512-4p6lOMU3bC+Vd5ARtKJ/FxpIC5G8v3XLoPEZ5s7mLR8h7411HWC/LmTXDHcrSXRC55zvAVia1eldy6zDLz8iFQ==",
|
|
139
|
+
"cpu": [
|
|
140
|
+
"x64"
|
|
141
|
+
],
|
|
142
|
+
"license": "Apache-2.0 AND MIT",
|
|
143
|
+
"optional": true,
|
|
144
|
+
"os": [
|
|
145
|
+
"linux"
|
|
146
|
+
],
|
|
147
|
+
"engines": {
|
|
148
|
+
"node": ">=10"
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"node_modules/@swc/core-linux-x64-musl": {
|
|
152
|
+
"version": "1.15.8",
|
|
153
|
+
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.8.tgz",
|
|
154
|
+
"integrity": "sha512-z3XBnbrZAL+6xDGAhJoN4lOueIxC/8rGrJ9tg+fEaeqLEuAtHSW2QHDHxDwkxZMjuF/pZ6MUTjHjbp8wLbuRLA==",
|
|
155
|
+
"cpu": [
|
|
156
|
+
"x64"
|
|
157
|
+
],
|
|
158
|
+
"license": "Apache-2.0 AND MIT",
|
|
159
|
+
"optional": true,
|
|
160
|
+
"os": [
|
|
161
|
+
"linux"
|
|
162
|
+
],
|
|
163
|
+
"engines": {
|
|
164
|
+
"node": ">=10"
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"node_modules/@swc/core-win32-arm64-msvc": {
|
|
168
|
+
"version": "1.15.8",
|
|
169
|
+
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.8.tgz",
|
|
170
|
+
"integrity": "sha512-djQPJ9Rh9vP8GTS/Df3hcc6XP6xnG5c8qsngWId/BLA9oX6C7UzCPAn74BG/wGb9a6j4w3RINuoaieJB3t+7iQ==",
|
|
171
|
+
"cpu": [
|
|
172
|
+
"arm64"
|
|
173
|
+
],
|
|
174
|
+
"license": "Apache-2.0 AND MIT",
|
|
175
|
+
"optional": true,
|
|
176
|
+
"os": [
|
|
177
|
+
"win32"
|
|
178
|
+
],
|
|
179
|
+
"engines": {
|
|
180
|
+
"node": ">=10"
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
"node_modules/@swc/core-win32-ia32-msvc": {
|
|
184
|
+
"version": "1.15.8",
|
|
185
|
+
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.8.tgz",
|
|
186
|
+
"integrity": "sha512-/wfAgxORg2VBaUoFdytcVBVCgf1isWZIEXB9MZEUty4wwK93M/PxAkjifOho9RN3WrM3inPLabICRCEgdHpKKQ==",
|
|
187
|
+
"cpu": [
|
|
188
|
+
"ia32"
|
|
189
|
+
],
|
|
190
|
+
"license": "Apache-2.0 AND MIT",
|
|
191
|
+
"optional": true,
|
|
192
|
+
"os": [
|
|
193
|
+
"win32"
|
|
194
|
+
],
|
|
195
|
+
"engines": {
|
|
196
|
+
"node": ">=10"
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
"node_modules/@swc/core-win32-x64-msvc": {
|
|
200
|
+
"version": "1.15.8",
|
|
201
|
+
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.8.tgz",
|
|
202
|
+
"integrity": "sha512-GpMePrh9Sl4d61o4KAHOOv5is5+zt6BEXCOCgs/H0FLGeii7j9bWDE8ExvKFy2GRRZVNR1ugsnzaGWHKM6kuzA==",
|
|
203
|
+
"cpu": [
|
|
204
|
+
"x64"
|
|
205
|
+
],
|
|
206
|
+
"license": "Apache-2.0 AND MIT",
|
|
207
|
+
"optional": true,
|
|
208
|
+
"os": [
|
|
209
|
+
"win32"
|
|
210
|
+
],
|
|
211
|
+
"engines": {
|
|
212
|
+
"node": ">=10"
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
"node_modules/@swc/counter": {
|
|
216
|
+
"version": "0.1.3",
|
|
217
|
+
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
|
|
218
|
+
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
|
|
219
|
+
"license": "Apache-2.0"
|
|
220
|
+
},
|
|
221
|
+
"node_modules/@swc/types": {
|
|
222
|
+
"version": "0.1.25",
|
|
223
|
+
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz",
|
|
224
|
+
"integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==",
|
|
225
|
+
"license": "Apache-2.0",
|
|
226
|
+
"dependencies": {
|
|
227
|
+
"@swc/counter": "^0.1.3"
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-components",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Design-to-code prompt to React components for Stitch MCP",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"validate": "node scripts/validate.js",
|
|
8
|
+
"fetch": "bash scripts/fetch-stitch.sh"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@swc/core": "^1.3.100"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18.0.0"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Architecture Quality Gate
|
|
2
|
+
|
|
3
|
+
### Structural integrity
|
|
4
|
+
- [ ] Logic extracted to custom hooks in `src/hooks/`.
|
|
5
|
+
- [ ] No monolithic files; strictly Atomic/Composite modularity.
|
|
6
|
+
- [ ] All static text/URLs moved to `src/data/mockData.ts`.
|
|
7
|
+
|
|
8
|
+
### Type safety and syntax
|
|
9
|
+
- [ ] Props use `Readonly<T>` interfaces.
|
|
10
|
+
- [ ] File is syntactically valid TypeScript (no red squiggles).
|
|
11
|
+
- [ ] Placeholders from templates (e.g., `StitchComponent`) have been replaced with actual names.
|
|
12
|
+
|
|
13
|
+
### Styling and theming
|
|
14
|
+
- [ ] Dark mode (`dark:`) applied to all color classes.
|
|
15
|
+
- [ ] No hardcoded hex values; use theme-mapped Tailwind classes.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import React from 'react';
|
|
18
|
+
|
|
19
|
+
// Use a valid identifier like 'StitchComponent' as the placeholder
|
|
20
|
+
interface StitchComponentProps {
|
|
21
|
+
readonly children?: React.ReactNode;
|
|
22
|
+
readonly className?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const StitchComponent: React.FC<StitchComponentProps> = ({
|
|
26
|
+
children,
|
|
27
|
+
className = '',
|
|
28
|
+
...props
|
|
29
|
+
}) => {
|
|
30
|
+
return (
|
|
31
|
+
<div className={`relative ${className}`} {...props}>
|
|
32
|
+
{children}
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default StitchComponent;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Stitch API reference
|
|
2
|
+
|
|
3
|
+
This document describes the data structures returned by the Stitch MCP server to ensure accurate component mapping.
|
|
4
|
+
|
|
5
|
+
### Metadata schema
|
|
6
|
+
When calling `get_screen`, the server returns a JSON object with these key properties:
|
|
7
|
+
* **htmlCode**: Contains a `downloadUrl`. This is a signed URL that requires a system-level fetch (curl) to handle redirects and security handshakes.
|
|
8
|
+
* **screenshot**: Includes a `downloadUrl` for the visual design. Use this to verify layout intent that might not be obvious in the raw HTML.
|
|
9
|
+
* **deviceType**: Usually set to `DESKTOP`. All generated components should prioritize the corresponding viewport (2560px width) as the base layout.
|
|
10
|
+
|
|
11
|
+
### Technical mapping rules
|
|
12
|
+
1. **Element tracking**: Preserve `data-stitch-id` attributes as comments in the TSX to allow for future design synchronization.
|
|
13
|
+
2. **Asset handling**: Treat background images in the HTML as dynamic data. Extract the URLs into `mockData.ts` rather than hardcoding them into the component styles.
|
|
14
|
+
3. **Style extraction**: The HTML `<head>` contains a localized `tailwind.config`. This config must be merged with the local project theme to ensure colors like `primary` and `background-dark` render correctly.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"theme": {
|
|
3
|
+
"colors": {
|
|
4
|
+
"primary": "#19e66f",
|
|
5
|
+
"background": {
|
|
6
|
+
"light": "#f6f8f7",
|
|
7
|
+
"dark": "#112118",
|
|
8
|
+
"elevated": "#1A1A1A"
|
|
9
|
+
},
|
|
10
|
+
"accent": {
|
|
11
|
+
"purple": "#8A2BE2",
|
|
12
|
+
"lavender": "#D0A9F5"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"typography": {
|
|
16
|
+
"display": [
|
|
17
|
+
"Space Grotesk",
|
|
18
|
+
"sans-serif"
|
|
19
|
+
],
|
|
20
|
+
"icons": "Material Symbols Outlined"
|
|
21
|
+
},
|
|
22
|
+
"spacing": {
|
|
23
|
+
"header-h": "72px",
|
|
24
|
+
"container-max": "960px"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Copyright 2026 Google LLC
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
URL=$1
|
|
17
|
+
OUTPUT=$2
|
|
18
|
+
if [ -z "$URL" ] || [ -z "$OUTPUT" ]; then
|
|
19
|
+
echo "Usage: $0 <url> <output_path>"
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
echo "Initiating high-reliability fetch for Stitch HTML..."
|
|
23
|
+
curl -L -f -sS --connect-timeout 10 --compressed "$URL" -o "$OUTPUT"
|
|
24
|
+
if [ $? -eq 0 ]; then
|
|
25
|
+
echo "✅ Successfully retrieved HTML at: $OUTPUT"
|
|
26
|
+
exit 0
|
|
27
|
+
else
|
|
28
|
+
echo "❌ Error: Failed to retrieve content. Check TLS/SNI or URL expiration."
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import swc from '@swc/core';
|
|
18
|
+
import fs from 'node:fs';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
|
|
21
|
+
const HEX_COLOR_REGEX = /#[0-9A-Fa-f]{6}/;
|
|
22
|
+
|
|
23
|
+
async function validateComponent(filePath) {
|
|
24
|
+
const code = fs.readFileSync(filePath, 'utf-8');
|
|
25
|
+
const filename = path.basename(filePath);
|
|
26
|
+
try {
|
|
27
|
+
const ast = await swc.parse(code, { syntax: "typescript", tsx: true });
|
|
28
|
+
let hasInterface = false;
|
|
29
|
+
let tailwindIssues = [];
|
|
30
|
+
|
|
31
|
+
console.log("🔍 Scanning AST...");
|
|
32
|
+
|
|
33
|
+
const walk = (node) => {
|
|
34
|
+
if (!node) return;
|
|
35
|
+
if (node.type === 'TsInterfaceDeclaration' && node.id.value.endsWith('Props')) hasInterface = true;
|
|
36
|
+
if (node.type === 'JSXAttribute' && node.name.name === 'className') {
|
|
37
|
+
if (node.value?.value && HEX_COLOR_REGEX.test(node.value.value)) tailwindIssues.push(node.value.value);
|
|
38
|
+
}
|
|
39
|
+
for (const key in node) { if (node[key] && typeof node[key] === 'object') walk(node[key]); }
|
|
40
|
+
};
|
|
41
|
+
walk(ast);
|
|
42
|
+
|
|
43
|
+
console.log(`--- Validation for: ${filename} ---`);
|
|
44
|
+
if (hasInterface) {
|
|
45
|
+
console.log("✅ Props declaration found.");
|
|
46
|
+
} else {
|
|
47
|
+
console.error("❌ MISSING: Props interface (must end in 'Props').");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (tailwindIssues.length === 0) {
|
|
51
|
+
console.log("✅ No hardcoded hex values found.");
|
|
52
|
+
} else {
|
|
53
|
+
console.error(`❌ STYLE: Found ${tailwindIssues.length} hardcoded hex codes.`);
|
|
54
|
+
tailwindIssues.forEach(hex => console.error(` - ${hex}`));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (hasInterface && tailwindIssues.length === 0) {
|
|
58
|
+
console.log("\n✨ COMPONENT VALID.");
|
|
59
|
+
process.exit(0);
|
|
60
|
+
} else {
|
|
61
|
+
console.error("\n🚫 VALIDATION FAILED.");
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
} catch (err) {
|
|
65
|
+
console.error("❌ PARSE ERROR:", err.message);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
validateComponent(process.argv[2]);
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Stitch-Remotion Video Walkthrough Skill
|
|
2
|
+
|
|
3
|
+
Generate professional walkthrough videos from Stitch app designs using Remotion.
|
|
4
|
+
|
|
5
|
+
## What This Skill Does
|
|
6
|
+
|
|
7
|
+
This skill bridges Stitch (UI design platform) and Remotion (programmatic video library) to automatically create walkthrough videos showcasing app screens with:
|
|
8
|
+
|
|
9
|
+
- **Smooth transitions**: Cross-fades, slides, and zoom effects
|
|
10
|
+
- **Text overlays**: Screen titles, descriptions, and feature callouts
|
|
11
|
+
- **Professional animations**: Spring-based natural motion
|
|
12
|
+
- **Customizable timing**: Control display duration per screen
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
1. **Stitch MCP Server**: Access to retrieve screens from Stitch projects
|
|
17
|
+
2. **Node.js**: For running Remotion
|
|
18
|
+
3. **Remotion**: Either Remotion MCP Server or Remotion CLI
|
|
19
|
+
|
|
20
|
+
## Example Use Case
|
|
21
|
+
|
|
22
|
+
**User Request:**
|
|
23
|
+
> "Look up the screens in my Stitch project 'Calculator App' and build a remotion video that shows a walkthrough of the screens."
|
|
24
|
+
|
|
25
|
+
**What Happens:**
|
|
26
|
+
1. Agent retrieves all screens from the Stitch project
|
|
27
|
+
2. Downloads screenshots for each screen
|
|
28
|
+
3. Creates a Remotion composition with transitions
|
|
29
|
+
4. Generates video with smooth animations and text overlays
|
|
30
|
+
5. Renders final MP4 video
|
|
31
|
+
|
|
32
|
+
## Key Features
|
|
33
|
+
|
|
34
|
+
- **Automated asset retrieval** from Stitch projects
|
|
35
|
+
- **Modular Remotion components** for easy customization
|
|
36
|
+
- **Multiple transition styles** (fade, slide, zoom)
|
|
37
|
+
- **Text overlay system** for annotations
|
|
38
|
+
- **Configurable timing** per screen
|
|
39
|
+
- **Professional rendering** with quality optimization
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
Install this skill using:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx skills add google-labs-code/stitch-skills --skill remotion --global
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## File Structure
|
|
50
|
+
|
|
51
|
+
When using this skill, the agent will create:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
project/
|
|
55
|
+
├── video/ # Remotion project
|
|
56
|
+
│ ├── src/
|
|
57
|
+
│ │ ├── WalkthroughComposition.tsx
|
|
58
|
+
│ │ ├── ScreenSlide.tsx
|
|
59
|
+
│ │ └── components/
|
|
60
|
+
│ ├── public/assets/screens/ # Stitch screenshots
|
|
61
|
+
│ └── remotion.config.ts
|
|
62
|
+
├── screens.json # Screen manifest
|
|
63
|
+
└── output.mp4 # Final video
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## How It Works
|
|
67
|
+
|
|
68
|
+
1. **Discovery**: Identifies Stitch and Remotion MCP servers
|
|
69
|
+
2. **Retrieval**: Fetches screens and metadata from Stitch project
|
|
70
|
+
3. **Asset Download**: Downloads screenshots for each screen
|
|
71
|
+
4. **Composition**: Generates Remotion React components
|
|
72
|
+
5. **Preview**: Opens Remotion Studio for refinement (optional)
|
|
73
|
+
6. **Render**: Produces final video file
|
|
74
|
+
|
|
75
|
+
## Integration Points
|
|
76
|
+
|
|
77
|
+
**With Stitch:**
|
|
78
|
+
- Uses Stitch MCP to list projects and screens
|
|
79
|
+
- Downloads screenshots and HTML code
|
|
80
|
+
- Extracts screen metadata (title, dimensions)
|
|
81
|
+
|
|
82
|
+
**With Remotion:**
|
|
83
|
+
- Creates TypeScript/React components
|
|
84
|
+
- Configures composition settings
|
|
85
|
+
- Renders video using Remotion CLI or MCP
|
|
86
|
+
|
|
87
|
+
## Advanced Capabilities
|
|
88
|
+
|
|
89
|
+
- **Dynamic text extraction**: Parse Stitch HTML to auto-generate annotations
|
|
90
|
+
- **Interactive hotspots**: Highlight clickable elements
|
|
91
|
+
- **Voiceover integration**: Sync narration with screen transitions
|
|
92
|
+
- **Multiple video patterns**: Slide show, feature highlight, user flow
|
|
93
|
+
|
|
94
|
+
## Related Skills
|
|
95
|
+
|
|
96
|
+
- **design-md**: Extract design system from Stitch projects (useful for consistent branding in videos)
|
|
97
|
+
- **react-components**: Convert Stitch designs to React (if you want interactive demos instead of videos)
|
|
98
|
+
|
|
99
|
+
## Learn More
|
|
100
|
+
|
|
101
|
+
See the full [SKILL.md](./SKILL.md) for detailed instructions, troubleshooting, and best practices.
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
This is not an officially supported Google product.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {Composition} from 'remotion';
|
|
2
|
+
import {Sequence} from 'remotion';
|
|
3
|
+
import {fade} from '@remotion/transitions/fade';
|
|
4
|
+
import {slide} from '@remotion/transitions/slide';
|
|
5
|
+
import {TransitionSeries} from '@remotion/transitions';
|
|
6
|
+
import {ScreenSlide} from './ScreenSlide';
|
|
7
|
+
import screensManifest from '../screens.json';
|
|
8
|
+
|
|
9
|
+
// Calculate total duration in frames
|
|
10
|
+
const calculateDuration = () => {
|
|
11
|
+
const totalSeconds = screensManifest.screens.reduce(
|
|
12
|
+
(sum, screen) => sum + screen.duration,
|
|
13
|
+
0
|
|
14
|
+
);
|
|
15
|
+
return totalSeconds * screensManifest.videoConfig.fps;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const WalkthroughComposition: React.FC = () => {
|
|
19
|
+
const {fps, width, height} = screensManifest.videoConfig;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<TransitionSeries>
|
|
23
|
+
{screensManifest.screens.map((screen, index) => {
|
|
24
|
+
const durationInFrames = screen.duration * fps;
|
|
25
|
+
|
|
26
|
+
// Select transition based on screen config
|
|
27
|
+
const transition =
|
|
28
|
+
screen.transitionType === 'slide'
|
|
29
|
+
? slide()
|
|
30
|
+
: screen.transitionType === 'zoom'
|
|
31
|
+
? fade() // Can customize with zoom effect
|
|
32
|
+
: fade();
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<TransitionSeries.Sequence
|
|
36
|
+
key={screen.id}
|
|
37
|
+
durationInFrames={durationInFrames}
|
|
38
|
+
>
|
|
39
|
+
<ScreenSlide
|
|
40
|
+
imageSrc={screen.imagePath}
|
|
41
|
+
title={screen.title}
|
|
42
|
+
description={screen.description}
|
|
43
|
+
width={screen.width}
|
|
44
|
+
height={screen.height}
|
|
45
|
+
/>
|
|
46
|
+
{index < screensManifest.screens.length - 1 && (
|
|
47
|
+
<TransitionSeries.Transition
|
|
48
|
+
presentation={transition}
|
|
49
|
+
timing={{
|
|
50
|
+
durationInFrames: 20, // 20 frames for transition
|
|
51
|
+
}}
|
|
52
|
+
/>
|
|
53
|
+
)}
|
|
54
|
+
</TransitionSeries.Sequence>
|
|
55
|
+
);
|
|
56
|
+
})}
|
|
57
|
+
</TransitionSeries>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Register composition
|
|
62
|
+
export const RemotionRoot: React.FC = () => {
|
|
63
|
+
const {fps, width, height} = screensManifest.videoConfig;
|
|
64
|
+
const durationInFrames = calculateDuration();
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<>
|
|
68
|
+
<Composition
|
|
69
|
+
id="WalkthroughComposition"
|
|
70
|
+
component={WalkthroughComposition}
|
|
71
|
+
durationInFrames={durationInFrames}
|
|
72
|
+
fps={fps}
|
|
73
|
+
width={width}
|
|
74
|
+
height={height}
|
|
75
|
+
/>
|
|
76
|
+
</>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"projectName": "Calculator App",
|
|
3
|
+
"projectId": "projects/13534454087919359824",
|
|
4
|
+
"videoConfig": {
|
|
5
|
+
"fps": 30,
|
|
6
|
+
"width": 1920,
|
|
7
|
+
"height": 1080,
|
|
8
|
+
"durationInSeconds": 20
|
|
9
|
+
},
|
|
10
|
+
"screens": [
|
|
11
|
+
{
|
|
12
|
+
"id": "1",
|
|
13
|
+
"screenId": "12345",
|
|
14
|
+
"title": "Home Screen",
|
|
15
|
+
"description": "Main calculator interface with number pad and basic operations",
|
|
16
|
+
"imagePath": "assets/screens/home.png",
|
|
17
|
+
"width": 1200,
|
|
18
|
+
"height": 800,
|
|
19
|
+
"duration": 5,
|
|
20
|
+
"transitionType": "fade"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "2",
|
|
24
|
+
"screenId": "12346",
|
|
25
|
+
"title": "History View",
|
|
26
|
+
"description": "View of previous calculations with option to reuse results",
|
|
27
|
+
"imagePath": "assets/screens/history.png",
|
|
28
|
+
"width": 1200,
|
|
29
|
+
"height": 800,
|
|
30
|
+
"duration": 4,
|
|
31
|
+
"transitionType": "slide"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "3",
|
|
35
|
+
"screenId": "12347",
|
|
36
|
+
"title": "Settings Panel",
|
|
37
|
+
"description": "Customize calculator behavior and appearance",
|
|
38
|
+
"imagePath": "assets/screens/settings.png",
|
|
39
|
+
"width": 1200,
|
|
40
|
+
"height": 800,
|
|
41
|
+
"duration": 4,
|
|
42
|
+
"transitionType": "fade"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "4",
|
|
46
|
+
"screenId": "12348",
|
|
47
|
+
"title": "Scientific Mode",
|
|
48
|
+
"description": "Advanced mathematical functions and operations",
|
|
49
|
+
"imagePath": "assets/screens/scientific.png",
|
|
50
|
+
"width": 1200,
|
|
51
|
+
"height": 800,
|
|
52
|
+
"duration": 5,
|
|
53
|
+
"transitionType": "zoom"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|