@codihaus/claude-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.
Files changed (46) hide show
  1. package/README.md +167 -0
  2. package/bin/cli.js +58 -0
  3. package/package.json +46 -0
  4. package/skills/_quality-attributes.md +392 -0
  5. package/skills/_registry.md +189 -0
  6. package/skills/debrief/SKILL.md +647 -0
  7. package/skills/debrief/references/change-request-template.md +124 -0
  8. package/skills/debrief/references/file-patterns.md +173 -0
  9. package/skills/debrief/references/group-codes.md +72 -0
  10. package/skills/debrief/references/research-queries.md +106 -0
  11. package/skills/debrief/references/use-case-template.md +141 -0
  12. package/skills/debrief/scripts/generate_questionnaire.py +195 -0
  13. package/skills/dev-arch/SKILL.md +747 -0
  14. package/skills/dev-changelog/SKILL.md +378 -0
  15. package/skills/dev-coding/SKILL.md +470 -0
  16. package/skills/dev-coding-backend/SKILL.md +361 -0
  17. package/skills/dev-coding-frontend/SKILL.md +534 -0
  18. package/skills/dev-coding-frontend/references/nextjs.md +477 -0
  19. package/skills/dev-review/SKILL.md +548 -0
  20. package/skills/dev-scout/SKILL.md +723 -0
  21. package/skills/dev-scout/references/feature-patterns.md +210 -0
  22. package/skills/dev-scout/references/file-patterns.md +252 -0
  23. package/skills/dev-scout/references/tech-detection.md +211 -0
  24. package/skills/dev-scout/scripts/scout-analyze.sh +280 -0
  25. package/skills/dev-specs/SKILL.md +577 -0
  26. package/skills/dev-specs/references/checklist.md +176 -0
  27. package/skills/dev-specs/references/spec-templates.md +460 -0
  28. package/skills/dev-test/SKILL.md +364 -0
  29. package/skills/utils/diagram/SKILL.md +205 -0
  30. package/skills/utils/diagram/references/common-errors.md +305 -0
  31. package/skills/utils/diagram/references/diagram-types.md +636 -0
  32. package/skills/utils/docs-graph/SKILL.md +204 -0
  33. package/skills/utils/gemini/SKILL.md +292 -0
  34. package/skills/utils/gemini/scripts/gemini-scan.py +340 -0
  35. package/skills/utils/gemini/scripts/setup.sh +169 -0
  36. package/src/commands/add.js +64 -0
  37. package/src/commands/doctor.js +179 -0
  38. package/src/commands/init.js +251 -0
  39. package/src/commands/list.js +88 -0
  40. package/src/commands/remove.js +60 -0
  41. package/src/commands/update.js +72 -0
  42. package/src/index.js +26 -0
  43. package/src/utils/config.js +272 -0
  44. package/src/utils/deps.js +599 -0
  45. package/src/utils/skills.js +253 -0
  46. package/templates/CLAUDE.md.template +58 -0
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Skills Management Utilities
3
+ *
4
+ * Copy, list, and manage skills in projects.
5
+ */
6
+
7
+ import fs from 'fs-extra';
8
+ import path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = path.dirname(__filename);
13
+
14
+ // Path to bundled skills (in npm package)
15
+ const SKILLS_SOURCE = path.join(__dirname, '../../skills');
16
+
17
+ /**
18
+ * Get list of all available skills
19
+ */
20
+ export async function getAvailableSkills() {
21
+ const skills = [];
22
+
23
+ // Read main skills
24
+ const mainSkills = await fs.readdir(SKILLS_SOURCE);
25
+
26
+ for (const name of mainSkills) {
27
+ const skillPath = path.join(SKILLS_SOURCE, name);
28
+ const stat = await fs.stat(skillPath);
29
+
30
+ if (!stat.isDirectory()) continue;
31
+
32
+ // Check if it's a skill (has SKILL.md) or a category folder (like utils/)
33
+ const skillMd = path.join(skillPath, 'SKILL.md');
34
+
35
+ if (await fs.pathExists(skillMd)) {
36
+ // It's a skill
37
+ const metadata = await parseSkillMetadata(skillMd);
38
+ skills.push({
39
+ name,
40
+ path: skillPath,
41
+ ...metadata
42
+ });
43
+ } else {
44
+ // It's a category folder (like utils/), check subdirectories
45
+ const subItems = await fs.readdir(skillPath);
46
+
47
+ for (const subName of subItems) {
48
+ const subPath = path.join(skillPath, subName);
49
+ const subStat = await fs.stat(subPath);
50
+
51
+ if (!subStat.isDirectory()) continue;
52
+
53
+ const subSkillMd = path.join(subPath, 'SKILL.md');
54
+ if (await fs.pathExists(subSkillMd)) {
55
+ const metadata = await parseSkillMetadata(subSkillMd);
56
+ skills.push({
57
+ name: `${name}/${subName}`,
58
+ path: subPath,
59
+ category: name,
60
+ ...metadata
61
+ });
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ // Also include special files
68
+ const specialFiles = ['_registry.md', '_quality-attributes.md'];
69
+ for (const file of specialFiles) {
70
+ const filePath = path.join(SKILLS_SOURCE, file);
71
+ if (await fs.pathExists(filePath)) {
72
+ skills.push({
73
+ name: file,
74
+ path: filePath,
75
+ type: 'config'
76
+ });
77
+ }
78
+ }
79
+
80
+ return skills;
81
+ }
82
+
83
+ /**
84
+ * Parse skill metadata from SKILL.md frontmatter
85
+ */
86
+ async function parseSkillMetadata(skillMdPath) {
87
+ try {
88
+ const content = await fs.readFile(skillMdPath, 'utf-8');
89
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
90
+
91
+ if (!frontmatterMatch) {
92
+ return { version: 'unknown', description: '' };
93
+ }
94
+
95
+ const frontmatter = frontmatterMatch[1];
96
+ const metadata = {};
97
+
98
+ // Parse YAML-like frontmatter
99
+ const lines = frontmatter.split('\n');
100
+ for (const line of lines) {
101
+ const match = line.match(/^(\w+):\s*(.+)$/);
102
+ if (match) {
103
+ metadata[match[1]] = match[2].trim();
104
+ }
105
+ }
106
+
107
+ return metadata;
108
+ } catch (e) {
109
+ return { version: 'unknown', description: '' };
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Get installed skills in a project
115
+ */
116
+ export async function getInstalledSkills(projectPath) {
117
+ const skillsPath = path.join(projectPath, '.claude', 'skills');
118
+
119
+ if (!await fs.pathExists(skillsPath)) {
120
+ return [];
121
+ }
122
+
123
+ const skills = [];
124
+ const items = await fs.readdir(skillsPath);
125
+
126
+ for (const name of items) {
127
+ const itemPath = path.join(skillsPath, name);
128
+ const stat = await fs.stat(itemPath);
129
+
130
+ if (!stat.isDirectory()) {
131
+ // Config files like _registry.md
132
+ if (name.endsWith('.md')) {
133
+ skills.push({ name, type: 'config' });
134
+ }
135
+ continue;
136
+ }
137
+
138
+ const skillMd = path.join(itemPath, 'SKILL.md');
139
+ if (await fs.pathExists(skillMd)) {
140
+ const metadata = await parseSkillMetadata(skillMd);
141
+ skills.push({
142
+ name,
143
+ path: itemPath,
144
+ ...metadata
145
+ });
146
+ } else {
147
+ // Check for nested skills (like utils/)
148
+ const subItems = await fs.readdir(itemPath);
149
+ for (const subName of subItems) {
150
+ const subPath = path.join(itemPath, subName);
151
+ const subStat = await fs.stat(subPath);
152
+
153
+ if (!subStat.isDirectory()) continue;
154
+
155
+ const subSkillMd = path.join(subPath, 'SKILL.md');
156
+ if (await fs.pathExists(subSkillMd)) {
157
+ const metadata = await parseSkillMetadata(subSkillMd);
158
+ skills.push({
159
+ name: `${name}/${subName}`,
160
+ path: subPath,
161
+ category: name,
162
+ ...metadata
163
+ });
164
+ }
165
+ }
166
+ }
167
+ }
168
+
169
+ return skills;
170
+ }
171
+
172
+ /**
173
+ * Copy skills to project
174
+ */
175
+ export async function copySkillsToProject(projectPath, skillNames = null) {
176
+ const targetPath = path.join(projectPath, '.claude', 'skills');
177
+
178
+ // Ensure target directory exists
179
+ await fs.ensureDir(targetPath);
180
+
181
+ const available = await getAvailableSkills();
182
+ const toCopy = skillNames
183
+ ? available.filter(s => skillNames.includes(s.name) || s.type === 'config')
184
+ : available;
185
+
186
+ const copied = [];
187
+ const errors = [];
188
+
189
+ for (const skill of toCopy) {
190
+ try {
191
+ const targetSkillPath = path.join(targetPath, skill.name);
192
+
193
+ if (skill.type === 'config') {
194
+ // Copy single file
195
+ await fs.copy(skill.path, path.join(targetPath, skill.name));
196
+ } else {
197
+ // Copy directory
198
+ await fs.copy(skill.path, targetSkillPath);
199
+ }
200
+
201
+ copied.push(skill.name);
202
+ } catch (e) {
203
+ errors.push({ name: skill.name, error: e.message });
204
+ }
205
+ }
206
+
207
+ return { copied, errors };
208
+ }
209
+
210
+ /**
211
+ * Remove a skill from project
212
+ */
213
+ export async function removeSkillFromProject(projectPath, skillName) {
214
+ const targetPath = path.join(projectPath, '.claude', 'skills', skillName);
215
+
216
+ if (!await fs.pathExists(targetPath)) {
217
+ return { success: false, error: 'Skill not found' };
218
+ }
219
+
220
+ try {
221
+ await fs.remove(targetPath);
222
+ return { success: true };
223
+ } catch (e) {
224
+ return { success: false, error: e.message };
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Check if skills need updating
230
+ */
231
+ export async function checkForUpdates(projectPath) {
232
+ const installed = await getInstalledSkills(projectPath);
233
+ const available = await getAvailableSkills();
234
+
235
+ const updates = [];
236
+
237
+ for (const installedSkill of installed) {
238
+ if (installedSkill.type === 'config') continue;
239
+
240
+ const availableSkill = available.find(a => a.name === installedSkill.name);
241
+ if (!availableSkill) continue;
242
+
243
+ if (installedSkill.version !== availableSkill.version) {
244
+ updates.push({
245
+ name: installedSkill.name,
246
+ current: installedSkill.version,
247
+ available: availableSkill.version
248
+ });
249
+ }
250
+ }
251
+
252
+ return updates;
253
+ }
@@ -0,0 +1,58 @@
1
+ # CLAUDE.md
2
+
3
+ Project-specific instructions for Claude Code.
4
+
5
+ ## Skills
6
+
7
+ This project uses CodiHaus Claude Skills. Available skills:
8
+
9
+ | Skill | Purpose |
10
+ |-------|---------|
11
+ | `/debrief` | Create BRD and use cases from requirements |
12
+ | `/dev-scout` | Explore and document existing codebase |
13
+ | `/dev-arch` | Make architecture decisions |
14
+ | `/dev-specs` | Create implementation specifications |
15
+ | `/dev-coding` | Implement features from specs |
16
+ | `/dev-test` | Automated UI testing |
17
+ | `/dev-review` | Code review with quality checks |
18
+ | `/dev-changelog` | Document what was implemented |
19
+
20
+ ### Utility Skills (called by other skills)
21
+
22
+ | Skill | Purpose |
23
+ |-------|---------|
24
+ | `/utils/diagram` | Mermaid diagram validation |
25
+ | `/utils/docs-graph` | Documentation relationship viewer |
26
+ | `/utils/gemini` | Large codebase scanning |
27
+
28
+ See `.claude/skills/_registry.md` for full documentation.
29
+
30
+ ## Project Overview
31
+
32
+ {Add your project description here}
33
+
34
+ ## Tech Stack
35
+
36
+ {List your technologies here}
37
+
38
+ ## Development
39
+
40
+ ### Getting Started
41
+
42
+ ```bash
43
+ # Install dependencies
44
+ npm install
45
+
46
+ # Start development server
47
+ npm run dev
48
+ ```
49
+
50
+ ### Testing
51
+
52
+ ```bash
53
+ npm test
54
+ ```
55
+
56
+ ## Conventions
57
+
58
+ {Add any project-specific conventions here}