skill-creator 1.4.2 → 1.5.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.
- package/dist/chunk-Da8dvM5T.mjs +1 -0
- package/dist/cli.d.mts +1016 -0
- package/dist/cli.d.mts.map +1 -0
- package/dist/cli.mjs +36 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/contentManager-8rmWJMb6.mjs +22 -0
- package/dist/contentManager-8rmWJMb6.mjs.map +1 -0
- package/dist/contentManager-Xt8N5psY.mjs +1 -0
- package/dist/dist-DZL34HNo.mjs +8 -0
- package/dist/dist-DZL34HNo.mjs.map +1 -0
- package/dist/dist-X_kVEzbK.mjs +1 -0
- package/dist/esm-8qfZdcpd.mjs +33 -0
- package/dist/esm-8qfZdcpd.mjs.map +1 -0
- package/dist/esm-BF5pvSbc.mjs +1 -0
- package/dist/esm-BbhxxeGF.mjs +4 -0
- package/dist/esm-BbhxxeGF.mjs.map +1 -0
- package/dist/index.d.mts +1964 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +21 -0
- package/dist/index.mjs.map +1 -0
- package/dist/listContext7-DKXzgWdn.mjs +2 -0
- package/dist/listContext7-DKXzgWdn.mjs.map +1 -0
- package/dist/package-B4FNst2t.mjs +2 -0
- package/dist/package-B4FNst2t.mjs.map +1 -0
- package/dist/path-CuoiIaIe.mjs +2 -0
- package/dist/path-CuoiIaIe.mjs.map +1 -0
- package/dist/removeContext7-DOXrTXeI.mjs +3 -0
- package/dist/removeContext7-DOXrTXeI.mjs.map +1 -0
- package/dist/removeSkill-C-ehFexk.mjs +5 -0
- package/dist/removeSkill-C-ehFexk.mjs.map +1 -0
- package/dist/removeSkill-DWwhvzej.mjs +1 -0
- package/dist/runScript-Cr9RRN9y.mjs +14 -0
- package/dist/runScript-Cr9RRN9y.mjs.map +1 -0
- package/dist/search_format-DIs-1lKk.mjs +5 -0
- package/dist/search_format-DIs-1lKk.mjs.map +1 -0
- package/dist/shared-CFoY2Xhg.mjs +2 -0
- package/dist/shared-CFoY2Xhg.mjs.map +1 -0
- package/dist/skillMdManager-DP8fGZb7.mjs +7 -0
- package/dist/skillMdManager-DP8fGZb7.mjs.map +1 -0
- package/dist/unifiedSearch-CGZXw0NB.mjs +1 -0
- package/dist/unifiedSearch-l-lrSc9C.mjs +4 -0
- package/dist/unifiedSearch-l-lrSc9C.mjs.map +1 -0
- package/package.json +30 -16
- package/dist/cli.d.ts +0 -8
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -513
- package/dist/cli.js.map +0 -1
- package/dist/commands/addContent.d.ts +0 -5
- package/dist/commands/addContent.d.ts.map +0 -1
- package/dist/commands/addContent.js +0 -88
- package/dist/commands/addContent.js.map +0 -1
- package/dist/commands/buildIndex.d.ts +0 -5
- package/dist/commands/buildIndex.d.ts.map +0 -1
- package/dist/commands/buildIndex.js +0 -16
- package/dist/commands/buildIndex.js.map +0 -1
- package/dist/commands/createSkill.d.ts +0 -6
- package/dist/commands/createSkill.d.ts.map +0 -1
- package/dist/commands/createSkill.js +0 -32
- package/dist/commands/createSkill.js.map +0 -1
- package/dist/commands/downloadContext7.d.ts +0 -5
- package/dist/commands/downloadContext7.d.ts.map +0 -1
- package/dist/commands/downloadContext7.js +0 -71
- package/dist/commands/downloadContext7.js.map +0 -1
- package/dist/commands/init.d.ts +0 -5
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -95
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/listContent.d.ts +0 -5
- package/dist/commands/listContent.d.ts.map +0 -1
- package/dist/commands/listContent.js +0 -34
- package/dist/commands/listContent.js.map +0 -1
- package/dist/commands/listContext7.d.ts +0 -5
- package/dist/commands/listContext7.d.ts.map +0 -1
- package/dist/commands/listContext7.js +0 -26
- package/dist/commands/listContext7.js.map +0 -1
- package/dist/commands/listSkills.d.ts +0 -5
- package/dist/commands/listSkills.d.ts.map +0 -1
- package/dist/commands/listSkills.js +0 -34
- package/dist/commands/listSkills.js.map +0 -1
- package/dist/commands/removeContext7.d.ts +0 -5
- package/dist/commands/removeContext7.d.ts.map +0 -1
- package/dist/commands/removeContext7.js +0 -54
- package/dist/commands/removeContext7.js.map +0 -1
- package/dist/commands/removeSkill.d.ts +0 -5
- package/dist/commands/removeSkill.d.ts.map +0 -1
- package/dist/commands/removeSkill.js +0 -83
- package/dist/commands/removeSkill.js.map +0 -1
- package/dist/commands/searchContent.d.ts +0 -5
- package/dist/commands/searchContent.d.ts.map +0 -1
- package/dist/commands/searchContent.js +0 -99
- package/dist/commands/searchContent.js.map +0 -1
- package/dist/commands/shared.d.ts +0 -21
- package/dist/commands/shared.d.ts.map +0 -1
- package/dist/commands/shared.js +0 -80
- package/dist/commands/shared.js.map +0 -1
- package/dist/core/autoSearchAdapter.d.ts +0 -42
- package/dist/core/autoSearchAdapter.d.ts.map +0 -1
- package/dist/core/autoSearchAdapter.js +0 -116
- package/dist/core/autoSearchAdapter.js.map +0 -1
- package/dist/core/chromaSearch.d.ts +0 -24
- package/dist/core/chromaSearch.d.ts.map +0 -1
- package/dist/core/chromaSearch.js +0 -194
- package/dist/core/chromaSearch.js.map +0 -1
- package/dist/core/chromaSearchAdapter.d.ts +0 -86
- package/dist/core/chromaSearchAdapter.d.ts.map +0 -1
- package/dist/core/chromaSearchAdapter.js +0 -477
- package/dist/core/chromaSearchAdapter.js.map +0 -1
- package/dist/core/chromaServerManager.d.ts +0 -64
- package/dist/core/chromaServerManager.d.ts.map +0 -1
- package/dist/core/chromaServerManager.js +0 -186
- package/dist/core/chromaServerManager.js.map +0 -1
- package/dist/core/contentManager.d.ts +0 -65
- package/dist/core/contentManager.d.ts.map +0 -1
- package/dist/core/contentManager.js +0 -533
- package/dist/core/contentManager.js.map +0 -1
- package/dist/core/fuzzySearchAdapter.d.ts +0 -33
- package/dist/core/fuzzySearchAdapter.d.ts.map +0 -1
- package/dist/core/fuzzySearchAdapter.js +0 -185
- package/dist/core/fuzzySearchAdapter.js.map +0 -1
- package/dist/core/portUtils.d.ts +0 -51
- package/dist/core/portUtils.d.ts.map +0 -1
- package/dist/core/portUtils.js +0 -120
- package/dist/core/portUtils.js.map +0 -1
- package/dist/core/runScript.d.ts +0 -5
- package/dist/core/runScript.d.ts.map +0 -1
- package/dist/core/runScript.js +0 -40
- package/dist/core/runScript.js.map +0 -1
- package/dist/core/searchAdapter.d.ts +0 -48
- package/dist/core/searchAdapter.d.ts.map +0 -1
- package/dist/core/searchAdapter.js +0 -6
- package/dist/core/searchAdapter.js.map +0 -1
- package/dist/core/searchEngineFactory.d.ts +0 -30
- package/dist/core/searchEngineFactory.d.ts.map +0 -1
- package/dist/core/searchEngineFactory.js +0 -41
- package/dist/core/searchEngineFactory.js.map +0 -1
- package/dist/core/skillCreator.d.ts +0 -12
- package/dist/core/skillCreator.d.ts.map +0 -1
- package/dist/core/skillCreator.js +0 -75
- package/dist/core/skillCreator.js.map +0 -1
- package/dist/core/templateManager.d.ts +0 -28
- package/dist/core/templateManager.d.ts.map +0 -1
- package/dist/core/templateManager.js +0 -583
- package/dist/core/templateManager.js.map +0 -1
- package/dist/core/unifiedSearch.d.ts +0 -69
- package/dist/core/unifiedSearch.d.ts.map +0 -1
- package/dist/core/unifiedSearch.js +0 -105
- package/dist/core/unifiedSearch.js.map +0 -1
- package/dist/index.d.ts +0 -13
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -11
- package/dist/index.js.map +0 -1
- package/dist/search_format/enhancedFormatter.d.ts +0 -109
- package/dist/search_format/enhancedFormatter.d.ts.map +0 -1
- package/dist/search_format/enhancedFormatter.js +0 -262
- package/dist/search_format/enhancedFormatter.js.map +0 -1
- package/dist/search_format/index.d.ts +0 -10
- package/dist/search_format/index.d.ts.map +0 -1
- package/dist/search_format/index.js +0 -22
- package/dist/search_format/index.js.map +0 -1
- package/dist/search_format/listFormatter.d.ts +0 -16
- package/dist/search_format/listFormatter.d.ts.map +0 -1
- package/dist/search_format/listFormatter.js +0 -51
- package/dist/search_format/listFormatter.js.map +0 -1
- package/dist/search_format/types.d.ts +0 -69
- package/dist/search_format/types.d.ts.map +0 -1
- package/dist/search_format/types.js +0 -5
- package/dist/search_format/types.js.map +0 -1
- package/dist/types/index.d.ts +0 -74
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -2
- package/dist/types/index.js.map +0 -1
- package/dist/utils/claudeCodeDetection.d.ts +0 -27
- package/dist/utils/claudeCodeDetection.d.ts.map +0 -1
- package/dist/utils/claudeCodeDetection.js +0 -81
- package/dist/utils/claudeCodeDetection.js.map +0 -1
- package/dist/utils/config.d.ts +0 -23
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js +0 -41
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/package.d.ts +0 -88
- package/dist/utils/package.d.ts.map +0 -1
- package/dist/utils/package.js +0 -221
- package/dist/utils/package.js.map +0 -1
- package/dist/utils/skillMdManager.d.ts +0 -44
- package/dist/utils/skillMdManager.d.ts.map +0 -1
- package/dist/utils/skillMdManager.js +0 -157
- package/dist/utils/skillMdManager.js.map +0 -1
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main skill creator class
|
|
3
|
-
*/
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { existsSync, mkdirSync, writeFileSync, readdirSync, readFileSync } from 'node:fs';
|
|
6
|
-
export class SkillCreator {
|
|
7
|
-
templateDir;
|
|
8
|
-
constructor() {
|
|
9
|
-
this.templateDir = join(import.meta.dirname, '../../templates');
|
|
10
|
-
}
|
|
11
|
-
async createSkill(options) {
|
|
12
|
-
const result = {
|
|
13
|
-
created: false,
|
|
14
|
-
message: '',
|
|
15
|
-
};
|
|
16
|
-
try {
|
|
17
|
-
// Create skill directory
|
|
18
|
-
const skillDir = join(options.baseDir, options.skillDirname);
|
|
19
|
-
if (existsSync(skillDir)) {
|
|
20
|
-
const files = readdirSync(skillDir);
|
|
21
|
-
// Filter out .gitkeep files
|
|
22
|
-
const realFiles = files.filter((f) => f !== '.gitkeep');
|
|
23
|
-
if (realFiles.length > 0 && !options.force) {
|
|
24
|
-
result.message = `Skill directory already exists and is not empty: ${skillDir}`;
|
|
25
|
-
return result;
|
|
26
|
-
}
|
|
27
|
-
else if (realFiles.length > 0 && options.force) {
|
|
28
|
-
console.log(`⚠️ Skill directory exists, forcing overwrite of existing files: ${skillDir}`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
mkdirSync(skillDir, { recursive: true });
|
|
32
|
-
// Create directory structure
|
|
33
|
-
this.createDirectoryStructure(skillDir);
|
|
34
|
-
// Create SKILL.md from template
|
|
35
|
-
await this.createSkillMdFromTemplate(skillDir, options);
|
|
36
|
-
result.created = true;
|
|
37
|
-
result.skillPath = skillDir;
|
|
38
|
-
result.message = `Skill created successfully: ${skillDir}`;
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
result.message = `Failed to create skill: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}`;
|
|
43
|
-
return result;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
createDirectoryStructure(skillDir) {
|
|
47
|
-
const dirs = [
|
|
48
|
-
'assets/references/context7', // Base directory for all context7 projects
|
|
49
|
-
'assets/references/user', // User-created content
|
|
50
|
-
'assets/chroma_db', // ChromaDB data
|
|
51
|
-
'assets/logs', // Logs
|
|
52
|
-
];
|
|
53
|
-
for (const dir of dirs) {
|
|
54
|
-
const dirPath = join(skillDir, dir);
|
|
55
|
-
mkdirSync(dirPath, { recursive: true });
|
|
56
|
-
// Only add .gitkeep to empty directories that should exist
|
|
57
|
-
writeFileSync(join(dirPath, '.gitkeep'), '');
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
async createSkillMdFromTemplate(skillDir, options) {
|
|
61
|
-
const templatePath = join(this.templateDir, 'SKILL.md');
|
|
62
|
-
if (!existsSync(templatePath)) {
|
|
63
|
-
throw new Error(`SKILL.md template not found at ${templatePath}`);
|
|
64
|
-
}
|
|
65
|
-
let templateContent = readFileSync(templatePath, 'utf-8');
|
|
66
|
-
// Replace template variables with options data
|
|
67
|
-
templateContent = templateContent
|
|
68
|
-
.replace(/{{NAME}}/g, options.skillName)
|
|
69
|
-
.replace(/{{DESCRIPTION}}/g, options.skillDescription ||
|
|
70
|
-
`Specialized ${options.skillName} expert assistant providing comprehensive technical support`)
|
|
71
|
-
.replace(/{{SKILL_PATH}}/g, skillDir);
|
|
72
|
-
writeFileSync(join(skillDir, 'SKILL.md'), templateContent);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
//# sourceMappingURL=skillCreator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skillCreator.js","sourceRoot":"","sources":["../../src/core/skillCreator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAW,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAa,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAWpG,MAAM,OAAO,YAAY;IACf,WAAW,CAAQ;IAE3B;QACE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAA;IACjE,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAA2B;QAC3C,MAAM,MAAM,GAAsB;YAChC,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,EAAE;SACZ,CAAA;QAED,IAAI,CAAC;YACH,yBAAyB;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;YAE5D,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;gBACnC,4BAA4B;gBAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,CAAA;gBACvD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;oBAC3C,MAAM,CAAC,OAAO,GAAG,oDAAoD,QAAQ,EAAE,CAAA;oBAC/E,OAAO,MAAM,CAAA;gBACf,CAAC;qBAAM,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;oBACjD,OAAO,CAAC,GAAG,CACT,oEAAoE,QAAQ,EAAE,CAC/E,CAAA;gBACH,CAAC;YACH,CAAC;YAED,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAExC,6BAA6B;YAC7B,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAA;YAEvC,gCAAgC;YAChC,MAAM,IAAI,CAAC,yBAAyB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAEvD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;YACrB,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAA;YAC3B,MAAM,CAAC,OAAO,GAAG,+BAA+B,QAAQ,EAAE,CAAA;YAE1D,OAAO,MAAM,CAAA;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,OAAO,GAAG,2BAA2B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;YACrH,OAAO,MAAM,CAAA;QACf,CAAC;IACH,CAAC;IAEO,wBAAwB,CAAC,QAAgB;QAC/C,MAAM,IAAI,GAAG;YACX,4BAA4B,EAAE,2CAA2C;YACzE,wBAAwB,EAAE,uBAAuB;YACjD,kBAAkB,EAAE,gBAAgB;YACpC,aAAa,EAAE,OAAO;SACvB,CAAA;QAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;YACnC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YACvC,2DAA2D;YAC3D,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,yBAAyB,CACrC,QAAgB,EAChB,OAA2B;QAE3B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;QAEvD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,kCAAkC,YAAY,EAAE,CAAC,CAAA;QACnE,CAAC;QAED,IAAI,eAAe,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QAEzD,+CAA+C;QAC/C,eAAe,GAAG,eAAe;aAC9B,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC;aACvC,OAAO,CACN,kBAAkB,EAClB,OAAO,CAAC,gBAAgB;YACtB,eAAe,OAAO,CAAC,SAAS,6DAA6D,CAChG;aACA,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAA;QAEvC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,eAAe,CAAC,CAAA;IAC5D,CAAC;CACF"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Template system for framework-specific skill enhancements
|
|
3
|
-
*/
|
|
4
|
-
import type { SkillConfig } from '../types/index.js';
|
|
5
|
-
export interface FrameworkTemplate {
|
|
6
|
-
name: string;
|
|
7
|
-
description: string;
|
|
8
|
-
context7Ids?: string[];
|
|
9
|
-
additionalDependencies?: Record<string, string>;
|
|
10
|
-
additionalScripts?: Record<string, string>;
|
|
11
|
-
postCreateScript?: string;
|
|
12
|
-
}
|
|
13
|
-
export declare class TemplateManager {
|
|
14
|
-
private templatesDir;
|
|
15
|
-
private templates;
|
|
16
|
-
constructor();
|
|
17
|
-
private loadTemplates;
|
|
18
|
-
getTemplate(name: string): FrameworkTemplate | undefined;
|
|
19
|
-
getAllTemplates(): FrameworkTemplate[];
|
|
20
|
-
detectFramework(packageName: string): FrameworkTemplate | null;
|
|
21
|
-
applyTemplate(template: FrameworkTemplate, skillPath: string, config: SkillConfig): void;
|
|
22
|
-
private generateFrameworkScripts;
|
|
23
|
-
private createExpressServerExample;
|
|
24
|
-
private createTypeormEntityGenerator;
|
|
25
|
-
private createPrismaSchemaGenerator;
|
|
26
|
-
private createReactExampleScripts;
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=templateManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"templateManager.d.ts","sourceRoot":"","sources":["../../src/core/templateManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAExE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,SAAS,CAA4C;;IAS7D,OAAO,CAAC,aAAa;IAyHrB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIxD,eAAe,IAAI,iBAAiB,EAAE;IAItC,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAoC9D,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAiCxF,OAAO,CAAC,wBAAwB;IAkBhC,OAAO,CAAC,0BAA0B;IAiClC,OAAO,CAAC,4BAA4B;IAsGpC,OAAO,CAAC,2BAA2B;IAgGnC,OAAO,CAAC,yBAAyB;CAmJlC"}
|
|
@@ -1,583 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Template system for framework-specific skill enhancements
|
|
3
|
-
*/
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { existsSync, writeFileSync, mkdirSync, chmodSync, readFileSync } from 'node:fs';
|
|
6
|
-
export class TemplateManager {
|
|
7
|
-
templatesDir;
|
|
8
|
-
templates = new Map();
|
|
9
|
-
constructor() {
|
|
10
|
-
const __filename = new URL(import.meta.url).pathname;
|
|
11
|
-
const __dirname = join(__filename, '..');
|
|
12
|
-
this.templatesDir = join(__dirname, 'templates', 'frameworks');
|
|
13
|
-
this.loadTemplates();
|
|
14
|
-
}
|
|
15
|
-
loadTemplates() {
|
|
16
|
-
// Define built-in templates
|
|
17
|
-
this.templates.set('react', {
|
|
18
|
-
name: 'React',
|
|
19
|
-
description: 'React JavaScript library for building user interfaces',
|
|
20
|
-
context7Ids: ['/react/docs', '/reactjs/react/docs'],
|
|
21
|
-
additionalDependencies: {
|
|
22
|
-
'@types/react': '^18.2.0',
|
|
23
|
-
'@types/react-dom': '^18.2.0',
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
this.templates.set('vue', {
|
|
27
|
-
name: 'Vue.js',
|
|
28
|
-
description: 'Progressive JavaScript framework',
|
|
29
|
-
context7Ids: ['/vuejs/core/docs', '/vuejs/vue/docs'],
|
|
30
|
-
additionalDependencies: {
|
|
31
|
-
'@types/node': '^20.0.0',
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
this.templates.set('angular', {
|
|
35
|
-
name: 'Angular',
|
|
36
|
-
description: 'Platform for building mobile and desktop web applications',
|
|
37
|
-
context7Ids: ['/angular/angular/docs'],
|
|
38
|
-
additionalDependencies: {
|
|
39
|
-
'@angular/common': '^17.0.0',
|
|
40
|
-
'@angular/core': '^17.0.0',
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
this.templates.set('express', {
|
|
44
|
-
name: 'Express.js',
|
|
45
|
-
description: 'Fast, unopinionated, minimalist web framework for Node.js',
|
|
46
|
-
context7Ids: ['/expressjs/express/docs'],
|
|
47
|
-
additionalDependencies: {
|
|
48
|
-
'@types/express': '^4.17.0',
|
|
49
|
-
cors: '^2.8.5',
|
|
50
|
-
helmet: '^7.0.0',
|
|
51
|
-
},
|
|
52
|
-
additionalScripts: {
|
|
53
|
-
'server-example': 'node scripts/server-example.js',
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
this.templates.set('nextjs', {
|
|
57
|
-
name: 'Next.js',
|
|
58
|
-
description: 'The React Framework for Production',
|
|
59
|
-
context7Ids: ['/vercel/next.js/docs'],
|
|
60
|
-
additionalDependencies: {
|
|
61
|
-
next: '^14.0.0',
|
|
62
|
-
react: '^18.0.0',
|
|
63
|
-
'react-dom': '^18.0.0',
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
this.templates.set('tanstack', {
|
|
67
|
-
name: 'TanStack',
|
|
68
|
-
description: 'Quality open-source software for web developers',
|
|
69
|
-
context7Ids: [
|
|
70
|
-
'/tanstack/query/docs',
|
|
71
|
-
'/tanstack/router/docs',
|
|
72
|
-
'/tanstack/table/docs',
|
|
73
|
-
'/tanstack/react-store/docs',
|
|
74
|
-
],
|
|
75
|
-
additionalDependencies: {
|
|
76
|
-
'@tanstack/react-query': '^5.0.0',
|
|
77
|
-
'@tanstack/react-router': '^1.0.0',
|
|
78
|
-
'@tanstack/react-table': '^8.0.0',
|
|
79
|
-
},
|
|
80
|
-
});
|
|
81
|
-
this.templates.set('typeorm', {
|
|
82
|
-
name: 'TypeORM',
|
|
83
|
-
description: 'Modern ORM for TypeScript and JavaScript',
|
|
84
|
-
context7Ids: ['/typeorm/typeorm/docs'],
|
|
85
|
-
additionalDependencies: {
|
|
86
|
-
typeorm: '^0.3.17',
|
|
87
|
-
'reflect-metadata': '^0.1.13',
|
|
88
|
-
},
|
|
89
|
-
additionalScripts: {
|
|
90
|
-
'generate-entity': 'node scripts/generate-entity.js',
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
this.templates.set('prisma', {
|
|
94
|
-
name: 'Prisma',
|
|
95
|
-
description: 'Next-generation Node.js and TypeScript ORM',
|
|
96
|
-
context7Ids: ['/prisma/prisma/docs'],
|
|
97
|
-
additionalDependencies: {
|
|
98
|
-
'@prisma/client': '^5.0.0',
|
|
99
|
-
prisma: '^5.0.0',
|
|
100
|
-
},
|
|
101
|
-
additionalScripts: {
|
|
102
|
-
'generate-schema': 'node scripts/generate-schema.js',
|
|
103
|
-
},
|
|
104
|
-
});
|
|
105
|
-
this.templates.set('nestjs', {
|
|
106
|
-
name: 'NestJS',
|
|
107
|
-
description: 'A progressive Node.js framework for building efficient applications',
|
|
108
|
-
context7Ids: ['/nestjs/nest/docs'],
|
|
109
|
-
additionalDependencies: {
|
|
110
|
-
'@nestjs/core': '^10.0.0',
|
|
111
|
-
'@nestjs/common': '^10.0.0',
|
|
112
|
-
'@nestjs/platform-express': '^10.0.0',
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
this.templates.set('fastify', {
|
|
116
|
-
name: 'Fastify',
|
|
117
|
-
description: 'Fast and low overhead web framework, for Node.js',
|
|
118
|
-
context7Ids: ['/fastify/fastify/docs'],
|
|
119
|
-
additionalDependencies: {
|
|
120
|
-
fastify: '^4.0.0',
|
|
121
|
-
'@fastify/cors': '^8.0.0',
|
|
122
|
-
'@fastify/helmet': '^11.0.0',
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
getTemplate(name) {
|
|
127
|
-
return this.templates.get(name.toLowerCase());
|
|
128
|
-
}
|
|
129
|
-
getAllTemplates() {
|
|
130
|
-
return Array.from(this.templates.values());
|
|
131
|
-
}
|
|
132
|
-
detectFramework(packageName) {
|
|
133
|
-
const keywords = packageName
|
|
134
|
-
.toLowerCase()
|
|
135
|
-
.replace(/[^a-z0-9]/g, ' ')
|
|
136
|
-
.split(/\s+/);
|
|
137
|
-
for (const [templateName, template] of this.templates) {
|
|
138
|
-
// Check if template name matches package keywords
|
|
139
|
-
if (keywords.includes(templateName)) {
|
|
140
|
-
return template;
|
|
141
|
-
}
|
|
142
|
-
// Check for common aliases
|
|
143
|
-
const aliases = {
|
|
144
|
-
react: ['react', 'reactjs', 'react-dom'],
|
|
145
|
-
vue: ['vue', 'vuejs'],
|
|
146
|
-
angular: ['angular', 'angularjs', '@angular'],
|
|
147
|
-
express: ['express', 'expressjs'],
|
|
148
|
-
nextjs: ['next', 'nextjs', '@next'],
|
|
149
|
-
tanstack: ['tanstack', '@tanstack'],
|
|
150
|
-
typeorm: ['typeorm', '@typeorm'],
|
|
151
|
-
prisma: ['prisma', '@prisma'],
|
|
152
|
-
nestjs: ['nestjs', '@nestjs'],
|
|
153
|
-
fastify: ['fastify', '@fastify'],
|
|
154
|
-
};
|
|
155
|
-
for (const [key, values] of Object.entries(aliases)) {
|
|
156
|
-
if (key === templateName && values.some((v) => keywords.includes(v))) {
|
|
157
|
-
return template;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
applyTemplate(template, skillPath, config) {
|
|
164
|
-
// Update package.json with additional dependencies
|
|
165
|
-
if (template.additionalDependencies) {
|
|
166
|
-
const packageJsonPath = join(skillPath, 'package.json');
|
|
167
|
-
if (existsSync(packageJsonPath)) {
|
|
168
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
169
|
-
packageJson.dependencies = {
|
|
170
|
-
...packageJson.dependencies,
|
|
171
|
-
...template.additionalDependencies,
|
|
172
|
-
};
|
|
173
|
-
// Add additional scripts
|
|
174
|
-
if (template.additionalScripts) {
|
|
175
|
-
packageJson.scripts = {
|
|
176
|
-
...packageJson.scripts,
|
|
177
|
-
...template.additionalScripts,
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
// Create additional script files
|
|
184
|
-
if (template.additionalScripts) {
|
|
185
|
-
const scriptsDir = join(skillPath, 'scripts');
|
|
186
|
-
mkdirSync(scriptsDir, { recursive: true });
|
|
187
|
-
// Generate framework-specific scripts
|
|
188
|
-
this.generateFrameworkScripts(template.name.toLowerCase(), scriptsDir);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
generateFrameworkScripts(framework, scriptsDir) {
|
|
192
|
-
switch (framework) {
|
|
193
|
-
case 'express':
|
|
194
|
-
this.createExpressServerExample(scriptsDir);
|
|
195
|
-
break;
|
|
196
|
-
case 'typeorm':
|
|
197
|
-
this.createTypeormEntityGenerator(scriptsDir);
|
|
198
|
-
break;
|
|
199
|
-
case 'prisma':
|
|
200
|
-
this.createPrismaSchemaGenerator(scriptsDir);
|
|
201
|
-
break;
|
|
202
|
-
case 'react':
|
|
203
|
-
case 'nextjs':
|
|
204
|
-
this.createReactExampleScripts(scriptsDir);
|
|
205
|
-
break;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
createExpressServerExample(scriptsDir) {
|
|
209
|
-
const content = `#!/usr/bin/env node
|
|
210
|
-
/**
|
|
211
|
-
* Example Express server setup
|
|
212
|
-
*/
|
|
213
|
-
|
|
214
|
-
const express = require('express')
|
|
215
|
-
const cors = require('cors')
|
|
216
|
-
const helmet = require('helmet')
|
|
217
|
-
|
|
218
|
-
const app = express()
|
|
219
|
-
const PORT = process.env.PORT || 3000
|
|
220
|
-
|
|
221
|
-
// Middleware
|
|
222
|
-
app.use(helmet())
|
|
223
|
-
app.use(cors())
|
|
224
|
-
app.use(express.json())
|
|
225
|
-
|
|
226
|
-
// Routes
|
|
227
|
-
app.get('/', (req, res) => {
|
|
228
|
-
res.json({ message: 'Express server is running!' })
|
|
229
|
-
})
|
|
230
|
-
|
|
231
|
-
// Start server
|
|
232
|
-
app.listen(PORT, () => {
|
|
233
|
-
console.log(\`Server is running on port \${PORT}\`)
|
|
234
|
-
})
|
|
235
|
-
`;
|
|
236
|
-
const serverScriptPath = join(scriptsDir, 'server-example.js');
|
|
237
|
-
writeFileSync(serverScriptPath, content);
|
|
238
|
-
chmodSync(serverScriptPath, 0o755);
|
|
239
|
-
}
|
|
240
|
-
createTypeormEntityGenerator(scriptsDir) {
|
|
241
|
-
const content = `#!/usr/bin/env node
|
|
242
|
-
/**
|
|
243
|
-
* TypeORM entity generator helper
|
|
244
|
-
*/
|
|
245
|
-
|
|
246
|
-
const inquirer = require('inquirer')
|
|
247
|
-
const fs = require('fs')
|
|
248
|
-
const path = require('path')
|
|
249
|
-
|
|
250
|
-
inquirer
|
|
251
|
-
.prompt([
|
|
252
|
-
{
|
|
253
|
-
type: 'input',
|
|
254
|
-
name: 'entityName',
|
|
255
|
-
message: 'Entity name:',
|
|
256
|
-
validate: input => input.length > 0 || 'Entity name is required'
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
type: 'checkbox',
|
|
260
|
-
name: 'columns',
|
|
261
|
-
message: 'Select columns:',
|
|
262
|
-
choices: [
|
|
263
|
-
{ name: 'id (primary key)', value: 'id', checked: true },
|
|
264
|
-
{ name: 'createdAt', value: 'createdAt', checked: true },
|
|
265
|
-
{ name: 'updatedAt', value: 'updatedAt', checked: true },
|
|
266
|
-
{ name: 'name (string)', value: 'name' },
|
|
267
|
-
{ name: 'email (string)', value: 'email' },
|
|
268
|
-
{ name: 'description (text)', value: 'description' },
|
|
269
|
-
{ name: 'isActive (boolean)', value: 'isActive' }
|
|
270
|
-
]
|
|
271
|
-
}
|
|
272
|
-
])
|
|
273
|
-
.then(answers => {
|
|
274
|
-
const { entityName, columns } = answers
|
|
275
|
-
const className = entityName.charAt(0).toUpperCase() + entityName.slice(1)
|
|
276
|
-
|
|
277
|
-
let entity = \`import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm'
|
|
278
|
-
|
|
279
|
-
@Entity()
|
|
280
|
-
export class \${className} {\`
|
|
281
|
-
|
|
282
|
-
if (columns.includes('id')) {
|
|
283
|
-
entity += \`
|
|
284
|
-
@PrimaryGeneratedColumn()
|
|
285
|
-
id: number\`
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
if (columns.includes('name')) {
|
|
289
|
-
entity += \`
|
|
290
|
-
@Column()
|
|
291
|
-
name: string\`
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (columns.includes('email')) {
|
|
295
|
-
entity += \`
|
|
296
|
-
@Column({ unique: true })
|
|
297
|
-
email: string\`
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (columns.includes('description')) {
|
|
301
|
-
entity += \`
|
|
302
|
-
@Column('text')
|
|
303
|
-
description: string\`
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (columns.includes('isActive')) {
|
|
307
|
-
entity += \`
|
|
308
|
-
@Column({ default: true })
|
|
309
|
-
isActive: boolean\`
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
if (columns.includes('createdAt')) {
|
|
313
|
-
entity += \`
|
|
314
|
-
@CreateDateColumn()
|
|
315
|
-
createdAt: Date\`
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (columns.includes('updatedAt')) {
|
|
319
|
-
entity += \`
|
|
320
|
-
@UpdateDateColumn()
|
|
321
|
-
updatedAt: Date\`
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
entity += '\n}'
|
|
325
|
-
|
|
326
|
-
const outputPath = path.join(process.cwd(), 'src', 'entities', \`\${entityName}.ts\`)
|
|
327
|
-
|
|
328
|
-
// Ensure directory exists
|
|
329
|
-
fs.mkdirSync(path.dirname(outputPath), { recursive: true })
|
|
330
|
-
|
|
331
|
-
// Write entity file
|
|
332
|
-
fs.writeFileSync(outputPath, entity)
|
|
333
|
-
|
|
334
|
-
console.log(\`✅ Entity created: \${outputPath}\`)
|
|
335
|
-
})
|
|
336
|
-
`;
|
|
337
|
-
const entityScriptPath = join(scriptsDir, 'generate-entity.js');
|
|
338
|
-
writeFileSync(entityScriptPath, content);
|
|
339
|
-
chmodSync(entityScriptPath, 0o755);
|
|
340
|
-
}
|
|
341
|
-
createPrismaSchemaGenerator(scriptsDir) {
|
|
342
|
-
const content = `#!/usr/bin/env node
|
|
343
|
-
/**
|
|
344
|
-
* Prisma schema helper
|
|
345
|
-
*/
|
|
346
|
-
|
|
347
|
-
const inquirer = require('inquirer')
|
|
348
|
-
const fs = require('fs')
|
|
349
|
-
|
|
350
|
-
inquirer
|
|
351
|
-
.prompt([
|
|
352
|
-
{
|
|
353
|
-
type: 'input',
|
|
354
|
-
name: 'modelName',
|
|
355
|
-
message: 'Model name:',
|
|
356
|
-
validate: input => input.length > 0 || 'Model name is required'
|
|
357
|
-
},
|
|
358
|
-
{
|
|
359
|
-
type: 'checkbox',
|
|
360
|
-
name: 'fields',
|
|
361
|
-
message: 'Select fields:',
|
|
362
|
-
choices: [
|
|
363
|
-
{ name: 'id (Int @id @default(autoincrement()))', value: 'id', checked: true },
|
|
364
|
-
{ name: 'email (String @unique)', value: 'email' },
|
|
365
|
-
{ name: 'name (String)', value: 'name' },
|
|
366
|
-
{ name: 'title (String)', value: 'title' },
|
|
367
|
-
{ name: 'content (String)', value: 'content' },
|
|
368
|
-
{ name: 'published (Boolean @default(false))', value: 'published' },
|
|
369
|
-
{ name: 'createdAt (DateTime @default(now()))', value: 'createdAt', checked: true },
|
|
370
|
-
{ name: 'updatedAt (DateTime @updatedAt)', value: 'updatedAt', checked: true }
|
|
371
|
-
]
|
|
372
|
-
}
|
|
373
|
-
])
|
|
374
|
-
.then(answers => {
|
|
375
|
-
const { modelName, fields } = answers
|
|
376
|
-
const capitalizedName = modelName.charAt(0).toUpperCase() + modelName.slice(1)
|
|
377
|
-
|
|
378
|
-
let model = \`model \${capitalizedName} {\`
|
|
379
|
-
|
|
380
|
-
if (fields.includes('id')) {
|
|
381
|
-
model += '\\n id Int @id @default(autoincrement())'
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
if (fields.includes('email')) {
|
|
385
|
-
model += '\\n email String @unique'
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
if (fields.includes('name')) {
|
|
389
|
-
model += '\\n name String'
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
if (fields.includes('title')) {
|
|
393
|
-
model += '\\n title String'
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
if (fields.includes('content')) {
|
|
397
|
-
model += '\\n content String'
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
if (fields.includes('published')) {
|
|
401
|
-
model += '\\n published Boolean @default(false)'
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
if (fields.includes('createdAt')) {
|
|
405
|
-
model += '\\n createdAt DateTime @default(now())'
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (fields.includes('updatedAt')) {
|
|
409
|
-
model += '\\n updatedAt DateTime @updatedAt'
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
model += '\\n}'
|
|
413
|
-
|
|
414
|
-
const schemaPath = 'prisma/schema.prisma'
|
|
415
|
-
|
|
416
|
-
// Read existing schema or create new
|
|
417
|
-
let existingSchema = ''
|
|
418
|
-
if (fs.existsSync(schemaPath)) {
|
|
419
|
-
existingSchema = fs.readFileSync(schemaPath, 'utf-8')
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// Append model to schema
|
|
423
|
-
const updatedSchema = existingSchema + '\\n\\n' + model
|
|
424
|
-
|
|
425
|
-
fs.writeFileSync(schemaPath, updatedSchema)
|
|
426
|
-
|
|
427
|
-
console.log(\`✅ Model added to schema.prisma\`)
|
|
428
|
-
console.log('\\nRun: npx prisma migrate dev --name init')
|
|
429
|
-
console.log('Then: npx prisma generate')
|
|
430
|
-
})
|
|
431
|
-
`;
|
|
432
|
-
const schemaScriptPath = join(scriptsDir, 'generate-schema.js');
|
|
433
|
-
writeFileSync(schemaScriptPath, content);
|
|
434
|
-
chmodSync(schemaScriptPath, 0o755);
|
|
435
|
-
}
|
|
436
|
-
createReactExampleScripts(scriptsDir) {
|
|
437
|
-
// Component generator
|
|
438
|
-
const componentContent = `#!/usr/bin/env node
|
|
439
|
-
/**
|
|
440
|
-
* React component generator
|
|
441
|
-
*/
|
|
442
|
-
|
|
443
|
-
const inquirer = require('inquirer')
|
|
444
|
-
const fs = require('fs')
|
|
445
|
-
const path = require('path')
|
|
446
|
-
|
|
447
|
-
inquirer
|
|
448
|
-
.prompt([
|
|
449
|
-
{
|
|
450
|
-
type: 'input',
|
|
451
|
-
name: 'componentName',
|
|
452
|
-
message: 'Component name:',
|
|
453
|
-
validate: input => /^[A-Z][a-zA-Z0-9]*$/.test(input) || 'Component name must start with uppercase letter'
|
|
454
|
-
},
|
|
455
|
-
{
|
|
456
|
-
type: 'list',
|
|
457
|
-
name: 'componentType',
|
|
458
|
-
message: 'Component type:',
|
|
459
|
-
choices: [
|
|
460
|
-
{ name: 'Functional Component', value: 'functional' },
|
|
461
|
-
{ name: 'Functional Component with Hooks', value: 'hooks' },
|
|
462
|
-
{ name: 'TypeScript Functional Component', value: 'ts-functional' }
|
|
463
|
-
]
|
|
464
|
-
},
|
|
465
|
-
{
|
|
466
|
-
type: 'checkbox',
|
|
467
|
-
name: 'features',
|
|
468
|
-
message: 'Include features:',
|
|
469
|
-
choices: [
|
|
470
|
-
{ name: 'Props interface', value: 'props' },
|
|
471
|
-
{ name: 'React hooks (useState, useEffect)', value: 'hooks' },
|
|
472
|
-
{ name: 'CSS Modules', value: 'css' },
|
|
473
|
-
{ name: 'Storybook story', value: 'storybook' }
|
|
474
|
-
]
|
|
475
|
-
}
|
|
476
|
-
])
|
|
477
|
-
.then(answers => {
|
|
478
|
-
const { componentName, componentType, features } = answers
|
|
479
|
-
let component = ''
|
|
480
|
-
|
|
481
|
-
if (componentType.includes('ts')) {
|
|
482
|
-
component = \`import React from 'react'\`
|
|
483
|
-
|
|
484
|
-
if (features.includes('props')) {
|
|
485
|
-
component += \`
|
|
486
|
-
interface \${componentName}Props {
|
|
487
|
-
// Define props here
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
export const \${componentName}: React.FC<\${componentName}Props> = (props) => {
|
|
491
|
-
return (
|
|
492
|
-
<div className="\${componentName.toLowerCase()}">
|
|
493
|
-
<h1>\${componentName} Component</h1>
|
|
494
|
-
</div>
|
|
495
|
-
)
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
export default \${componentName}\`
|
|
499
|
-
} else {
|
|
500
|
-
component = \`
|
|
501
|
-
export const \${componentName}: React.FC = () => {
|
|
502
|
-
return (
|
|
503
|
-
<div className="\${componentName.toLowerCase()}">
|
|
504
|
-
<h1>\${componentName} Component</h1>
|
|
505
|
-
</div>
|
|
506
|
-
)
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
export default \${componentName}\`
|
|
510
|
-
}
|
|
511
|
-
} else {
|
|
512
|
-
component = \`import React from 'react'
|
|
513
|
-
|
|
514
|
-
export const \${componentName} = () => {
|
|
515
|
-
return (
|
|
516
|
-
<div className="\${componentName.toLowerCase()}">
|
|
517
|
-
<h1>\${componentName} Component</h1>
|
|
518
|
-
</div>
|
|
519
|
-
)
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
export default \${componentName}\`
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
const outputPath = path.join(process.cwd(), 'src', 'components', \`\${componentName}.tsx\`)
|
|
526
|
-
|
|
527
|
-
// Ensure directory exists
|
|
528
|
-
fs.mkdirSync(path.dirname(outputPath), { recursive: true })
|
|
529
|
-
|
|
530
|
-
// Write component file
|
|
531
|
-
fs.writeFileSync(outputPath, component)
|
|
532
|
-
|
|
533
|
-
console.log(\`✅ Component created: \${outputPath}\`)
|
|
534
|
-
|
|
535
|
-
// Create CSS module if requested
|
|
536
|
-
if (features.includes('css')) {
|
|
537
|
-
const cssContent = \`.\${componentName.toLowerCase()} {
|
|
538
|
-
/* Add your styles here */
|
|
539
|
-
padding: 1rem;
|
|
540
|
-
border: 1px solid #ddd;
|
|
541
|
-
border-radius: 4px;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
.\${componentName.toLowerCase()} h1 {
|
|
545
|
-
margin: 0 0 1rem 0;
|
|
546
|
-
font-size: 1.5rem;
|
|
547
|
-
}\`
|
|
548
|
-
|
|
549
|
-
const cssPath = outputPath.replace('.tsx', '.module.css')
|
|
550
|
-
fs.writeFileSync(cssPath, cssContent)
|
|
551
|
-
console.log(\`✅ CSS module created: \${cssPath}\`)
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
// Create Storybook story if requested
|
|
555
|
-
if (features.includes('storybook')) {
|
|
556
|
-
const storyContent = \`import type { Meta, StoryObj } from '@storybook/react'
|
|
557
|
-
import \${componentName} from './\${componentName}'
|
|
558
|
-
|
|
559
|
-
const meta: Meta<typeof \${componentName}> = {
|
|
560
|
-
title: 'Components/\${componentName}',
|
|
561
|
-
component: \${componentName},
|
|
562
|
-
tags: ['autodocs'],
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
export default meta
|
|
566
|
-
type Story = StoryObj<typeof meta>
|
|
567
|
-
|
|
568
|
-
export const Primary: Story = {}\`
|
|
569
|
-
|
|
570
|
-
const storyPath = outputPath.replace('.tsx', '.stories.tsx')
|
|
571
|
-
fs.writeFileSync(storyPath, storyContent)
|
|
572
|
-
console.log(\`✅ Storybook story created: \${storyPath}\`)
|
|
573
|
-
}
|
|
574
|
-
})
|
|
575
|
-
`;
|
|
576
|
-
const componentScriptPath = join(scriptsDir, 'generate-component.js');
|
|
577
|
-
writeFileSync(componentScriptPath, componentContent);
|
|
578
|
-
chmodSync(componentScriptPath, 0o755);
|
|
579
|
-
// Note: The package.json update is handled by the script itself
|
|
580
|
-
console.log('✅ React component generator created');
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
//# sourceMappingURL=templateManager.js.map
|