@flitzrrr/frontend-design-skills 1.0.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/.aider/conventions.md +47 -0
- package/.cursorrules +38 -0
- package/.github/copilot-instructions.md +47 -0
- package/.lovable +31 -0
- package/.windsurfrules +38 -0
- package/AGENTS.md +18 -0
- package/CLAUDE.md +18 -0
- package/LICENSE +21 -0
- package/README.md +265 -0
- package/bin/cli.js +317 -0
- package/bin/test-cli.js +119 -0
- package/package.json +55 -0
- package/skills-src/_template/SKILL.md +36 -0
- package/skills-src/_template/references/.gitkeep +0 -0
- package/skills-src/accessibility/SKILL.md +186 -0
- package/skills-src/accessibility/references/patterns.md +192 -0
- package/skills-src/agent-ui-design/SKILL.md +134 -0
- package/skills-src/agent-ui-design/references/implementation.md +140 -0
- package/skills-src/agent-ui-design/references/patterns.md +79 -0
- package/skills-src/ai-design-workflow/SKILL.md +145 -0
- package/skills-src/branding-identity/SKILL.md +156 -0
- package/skills-src/color-theory/SKILL.md +138 -0
- package/skills-src/color-theory/references/patterns.md +123 -0
- package/skills-src/component-patterns/SKILL.md +127 -0
- package/skills-src/component-patterns/references/implementation.md +130 -0
- package/skills-src/component-patterns/references/patterns.md +60 -0
- package/skills-src/customer-journey/SKILL.md +141 -0
- package/skills-src/design-process/SKILL.md +148 -0
- package/skills-src/design-trends/SKILL.md +126 -0
- package/skills-src/design-trends/references/patterns.md +96 -0
- package/skills-src/images-media/SKILL.md +161 -0
- package/skills-src/landing-pages/SKILL.md +153 -0
- package/skills-src/navigation-design/SKILL.md +173 -0
- package/skills-src/responsive-design/SKILL.md +162 -0
- package/skills-src/ui-design/SKILL.md +126 -0
- package/skills-src/ui-design/references/patterns.md +90 -0
- package/skills-src/ui-patterns/SKILL.md +135 -0
- package/skills-src/ui-patterns/references/extended-rules.md +31 -0
- package/skills-src/ui-patterns/references/patterns.md +52 -0
- package/skills-src/usability/SKILL.md +153 -0
- package/skills-src/ux-design/SKILL.md +140 -0
- package/skills-src/ux-design/references/patterns.md +98 -0
- package/skills-src/visual-direction/SKILL.md +138 -0
- package/skills-src/visual-direction/references/archetypen.md +93 -0
- package/skills-src/web-typography/SKILL.md +133 -0
- package/skills-src/web-typography/references/patterns.md +109 -0
- package/skills-src/webdesign-review/SKILL.md +130 -0
- package/skills-src/webdesign-review/references/review-workflow.md +143 -0
- package/skills-src/website-audit/SKILL.md +171 -0
- package/spec/content-map.json +54 -0
- package/spec/design-spec.md +121 -0
- package/spec/domains/01-ui-design.md +136 -0
- package/spec/domains/02-ux-design.md +143 -0
- package/spec/domains/03-typography.md +150 -0
- package/spec/domains/04-color-theory.md +145 -0
- package/spec/domains/05-accessibility.md +213 -0
- package/spec/domains/06-usability.md +181 -0
- package/spec/domains/07-responsive-design.md +201 -0
- package/spec/domains/08-navigation.md +201 -0
- package/spec/domains/09-images-media.md +198 -0
- package/spec/domains/10-branding.md +195 -0
- package/spec/domains/11-customer-journey.md +164 -0
- package/spec/domains/12-design-process.md +154 -0
- package/spec/domains/13-ai-design-workflow.md +155 -0
- package/spec/domains/14-landing-pages.md +169 -0
- package/spec/domains/15-website-audit-relaunch.md +216 -0
- package/spec/domains/16-design-trends.md +150 -0
- package/spec/domains/17-ui-patterns.md +169 -0
- package/spec/domains/18-visual-direction.md +166 -0
- package/spec/domains/19-component-architecture.md +183 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
|
|
8
|
+
const REPO_URL = "https://github.com/flitzrrr/frontend-design-skills.git";
|
|
9
|
+
const SKILL_DIR = path.join(os.homedir(), ".frontend-design-skills");
|
|
10
|
+
|
|
11
|
+
// Resolve the package root (where skills-src/ and integration files live)
|
|
12
|
+
const PKG_ROOT = path.resolve(__dirname, "..");
|
|
13
|
+
|
|
14
|
+
const PLATFORMS = {
|
|
15
|
+
"claude-code": {
|
|
16
|
+
name: "Claude Code",
|
|
17
|
+
type: "project",
|
|
18
|
+
files: ["CLAUDE.md"],
|
|
19
|
+
},
|
|
20
|
+
cursor: {
|
|
21
|
+
name: "Cursor",
|
|
22
|
+
type: "project",
|
|
23
|
+
files: [".cursorrules"],
|
|
24
|
+
},
|
|
25
|
+
windsurf: {
|
|
26
|
+
name: "Windsurf",
|
|
27
|
+
type: "project",
|
|
28
|
+
files: [".windsurfrules"],
|
|
29
|
+
},
|
|
30
|
+
lovable: {
|
|
31
|
+
name: "Lovable",
|
|
32
|
+
type: "project",
|
|
33
|
+
files: [".lovable"],
|
|
34
|
+
},
|
|
35
|
+
codex: {
|
|
36
|
+
name: "Codex (OpenAI)",
|
|
37
|
+
type: "global",
|
|
38
|
+
dir: path.join(os.homedir(), ".codex", "skills"),
|
|
39
|
+
files: ["AGENTS.md"],
|
|
40
|
+
},
|
|
41
|
+
copilot: {
|
|
42
|
+
name: "VS Code (GitHub Copilot)",
|
|
43
|
+
type: "global",
|
|
44
|
+
dir: path.join(os.homedir(), ".copilot", "skills"),
|
|
45
|
+
},
|
|
46
|
+
antigravity: {
|
|
47
|
+
name: "Antigravity (Gemini)",
|
|
48
|
+
type: "global",
|
|
49
|
+
dir: path.join(os.homedir(), ".gemini", "antigravity", "skills"),
|
|
50
|
+
},
|
|
51
|
+
opencode: {
|
|
52
|
+
name: "OpenCode",
|
|
53
|
+
type: "global",
|
|
54
|
+
dir: path.join(os.homedir(), ".config", "opencode", "skills"),
|
|
55
|
+
},
|
|
56
|
+
aider: {
|
|
57
|
+
name: "Aider",
|
|
58
|
+
type: "project",
|
|
59
|
+
files: [".aider/conventions.md"],
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
function log(msg) {
|
|
64
|
+
console.log(` ${msg}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function header(msg) {
|
|
68
|
+
console.log(`\n> ${msg}\n`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function ensureSkillCache() {
|
|
72
|
+
if (fs.existsSync(SKILL_DIR)) {
|
|
73
|
+
log("Updating skill cache...");
|
|
74
|
+
try {
|
|
75
|
+
execSync("git pull --ff-only", { cwd: SKILL_DIR, stdio: "pipe" });
|
|
76
|
+
log("Updated to latest version.");
|
|
77
|
+
} catch {
|
|
78
|
+
log("Warning: Could not update. Using existing cache.");
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
log(`Cloning ${REPO_URL}...`);
|
|
82
|
+
execSync(`git clone --depth 1 ${REPO_URL} "${SKILL_DIR}"`, {
|
|
83
|
+
stdio: "pipe",
|
|
84
|
+
});
|
|
85
|
+
log("Cloned successfully.");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Resolve skills-src from npm package (preferred) or git cache (fallback)
|
|
90
|
+
function resolveSkillsSrc() {
|
|
91
|
+
const pkgSkills = path.join(PKG_ROOT, "skills-src");
|
|
92
|
+
if (fs.existsSync(pkgSkills)) return pkgSkills;
|
|
93
|
+
const cacheSkills = path.join(SKILL_DIR, "skills-src");
|
|
94
|
+
if (fs.existsSync(cacheSkills)) return cacheSkills;
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function copyFile(src, dst) {
|
|
99
|
+
const dstDir = path.dirname(dst);
|
|
100
|
+
fs.mkdirSync(dstDir, { recursive: true });
|
|
101
|
+
fs.copyFileSync(src, dst);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function linkSkillsTo(targetDir, skillsSrc) {
|
|
105
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
106
|
+
|
|
107
|
+
const skills = fs
|
|
108
|
+
.readdirSync(skillsSrc)
|
|
109
|
+
.filter(
|
|
110
|
+
(d) =>
|
|
111
|
+
!d.startsWith("_") &&
|
|
112
|
+
fs.statSync(path.join(skillsSrc, d)).isDirectory()
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
let linked = 0;
|
|
116
|
+
for (const skill of skills) {
|
|
117
|
+
const src = path.join(skillsSrc, skill);
|
|
118
|
+
const dst = path.join(targetDir, skill);
|
|
119
|
+
|
|
120
|
+
if (fs.existsSync(dst)) {
|
|
121
|
+
try {
|
|
122
|
+
fs.rmSync(dst, { recursive: true });
|
|
123
|
+
} catch {
|
|
124
|
+
/* ignore */
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
fs.symlinkSync(src, dst, "junction");
|
|
130
|
+
linked++;
|
|
131
|
+
} catch {
|
|
132
|
+
log(`Warning: Could not symlink ${skill}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return linked;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function installPlatform(platform) {
|
|
140
|
+
const config = PLATFORMS[platform];
|
|
141
|
+
if (!config) {
|
|
142
|
+
console.error(
|
|
143
|
+
`Unknown platform: ${platform}\nAvailable: ${Object.keys(PLATFORMS).join(", ")}`
|
|
144
|
+
);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
header(`Installing for ${config.name}`);
|
|
149
|
+
|
|
150
|
+
const skillsSrc = resolveSkillsSrc();
|
|
151
|
+
if (!skillsSrc) {
|
|
152
|
+
ensureSkillCache();
|
|
153
|
+
}
|
|
154
|
+
const finalSkillsSrc = skillsSrc || path.join(SKILL_DIR, "skills-src");
|
|
155
|
+
|
|
156
|
+
if (!fs.existsSync(finalSkillsSrc)) {
|
|
157
|
+
console.error("Error: skills-src/ not found.");
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (config.type === "project") {
|
|
162
|
+
// Project-level: copy integration files + symlink skills-src into cwd
|
|
163
|
+
const cwd = process.cwd();
|
|
164
|
+
|
|
165
|
+
// Copy integration files
|
|
166
|
+
if (config.files) {
|
|
167
|
+
for (const file of config.files) {
|
|
168
|
+
const src = path.join(PKG_ROOT, file);
|
|
169
|
+
const dst = path.join(cwd, file);
|
|
170
|
+
if (fs.existsSync(src)) {
|
|
171
|
+
copyFile(src, dst);
|
|
172
|
+
log(`Copied ${file}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Symlink skills-src into project
|
|
178
|
+
const dst = path.join(cwd, "skills-src");
|
|
179
|
+
if (!fs.existsSync(dst)) {
|
|
180
|
+
try {
|
|
181
|
+
fs.symlinkSync(finalSkillsSrc, dst, "junction");
|
|
182
|
+
log(`Linked skills-src/ → ${finalSkillsSrc}`);
|
|
183
|
+
} catch {
|
|
184
|
+
log("Warning: Could not symlink skills-src/. Copy manually if needed.");
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
log("skills-src/ already exists in project.");
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
// Global: symlink individual skills into global dir
|
|
191
|
+
if (!skillsSrc) ensureSkillCache();
|
|
192
|
+
const linked = linkSkillsTo(config.dir, finalSkillsSrc);
|
|
193
|
+
log(`Linked ${linked} skills to ${config.dir}`);
|
|
194
|
+
|
|
195
|
+
// Copy project-level integration files if specified
|
|
196
|
+
if (config.files) {
|
|
197
|
+
const cwd = process.cwd();
|
|
198
|
+
for (const file of config.files) {
|
|
199
|
+
const src = path.join(PKG_ROOT, file);
|
|
200
|
+
const dst = path.join(cwd, file);
|
|
201
|
+
if (fs.existsSync(src)) {
|
|
202
|
+
copyFile(src, dst);
|
|
203
|
+
log(`Copied ${file} to project`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function installAll() {
|
|
211
|
+
header("Frontend Design Skills — Installing for all detected platforms");
|
|
212
|
+
|
|
213
|
+
const skillsSrc = resolveSkillsSrc();
|
|
214
|
+
if (!skillsSrc) ensureSkillCache();
|
|
215
|
+
|
|
216
|
+
for (const [platform] of Object.entries(PLATFORMS)) {
|
|
217
|
+
installPlatform(platform);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function listSkills() {
|
|
222
|
+
header("Frontend Design Skills — 21 Skills");
|
|
223
|
+
|
|
224
|
+
const categories = {
|
|
225
|
+
Meta: ["webdesign-review"],
|
|
226
|
+
"Core Design": ["ui-design", "ux-design"],
|
|
227
|
+
Detail: ["web-typography", "color-theory", "accessibility"],
|
|
228
|
+
Implementation: [
|
|
229
|
+
"usability",
|
|
230
|
+
"responsive-design",
|
|
231
|
+
"navigation-design",
|
|
232
|
+
"images-media",
|
|
233
|
+
"branding-identity",
|
|
234
|
+
],
|
|
235
|
+
Strategy: [
|
|
236
|
+
"customer-journey",
|
|
237
|
+
"design-process",
|
|
238
|
+
"ai-design-workflow",
|
|
239
|
+
"landing-pages",
|
|
240
|
+
"website-audit",
|
|
241
|
+
],
|
|
242
|
+
"Trends & Patterns": [
|
|
243
|
+
"design-trends",
|
|
244
|
+
"ui-patterns",
|
|
245
|
+
"visual-direction",
|
|
246
|
+
"component-patterns",
|
|
247
|
+
"agent-ui-design",
|
|
248
|
+
],
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
for (const [category, skills] of Object.entries(categories)) {
|
|
252
|
+
log(`\n ${category}:`);
|
|
253
|
+
for (const skill of skills) {
|
|
254
|
+
log(` - ${skill}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
log(`\n Total: 21 skills from 12 sources`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function update() {
|
|
262
|
+
header("Updating Frontend Design Skills");
|
|
263
|
+
if (!fs.existsSync(SKILL_DIR)) {
|
|
264
|
+
log("Not installed yet. Run 'install' first.");
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
ensureSkillCache();
|
|
268
|
+
log("Done. Run 'install' again to re-link if needed.");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function showUsage() {
|
|
272
|
+
console.log(`
|
|
273
|
+
Frontend Design Skills — 21 web design skills for AI coding tools
|
|
274
|
+
|
|
275
|
+
Usage:
|
|
276
|
+
npx @flitzrrr/frontend-design-skills <command> [platform]
|
|
277
|
+
|
|
278
|
+
Commands:
|
|
279
|
+
install Install for all detected platforms
|
|
280
|
+
install <platform> Install for a specific platform
|
|
281
|
+
update Pull latest skills
|
|
282
|
+
list List all available skills
|
|
283
|
+
|
|
284
|
+
Platforms:
|
|
285
|
+
${Object.entries(PLATFORMS)
|
|
286
|
+
.map(([k, v]) => `${k.padEnd(16)} ${v.name}`)
|
|
287
|
+
.join("\n ")}
|
|
288
|
+
|
|
289
|
+
Examples:
|
|
290
|
+
npx @flitzrrr/frontend-design-skills install
|
|
291
|
+
npx @flitzrrr/frontend-design-skills install codex
|
|
292
|
+
npx @flitzrrr/frontend-design-skills list
|
|
293
|
+
`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Main
|
|
297
|
+
const args = process.argv.slice(2);
|
|
298
|
+
const command = args[0];
|
|
299
|
+
|
|
300
|
+
switch (command) {
|
|
301
|
+
case "install":
|
|
302
|
+
if (args[1]) {
|
|
303
|
+
installPlatform(args[1]);
|
|
304
|
+
} else {
|
|
305
|
+
installAll();
|
|
306
|
+
}
|
|
307
|
+
break;
|
|
308
|
+
case "update":
|
|
309
|
+
update();
|
|
310
|
+
break;
|
|
311
|
+
case "list":
|
|
312
|
+
listSkills();
|
|
313
|
+
break;
|
|
314
|
+
default:
|
|
315
|
+
showUsage();
|
|
316
|
+
break;
|
|
317
|
+
}
|
package/bin/test-cli.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Basic tests for the frontend-design-skills CLI.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { execSync } = require("child_process");
|
|
8
|
+
const path = require("path");
|
|
9
|
+
const fs = require("fs");
|
|
10
|
+
|
|
11
|
+
const CLI = path.join(__dirname, "cli.js");
|
|
12
|
+
let passed = 0;
|
|
13
|
+
let failed = 0;
|
|
14
|
+
|
|
15
|
+
function test(name, fn) {
|
|
16
|
+
try {
|
|
17
|
+
fn();
|
|
18
|
+
console.log(` PASS ${name}`);
|
|
19
|
+
passed++;
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.log(` FAIL ${name}`);
|
|
22
|
+
console.log(` ${err.message}`);
|
|
23
|
+
failed++;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function assert(condition, msg) {
|
|
28
|
+
if (!condition) throw new Error(msg || "Assertion failed");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function run(args = "") {
|
|
32
|
+
return execSync(`"${process.execPath}" "${CLI}" ${args}`, { encoding: "utf-8", timeout: 10000 });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.log("\n> Frontend Design Skills — CLI Tests\n");
|
|
36
|
+
|
|
37
|
+
// Test: no args shows usage
|
|
38
|
+
test("no args shows usage", () => {
|
|
39
|
+
const out = run();
|
|
40
|
+
assert(out.includes("Usage:"), "Should show usage");
|
|
41
|
+
assert(out.includes("install"), "Should mention install command");
|
|
42
|
+
assert(out.includes("frontend-design-skills"), "Should mention package name");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Test: list command
|
|
46
|
+
test("list shows all 21 skills", () => {
|
|
47
|
+
const out = run("list");
|
|
48
|
+
assert(out.includes("21 Skills"), "Should show 21 skills");
|
|
49
|
+
assert(out.includes("webdesign-review"), "Should list webdesign-review");
|
|
50
|
+
assert(out.includes("ui-design"), "Should list ui-design");
|
|
51
|
+
assert(out.includes("agent-ui-design"), "Should list agent-ui-design");
|
|
52
|
+
assert(out.includes("Core Design"), "Should show Core Design category");
|
|
53
|
+
assert(out.includes("Trends & Patterns"), "Should show Trends category");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Test: unknown platform errors
|
|
57
|
+
test("unknown platform shows error", () => {
|
|
58
|
+
try {
|
|
59
|
+
run("install nonexistent-platform");
|
|
60
|
+
assert(false, "Should have thrown");
|
|
61
|
+
} catch (err) {
|
|
62
|
+
assert(err.stderr.includes("Unknown platform") || err.status !== 0, "Should error on unknown platform");
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Test: skills-src directory exists
|
|
67
|
+
test("skills-src/ has 21 skills", () => {
|
|
68
|
+
const skillsDir = path.join(__dirname, "..", "skills-src");
|
|
69
|
+
const skills = fs
|
|
70
|
+
.readdirSync(skillsDir)
|
|
71
|
+
.filter(
|
|
72
|
+
(d) =>
|
|
73
|
+
!d.startsWith("_") &&
|
|
74
|
+
fs.statSync(path.join(skillsDir, d)).isDirectory() &&
|
|
75
|
+
fs.existsSync(path.join(skillsDir, d, "SKILL.md"))
|
|
76
|
+
);
|
|
77
|
+
assert(skills.length === 21, `Expected 21 skills, got ${skills.length}`);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Test: all integration files exist
|
|
81
|
+
test("integration files exist", () => {
|
|
82
|
+
const root = path.join(__dirname, "..");
|
|
83
|
+
const files = [
|
|
84
|
+
"CLAUDE.md",
|
|
85
|
+
"AGENTS.md",
|
|
86
|
+
".cursorrules",
|
|
87
|
+
".windsurfrules",
|
|
88
|
+
".lovable",
|
|
89
|
+
".github/copilot-instructions.md",
|
|
90
|
+
];
|
|
91
|
+
for (const f of files) {
|
|
92
|
+
assert(fs.existsSync(path.join(root, f)), `Missing: ${f}`);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Test: each SKILL.md has frontmatter
|
|
97
|
+
test("all SKILL.md files have name and description", () => {
|
|
98
|
+
const skillsDir = path.join(__dirname, "..", "skills-src");
|
|
99
|
+
const skills = fs
|
|
100
|
+
.readdirSync(skillsDir)
|
|
101
|
+
.filter(
|
|
102
|
+
(d) =>
|
|
103
|
+
!d.startsWith("_") &&
|
|
104
|
+
fs.statSync(path.join(skillsDir, d)).isDirectory() &&
|
|
105
|
+
fs.existsSync(path.join(skillsDir, d, "SKILL.md"))
|
|
106
|
+
);
|
|
107
|
+
for (const skill of skills) {
|
|
108
|
+
const content = fs.readFileSync(
|
|
109
|
+
path.join(skillsDir, skill, "SKILL.md"),
|
|
110
|
+
"utf-8"
|
|
111
|
+
);
|
|
112
|
+
assert(content.startsWith("---"), `${skill}: Missing frontmatter`);
|
|
113
|
+
assert(content.includes("name:"), `${skill}: Missing name field`);
|
|
114
|
+
assert(content.includes("description:"), `${skill}: Missing description`);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
console.log(`\n ${passed} passed, ${failed} failed\n`);
|
|
119
|
+
process.exit(failed > 0 ? 1 : 0);
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flitzrrr/frontend-design-skills",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "21 opinionated web design skills from 12 curated sources — one install, every major AI coding tool.",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "node bin/test-cli.js",
|
|
7
|
+
"build": "python3 scripts/build-skills.py",
|
|
8
|
+
"validate": "python3 scripts/validate-skills.py",
|
|
9
|
+
"check-counts": "node scripts/update-counts.js --check",
|
|
10
|
+
"update-counts": "node scripts/update-counts.js"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"frontend-design-skills": "bin/cli.js"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ai",
|
|
17
|
+
"agent",
|
|
18
|
+
"skills",
|
|
19
|
+
"web-design",
|
|
20
|
+
"frontend",
|
|
21
|
+
"ui-design",
|
|
22
|
+
"ux-design",
|
|
23
|
+
"typography",
|
|
24
|
+
"accessibility",
|
|
25
|
+
"design-system",
|
|
26
|
+
"claude",
|
|
27
|
+
"cursor",
|
|
28
|
+
"windsurf",
|
|
29
|
+
"gemini",
|
|
30
|
+
"codex",
|
|
31
|
+
"aider",
|
|
32
|
+
"SKILL.md",
|
|
33
|
+
"AGENTS.md"
|
|
34
|
+
],
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/flitzrrr/frontend-design-skills.git"
|
|
38
|
+
},
|
|
39
|
+
"author": "flitzrrr",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"files": [
|
|
42
|
+
"bin/",
|
|
43
|
+
"skills-src/",
|
|
44
|
+
"spec/",
|
|
45
|
+
"AGENTS.md",
|
|
46
|
+
"CLAUDE.md",
|
|
47
|
+
".cursorrules",
|
|
48
|
+
".windsurfrules",
|
|
49
|
+
".lovable",
|
|
50
|
+
".github/copilot-instructions.md",
|
|
51
|
+
".aider/conventions.md",
|
|
52
|
+
"README.md",
|
|
53
|
+
"LICENSE"
|
|
54
|
+
]
|
|
55
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: SKILL-NAME-HERE
|
|
3
|
+
description: DESCRIPTION-HERE
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DOMAIN-TITEL
|
|
7
|
+
|
|
8
|
+
> KURZBESCHREIBUNG
|
|
9
|
+
|
|
10
|
+
## Anwendungsbereich
|
|
11
|
+
|
|
12
|
+
Verwende diesen Skill wenn: ANWENDUNGSFALL
|
|
13
|
+
|
|
14
|
+
## Prinzipien
|
|
15
|
+
|
|
16
|
+
<!-- Übernahme der wichtigsten Prinzipien aus der Domain-Spezifikation -->
|
|
17
|
+
|
|
18
|
+
## Regeln
|
|
19
|
+
|
|
20
|
+
<!-- DO/DON'T Regeln, priorisiert nach Wirkung -->
|
|
21
|
+
|
|
22
|
+
## Patterns
|
|
23
|
+
|
|
24
|
+
<!-- Empfohlene Muster mit Codebeispielen -->
|
|
25
|
+
|
|
26
|
+
## Anti-Patterns
|
|
27
|
+
|
|
28
|
+
<!-- Häufige Fehler mit Erklärung -->
|
|
29
|
+
|
|
30
|
+
## Checkliste
|
|
31
|
+
|
|
32
|
+
<!-- Prüfpunkte vor Abschluss einer Aufgabe -->
|
|
33
|
+
|
|
34
|
+
## Querverweise
|
|
35
|
+
|
|
36
|
+
<!-- Links zu verwandten Skills und Domain-Dateien -->
|
|
File without changes
|