codedev-mcp 3.2.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 (229) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/LICENSE +21 -0
  3. package/README.md +760 -0
  4. package/dist/analyzers/api-contract.d.ts +46 -0
  5. package/dist/analyzers/api-contract.d.ts.map +1 -0
  6. package/dist/analyzers/api-contract.js +319 -0
  7. package/dist/analyzers/api-contract.js.map +1 -0
  8. package/dist/analyzers/architecture.d.ts +37 -0
  9. package/dist/analyzers/architecture.d.ts.map +1 -0
  10. package/dist/analyzers/architecture.js +149 -0
  11. package/dist/analyzers/architecture.js.map +1 -0
  12. package/dist/analyzers/branch-compare.d.ts +46 -0
  13. package/dist/analyzers/branch-compare.d.ts.map +1 -0
  14. package/dist/analyzers/branch-compare.js +128 -0
  15. package/dist/analyzers/branch-compare.js.map +1 -0
  16. package/dist/analyzers/cicd.d.ts +42 -0
  17. package/dist/analyzers/cicd.d.ts.map +1 -0
  18. package/dist/analyzers/cicd.js +237 -0
  19. package/dist/analyzers/cicd.js.map +1 -0
  20. package/dist/analyzers/codebase.d.ts +64 -0
  21. package/dist/analyzers/codebase.d.ts.map +1 -0
  22. package/dist/analyzers/codebase.js +354 -0
  23. package/dist/analyzers/codebase.js.map +1 -0
  24. package/dist/analyzers/complexity-heatmap.d.ts +50 -0
  25. package/dist/analyzers/complexity-heatmap.d.ts.map +1 -0
  26. package/dist/analyzers/complexity-heatmap.js +156 -0
  27. package/dist/analyzers/complexity-heatmap.js.map +1 -0
  28. package/dist/analyzers/context-pack.d.ts +43 -0
  29. package/dist/analyzers/context-pack.d.ts.map +1 -0
  30. package/dist/analyzers/context-pack.js +232 -0
  31. package/dist/analyzers/context-pack.js.map +1 -0
  32. package/dist/analyzers/coverage.d.ts +70 -0
  33. package/dist/analyzers/coverage.d.ts.map +1 -0
  34. package/dist/analyzers/coverage.js +313 -0
  35. package/dist/analyzers/coverage.js.map +1 -0
  36. package/dist/analyzers/db-schema.d.ts +55 -0
  37. package/dist/analyzers/db-schema.d.ts.map +1 -0
  38. package/dist/analyzers/db-schema.js +237 -0
  39. package/dist/analyzers/db-schema.js.map +1 -0
  40. package/dist/analyzers/dead-code.d.ts +34 -0
  41. package/dist/analyzers/dead-code.d.ts.map +1 -0
  42. package/dist/analyzers/dead-code.js +131 -0
  43. package/dist/analyzers/dead-code.js.map +1 -0
  44. package/dist/analyzers/dep-vuln.d.ts +36 -0
  45. package/dist/analyzers/dep-vuln.d.ts.map +1 -0
  46. package/dist/analyzers/dep-vuln.js +342 -0
  47. package/dist/analyzers/dep-vuln.js.map +1 -0
  48. package/dist/analyzers/docs.d.ts +47 -0
  49. package/dist/analyzers/docs.d.ts.map +1 -0
  50. package/dist/analyzers/docs.js +473 -0
  51. package/dist/analyzers/docs.js.map +1 -0
  52. package/dist/analyzers/git.d.ts +115 -0
  53. package/dist/analyzers/git.d.ts.map +1 -0
  54. package/dist/analyzers/git.js +214 -0
  55. package/dist/analyzers/git.js.map +1 -0
  56. package/dist/analyzers/iac.d.ts +39 -0
  57. package/dist/analyzers/iac.d.ts.map +1 -0
  58. package/dist/analyzers/iac.js +233 -0
  59. package/dist/analyzers/iac.js.map +1 -0
  60. package/dist/analyzers/impact.d.ts +51 -0
  61. package/dist/analyzers/impact.d.ts.map +1 -0
  62. package/dist/analyzers/impact.js +235 -0
  63. package/dist/analyzers/impact.js.map +1 -0
  64. package/dist/analyzers/monorepo.d.ts +36 -0
  65. package/dist/analyzers/monorepo.d.ts.map +1 -0
  66. package/dist/analyzers/monorepo.js +233 -0
  67. package/dist/analyzers/monorepo.js.map +1 -0
  68. package/dist/analyzers/notebook.d.ts +53 -0
  69. package/dist/analyzers/notebook.d.ts.map +1 -0
  70. package/dist/analyzers/notebook.js +149 -0
  71. package/dist/analyzers/notebook.js.map +1 -0
  72. package/dist/analyzers/perf-profile.d.ts +39 -0
  73. package/dist/analyzers/perf-profile.d.ts.map +1 -0
  74. package/dist/analyzers/perf-profile.js +222 -0
  75. package/dist/analyzers/perf-profile.js.map +1 -0
  76. package/dist/analyzers/scaffold.d.ts +46 -0
  77. package/dist/analyzers/scaffold.d.ts.map +1 -0
  78. package/dist/analyzers/scaffold.js +313 -0
  79. package/dist/analyzers/scaffold.js.map +1 -0
  80. package/dist/analyzers/security.d.ts +42 -0
  81. package/dist/analyzers/security.d.ts.map +1 -0
  82. package/dist/analyzers/security.js +281 -0
  83. package/dist/analyzers/security.js.map +1 -0
  84. package/dist/analyzers/symbols.d.ts +49 -0
  85. package/dist/analyzers/symbols.d.ts.map +1 -0
  86. package/dist/analyzers/symbols.js +212 -0
  87. package/dist/analyzers/symbols.js.map +1 -0
  88. package/dist/analyzers/tree-sitter.d.ts +71 -0
  89. package/dist/analyzers/tree-sitter.d.ts.map +1 -0
  90. package/dist/analyzers/tree-sitter.js +333 -0
  91. package/dist/analyzers/tree-sitter.js.map +1 -0
  92. package/dist/analyzers/type-flow.d.ts +39 -0
  93. package/dist/analyzers/type-flow.d.ts.map +1 -0
  94. package/dist/analyzers/type-flow.js +75 -0
  95. package/dist/analyzers/type-flow.js.map +1 -0
  96. package/dist/cache/memory-cache.d.ts +130 -0
  97. package/dist/cache/memory-cache.d.ts.map +1 -0
  98. package/dist/cache/memory-cache.js +273 -0
  99. package/dist/cache/memory-cache.js.map +1 -0
  100. package/dist/config.d.ts +32 -0
  101. package/dist/config.d.ts.map +1 -0
  102. package/dist/config.js +57 -0
  103. package/dist/config.js.map +1 -0
  104. package/dist/constants/instructions.d.ts +2 -0
  105. package/dist/constants/instructions.d.ts.map +1 -0
  106. package/dist/constants/instructions.js +82 -0
  107. package/dist/constants/instructions.js.map +1 -0
  108. package/dist/db/connection.d.ts +12 -0
  109. package/dist/db/connection.d.ts.map +1 -0
  110. package/dist/db/connection.js +34 -0
  111. package/dist/db/connection.js.map +1 -0
  112. package/dist/db/json-store.d.ts +111 -0
  113. package/dist/db/json-store.d.ts.map +1 -0
  114. package/dist/db/json-store.js +201 -0
  115. package/dist/db/json-store.js.map +1 -0
  116. package/dist/db/sqlite-store.d.ts +153 -0
  117. package/dist/db/sqlite-store.d.ts.map +1 -0
  118. package/dist/db/sqlite-store.js +388 -0
  119. package/dist/db/sqlite-store.js.map +1 -0
  120. package/dist/index.d.ts +17 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +116 -0
  123. package/dist/index.js.map +1 -0
  124. package/dist/resources/health.d.ts +35 -0
  125. package/dist/resources/health.d.ts.map +1 -0
  126. package/dist/resources/health.js +81 -0
  127. package/dist/resources/health.js.map +1 -0
  128. package/dist/schemas/output-schemas.d.ts +517 -0
  129. package/dist/schemas/output-schemas.d.ts.map +1 -0
  130. package/dist/schemas/output-schemas.js +296 -0
  131. package/dist/schemas/output-schemas.js.map +1 -0
  132. package/dist/search/fast-search.d.ts +90 -0
  133. package/dist/search/fast-search.d.ts.map +1 -0
  134. package/dist/search/fast-search.js +387 -0
  135. package/dist/search/fast-search.js.map +1 -0
  136. package/dist/search/semantic.d.ts +26 -0
  137. package/dist/search/semantic.d.ts.map +1 -0
  138. package/dist/search/semantic.js +458 -0
  139. package/dist/search/semantic.js.map +1 -0
  140. package/dist/tools/analysis.d.ts +7 -0
  141. package/dist/tools/analysis.d.ts.map +1 -0
  142. package/dist/tools/analysis.js +491 -0
  143. package/dist/tools/analysis.js.map +1 -0
  144. package/dist/tools/architecture.d.ts +7 -0
  145. package/dist/tools/architecture.d.ts.map +1 -0
  146. package/dist/tools/architecture.js +176 -0
  147. package/dist/tools/architecture.js.map +1 -0
  148. package/dist/tools/devops.d.ts +7 -0
  149. package/dist/tools/devops.d.ts.map +1 -0
  150. package/dist/tools/devops.js +179 -0
  151. package/dist/tools/devops.js.map +1 -0
  152. package/dist/tools/docs.d.ts +7 -0
  153. package/dist/tools/docs.d.ts.map +1 -0
  154. package/dist/tools/docs.js +102 -0
  155. package/dist/tools/docs.js.map +1 -0
  156. package/dist/tools/git.d.ts +7 -0
  157. package/dist/tools/git.d.ts.map +1 -0
  158. package/dist/tools/git.js +475 -0
  159. package/dist/tools/git.js.map +1 -0
  160. package/dist/tools/nav.d.ts +7 -0
  161. package/dist/tools/nav.d.ts.map +1 -0
  162. package/dist/tools/nav.js +275 -0
  163. package/dist/tools/nav.js.map +1 -0
  164. package/dist/tools/notebook.d.ts +7 -0
  165. package/dist/tools/notebook.d.ts.map +1 -0
  166. package/dist/tools/notebook.js +102 -0
  167. package/dist/tools/notebook.js.map +1 -0
  168. package/dist/tools/performance.d.ts +7 -0
  169. package/dist/tools/performance.d.ts.map +1 -0
  170. package/dist/tools/performance.js +59 -0
  171. package/dist/tools/performance.js.map +1 -0
  172. package/dist/tools/quality.d.ts +7 -0
  173. package/dist/tools/quality.d.ts.map +1 -0
  174. package/dist/tools/quality.js +279 -0
  175. package/dist/tools/quality.js.map +1 -0
  176. package/dist/tools/scaffold.d.ts +7 -0
  177. package/dist/tools/scaffold.d.ts.map +1 -0
  178. package/dist/tools/scaffold.js +80 -0
  179. package/dist/tools/scaffold.js.map +1 -0
  180. package/dist/tools/search.d.ts +7 -0
  181. package/dist/tools/search.d.ts.map +1 -0
  182. package/dist/tools/search.js +308 -0
  183. package/dist/tools/search.js.map +1 -0
  184. package/dist/tools/security.d.ts +7 -0
  185. package/dist/tools/security.d.ts.map +1 -0
  186. package/dist/tools/security.js +138 -0
  187. package/dist/tools/security.js.map +1 -0
  188. package/dist/utils/analytics.d.ts +69 -0
  189. package/dist/utils/analytics.d.ts.map +1 -0
  190. package/dist/utils/analytics.js +144 -0
  191. package/dist/utils/analytics.js.map +1 -0
  192. package/dist/utils/concurrency.d.ts +43 -0
  193. package/dist/utils/concurrency.d.ts.map +1 -0
  194. package/dist/utils/concurrency.js +78 -0
  195. package/dist/utils/concurrency.js.map +1 -0
  196. package/dist/utils/fallback.d.ts +52 -0
  197. package/dist/utils/fallback.d.ts.map +1 -0
  198. package/dist/utils/fallback.js +137 -0
  199. package/dist/utils/fallback.js.map +1 -0
  200. package/dist/utils/git-hooks.d.ts +24 -0
  201. package/dist/utils/git-hooks.d.ts.map +1 -0
  202. package/dist/utils/git-hooks.js +108 -0
  203. package/dist/utils/git-hooks.js.map +1 -0
  204. package/dist/utils/languages.d.ts +72 -0
  205. package/dist/utils/languages.d.ts.map +1 -0
  206. package/dist/utils/languages.js +463 -0
  207. package/dist/utils/languages.js.map +1 -0
  208. package/dist/utils/logger.d.ts +13 -0
  209. package/dist/utils/logger.d.ts.map +1 -0
  210. package/dist/utils/logger.js +34 -0
  211. package/dist/utils/logger.js.map +1 -0
  212. package/dist/utils/plugins.d.ts +105 -0
  213. package/dist/utils/plugins.d.ts.map +1 -0
  214. package/dist/utils/plugins.js +325 -0
  215. package/dist/utils/plugins.js.map +1 -0
  216. package/dist/utils/security.d.ts +17 -0
  217. package/dist/utils/security.d.ts.map +1 -0
  218. package/dist/utils/security.js +48 -0
  219. package/dist/utils/security.js.map +1 -0
  220. package/dist/utils/streaming.d.ts +56 -0
  221. package/dist/utils/streaming.d.ts.map +1 -0
  222. package/dist/utils/streaming.js +95 -0
  223. package/dist/utils/streaming.js.map +1 -0
  224. package/dist/version.d.ts +3 -0
  225. package/dist/version.d.ts.map +1 -0
  226. package/dist/version.js +3 -0
  227. package/dist/version.js.map +1 -0
  228. package/mcp.json +100 -0
  229. package/package.json +89 -0
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Code Generation Templates / Scaffolding
3
+ * Generates boilerplate code from symbol signatures.
4
+ * Supports: React components, Express routes, test files, API handlers,
5
+ * class stubs, and module scaffolds based on project conventions.
6
+ */
7
+ import { listFiles } from '../search/fast-search.js';
8
+ import { readFile } from 'node:fs/promises';
9
+ import path from 'node:path';
10
+ /**
11
+ * Detect project conventions from existing files.
12
+ * @param cwd - The working directory
13
+ * @returns Detected project type and convention patterns
14
+ */
15
+ async function detectConventions(cwd) {
16
+ const patterns = [];
17
+ let projectType = 'generic';
18
+ try {
19
+ const pkgContent = await readFile(path.join(cwd, 'package.json'), 'utf-8');
20
+ const pkg = JSON.parse(pkgContent);
21
+ const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
22
+ if (allDeps.react || allDeps['react-dom']) {
23
+ projectType = allDeps.next ? 'nextjs' : 'react';
24
+ patterns.push('React project detected');
25
+ }
26
+ if (allDeps.express) {
27
+ projectType = projectType === 'generic' ? 'express' : projectType;
28
+ patterns.push('Express backend');
29
+ }
30
+ if (allDeps['@nestjs/core']) {
31
+ projectType = 'nestjs';
32
+ patterns.push('NestJS project');
33
+ }
34
+ if (allDeps.vue) {
35
+ projectType = 'vue';
36
+ patterns.push('Vue project');
37
+ }
38
+ if (allDeps.vitest)
39
+ patterns.push('Vitest testing');
40
+ if (allDeps.jest)
41
+ patterns.push('Jest testing');
42
+ if (allDeps.typescript)
43
+ patterns.push('TypeScript');
44
+ if (allDeps.tailwindcss)
45
+ patterns.push('Tailwind CSS');
46
+ if (allDeps.prisma || allDeps['@prisma/client'])
47
+ patterns.push('Prisma ORM');
48
+ if (allDeps.zod)
49
+ patterns.push('Zod validation');
50
+ }
51
+ catch {
52
+ /* no package.json */
53
+ }
54
+ // Check for Python
55
+ try {
56
+ await readFile(path.join(cwd, 'pyproject.toml'), 'utf-8');
57
+ projectType = 'python';
58
+ patterns.push('Python project');
59
+ }
60
+ catch {
61
+ /* skip */
62
+ }
63
+ try {
64
+ await readFile(path.join(cwd, 'Cargo.toml'), 'utf-8');
65
+ projectType = 'rust';
66
+ patterns.push('Rust project');
67
+ }
68
+ catch {
69
+ /* skip */
70
+ }
71
+ // Check file naming conventions
72
+ const tsFiles = await listFiles(cwd, { glob: 'src/**/*.{ts,tsx}' });
73
+ const hasPascalCase = tsFiles.some((f) => /[A-Z][a-z]+[A-Z]/.test(path.basename(f, path.extname(f))));
74
+ const hasKebabCase = tsFiles.some((f) => /[a-z]+-[a-z]+/.test(path.basename(f, path.extname(f))));
75
+ if (hasPascalCase)
76
+ patterns.push('PascalCase file naming');
77
+ if (hasKebabCase)
78
+ patterns.push('kebab-case file naming');
79
+ return { projectType, patterns };
80
+ }
81
+ /**
82
+ * Generate a React component scaffold.
83
+ * @param name - Component name
84
+ * @param conventions - Detected project conventions
85
+ * @returns Generated component code
86
+ */
87
+ function reactComponent(name, conventions) {
88
+ const hasTs = conventions.includes('TypeScript');
89
+ const hasTailwind = conventions.includes('Tailwind CSS');
90
+ const propsType = hasTs ? `\ninterface ${name}Props {\n // TODO: define props\n}\n` : '';
91
+ const propsParam = hasTs ? `{ }: ${name}Props` : '{ }';
92
+ const className = hasTailwind ? ' className="flex items-center gap-2"' : '';
93
+ return `${propsType}
94
+ export default function ${name}(${propsParam}) {
95
+ return (
96
+ <div${className}>
97
+ <h2>${name}</h2>
98
+ {/* TODO: implement component */}
99
+ </div>
100
+ );
101
+ }
102
+ `;
103
+ }
104
+ /**
105
+ * Generate a test file scaffold.
106
+ * @param name - Module or function name to test
107
+ * @param conventions - Detected project conventions
108
+ * @param targetFile - Path to the file being tested
109
+ * @returns Generated test file code
110
+ */
111
+ function testFile(name, conventions, targetFile) {
112
+ const isVitest = conventions.includes('Vitest testing');
113
+ const importFrom = isVitest ? 'vitest' : '@jest/globals';
114
+ return `import { describe, it, expect } from '${importFrom}';
115
+ import { ${name} } from '${targetFile.replace(/\.(ts|tsx|js|jsx)$/, '')}';
116
+
117
+ describe('${name}', () => {
118
+ it('should exist', () => {
119
+ expect(${name}).toBeDefined();
120
+ });
121
+
122
+ it('should work correctly', () => {
123
+ // TODO: add test cases
124
+ const result = ${name}();
125
+ expect(result).toBeTruthy();
126
+ });
127
+
128
+ it('should handle edge cases', () => {
129
+ // TODO: add edge case tests
130
+ });
131
+ });
132
+ `;
133
+ }
134
+ /**
135
+ * Generate an Express route scaffold.
136
+ * @param name - Route name
137
+ * @param conventions - Detected project conventions
138
+ * @returns Generated Express route code
139
+ */
140
+ function expressRoute(name, conventions) {
141
+ const hasTs = conventions.includes('TypeScript');
142
+ const hasZod = conventions.includes('Zod validation');
143
+ const types = hasTs ? ': Router' : '';
144
+ const importLine = hasTs
145
+ ? "import { Router, Request, Response } from 'express';\n"
146
+ : "const { Router } = require('express');\n";
147
+ const zodLine = hasZod
148
+ ? "import { z } from 'zod';\n\nconst createSchema = z.object({\n // TODO: define validation schema\n});\n"
149
+ : '';
150
+ return `${importLine}${zodLine}
151
+ const router${types} = Router();
152
+
153
+ router.get('/${name.toLowerCase()}', async (req${hasTs ? ': Request' : ''}, res${hasTs ? ': Response' : ''}) => {
154
+ try {
155
+ // TODO: implement GET handler
156
+ res.json({ message: 'GET /${name.toLowerCase()}' });
157
+ } catch (error) {
158
+ res.status(500).json({ error: 'Internal server error' });
159
+ }
160
+ });
161
+
162
+ router.post('/${name.toLowerCase()}', async (req${hasTs ? ': Request' : ''}, res${hasTs ? ': Response' : ''}) => {
163
+ try {
164
+ ${hasZod ? 'const body = createSchema.parse(req.body);\n ' : ''}// TODO: implement POST handler
165
+ res.status(201).json({ message: 'Created' });
166
+ } catch (error) {
167
+ res.status(500).json({ error: 'Internal server error' });
168
+ }
169
+ });
170
+
171
+ export default router;
172
+ `;
173
+ }
174
+ /**
175
+ * Generate a service/module scaffold.
176
+ * @param name - Service name
177
+ * @param conventions - Detected project conventions
178
+ * @returns Generated service class code
179
+ */
180
+ function serviceModule(name, conventions) {
181
+ const hasTs = conventions.includes('TypeScript');
182
+ const iface = hasTs ? `\nexport interface ${name}Options {\n // TODO: define options\n}\n` : '';
183
+ return `${iface}
184
+ export class ${name}Service {
185
+ ${hasTs ? 'private initialized = false;\n' : ''}
186
+ constructor(${hasTs ? `options?: ${name}Options` : 'options'}) {
187
+ // TODO: initialize service
188
+ }
189
+
190
+ async init()${hasTs ? ': Promise<void>' : ''} {
191
+ // TODO: setup
192
+ this.initialized = true;
193
+ }
194
+
195
+ async execute(input${hasTs ? ': unknown' : ''})${hasTs ? ': Promise<unknown>' : ''} {
196
+ if (!this.initialized) throw new Error('${name}Service not initialized');
197
+ // TODO: implement core logic
198
+ return input;
199
+ }
200
+
201
+ async dispose()${hasTs ? ': Promise<void>' : ''} {
202
+ // TODO: cleanup resources
203
+ }
204
+ }
205
+
206
+ export function create${name}(${hasTs ? `options?: ${name}Options` : 'options'}) {
207
+ return new ${name}Service(options);
208
+ }
209
+ `;
210
+ }
211
+ /**
212
+ * List available scaffold templates based on project conventions.
213
+ * @param cwd - The working directory
214
+ * @returns Available templates, detected patterns, and project type
215
+ */
216
+ export async function listTemplates(cwd) {
217
+ const { projectType, patterns } = await detectConventions(cwd);
218
+ const templates = [];
219
+ // Universal templates
220
+ templates.push({
221
+ name: 'test',
222
+ description: 'Test file for a module/function',
223
+ language: 'typescript',
224
+ category: 'test',
225
+ });
226
+ templates.push({
227
+ name: 'service',
228
+ description: 'Service class with init/execute/dispose lifecycle',
229
+ language: 'typescript',
230
+ category: 'service',
231
+ });
232
+ templates.push({
233
+ name: 'util',
234
+ description: 'Utility module with exported functions',
235
+ language: 'typescript',
236
+ category: 'util',
237
+ });
238
+ // React templates
239
+ if (['react', 'nextjs', 'vue'].includes(projectType)) {
240
+ templates.push({
241
+ name: 'component',
242
+ description: 'React functional component',
243
+ language: 'tsx',
244
+ category: 'component',
245
+ });
246
+ templates.push({ name: 'hook', description: 'Custom React hook', language: 'typescript', category: 'hook' });
247
+ }
248
+ // Backend templates
249
+ if (['express', 'nestjs'].includes(projectType) || patterns.includes('Express backend')) {
250
+ templates.push({
251
+ name: 'route',
252
+ description: 'Express route with GET/POST handlers',
253
+ language: 'typescript',
254
+ category: 'route',
255
+ });
256
+ templates.push({ name: 'model', description: 'Data model/entity', language: 'typescript', category: 'model' });
257
+ }
258
+ return { templates, detectedPatterns: patterns, projectType };
259
+ }
260
+ /**
261
+ * Generate scaffold code for a given template and name.
262
+ * @param cwd - The working directory
263
+ * @param options - Scaffold options
264
+ * @param options.template - Template type to generate
265
+ * @param options.name - Name for the generated code
266
+ * @param options.targetFile - Optional target file path
267
+ * @returns Generated scaffold result with code and metadata
268
+ */
269
+ export async function generateScaffold(cwd, options) {
270
+ const { patterns } = await detectConventions(cwd);
271
+ const { template, name, targetFile } = options;
272
+ let generatedCode;
273
+ let fileName;
274
+ let language = 'typescript';
275
+ switch (template) {
276
+ case 'component':
277
+ generatedCode = reactComponent(name, patterns);
278
+ fileName = `${name}.tsx`;
279
+ language = 'tsx';
280
+ break;
281
+ case 'test':
282
+ generatedCode = testFile(name, patterns, targetFile || `./${name}`);
283
+ fileName = `${name}.test.ts`;
284
+ break;
285
+ case 'route':
286
+ generatedCode = expressRoute(name, patterns);
287
+ fileName = `${name}.routes.ts`;
288
+ break;
289
+ case 'service':
290
+ generatedCode = serviceModule(name, patterns);
291
+ fileName = `${name}.service.ts`;
292
+ break;
293
+ case 'hook':
294
+ generatedCode = `import { useState, useEffect } from 'react';\n\nexport function use${name}() {\n const [state, setState] = useState(null);\n\n useEffect(() => {\n // TODO: implement hook logic\n }, []);\n\n return { state };\n}\n`;
295
+ fileName = `use${name}.ts`;
296
+ break;
297
+ case 'util':
298
+ generatedCode = `/**\n * ${name} utilities\n */\n\nexport function ${name.charAt(0).toLowerCase() + name.slice(1)}() {\n // TODO: implement\n}\n`;
299
+ fileName = `${name.toLowerCase()}.ts`;
300
+ break;
301
+ default:
302
+ generatedCode = `// Template '${template}' not recognized. Available: component, test, route, service, hook, util`;
303
+ fileName = `${name}.ts`;
304
+ }
305
+ return {
306
+ template,
307
+ generatedCode,
308
+ fileName,
309
+ language,
310
+ conventions: patterns,
311
+ };
312
+ }
313
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/analyzers/scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Security scanning module.
3
+ * - Dependency vulnerability checking (lock file analysis)
4
+ * - SAST-lite: common security anti-patterns
5
+ * - Secret/credential detection
6
+ * - No external API dependencies
7
+ */
8
+ export interface SecurityFinding {
9
+ severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
10
+ category: string;
11
+ message: string;
12
+ file: string;
13
+ line?: number;
14
+ snippet?: string;
15
+ recommendation: string;
16
+ }
17
+ export interface SecurityReport {
18
+ scanDate: string;
19
+ totalFindings: number;
20
+ bySeverity: Record<string, number>;
21
+ findings: SecurityFinding[];
22
+ dependencyInfo?: {
23
+ total: number;
24
+ directDeps: number;
25
+ lockfileFound: boolean;
26
+ };
27
+ }
28
+ /**
29
+ * Run security scan on codebase.
30
+ * @param cwd - The working directory
31
+ * @param options - Scan options
32
+ * @param options.category - Filter by finding category
33
+ * @param options.severity - Filter by severity level
34
+ * @param options.fileGlob - Glob pattern for files to scan
35
+ * @returns Security report with findings and dependency info
36
+ */
37
+ export declare function securityScan(cwd: string, options?: {
38
+ category?: string;
39
+ severity?: string;
40
+ fileGlob?: string;
41
+ }): Promise<SecurityReport>;
42
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/analyzers/security.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,OAAO,CAAA;KAAE,CAAC;CAChF;AAyID;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,OAAO,CAAC,cAAc,CAAC,CAqFzB"}
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Security scanning module.
3
+ * - Dependency vulnerability checking (lock file analysis)
4
+ * - SAST-lite: common security anti-patterns
5
+ * - Secret/credential detection
6
+ * - No external API dependencies
7
+ */
8
+ import { readFile, access } from 'node:fs/promises';
9
+ import path from 'node:path';
10
+ import { glob } from 'glob';
11
+ /**
12
+ * SAST patterns to detect.
13
+ */
14
+ const SAST_PATTERNS = [
15
+ // SQL Injection
16
+ {
17
+ name: 'SQL injection risk',
18
+ category: 'injection',
19
+ severity: 'critical',
20
+ pattern: /(?:query|execute|exec|raw)\s*\(\s*[`'"]\s*(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER).*?\$\{|%s|%d|\+\s*\w/i,
21
+ recommendation: 'Use parameterized queries or an ORM instead of string concatenation in SQL.',
22
+ },
23
+ // Command Injection
24
+ {
25
+ name: 'Command injection risk',
26
+ category: 'injection',
27
+ severity: 'critical',
28
+ pattern: /(?:exec|spawn|system|popen|subprocess\.(?:call|run|Popen))\s*\([^)]*(?:\$\{|\+\s*\w|%s|f['"]\s*\{)/,
29
+ recommendation: 'Avoid passing user input to shell commands. Use parameterized APIs or allowlists.',
30
+ },
31
+ // XSS
32
+ {
33
+ name: 'Potential XSS via innerHTML',
34
+ category: 'xss',
35
+ severity: 'high',
36
+ pattern: /\.innerHTML\s*=|dangerouslySetInnerHTML|v-html\s*=/,
37
+ recommendation: 'Use textContent instead of innerHTML, or sanitize with DOMPurify.',
38
+ },
39
+ // Hardcoded secrets
40
+ {
41
+ name: 'Hardcoded secret/credential',
42
+ category: 'secrets',
43
+ severity: 'critical',
44
+ pattern: /(?:password|secret|api_key|apikey|token|private_key|access_key|auth_token|client_secret)\s*[:=]\s*['"]\S{8,}['"]/i,
45
+ recommendation: 'Move secrets to environment variables or a secret manager (AWS Secrets Manager, Vault, etc).',
46
+ },
47
+ // Hardcoded URLs with credentials
48
+ {
49
+ name: 'Credential in URL',
50
+ category: 'secrets',
51
+ severity: 'high',
52
+ pattern: /(?:https?|ftp):\/\/\w+:\w+@/,
53
+ recommendation: 'Remove credentials from URLs. Use environment variables for connection strings.',
54
+ },
55
+ // Insecure randomness
56
+ {
57
+ name: 'Insecure randomness',
58
+ category: 'crypto',
59
+ severity: 'medium',
60
+ pattern: /Math\.random\(\)|random\.random\(\)|rand\(\)/,
61
+ recommendation: 'Use crypto.randomBytes() or secrets module for security-sensitive random values.',
62
+ },
63
+ // Weak hashing
64
+ {
65
+ name: 'Weak hash algorithm (MD5/SHA1)',
66
+ category: 'crypto',
67
+ severity: 'medium',
68
+ pattern: /(?:createHash|hashlib\.md5|hashlib\.sha1|MD5|SHA1)\s*\(/,
69
+ recommendation: 'Use SHA-256 or bcrypt/argon2 for passwords.',
70
+ },
71
+ // Eval usage
72
+ {
73
+ name: 'Dangerous eval() usage',
74
+ category: 'injection',
75
+ severity: 'high',
76
+ pattern: /\beval\s*\((?!['"][^'"]+['"])|new\s+Function\s*\(/,
77
+ recommendation: 'Avoid eval(). Use JSON.parse() for data or a sandboxed environment.',
78
+ },
79
+ // CORS wildcard
80
+ {
81
+ name: 'CORS wildcard origin',
82
+ category: 'config',
83
+ severity: 'medium',
84
+ pattern: /(?:Access-Control-Allow-Origin|cors)\s*[:({]\s*['"]\*['"]/,
85
+ recommendation: 'Restrict CORS to specific trusted origins instead of wildcard *.',
86
+ },
87
+ // Unvalidated redirect
88
+ {
89
+ name: 'Open redirect risk',
90
+ category: 'redirect',
91
+ severity: 'medium',
92
+ pattern: /(?:redirect|location\.href|window\.location)\s*=\s*(?:req\.|request\.|params\.|query\.)/,
93
+ recommendation: 'Validate redirect URLs against an allowlist of trusted domains.',
94
+ },
95
+ // Disabled security features
96
+ {
97
+ name: 'TLS/SSL verification disabled',
98
+ category: 'config',
99
+ severity: 'high',
100
+ pattern: /verify\s*=\s*False|rejectUnauthorized\s*:\s*false|NODE_TLS_REJECT_UNAUTHORIZED\s*=\s*['"]?0/,
101
+ recommendation: 'Never disable TLS verification in production.',
102
+ },
103
+ // Debug mode in production
104
+ {
105
+ name: 'Debug mode enabled',
106
+ category: 'config',
107
+ severity: 'medium',
108
+ pattern: /DEBUG\s*=\s*True|debug\s*:\s*true|app\.debug\s*=\s*True/,
109
+ recommendation: 'Ensure debug mode is disabled in production environments.',
110
+ },
111
+ // Empty catch blocks
112
+ {
113
+ name: 'Swallowed security exception',
114
+ category: 'error-handling',
115
+ severity: 'low',
116
+ pattern: /catch\s*\([^)]*\)\s*\{\s*\}|except:\s*pass/,
117
+ recommendation: 'Log exceptions properly. Swallowed exceptions can hide security issues.',
118
+ },
119
+ // Path traversal
120
+ {
121
+ name: 'Path traversal risk',
122
+ category: 'injection',
123
+ severity: 'high',
124
+ pattern: /path\.join\s*\([^)]*req\.|path\.resolve\s*\([^)]*req\.|os\.path\.join\s*\([^)]*request\./,
125
+ recommendation: 'Validate and sanitize file paths. Use path.resolve() and check against base directory.',
126
+ },
127
+ // JWT without verification
128
+ {
129
+ name: 'JWT without verification',
130
+ category: 'auth',
131
+ severity: 'high',
132
+ pattern: /jwt\.decode\s*\([^)]*verify\s*=\s*False|algorithms\s*=\s*\[\s*['"]none['"]/,
133
+ recommendation: 'Always verify JWT signatures. Never allow "none" algorithm.',
134
+ },
135
+ ];
136
+ /**
137
+ * Run security scan on codebase.
138
+ * @param cwd - The working directory
139
+ * @param options - Scan options
140
+ * @param options.category - Filter by finding category
141
+ * @param options.severity - Filter by severity level
142
+ * @param options.fileGlob - Glob pattern for files to scan
143
+ * @returns Security report with findings and dependency info
144
+ */
145
+ export async function securityScan(cwd, options = {}) {
146
+ const findings = [];
147
+ // Find all source files
148
+ const files = await glob(options.fileGlob || '**/*.{ts,tsx,js,jsx,py,java,go,rs,rb,php,cs}', {
149
+ cwd,
150
+ ignore: ['node_modules/**', 'dist/**', 'build/**', '.git/**', 'vendor/**', '__pycache__/**'],
151
+ });
152
+ // Scan each file against SAST patterns
153
+ for (const file of files.slice(0, 1000)) {
154
+ try {
155
+ const content = await readFile(path.join(cwd, file), 'utf-8');
156
+ const lines = content.split('\n');
157
+ for (const pattern of SAST_PATTERNS) {
158
+ if (options.category && pattern.category !== options.category)
159
+ continue;
160
+ if (options.severity && pattern.severity !== options.severity)
161
+ continue;
162
+ for (let i = 0; i < lines.length; i++) {
163
+ if (pattern.pattern.test(lines[i])) {
164
+ // Skip if in a comment
165
+ const trimmed = lines[i].trim();
166
+ if (trimmed.startsWith('//') || trimmed.startsWith('#') || trimmed.startsWith('*'))
167
+ continue;
168
+ findings.push({
169
+ severity: pattern.severity,
170
+ category: pattern.category,
171
+ message: pattern.name,
172
+ file,
173
+ line: i + 1,
174
+ snippet: lines[i].trim().slice(0, 120),
175
+ recommendation: pattern.recommendation,
176
+ });
177
+ }
178
+ }
179
+ }
180
+ }
181
+ catch {
182
+ /* skip unreadable files */
183
+ }
184
+ }
185
+ // Check for common insecure files
186
+ const insecureFiles = [
187
+ { file: '.env', message: '.env file should not be committed to version control' },
188
+ { file: 'id_rsa', message: 'Private SSH key should not be in repository' },
189
+ { file: 'id_ed25519', message: 'Private SSH key should not be in repository' },
190
+ { file: '.npmrc', message: 'npm config may contain auth tokens' },
191
+ { file: '.pypirc', message: 'PyPI config may contain auth tokens' },
192
+ ];
193
+ for (const check of insecureFiles) {
194
+ try {
195
+ await access(path.join(cwd, check.file));
196
+ findings.push({
197
+ severity: 'high',
198
+ category: 'secrets',
199
+ message: check.message,
200
+ file: check.file,
201
+ recommendation: `Add ${check.file} to .gitignore and remove from version control.`,
202
+ });
203
+ }
204
+ catch {
205
+ /* not present, good */
206
+ }
207
+ }
208
+ // Check dependency info
209
+ const depInfo = await analyzeDependencies(cwd);
210
+ // Build severity counts
211
+ const bySeverity = {};
212
+ for (const f of findings) {
213
+ bySeverity[f.severity] = (bySeverity[f.severity] || 0) + 1;
214
+ }
215
+ return {
216
+ scanDate: new Date().toISOString(),
217
+ totalFindings: findings.length,
218
+ bySeverity,
219
+ findings: findings.sort((a, b) => {
220
+ const order = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
221
+ return (order[a.severity] || 4) - (order[b.severity] || 4);
222
+ }),
223
+ dependencyInfo: depInfo,
224
+ };
225
+ }
226
+ /**
227
+ * Analyze dependency files for basic info.
228
+ * @param cwd - The working directory
229
+ * @returns Dependency count information and lockfile presence
230
+ */
231
+ async function analyzeDependencies(cwd) {
232
+ // Check for lockfiles
233
+ const lockfiles = [
234
+ 'package-lock.json',
235
+ 'yarn.lock',
236
+ 'pnpm-lock.yaml',
237
+ 'Pipfile.lock',
238
+ 'poetry.lock',
239
+ 'Cargo.lock',
240
+ 'go.sum',
241
+ ];
242
+ let lockfileFound = false;
243
+ for (const lf of lockfiles) {
244
+ try {
245
+ await access(path.join(cwd, lf));
246
+ lockfileFound = true;
247
+ break;
248
+ }
249
+ catch {
250
+ continue;
251
+ }
252
+ }
253
+ // Count deps from package.json / requirements.txt / etc.
254
+ let directDeps = 0;
255
+ let totalDeps = 0;
256
+ try {
257
+ const pkgJson = JSON.parse(await readFile(path.join(cwd, 'package.json'), 'utf-8'));
258
+ directDeps = Object.keys(pkgJson.dependencies || {}).length + Object.keys(pkgJson.devDependencies || {}).length;
259
+ // Rough total from lock file
260
+ try {
261
+ const lockContent = await readFile(path.join(cwd, 'package-lock.json'), 'utf-8');
262
+ const lockData = JSON.parse(lockContent);
263
+ totalDeps = Object.keys(lockData.packages || lockData.dependencies || {}).length;
264
+ }
265
+ catch {
266
+ totalDeps = directDeps;
267
+ }
268
+ }
269
+ catch {
270
+ try {
271
+ const reqs = await readFile(path.join(cwd, 'requirements.txt'), 'utf-8');
272
+ directDeps = reqs.split('\n').filter((l) => l.trim() && !l.startsWith('#')).length;
273
+ totalDeps = directDeps;
274
+ }
275
+ catch {
276
+ /* no deps file found */
277
+ }
278
+ }
279
+ return { total: totalDeps, directDeps, lockfileFound };
280
+ }
281
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/analyzers/security.ts"],"names":[],"mappings":"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"}