@codihaus/claude-skills 1.6.19 → 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/knowledge/stacks/nextjs/_index.md +32 -0
- package/knowledge/stacks/nextjs/references/rsc-patterns.md +705 -0
- package/knowledge/stacks/react/_index.md +21 -0
- package/knowledge/stacks/react/references/performance.md +573 -0
- 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
|
@@ -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
|
*/
|