@codihaus/claude-skills 1.6.20 → 1.6.21
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 +1 -0
- package/knowledge/stacks/_index.md +29 -3
- package/package.json +1 -1
- package/skills/_registry.md +23 -0
- package/skills/debrief/SKILL.md +44 -0
- package/skills/dev-coding/SKILL.md +6 -0
- package/src/commands/init.js +7 -2
- package/src/utils/skills.js +153 -6
package/bin/cli.js
CHANGED
|
@@ -23,6 +23,7 @@ program
|
|
|
23
23
|
.option('--all', 'Install all skills (default)', true)
|
|
24
24
|
.option('--no-deps', 'Skip dependency checking')
|
|
25
25
|
.option('--no-hooks', 'Skip hooks setup')
|
|
26
|
+
.option('-k, --knowledge <path>', 'Path to custom knowledge base to install')
|
|
26
27
|
.option('-y, --yes', 'Skip confirmation prompts')
|
|
27
28
|
.action(init);
|
|
28
29
|
|
|
@@ -28,7 +28,7 @@ Each stack follows this structure:
|
|
|
28
28
|
|
|
29
29
|
```
|
|
30
30
|
stacks/{stack-name}/
|
|
31
|
-
├── _index.md # Main knowledge file
|
|
31
|
+
├── _index.md # Main knowledge file (always read first)
|
|
32
32
|
│ ├── Overview # What it is, when to use
|
|
33
33
|
│ ├── Best Practices # Patterns to follow
|
|
34
34
|
│ ├── Anti-Patterns # What to avoid
|
|
@@ -37,17 +37,43 @@ stacks/{stack-name}/
|
|
|
37
37
|
│ ├── For /dev-review # Review checklists
|
|
38
38
|
│ └── Integration # How it works with other stacks
|
|
39
39
|
│
|
|
40
|
-
├── references/ # Detailed documentation
|
|
40
|
+
├── references/ # Detailed documentation (load as needed)
|
|
41
41
|
│ ├── api.md # API reference
|
|
42
42
|
│ ├── patterns.md # Common patterns
|
|
43
43
|
│ └── performance.md # Performance optimization
|
|
44
44
|
│
|
|
45
|
-
└── assets/ # Code templates
|
|
45
|
+
└── assets/ # Code templates (load as needed)
|
|
46
46
|
├── composable.ts # Example composable
|
|
47
47
|
├── component.vue # Example component
|
|
48
48
|
└── config.ts # Example config
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
## Loading Knowledge
|
|
52
|
+
|
|
53
|
+
Skills can load knowledge in two ways:
|
|
54
|
+
|
|
55
|
+
### 1. Quick Reference (Default)
|
|
56
|
+
Load only `_index.md` for overview and skill-specific guidance:
|
|
57
|
+
```
|
|
58
|
+
Read knowledge/stacks/{stack}/_index.md
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2. Deep Dive (When Needed)
|
|
62
|
+
Use `_knowledge.json` to discover and load additional files:
|
|
63
|
+
```
|
|
64
|
+
1. Read knowledge/_knowledge.json → Get file list for {stack}
|
|
65
|
+
2. Read knowledge/stacks/{stack}/_index.md → Main guidance
|
|
66
|
+
3. Read knowledge/stacks/{stack}/references/patterns.md → Detailed patterns
|
|
67
|
+
4. Read knowledge/stacks/{stack}/references/performance.md → Performance tips
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### When to Load More Than _index.md
|
|
71
|
+
|
|
72
|
+
- **Specs**: Usually `_index.md` is enough (high-level patterns)
|
|
73
|
+
- **Coding**: Load `references/` when implementing complex features
|
|
74
|
+
- **Review**: Load `references/performance.md` for performance reviews
|
|
75
|
+
- **Architecture**: Load `references/` for deep architectural decisions
|
|
76
|
+
|
|
51
77
|
## How Skills Use Stack Knowledge
|
|
52
78
|
|
|
53
79
|
### /dev-scout
|
package/package.json
CHANGED
package/skills/_registry.md
CHANGED
|
@@ -227,6 +227,29 @@ Domain knowledge captures:
|
|
|
227
227
|
|
|
228
228
|
See `knowledge/stacks/_index.md` and `knowledge/domains/_index.md` for details.
|
|
229
229
|
|
|
230
|
+
### Knowledge Loading Patterns
|
|
231
|
+
|
|
232
|
+
Skills can load knowledge at two depths:
|
|
233
|
+
|
|
234
|
+
**Quick Reference (Default):**
|
|
235
|
+
- Load `knowledge/stacks/{stack}/_index.md` for overview and skill-specific sections
|
|
236
|
+
- Use for most tasks where general guidance is enough
|
|
237
|
+
- Examples: Specs, basic reviews, standard implementations
|
|
238
|
+
|
|
239
|
+
**Deep Dive (When Needed):**
|
|
240
|
+
1. Read `knowledge/_knowledge.json` to discover available files
|
|
241
|
+
2. Load `_index.md` for overview
|
|
242
|
+
3. Load additional reference files based on needs:
|
|
243
|
+
- `references/patterns.md` - Detailed implementation patterns
|
|
244
|
+
- `references/performance.md` - Performance optimization
|
|
245
|
+
- `references/api.md` - API reference
|
|
246
|
+
|
|
247
|
+
**When to go deep:**
|
|
248
|
+
- Complex or performance-critical implementations
|
|
249
|
+
- Architecture decisions requiring deep framework knowledge
|
|
250
|
+
- Comprehensive code reviews
|
|
251
|
+
- Learning new patterns for unfamiliar stacks
|
|
252
|
+
|
|
230
253
|
## Skill Awareness Protocol
|
|
231
254
|
|
|
232
255
|
Every skill should:
|
package/skills/debrief/SKILL.md
CHANGED
|
@@ -28,6 +28,7 @@ Create and maintain the unified BRD for a project. Handles initial requirements
|
|
|
28
28
|
/debrief requirements.pdf # From document
|
|
29
29
|
/debrief # Interactive
|
|
30
30
|
/debrief --answers questionnaire.xlsx # Process customer answers
|
|
31
|
+
/debrief --questionnaire-only # Generate questionnaire only (no BRD)
|
|
31
32
|
```
|
|
32
33
|
|
|
33
34
|
## Output Structure
|
|
@@ -89,6 +90,11 @@ Depending on mode:
|
|
|
89
90
|
- Open questions resolved
|
|
90
91
|
- Status updated to "Confirmed" if complete
|
|
91
92
|
|
|
93
|
+
**Questionnaire Only:**
|
|
94
|
+
- Excel questionnaire file generated
|
|
95
|
+
- No BRD or feature folders created
|
|
96
|
+
- Ready to send to customer for answers
|
|
97
|
+
|
|
92
98
|
## Success Criteria
|
|
93
99
|
|
|
94
100
|
- Use cases are testable (clear acceptance criteria)
|
|
@@ -108,6 +114,7 @@ Detect automatically on start:
|
|
|
108
114
|
| `plans/brd/` exists, adding features | **Add Feature** | Add to existing BRD, check for duplicates |
|
|
109
115
|
| Modifying confirmed use cases | **Change Request** | Create CR first, then update |
|
|
110
116
|
| `--answers` flag provided | **Process Answers** | Update use cases with customer responses |
|
|
117
|
+
| `--questionnaire-only` flag provided | **Questionnaire Only** | Generate questionnaire Excel file only, no BRD |
|
|
111
118
|
|
|
112
119
|
## Context Gathering
|
|
113
120
|
|
|
@@ -345,6 +352,43 @@ Provide summary with:
|
|
|
345
352
|
|
|
346
353
|
---
|
|
347
354
|
|
|
355
|
+
## Questionnaire-Only Mode
|
|
356
|
+
|
|
357
|
+
When `--questionnaire-only` flag is provided, skip BRD generation and only create questionnaire file.
|
|
358
|
+
|
|
359
|
+
### Use Cases
|
|
360
|
+
- Quick requirements gathering without full debrief
|
|
361
|
+
- Ad-hoc customer clarifications
|
|
362
|
+
- Focused question sets for specific topics
|
|
363
|
+
|
|
364
|
+
### Workflow
|
|
365
|
+
|
|
366
|
+
1. **Ask Context Questions**
|
|
367
|
+
- Project name (or use current folder name)
|
|
368
|
+
- Topic/Feature being questioned
|
|
369
|
+
- Custom questions (user provides as text/list)
|
|
370
|
+
|
|
371
|
+
2. **Generate Questionnaire**
|
|
372
|
+
- Create Excel file at `questionnaire-{YYYY-MM-DD}.xlsx` in current directory
|
|
373
|
+
- Include only the questions provided by user
|
|
374
|
+
- Use standard questionnaire format (Summary + Questions sheets)
|
|
375
|
+
|
|
376
|
+
3. **Output Summary**
|
|
377
|
+
- File location
|
|
378
|
+
- Question count
|
|
379
|
+
- Next steps (send to customer, process with --answers)
|
|
380
|
+
|
|
381
|
+
### Example
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
/debrief --questionnaire-only "I need to ask customer about payment methods, billing cycle, and refund policy"
|
|
385
|
+
|
|
386
|
+
# Creates: questionnaire-2024-01-20.xlsx with 3 questions
|
|
387
|
+
# Ready to send to customer
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
348
392
|
## Process Answers Workflow
|
|
349
393
|
|
|
350
394
|
When customer returns filled questionnaire, run:
|
|
@@ -73,6 +73,12 @@ You have three layers of knowledge to apply:
|
|
|
73
73
|
- "Nuxt" → `knowledge/stacks/nuxt/_index.md`
|
|
74
74
|
- "Directus" → `knowledge/stacks/directus/_index.md`
|
|
75
75
|
|
|
76
|
+
**Deep knowledge loading (for complex features):**
|
|
77
|
+
- First read `knowledge/_knowledge.json` to discover available reference files
|
|
78
|
+
- Load additional references when needed: `knowledge/stacks/{stack}/references/*.md`
|
|
79
|
+
- Example: For performance-critical features, load `references/performance.md`
|
|
80
|
+
- Example: For complex patterns, load `references/patterns.md`
|
|
81
|
+
|
|
76
82
|
**If you skip this step**, you'll implement using generic patterns instead of framework-specific best practices (e.g., using fetch instead of Server Actions in Next.js).
|
|
77
83
|
|
|
78
84
|
## Expected Outcome
|
package/src/commands/init.js
CHANGED
|
@@ -186,17 +186,22 @@ export async function init(options) {
|
|
|
186
186
|
const knowledgeSpinner = ora('Installing knowledge base...').start();
|
|
187
187
|
|
|
188
188
|
try {
|
|
189
|
-
const { copied: knowledgeCopied, errors: knowledgeErrors } = await copyKnowledgeToProject(
|
|
189
|
+
const { copied: knowledgeCopied, errors: knowledgeErrors } = await copyKnowledgeToProject(
|
|
190
|
+
projectPath,
|
|
191
|
+
options.knowledge // Custom knowledge path if provided
|
|
192
|
+
);
|
|
190
193
|
|
|
191
194
|
if (knowledgeErrors.length > 0) {
|
|
192
195
|
knowledgeSpinner.warn(`Installed ${knowledgeCopied.length} knowledge folders with ${knowledgeErrors.length} errors`);
|
|
193
196
|
} else if (knowledgeCopied.length > 0) {
|
|
194
|
-
|
|
197
|
+
const source = options.knowledge ? ` from ${options.knowledge}` : '';
|
|
198
|
+
knowledgeSpinner.succeed(`Installed knowledge${source}: ${knowledgeCopied.join(', ')}`);
|
|
195
199
|
} else {
|
|
196
200
|
knowledgeSpinner.info('No knowledge to install');
|
|
197
201
|
}
|
|
198
202
|
} catch (e) {
|
|
199
203
|
knowledgeSpinner.warn('Failed to install knowledge');
|
|
204
|
+
console.error(chalk.gray(` ${e.message}`));
|
|
200
205
|
}
|
|
201
206
|
|
|
202
207
|
// Step 6: Copy scripts (graph.py, etc.)
|
package/src/utils/skills.js
CHANGED
|
@@ -272,13 +272,24 @@ export async function checkForUpdates(projectPath) {
|
|
|
272
272
|
|
|
273
273
|
/**
|
|
274
274
|
* Copy knowledge (stacks, domains) to project
|
|
275
|
+
* @param {string} projectPath - Target project path
|
|
276
|
+
* @param {string} customSource - Optional custom knowledge source path
|
|
275
277
|
*/
|
|
276
|
-
export async function copyKnowledgeToProject(projectPath) {
|
|
278
|
+
export async function copyKnowledgeToProject(projectPath, customSource = null) {
|
|
277
279
|
const targetPath = path.join(projectPath, '.claude', 'knowledge');
|
|
280
|
+
const sourcePath = customSource
|
|
281
|
+
? path.resolve(customSource)
|
|
282
|
+
: KNOWLEDGE_SOURCE;
|
|
278
283
|
|
|
279
284
|
// Check if source exists
|
|
280
|
-
if (!await fs.pathExists(
|
|
281
|
-
return {
|
|
285
|
+
if (!await fs.pathExists(sourcePath)) {
|
|
286
|
+
return {
|
|
287
|
+
copied: [],
|
|
288
|
+
errors: [{
|
|
289
|
+
name: 'knowledge',
|
|
290
|
+
error: `Source not found: ${sourcePath}`
|
|
291
|
+
}]
|
|
292
|
+
};
|
|
282
293
|
}
|
|
283
294
|
|
|
284
295
|
// Remove existing and copy fresh
|
|
@@ -289,22 +300,27 @@ export async function copyKnowledgeToProject(projectPath) {
|
|
|
289
300
|
const errors = [];
|
|
290
301
|
|
|
291
302
|
try {
|
|
292
|
-
const items = await fs.readdir(
|
|
303
|
+
const items = await fs.readdir(sourcePath);
|
|
293
304
|
|
|
294
305
|
for (const item of items) {
|
|
295
306
|
// Skip hidden files
|
|
296
307
|
if (item.startsWith('.')) continue;
|
|
297
308
|
|
|
298
|
-
const
|
|
309
|
+
const itemSourcePath = path.join(sourcePath, item);
|
|
299
310
|
const targetItemPath = path.join(targetPath, item);
|
|
300
311
|
|
|
301
312
|
try {
|
|
302
|
-
await fs.copy(
|
|
313
|
+
await fs.copy(itemSourcePath, targetItemPath);
|
|
303
314
|
copied.push(item);
|
|
304
315
|
} catch (e) {
|
|
305
316
|
errors.push({ name: item, error: e.message });
|
|
306
317
|
}
|
|
307
318
|
}
|
|
319
|
+
|
|
320
|
+
// Generate knowledge declaration file
|
|
321
|
+
if (copied.length > 0) {
|
|
322
|
+
await generateKnowledgeDeclare(targetPath);
|
|
323
|
+
}
|
|
308
324
|
} catch (e) {
|
|
309
325
|
errors.push({ name: 'knowledge', error: e.message });
|
|
310
326
|
}
|
|
@@ -312,6 +328,137 @@ export async function copyKnowledgeToProject(projectPath) {
|
|
|
312
328
|
return { copied, errors };
|
|
313
329
|
}
|
|
314
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Generate knowledge declaration file
|
|
333
|
+
* Creates _knowledge.json that maps stacks/domains to their available files
|
|
334
|
+
*/
|
|
335
|
+
async function generateKnowledgeDeclare(knowledgePath) {
|
|
336
|
+
const declaration = {
|
|
337
|
+
stacks: {},
|
|
338
|
+
domains: {},
|
|
339
|
+
generated: new Date().toISOString()
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// Scan stacks
|
|
343
|
+
const stacksPath = path.join(knowledgePath, 'stacks');
|
|
344
|
+
if (await fs.pathExists(stacksPath)) {
|
|
345
|
+
const stacks = await fs.readdir(stacksPath);
|
|
346
|
+
|
|
347
|
+
for (const stack of stacks) {
|
|
348
|
+
if (stack.startsWith('.') || stack === '_index.md') continue;
|
|
349
|
+
|
|
350
|
+
const stackPath = path.join(stacksPath, stack);
|
|
351
|
+
const stat = await fs.stat(stackPath);
|
|
352
|
+
|
|
353
|
+
if (stat.isDirectory()) {
|
|
354
|
+
// Scan files in stack folder
|
|
355
|
+
const files = await scanKnowledgeFiles(stackPath);
|
|
356
|
+
if (files.length > 0) {
|
|
357
|
+
declaration.stacks[stack] = files;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Scan domains
|
|
364
|
+
const domainsPath = path.join(knowledgePath, 'domains');
|
|
365
|
+
if (await fs.pathExists(domainsPath)) {
|
|
366
|
+
const domains = await fs.readdir(domainsPath);
|
|
367
|
+
|
|
368
|
+
for (const domain of domains) {
|
|
369
|
+
if (domain.startsWith('.') || domain === '_index.md') continue;
|
|
370
|
+
|
|
371
|
+
const domainPath = path.join(domainsPath, domain);
|
|
372
|
+
const stat = await fs.stat(domainPath);
|
|
373
|
+
|
|
374
|
+
if (stat.isDirectory()) {
|
|
375
|
+
// Scan files in domain folder
|
|
376
|
+
const files = await scanKnowledgeFiles(domainPath);
|
|
377
|
+
if (files.length > 0) {
|
|
378
|
+
declaration.domains[domain] = files;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Write declaration file
|
|
385
|
+
const declarePath = path.join(knowledgePath, '_knowledge.json');
|
|
386
|
+
await fs.writeJson(declarePath, declaration, { spaces: 2 });
|
|
387
|
+
|
|
388
|
+
// Also create a markdown version for easy reading
|
|
389
|
+
await generateKnowledgeDeclareMd(knowledgePath, declaration);
|
|
390
|
+
|
|
391
|
+
return declaration;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Scan knowledge folder and return list of files with metadata
|
|
396
|
+
*/
|
|
397
|
+
async function scanKnowledgeFiles(folderPath) {
|
|
398
|
+
const files = [];
|
|
399
|
+
|
|
400
|
+
async function scan(dir, relativePath = '') {
|
|
401
|
+
const items = await fs.readdir(dir);
|
|
402
|
+
|
|
403
|
+
for (const item of items) {
|
|
404
|
+
if (item.startsWith('.')) continue;
|
|
405
|
+
|
|
406
|
+
const itemPath = path.join(dir, item);
|
|
407
|
+
const stat = await fs.stat(itemPath);
|
|
408
|
+
const relPath = relativePath ? `${relativePath}/${item}` : item;
|
|
409
|
+
|
|
410
|
+
if (stat.isFile() && item.endsWith('.md')) {
|
|
411
|
+
files.push({
|
|
412
|
+
path: relPath,
|
|
413
|
+
name: item,
|
|
414
|
+
size: stat.size
|
|
415
|
+
});
|
|
416
|
+
} else if (stat.isDirectory()) {
|
|
417
|
+
await scan(itemPath, relPath);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
await scan(folderPath);
|
|
423
|
+
return files;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Generate markdown version of knowledge declaration
|
|
428
|
+
*/
|
|
429
|
+
async function generateKnowledgeDeclareMd(knowledgePath, declaration) {
|
|
430
|
+
let content = '# Knowledge Base Index\n\n';
|
|
431
|
+
content += `Generated: ${new Date().toLocaleString()}\n\n`;
|
|
432
|
+
content += 'This file is auto-generated. It lists all available knowledge files in this project.\n\n';
|
|
433
|
+
|
|
434
|
+
// Stacks
|
|
435
|
+
if (Object.keys(declaration.stacks).length > 0) {
|
|
436
|
+
content += '## Stacks\n\n';
|
|
437
|
+
for (const [stack, files] of Object.entries(declaration.stacks)) {
|
|
438
|
+
content += `### ${stack}\n\n`;
|
|
439
|
+
for (const file of files) {
|
|
440
|
+
content += `- \`${file.path}\`\n`;
|
|
441
|
+
}
|
|
442
|
+
content += '\n';
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Domains
|
|
447
|
+
if (Object.keys(declaration.domains).length > 0) {
|
|
448
|
+
content += '## Domains\n\n';
|
|
449
|
+
for (const [domain, files] of Object.entries(declaration.domains)) {
|
|
450
|
+
content += `### ${domain}\n\n`;
|
|
451
|
+
for (const file of files) {
|
|
452
|
+
content += `- \`${file.path}\`\n`;
|
|
453
|
+
}
|
|
454
|
+
content += '\n';
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const declarePath = path.join(knowledgePath, '_knowledge.md');
|
|
459
|
+
await fs.writeFile(declarePath, content);
|
|
460
|
+
}
|
|
461
|
+
|
|
315
462
|
/**
|
|
316
463
|
* Copy scripts (graph.py, etc.) to project
|
|
317
464
|
*/
|