@valentia-ai-skills/framework 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.
Files changed (29) hide show
  1. package/README.md +103 -0
  2. package/bin/cli.js +482 -0
  3. package/package.json +42 -0
  4. package/scripts/postinstall.js +18 -0
  5. package/skills/global/api-design/SKILL.md +248 -0
  6. package/skills/global/api-design/tests/test-prompts.md +25 -0
  7. package/skills/global/code-standards/SKILL.md +245 -0
  8. package/skills/global/code-standards/tests/test-prompts.md +26 -0
  9. package/skills/global/deployment/SKILL.md +240 -0
  10. package/skills/global/deployment/tests/test-prompts.md +27 -0
  11. package/skills/global/documentation/SKILL.md +298 -0
  12. package/skills/global/documentation/tests/test-prompts.md +26 -0
  13. package/skills/global/git-workflow/SKILL.md +177 -0
  14. package/skills/global/git-workflow/tests/test-prompts.md +11 -0
  15. package/skills/global/security-baseline/SKILL.md +239 -0
  16. package/skills/global/security-baseline/tests/test-prompts.md +23 -0
  17. package/skills/global/testing-standards/SKILL.md +257 -0
  18. package/skills/global/testing-standards/tests/test-prompts.md +25 -0
  19. package/skills/onboarding/SKILL.md +110 -0
  20. package/skills/stack/devops/SKILL.md +220 -0
  21. package/skills/stack/devops/tests/test-prompts.md +29 -0
  22. package/skills/stack/node-backend/SKILL.md +304 -0
  23. package/skills/stack/node-backend/tests/test-prompts.md +27 -0
  24. package/skills/stack/python-backend/SKILL.md +304 -0
  25. package/skills/stack/python-backend/tests/test-prompts.md +27 -0
  26. package/skills/stack/react/SKILL.md +251 -0
  27. package/skills/stack/react/tests/test-prompts.md +26 -0
  28. package/skills/stack/react-native/SKILL.md +255 -0
  29. package/skills/stack/react-native/tests/test-prompts.md +26 -0
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # AI Skills Framework
2
+
3
+ Centralized coding standards, security patterns, and SOPs for AI-assisted development.
4
+
5
+ **One install. All AI tools. Every team follows the same rules.**
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ # Install
11
+ npm install --save-dev @valentia-ai-skills/framework
12
+
13
+ # Setup (auto-detects your AI tools)
14
+ npx ai-skills setup
15
+
16
+ # Done. Your AI tools now follow your org's standards.
17
+ ```
18
+
19
+ ## What It Does
20
+
21
+ This package installs your organization's coding standards into whatever AI coding tool your team uses:
22
+
23
+ | AI Tool | What Gets Created |
24
+ |---------|------------------|
25
+ | **Claude Code** | Individual skill folders in `.claude/skills/` |
26
+ | **Cursor** | Merged rules file at `.cursor/rules/ai-skills.mdc` |
27
+ | **GitHub Copilot** | Merged rules at `.github/copilot-instructions.md` |
28
+ | **Windsurf** | Merged rules at `.windsurfrules` |
29
+ | **Any other tool** | Generic `.ai-rules` file |
30
+
31
+ The CLI auto-detects which tools you're using and installs the right format.
32
+
33
+ ## Included Skills
34
+
35
+ ### Global (all teams)
36
+ - **code-standards** — Naming, file structure, formatting, error handling
37
+ - **git-workflow** — Branching, commits, PRs, releases
38
+ - **security-baseline** — Auth, validation, secrets, XSS, SQL injection
39
+ - **api-design** — REST URLs, status codes, pagination, versioning
40
+ - **testing-standards** — Coverage, AAA pattern, mocking, integration/E2E
41
+ - **documentation** — READMEs, API docs, ADRs, changelogs, runbooks
42
+ - **deployment** — CI/CD, Docker, environments, rollback, feature flags
43
+
44
+ ### Stack-specific
45
+ - **react** — Components, hooks, state management, performance
46
+ - **react-native** — Navigation, FlatList, offline-first, platform code
47
+ - **node-backend** — Layered architecture, DI, error handling, health checks
48
+ - **python-backend** — FastAPI, Pydantic, async patterns, pytest
49
+ - **devops** — Terraform, Kubernetes, monitoring, SLOs, alerting
50
+
51
+ ## Commands
52
+
53
+ ```bash
54
+ npx ai-skills setup # First-time setup
55
+ npx ai-skills update # Update to latest skills
56
+ npx ai-skills status # Check what's installed
57
+ npx ai-skills list # Show all available skills
58
+ npx ai-skills doctor # Health check
59
+ ```
60
+
61
+ ## Updating
62
+
63
+ ```bash
64
+ # Update the package
65
+ npm update @valentia-ai-skills/framework
66
+
67
+ # Refresh the installed skills
68
+ npx ai-skills update
69
+ ```
70
+
71
+ ## How It Works
72
+
73
+ 1. **Install** — `npm install` adds the package to your project
74
+ 2. **Setup** — `npx ai-skills setup` detects your AI tools and writes config files
75
+ 3. **Code** — When you use any AI coding tool, it reads those config files and follows the rules
76
+ 4. **Update** — `npm update` + `npx ai-skills update` refreshes everything
77
+
78
+ The skills never touch your application code. They only tell AI tools what conventions to follow.
79
+
80
+ ## For Team Leads
81
+
82
+ Add this to your project's `package.json` so every developer gets the skills on `npm install`:
83
+
84
+ ```json
85
+ {
86
+ "devDependencies": {
87
+ "@valentia-ai-skills/framework": "^1.0.0"
88
+ },
89
+ "scripts": {
90
+ "postinstall": "npx ai-skills setup"
91
+ }
92
+ }
93
+ ```
94
+
95
+ Now every `git clone` + `npm install` automatically configures AI skills.
96
+
97
+ ## Customization
98
+
99
+ After setup, a `.ai-skills.json` config file tracks your preferences. The generated rules files can be committed to git so the whole team shares the same setup.
100
+
101
+ ## Contributing
102
+
103
+ To add or modify skills, edit the SKILL.md files in the `skills/` directory and publish a new package version.
package/bin/cli.js ADDED
@@ -0,0 +1,482 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ai-skills CLI
5
+ *
6
+ * Usage:
7
+ * npx ai-skills setup # First-time setup — detects your AI tools and installs skills
8
+ * npx ai-skills update # Pull latest skills into your project
9
+ * npx ai-skills status # Show which skills are installed and which tools are configured
10
+ * npx ai-skills list # List all available skills
11
+ * npx ai-skills add <skill> # Add a specific skill
12
+ * npx ai-skills remove <skill> # Remove a specific skill
13
+ * npx ai-skills doctor # Check setup health
14
+ */
15
+
16
+ const fs = require("fs");
17
+ const path = require("path");
18
+
19
+ // ── Constants ──
20
+
21
+ const SKILLS_SOURCE = path.join(__dirname, "..", "skills");
22
+ const PROJECT_ROOT = process.cwd();
23
+
24
+ const TOOL_CONFIGS = {
25
+ "claude-code": {
26
+ name: "Claude Code",
27
+ skillsDir: ".claude/skills",
28
+ rulesFile: null,
29
+ detect: () => fs.existsSync(path.join(PROJECT_ROOT, ".claude")) || shellHas("claude"),
30
+ format: "skill-folder", // copies full SKILL.md folder structure
31
+ },
32
+ cursor: {
33
+ name: "Cursor",
34
+ skillsDir: null,
35
+ rulesFile: ".cursor/rules/ai-skills.mdc",
36
+ detect: () =>
37
+ fs.existsSync(path.join(PROJECT_ROOT, ".cursor")) ||
38
+ fs.existsSync(path.join(PROJECT_ROOT, ".cursorules")),
39
+ format: "rules-file", // merges into a single rules file
40
+ },
41
+ copilot: {
42
+ name: "GitHub Copilot",
43
+ skillsDir: null,
44
+ rulesFile: ".github/copilot-instructions.md",
45
+ detect: () =>
46
+ fs.existsSync(path.join(PROJECT_ROOT, ".github")) ||
47
+ fs.existsSync(path.join(PROJECT_ROOT, ".github/copilot-instructions.md")),
48
+ format: "rules-file",
49
+ },
50
+ windsurf: {
51
+ name: "Windsurf",
52
+ skillsDir: null,
53
+ rulesFile: ".windsurfrules",
54
+ detect: () => fs.existsSync(path.join(PROJECT_ROOT, ".windsurfrules")),
55
+ format: "rules-file",
56
+ },
57
+ generic: {
58
+ name: "Generic (.ai-rules)",
59
+ skillsDir: null,
60
+ rulesFile: ".ai-rules",
61
+ detect: () => true, // always available as fallback
62
+ format: "rules-file",
63
+ },
64
+ };
65
+
66
+ const COLORS = {
67
+ green: "\x1b[32m",
68
+ yellow: "\x1b[33m",
69
+ blue: "\x1b[34m",
70
+ red: "\x1b[31m",
71
+ dim: "\x1b[2m",
72
+ bold: "\x1b[1m",
73
+ reset: "\x1b[0m",
74
+ };
75
+
76
+ // ── Helpers ──
77
+
78
+ function c(color, text) {
79
+ return `${COLORS[color]}${text}${COLORS.reset}`;
80
+ }
81
+
82
+ function shellHas(cmd) {
83
+ try {
84
+ require("child_process").execSync(`which ${cmd} 2>/dev/null`, { stdio: "ignore" });
85
+ return true;
86
+ } catch {
87
+ return false;
88
+ }
89
+ }
90
+
91
+ function getAllSkills() {
92
+ const skills = [];
93
+ if (!fs.existsSync(SKILLS_SOURCE)) return skills;
94
+
95
+ for (const category of ["global", "stack", "onboarding"]) {
96
+ const catDir = path.join(SKILLS_SOURCE, category);
97
+ if (!fs.existsSync(catDir)) continue;
98
+
99
+ if (category === "onboarding") {
100
+ if (fs.existsSync(path.join(catDir, "SKILL.md"))) {
101
+ skills.push({ name: "onboarding", category, path: catDir });
102
+ }
103
+ continue;
104
+ }
105
+
106
+ for (const item of fs.readdirSync(catDir)) {
107
+ const itemPath = path.join(catDir, item);
108
+ if (fs.statSync(itemPath).isDirectory() && fs.existsSync(path.join(itemPath, "SKILL.md"))) {
109
+ skills.push({ name: item, category, path: itemPath });
110
+ }
111
+ }
112
+ }
113
+ return skills;
114
+ }
115
+
116
+ function readSkillContent(skillPath) {
117
+ const skillMd = path.join(skillPath, "SKILL.md");
118
+ if (!fs.existsSync(skillMd)) return null;
119
+ return fs.readFileSync(skillMd, "utf-8");
120
+ }
121
+
122
+ function extractSkillRules(content) {
123
+ // Remove YAML frontmatter
124
+ const withoutFrontmatter = content.replace(/^---[\s\S]*?---\n*/m, "");
125
+ return withoutFrontmatter.trim();
126
+ }
127
+
128
+ function mkdirp(dirPath) {
129
+ if (!fs.existsSync(dirPath)) {
130
+ fs.mkdirSync(dirPath, { recursive: true });
131
+ }
132
+ }
133
+
134
+ function copyDir(src, dest) {
135
+ mkdirp(dest);
136
+ for (const item of fs.readdirSync(src)) {
137
+ const srcItem = path.join(src, item);
138
+ const destItem = path.join(dest, item);
139
+ if (item === "tests") continue; // skip test prompts in installed version
140
+ if (fs.statSync(srcItem).isDirectory()) {
141
+ copyDir(srcItem, destItem);
142
+ } else {
143
+ fs.copyFileSync(srcItem, destItem);
144
+ }
145
+ }
146
+ }
147
+
148
+ function detectTools() {
149
+ const detected = [];
150
+ for (const [key, config] of Object.entries(TOOL_CONFIGS)) {
151
+ if (key === "generic") continue;
152
+ if (config.detect()) {
153
+ detected.push(key);
154
+ }
155
+ }
156
+ return detected;
157
+ }
158
+
159
+ function loadProjectConfig() {
160
+ const configPath = path.join(PROJECT_ROOT, ".ai-skills.json");
161
+ if (fs.existsSync(configPath)) {
162
+ return JSON.parse(fs.readFileSync(configPath, "utf-8"));
163
+ }
164
+ return null;
165
+ }
166
+
167
+ function saveProjectConfig(config) {
168
+ const configPath = path.join(PROJECT_ROOT, ".ai-skills.json");
169
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
170
+ }
171
+
172
+ // ── Commands ──
173
+
174
+ function cmdSetup() {
175
+ console.log(c("blue", "\n━━━ AI Skills Framework — Setup ━━━\n"));
176
+
177
+ // 1. Detect AI tools
178
+ const tools = detectTools();
179
+ if (tools.length === 0) {
180
+ console.log(c("yellow", "No AI coding tools detected in this project."));
181
+ console.log("Will create a generic .ai-rules file that works with any tool.\n");
182
+ tools.push("generic");
183
+ } else {
184
+ console.log(`Detected AI tools: ${tools.map((t) => c("green", TOOL_CONFIGS[t].name)).join(", ")}\n`);
185
+ }
186
+
187
+ // 2. Get all available skills
188
+ const allSkills = getAllSkills();
189
+ const globalSkills = allSkills.filter((s) => s.category === "global");
190
+ const stackSkills = allSkills.filter((s) => s.category === "stack");
191
+
192
+ console.log(`Available skills: ${c("bold", allSkills.length)}`);
193
+ console.log(` Global: ${globalSkills.map((s) => s.name).join(", ")}`);
194
+ console.log(` Stack: ${stackSkills.map((s) => s.name).join(", ")}\n`);
195
+
196
+ // 3. Install for each detected tool
197
+ let installedCount = 0;
198
+
199
+ for (const toolKey of tools) {
200
+ const tool = TOOL_CONFIGS[toolKey];
201
+ console.log(c("yellow", `Setting up for ${tool.name}...`));
202
+
203
+ if (tool.format === "skill-folder") {
204
+ // Claude Code: copy individual SKILL.md folders
205
+ const skillsDir = path.join(PROJECT_ROOT, tool.skillsDir);
206
+ for (const skill of allSkills) {
207
+ const dest = path.join(skillsDir, skill.name);
208
+ copyDir(skill.path, dest);
209
+ console.log(` ${c("green", "✓")} ${skill.name}`);
210
+ installedCount++;
211
+ }
212
+ } else if (tool.format === "rules-file") {
213
+ // Cursor / Copilot / Windsurf / Generic: merge into single rules file
214
+ const rulesPath = path.join(PROJECT_ROOT, tool.rulesFile);
215
+ mkdirp(path.dirname(rulesPath));
216
+
217
+ let rulesContent = `# AI Development Skills Framework\n`;
218
+ rulesContent += `# Auto-generated by @valentia-ai-skills/framework\n`;
219
+ rulesContent += `# Do not edit manually — run 'npx ai-skills update' to refresh\n`;
220
+ rulesContent += `# Last updated: ${new Date().toISOString().split("T")[0]}\n\n`;
221
+
222
+ for (const skill of allSkills) {
223
+ const content = readSkillContent(skill.path);
224
+ if (content) {
225
+ const rules = extractSkillRules(content);
226
+ rulesContent += `\n${"=".repeat(60)}\n`;
227
+ rulesContent += `# SKILL: ${skill.name} (${skill.category})\n`;
228
+ rulesContent += `${"=".repeat(60)}\n\n`;
229
+ rulesContent += rules + "\n";
230
+ }
231
+ }
232
+
233
+ fs.writeFileSync(rulesPath, rulesContent);
234
+ console.log(` ${c("green", "✓")} Written to ${tool.rulesFile} (${allSkills.length} skills merged)`);
235
+ installedCount += allSkills.length;
236
+ }
237
+ console.log("");
238
+ }
239
+
240
+ // 4. Save project config
241
+ const config = {
242
+ version: "1.0.0",
243
+ installedAt: new Date().toISOString(),
244
+ tools,
245
+ skills: allSkills.map((s) => ({ name: s.name, category: s.category })),
246
+ };
247
+ saveProjectConfig(config);
248
+
249
+ // 5. Summary
250
+ console.log(c("blue", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
251
+ console.log(c("green", `✅ Setup complete!`));
252
+ console.log(` ${allSkills.length} skills installed for ${tools.length} tool(s)\n`);
253
+ console.log(`Config saved to ${c("dim", ".ai-skills.json")}`);
254
+ console.log(`To update later: ${c("bold", "npx ai-skills update")}`);
255
+ console.log(`To check status: ${c("bold", "npx ai-skills status")}\n`);
256
+ }
257
+
258
+ function cmdUpdate() {
259
+ console.log(c("blue", "\n━━━ AI Skills Framework — Update ━━━\n"));
260
+
261
+ const config = loadProjectConfig();
262
+ if (!config) {
263
+ console.log(c("yellow", "No .ai-skills.json found. Run 'npx ai-skills setup' first."));
264
+ process.exit(1);
265
+ }
266
+
267
+ // Re-run setup with saved tool preferences
268
+ const tools = config.tools || detectTools();
269
+ const allSkills = getAllSkills();
270
+
271
+ for (const toolKey of tools) {
272
+ const tool = TOOL_CONFIGS[toolKey];
273
+ if (!tool) continue;
274
+
275
+ console.log(c("yellow", `Updating ${tool.name}...`));
276
+
277
+ if (tool.format === "skill-folder") {
278
+ const skillsDir = path.join(PROJECT_ROOT, tool.skillsDir);
279
+ for (const skill of allSkills) {
280
+ const dest = path.join(skillsDir, skill.name);
281
+ copyDir(skill.path, dest);
282
+ console.log(` ${c("green", "✓")} ${skill.name}`);
283
+ }
284
+ } else if (tool.format === "rules-file") {
285
+ const rulesPath = path.join(PROJECT_ROOT, tool.rulesFile);
286
+ mkdirp(path.dirname(rulesPath));
287
+
288
+ let rulesContent = `# AI Development Skills Framework\n`;
289
+ rulesContent += `# Auto-generated by @valentia-ai-skills/framework\n`;
290
+ rulesContent += `# Do not edit manually — run 'npx ai-skills update' to refresh\n`;
291
+ rulesContent += `# Last updated: ${new Date().toISOString().split("T")[0]}\n\n`;
292
+
293
+ for (const skill of allSkills) {
294
+ const content = readSkillContent(skill.path);
295
+ if (content) {
296
+ const rules = extractSkillRules(content);
297
+ rulesContent += `\n${"=".repeat(60)}\n`;
298
+ rulesContent += `# SKILL: ${skill.name} (${skill.category})\n`;
299
+ rulesContent += `${"=".repeat(60)}\n\n`;
300
+ rulesContent += rules + "\n";
301
+ }
302
+ }
303
+
304
+ fs.writeFileSync(rulesPath, rulesContent);
305
+ console.log(` ${c("green", "✓")} ${tool.rulesFile} updated`);
306
+ }
307
+ }
308
+
309
+ // Update config
310
+ config.updatedAt = new Date().toISOString();
311
+ config.skills = allSkills.map((s) => ({ name: s.name, category: s.category }));
312
+ saveProjectConfig(config);
313
+
314
+ console.log(c("green", `\n✅ Updated ${allSkills.length} skills!\n`));
315
+ }
316
+
317
+ function cmdStatus() {
318
+ console.log(c("blue", "\n━━━ AI Skills Framework — Status ━━━\n"));
319
+
320
+ const config = loadProjectConfig();
321
+ const allSkills = getAllSkills();
322
+ const tools = detectTools();
323
+
324
+ // Package version
325
+ const pkg = require(path.join(__dirname, "..", "package.json"));
326
+ console.log(`Package version: ${c("bold", pkg.version)}`);
327
+ console.log(`Skills available: ${c("bold", allSkills.length)}`);
328
+
329
+ // Installed status
330
+ if (config) {
331
+ console.log(`Installed: ${c("green", "Yes")} (${config.installedAt.split("T")[0]})`);
332
+ if (config.updatedAt) {
333
+ console.log(`Last updated: ${config.updatedAt.split("T")[0]}`);
334
+ }
335
+ console.log(`Tools configured: ${config.tools.map((t) => TOOL_CONFIGS[t]?.name || t).join(", ")}`);
336
+ } else {
337
+ console.log(`Installed: ${c("red", "No")} — run 'npx ai-skills setup'`);
338
+ }
339
+
340
+ // Detected tools
341
+ console.log(`\nDetected AI tools in this project:`);
342
+ for (const [key, toolConfig] of Object.entries(TOOL_CONFIGS)) {
343
+ if (key === "generic") continue;
344
+ const detected = toolConfig.detect();
345
+ console.log(` ${detected ? c("green", "●") : c("dim", "○")} ${toolConfig.name}`);
346
+ }
347
+
348
+ // Skill inventory
349
+ console.log(`\nSkill inventory:`);
350
+ for (const skill of allSkills) {
351
+ const content = readSkillContent(skill.path);
352
+ const versionMatch = content?.match(/version:\s*["']?([^"'\n]+)/);
353
+ const version = versionMatch ? versionMatch[1].trim() : "?";
354
+ console.log(` ${c("green", "✓")} ${skill.name} ${c("dim", `v${version}`)} ${c("dim", `(${skill.category})`)}`);
355
+ }
356
+ console.log("");
357
+ }
358
+
359
+ function cmdList() {
360
+ const allSkills = getAllSkills();
361
+ console.log(c("blue", "\n━━━ Available Skills ━━━\n"));
362
+
363
+ const categories = {};
364
+ for (const skill of allSkills) {
365
+ if (!categories[skill.category]) categories[skill.category] = [];
366
+ categories[skill.category].push(skill);
367
+ }
368
+
369
+ for (const [cat, skills] of Object.entries(categories)) {
370
+ console.log(c("yellow", `${cat.toUpperCase()}`));
371
+ for (const s of skills) {
372
+ const content = readSkillContent(s.path);
373
+ const descMatch = content?.match(/description:\s*>?\s*\n?\s*(.+)/);
374
+ const desc = descMatch ? descMatch[1].trim().slice(0, 70) + "..." : "";
375
+ console.log(` ${s.name.padEnd(22)} ${c("dim", desc)}`);
376
+ }
377
+ console.log("");
378
+ }
379
+ }
380
+
381
+ function cmdDoctor() {
382
+ console.log(c("blue", "\n━━━ AI Skills — Health Check ━━━\n"));
383
+
384
+ let issues = 0;
385
+ const allSkills = getAllSkills();
386
+
387
+ // Check skills source exists
388
+ if (allSkills.length === 0) {
389
+ console.log(c("red", "✗ No skills found in package. Package may be corrupted."));
390
+ issues++;
391
+ } else {
392
+ console.log(c("green", `✓ ${allSkills.length} skills found in package`));
393
+ }
394
+
395
+ // Check project config
396
+ const config = loadProjectConfig();
397
+ if (!config) {
398
+ console.log(c("yellow", "⚠ No .ai-skills.json — run 'npx ai-skills setup'"));
399
+ issues++;
400
+ } else {
401
+ console.log(c("green", `✓ Project configured (${config.tools.length} tool(s))`));
402
+
403
+ // Check each tool's files exist
404
+ for (const toolKey of config.tools) {
405
+ const tool = TOOL_CONFIGS[toolKey];
406
+ if (!tool) continue;
407
+
408
+ if (tool.format === "skill-folder") {
409
+ const dir = path.join(PROJECT_ROOT, tool.skillsDir);
410
+ if (fs.existsSync(dir)) {
411
+ const count = fs.readdirSync(dir).filter(
412
+ (f) => fs.existsSync(path.join(dir, f, "SKILL.md"))
413
+ ).length;
414
+ console.log(c("green", `✓ ${tool.name}: ${count} skills in ${tool.skillsDir}/`));
415
+ } else {
416
+ console.log(c("red", `✗ ${tool.name}: ${tool.skillsDir}/ missing`));
417
+ issues++;
418
+ }
419
+ } else if (tool.rulesFile) {
420
+ const rulesPath = path.join(PROJECT_ROOT, tool.rulesFile);
421
+ if (fs.existsSync(rulesPath)) {
422
+ console.log(c("green", `✓ ${tool.name}: ${tool.rulesFile} exists`));
423
+ } else {
424
+ console.log(c("red", `✗ ${tool.name}: ${tool.rulesFile} missing`));
425
+ issues++;
426
+ }
427
+ }
428
+ }
429
+ }
430
+
431
+ console.log(issues === 0
432
+ ? c("green", "\n✅ Everything looks good!\n")
433
+ : c("yellow", `\n⚠ ${issues} issue(s) found. Run 'npx ai-skills setup' to fix.\n`)
434
+ );
435
+ }
436
+
437
+ // ── Main ──
438
+
439
+ const command = process.argv[2] || "setup";
440
+
441
+ switch (command) {
442
+ case "setup":
443
+ cmdSetup();
444
+ break;
445
+ case "update":
446
+ cmdUpdate();
447
+ break;
448
+ case "status":
449
+ cmdStatus();
450
+ break;
451
+ case "list":
452
+ cmdList();
453
+ break;
454
+ case "doctor":
455
+ cmdDoctor();
456
+ break;
457
+ case "help":
458
+ case "--help":
459
+ case "-h":
460
+ console.log(`
461
+ ${c("blue", "AI Skills Framework")}
462
+
463
+ Usage:
464
+ npx ai-skills setup Setup skills for detected AI tools
465
+ npx ai-skills update Update skills to latest version
466
+ npx ai-skills status Show installed skills and tools
467
+ npx ai-skills list List all available skills
468
+ npx ai-skills doctor Check setup health
469
+ npx ai-skills help Show this help
470
+
471
+ How it works:
472
+ 1. Install: npm install --save-dev @valentia-ai-skills/framework
473
+ 2. Setup: npx ai-skills setup
474
+ 3. Code: Your AI tools now follow your org's standards
475
+ 4. Update: npm update @valentia-ai-skills/framework && npx ai-skills update
476
+ `);
477
+ break;
478
+ default:
479
+ console.log(c("red", `Unknown command: ${command}`));
480
+ console.log("Run 'npx ai-skills help' for usage info.");
481
+ process.exit(1);
482
+ }
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@valentia-ai-skills/framework",
3
+ "version": "1.0.0",
4
+ "description": "AI development skills framework — centralized coding standards, security patterns, and SOPs for AI-assisted development. Works with Claude Code, Cursor, Copilot, Windsurf, and any AI coding tool.",
5
+ "keywords": [
6
+ "ai-skills",
7
+ "claude-code",
8
+ "cursor",
9
+ "copilot",
10
+ "windsurf",
11
+ "coding-standards",
12
+ "development-framework",
13
+ "ai-development"
14
+ ],
15
+ "author": "Valentia",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/codearraydev/valentia-awsome-skills.git"
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "bin": {
25
+ "ai-skills": "./bin/cli.js"
26
+ },
27
+ "scripts": {
28
+ "postinstall": "node scripts/postinstall.js",
29
+ "setup": "node bin/cli.js setup",
30
+ "update": "node bin/cli.js update"
31
+ },
32
+ "files": [
33
+ "bin/",
34
+ "src/",
35
+ "skills/",
36
+ "scripts/",
37
+ "README.md"
38
+ ],
39
+ "engines": {
40
+ "node": ">=18"
41
+ }
42
+ }
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Runs after npm install. Prints a friendly message.
5
+ * Does NOT auto-setup — that's intentional so devs can choose.
6
+ */
7
+
8
+ const G = "\x1b[32m";
9
+ const B = "\x1b[34m";
10
+ const R = "\x1b[0m";
11
+ const D = "\x1b[2m";
12
+
13
+ console.log(`
14
+ ${B}━━━ AI Skills Framework installed ━━━${R}
15
+
16
+ Run ${G}npx ai-skills setup${R} to configure for your AI tools.
17
+ ${D}(Claude Code, Cursor, Copilot, Windsurf auto-detected)${R}
18
+ `);