@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,272 @@
1
+ /**
2
+ * Configuration Utilities
3
+ *
4
+ * Set up Claude Code settings, hooks, and project configuration.
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
+ const TEMPLATES_PATH = path.join(__dirname, '../../templates');
15
+
16
+ /**
17
+ * Default settings for Claude Code
18
+ */
19
+ const DEFAULT_SETTINGS = {
20
+ permissions: {
21
+ allow: [
22
+ "Bash(npm run *)",
23
+ "Bash(npm test*)",
24
+ "Bash(npm install*)",
25
+ "Bash(npx *)",
26
+ "Bash(git *)",
27
+ "Bash(python3 *)",
28
+ "Bash(curl *)",
29
+ "Bash(ls *)",
30
+ "Bash(find *)",
31
+ "Bash(grep *)",
32
+ "Bash(cat *)",
33
+ "Bash(mkdir *)",
34
+ "Bash(cp *)",
35
+ "Bash(mv *)",
36
+ "Bash(rm -rf node_modules*)",
37
+ "Bash(rm -rf .next*)",
38
+ "Bash(rm -rf dist*)",
39
+ "Read(*)",
40
+ "Write(*)",
41
+ "Edit(*)"
42
+ ],
43
+ deny: []
44
+ }
45
+ };
46
+
47
+ /**
48
+ * Hooks for automatic graph updates
49
+ */
50
+ const DEFAULT_HOOKS = {
51
+ postToolUse: [
52
+ {
53
+ matcher: {
54
+ toolName: "Write|Edit",
55
+ path: "plans/**/*"
56
+ },
57
+ command: "python3 scripts/graph.py --check-path $PATH || true"
58
+ }
59
+ ]
60
+ };
61
+
62
+ /**
63
+ * Set up Claude Code settings
64
+ */
65
+ export async function setupSettings(projectPath, options = {}) {
66
+ const claudePath = path.join(projectPath, '.claude');
67
+ const settingsPath = path.join(claudePath, 'settings.local.json');
68
+
69
+ await fs.ensureDir(claudePath);
70
+
71
+ let settings = DEFAULT_SETTINGS;
72
+
73
+ // Merge with existing if present
74
+ if (await fs.pathExists(settingsPath)) {
75
+ try {
76
+ const existing = await fs.readJson(settingsPath);
77
+ settings = mergeSettings(existing, settings);
78
+ } catch (e) {
79
+ // Invalid JSON, use defaults
80
+ }
81
+ }
82
+
83
+ await fs.writeJson(settingsPath, settings, { spaces: 2 });
84
+
85
+ return { path: settingsPath, settings };
86
+ }
87
+
88
+ /**
89
+ * Set up hooks
90
+ */
91
+ export async function setupHooks(projectPath, options = {}) {
92
+ if (options.noHooks) return null;
93
+
94
+ const claudePath = path.join(projectPath, '.claude');
95
+ const hooksPath = path.join(claudePath, 'hooks.json');
96
+
97
+ await fs.ensureDir(claudePath);
98
+
99
+ let hooks = DEFAULT_HOOKS;
100
+
101
+ // Merge with existing if present
102
+ if (await fs.pathExists(hooksPath)) {
103
+ try {
104
+ const existing = await fs.readJson(hooksPath);
105
+ hooks = mergeHooks(existing, hooks);
106
+ } catch (e) {
107
+ // Invalid JSON, use defaults
108
+ }
109
+ }
110
+
111
+ await fs.writeJson(hooksPath, hooks, { spaces: 2 });
112
+
113
+ return { path: hooksPath, hooks };
114
+ }
115
+
116
+ /**
117
+ * Set up or update CLAUDE.md
118
+ */
119
+ export async function setupClaudeMd(projectPath, options = {}) {
120
+ const claudeMdPath = path.join(projectPath, 'CLAUDE.md');
121
+ const templatePath = path.join(TEMPLATES_PATH, 'CLAUDE.md.template');
122
+
123
+ // Check if CLAUDE.md already exists
124
+ if (await fs.pathExists(claudeMdPath)) {
125
+ if (options.skipExisting) {
126
+ return { path: claudeMdPath, action: 'skipped', reason: 'already exists' };
127
+ }
128
+
129
+ // Don't overwrite, but append skills reference if not present
130
+ const content = await fs.readFile(claudeMdPath, 'utf-8');
131
+
132
+ if (!content.includes('## Skills')) {
133
+ const skillsSection = `
134
+ ## Skills
135
+
136
+ This project uses CodiHaus Claude Skills. Available skills:
137
+
138
+ - \`/debrief\` - Create BRD and use cases
139
+ - \`/dev-scout\` - Explore and document codebase
140
+ - \`/dev-arch\` - Architecture decisions
141
+ - \`/dev-specs\` - Create implementation plans
142
+ - \`/dev-coding\` - Implement features
143
+ - \`/dev-test\` - Automated testing
144
+ - \`/dev-review\` - Code review
145
+ - \`/dev-changelog\` - Document what was built
146
+
147
+ See \`.claude/skills/_registry.md\` for full documentation.
148
+ `;
149
+ await fs.appendFile(claudeMdPath, skillsSection);
150
+ return { path: claudeMdPath, action: 'updated', reason: 'added skills section' };
151
+ }
152
+
153
+ return { path: claudeMdPath, action: 'skipped', reason: 'skills section exists' };
154
+ }
155
+
156
+ // Create from template
157
+ if (await fs.pathExists(templatePath)) {
158
+ await fs.copy(templatePath, claudeMdPath);
159
+ return { path: claudeMdPath, action: 'created', reason: 'from template' };
160
+ }
161
+
162
+ // Create minimal CLAUDE.md
163
+ const minimalContent = `# CLAUDE.md
164
+
165
+ Project-specific instructions for Claude Code.
166
+
167
+ ## Skills
168
+
169
+ This project uses CodiHaus Claude Skills. Available skills:
170
+
171
+ - \`/debrief\` - Create BRD and use cases
172
+ - \`/dev-scout\` - Explore and document codebase
173
+ - \`/dev-arch\` - Architecture decisions
174
+ - \`/dev-specs\` - Create implementation plans
175
+ - \`/dev-coding\` - Implement features
176
+ - \`/dev-test\` - Automated testing
177
+ - \`/dev-review\` - Code review
178
+ - \`/dev-changelog\` - Document what was built
179
+
180
+ See \`.claude/skills/_registry.md\` for full documentation.
181
+
182
+ ## Project Overview
183
+
184
+ {Add your project description here}
185
+
186
+ ## Development
187
+
188
+ {Add development instructions here}
189
+ `;
190
+
191
+ await fs.writeFile(claudeMdPath, minimalContent);
192
+ return { path: claudeMdPath, action: 'created', reason: 'minimal template' };
193
+ }
194
+
195
+ /**
196
+ * Set up scripts directory
197
+ */
198
+ export async function setupScripts(projectPath) {
199
+ const scriptsPath = path.join(projectPath, 'scripts');
200
+ const sourceScripts = path.join(TEMPLATES_PATH, 'scripts');
201
+
202
+ await fs.ensureDir(scriptsPath);
203
+
204
+ // Copy graph.py if it exists in templates
205
+ const graphPy = path.join(sourceScripts, 'graph.py');
206
+ if (await fs.pathExists(graphPy)) {
207
+ await fs.copy(graphPy, path.join(scriptsPath, 'graph.py'));
208
+ }
209
+
210
+ return { path: scriptsPath };
211
+ }
212
+
213
+ /**
214
+ * Add to .gitignore
215
+ */
216
+ export async function updateGitignore(projectPath) {
217
+ const gitignorePath = path.join(projectPath, '.gitignore');
218
+
219
+ const entriesToAdd = [
220
+ '',
221
+ '# Claude Code',
222
+ '.claude/settings.local.json',
223
+ '.env',
224
+ '*.env.local',
225
+ ''
226
+ ];
227
+
228
+ if (await fs.pathExists(gitignorePath)) {
229
+ const content = await fs.readFile(gitignorePath, 'utf-8');
230
+
231
+ // Check if already has Claude section
232
+ if (content.includes('# Claude Code')) {
233
+ return { action: 'skipped' };
234
+ }
235
+
236
+ await fs.appendFile(gitignorePath, entriesToAdd.join('\n'));
237
+ return { action: 'updated' };
238
+ }
239
+
240
+ await fs.writeFile(gitignorePath, entriesToAdd.join('\n'));
241
+ return { action: 'created' };
242
+ }
243
+
244
+ /**
245
+ * Merge settings objects
246
+ */
247
+ function mergeSettings(existing, defaults) {
248
+ return {
249
+ permissions: {
250
+ allow: [...new Set([
251
+ ...(existing.permissions?.allow || []),
252
+ ...(defaults.permissions?.allow || [])
253
+ ])],
254
+ deny: [...new Set([
255
+ ...(existing.permissions?.deny || []),
256
+ ...(defaults.permissions?.deny || [])
257
+ ])]
258
+ }
259
+ };
260
+ }
261
+
262
+ /**
263
+ * Merge hooks objects
264
+ */
265
+ function mergeHooks(existing, defaults) {
266
+ // For now, just use defaults if hooks exist
267
+ // More sophisticated merging could be added
268
+ return {
269
+ ...defaults,
270
+ ...existing
271
+ };
272
+ }