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.
Files changed (187) hide show
  1. package/dist/chunk-Da8dvM5T.mjs +1 -0
  2. package/dist/cli.d.mts +1016 -0
  3. package/dist/cli.d.mts.map +1 -0
  4. package/dist/cli.mjs +36 -0
  5. package/dist/cli.mjs.map +1 -0
  6. package/dist/contentManager-8rmWJMb6.mjs +22 -0
  7. package/dist/contentManager-8rmWJMb6.mjs.map +1 -0
  8. package/dist/contentManager-Xt8N5psY.mjs +1 -0
  9. package/dist/dist-DZL34HNo.mjs +8 -0
  10. package/dist/dist-DZL34HNo.mjs.map +1 -0
  11. package/dist/dist-X_kVEzbK.mjs +1 -0
  12. package/dist/esm-8qfZdcpd.mjs +33 -0
  13. package/dist/esm-8qfZdcpd.mjs.map +1 -0
  14. package/dist/esm-BF5pvSbc.mjs +1 -0
  15. package/dist/esm-BbhxxeGF.mjs +4 -0
  16. package/dist/esm-BbhxxeGF.mjs.map +1 -0
  17. package/dist/index.d.mts +1964 -0
  18. package/dist/index.d.mts.map +1 -0
  19. package/dist/index.mjs +21 -0
  20. package/dist/index.mjs.map +1 -0
  21. package/dist/listContext7-DKXzgWdn.mjs +2 -0
  22. package/dist/listContext7-DKXzgWdn.mjs.map +1 -0
  23. package/dist/package-B4FNst2t.mjs +2 -0
  24. package/dist/package-B4FNst2t.mjs.map +1 -0
  25. package/dist/path-CuoiIaIe.mjs +2 -0
  26. package/dist/path-CuoiIaIe.mjs.map +1 -0
  27. package/dist/removeContext7-DOXrTXeI.mjs +3 -0
  28. package/dist/removeContext7-DOXrTXeI.mjs.map +1 -0
  29. package/dist/removeSkill-C-ehFexk.mjs +5 -0
  30. package/dist/removeSkill-C-ehFexk.mjs.map +1 -0
  31. package/dist/removeSkill-DWwhvzej.mjs +1 -0
  32. package/dist/runScript-Cr9RRN9y.mjs +14 -0
  33. package/dist/runScript-Cr9RRN9y.mjs.map +1 -0
  34. package/dist/search_format-DIs-1lKk.mjs +5 -0
  35. package/dist/search_format-DIs-1lKk.mjs.map +1 -0
  36. package/dist/shared-CFoY2Xhg.mjs +2 -0
  37. package/dist/shared-CFoY2Xhg.mjs.map +1 -0
  38. package/dist/skillMdManager-DP8fGZb7.mjs +7 -0
  39. package/dist/skillMdManager-DP8fGZb7.mjs.map +1 -0
  40. package/dist/unifiedSearch-CGZXw0NB.mjs +1 -0
  41. package/dist/unifiedSearch-l-lrSc9C.mjs +4 -0
  42. package/dist/unifiedSearch-l-lrSc9C.mjs.map +1 -0
  43. package/package.json +30 -16
  44. package/dist/cli.d.ts +0 -8
  45. package/dist/cli.d.ts.map +0 -1
  46. package/dist/cli.js +0 -513
  47. package/dist/cli.js.map +0 -1
  48. package/dist/commands/addContent.d.ts +0 -5
  49. package/dist/commands/addContent.d.ts.map +0 -1
  50. package/dist/commands/addContent.js +0 -88
  51. package/dist/commands/addContent.js.map +0 -1
  52. package/dist/commands/buildIndex.d.ts +0 -5
  53. package/dist/commands/buildIndex.d.ts.map +0 -1
  54. package/dist/commands/buildIndex.js +0 -16
  55. package/dist/commands/buildIndex.js.map +0 -1
  56. package/dist/commands/createSkill.d.ts +0 -6
  57. package/dist/commands/createSkill.d.ts.map +0 -1
  58. package/dist/commands/createSkill.js +0 -32
  59. package/dist/commands/createSkill.js.map +0 -1
  60. package/dist/commands/downloadContext7.d.ts +0 -5
  61. package/dist/commands/downloadContext7.d.ts.map +0 -1
  62. package/dist/commands/downloadContext7.js +0 -71
  63. package/dist/commands/downloadContext7.js.map +0 -1
  64. package/dist/commands/init.d.ts +0 -5
  65. package/dist/commands/init.d.ts.map +0 -1
  66. package/dist/commands/init.js +0 -95
  67. package/dist/commands/init.js.map +0 -1
  68. package/dist/commands/listContent.d.ts +0 -5
  69. package/dist/commands/listContent.d.ts.map +0 -1
  70. package/dist/commands/listContent.js +0 -34
  71. package/dist/commands/listContent.js.map +0 -1
  72. package/dist/commands/listContext7.d.ts +0 -5
  73. package/dist/commands/listContext7.d.ts.map +0 -1
  74. package/dist/commands/listContext7.js +0 -26
  75. package/dist/commands/listContext7.js.map +0 -1
  76. package/dist/commands/listSkills.d.ts +0 -5
  77. package/dist/commands/listSkills.d.ts.map +0 -1
  78. package/dist/commands/listSkills.js +0 -34
  79. package/dist/commands/listSkills.js.map +0 -1
  80. package/dist/commands/removeContext7.d.ts +0 -5
  81. package/dist/commands/removeContext7.d.ts.map +0 -1
  82. package/dist/commands/removeContext7.js +0 -54
  83. package/dist/commands/removeContext7.js.map +0 -1
  84. package/dist/commands/removeSkill.d.ts +0 -5
  85. package/dist/commands/removeSkill.d.ts.map +0 -1
  86. package/dist/commands/removeSkill.js +0 -83
  87. package/dist/commands/removeSkill.js.map +0 -1
  88. package/dist/commands/searchContent.d.ts +0 -5
  89. package/dist/commands/searchContent.d.ts.map +0 -1
  90. package/dist/commands/searchContent.js +0 -99
  91. package/dist/commands/searchContent.js.map +0 -1
  92. package/dist/commands/shared.d.ts +0 -21
  93. package/dist/commands/shared.d.ts.map +0 -1
  94. package/dist/commands/shared.js +0 -80
  95. package/dist/commands/shared.js.map +0 -1
  96. package/dist/core/autoSearchAdapter.d.ts +0 -42
  97. package/dist/core/autoSearchAdapter.d.ts.map +0 -1
  98. package/dist/core/autoSearchAdapter.js +0 -116
  99. package/dist/core/autoSearchAdapter.js.map +0 -1
  100. package/dist/core/chromaSearch.d.ts +0 -24
  101. package/dist/core/chromaSearch.d.ts.map +0 -1
  102. package/dist/core/chromaSearch.js +0 -194
  103. package/dist/core/chromaSearch.js.map +0 -1
  104. package/dist/core/chromaSearchAdapter.d.ts +0 -86
  105. package/dist/core/chromaSearchAdapter.d.ts.map +0 -1
  106. package/dist/core/chromaSearchAdapter.js +0 -477
  107. package/dist/core/chromaSearchAdapter.js.map +0 -1
  108. package/dist/core/chromaServerManager.d.ts +0 -64
  109. package/dist/core/chromaServerManager.d.ts.map +0 -1
  110. package/dist/core/chromaServerManager.js +0 -186
  111. package/dist/core/chromaServerManager.js.map +0 -1
  112. package/dist/core/contentManager.d.ts +0 -65
  113. package/dist/core/contentManager.d.ts.map +0 -1
  114. package/dist/core/contentManager.js +0 -533
  115. package/dist/core/contentManager.js.map +0 -1
  116. package/dist/core/fuzzySearchAdapter.d.ts +0 -33
  117. package/dist/core/fuzzySearchAdapter.d.ts.map +0 -1
  118. package/dist/core/fuzzySearchAdapter.js +0 -185
  119. package/dist/core/fuzzySearchAdapter.js.map +0 -1
  120. package/dist/core/portUtils.d.ts +0 -51
  121. package/dist/core/portUtils.d.ts.map +0 -1
  122. package/dist/core/portUtils.js +0 -120
  123. package/dist/core/portUtils.js.map +0 -1
  124. package/dist/core/runScript.d.ts +0 -5
  125. package/dist/core/runScript.d.ts.map +0 -1
  126. package/dist/core/runScript.js +0 -40
  127. package/dist/core/runScript.js.map +0 -1
  128. package/dist/core/searchAdapter.d.ts +0 -48
  129. package/dist/core/searchAdapter.d.ts.map +0 -1
  130. package/dist/core/searchAdapter.js +0 -6
  131. package/dist/core/searchAdapter.js.map +0 -1
  132. package/dist/core/searchEngineFactory.d.ts +0 -30
  133. package/dist/core/searchEngineFactory.d.ts.map +0 -1
  134. package/dist/core/searchEngineFactory.js +0 -41
  135. package/dist/core/searchEngineFactory.js.map +0 -1
  136. package/dist/core/skillCreator.d.ts +0 -12
  137. package/dist/core/skillCreator.d.ts.map +0 -1
  138. package/dist/core/skillCreator.js +0 -75
  139. package/dist/core/skillCreator.js.map +0 -1
  140. package/dist/core/templateManager.d.ts +0 -28
  141. package/dist/core/templateManager.d.ts.map +0 -1
  142. package/dist/core/templateManager.js +0 -583
  143. package/dist/core/templateManager.js.map +0 -1
  144. package/dist/core/unifiedSearch.d.ts +0 -69
  145. package/dist/core/unifiedSearch.d.ts.map +0 -1
  146. package/dist/core/unifiedSearch.js +0 -105
  147. package/dist/core/unifiedSearch.js.map +0 -1
  148. package/dist/index.d.ts +0 -13
  149. package/dist/index.d.ts.map +0 -1
  150. package/dist/index.js +0 -11
  151. package/dist/index.js.map +0 -1
  152. package/dist/search_format/enhancedFormatter.d.ts +0 -109
  153. package/dist/search_format/enhancedFormatter.d.ts.map +0 -1
  154. package/dist/search_format/enhancedFormatter.js +0 -262
  155. package/dist/search_format/enhancedFormatter.js.map +0 -1
  156. package/dist/search_format/index.d.ts +0 -10
  157. package/dist/search_format/index.d.ts.map +0 -1
  158. package/dist/search_format/index.js +0 -22
  159. package/dist/search_format/index.js.map +0 -1
  160. package/dist/search_format/listFormatter.d.ts +0 -16
  161. package/dist/search_format/listFormatter.d.ts.map +0 -1
  162. package/dist/search_format/listFormatter.js +0 -51
  163. package/dist/search_format/listFormatter.js.map +0 -1
  164. package/dist/search_format/types.d.ts +0 -69
  165. package/dist/search_format/types.d.ts.map +0 -1
  166. package/dist/search_format/types.js +0 -5
  167. package/dist/search_format/types.js.map +0 -1
  168. package/dist/types/index.d.ts +0 -74
  169. package/dist/types/index.d.ts.map +0 -1
  170. package/dist/types/index.js +0 -2
  171. package/dist/types/index.js.map +0 -1
  172. package/dist/utils/claudeCodeDetection.d.ts +0 -27
  173. package/dist/utils/claudeCodeDetection.d.ts.map +0 -1
  174. package/dist/utils/claudeCodeDetection.js +0 -81
  175. package/dist/utils/claudeCodeDetection.js.map +0 -1
  176. package/dist/utils/config.d.ts +0 -23
  177. package/dist/utils/config.d.ts.map +0 -1
  178. package/dist/utils/config.js +0 -41
  179. package/dist/utils/config.js.map +0 -1
  180. package/dist/utils/package.d.ts +0 -88
  181. package/dist/utils/package.d.ts.map +0 -1
  182. package/dist/utils/package.js +0 -221
  183. package/dist/utils/package.js.map +0 -1
  184. package/dist/utils/skillMdManager.d.ts +0 -44
  185. package/dist/utils/skillMdManager.d.ts.map +0 -1
  186. package/dist/utils/skillMdManager.js +0 -157
  187. 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":"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"}
@@ -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