project-context-ai 1.3.0 → 1.3.1
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/generators/template.d.ts.map +1 -1
- package/dist/generators/template.js +127 -22
- package/dist/generators/template.js.map +1 -1
- package/dist/scanner/business.js +99 -6
- package/dist/scanner/business.js.map +1 -1
- package/dist/scanner/database.js +31 -1
- package/dist/scanner/database.js.map +1 -1
- package/dist/scanner/patterns.d.ts +23 -0
- package/dist/scanner/patterns.d.ts.map +1 -1
- package/dist/scanner/patterns.js +263 -92
- package/dist/scanner/patterns.js.map +1 -1
- package/dist/scanner/routes.js +16 -2
- package/dist/scanner/routes.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/scanner/database.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/scanner/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,10 @@ export interface CodePatterns {
|
|
|
7
7
|
codeConventions: string[];
|
|
8
8
|
ideSkills: IDESkill[];
|
|
9
9
|
ideCommands: IDECommand[];
|
|
10
|
+
errorHandling: ErrorPattern[];
|
|
11
|
+
testPatterns: TestPatternInfo | null;
|
|
12
|
+
architecturalRules: string[];
|
|
13
|
+
codeExamples: CodeExample[];
|
|
10
14
|
}
|
|
11
15
|
export interface NamingConventions {
|
|
12
16
|
files: string;
|
|
@@ -24,5 +28,24 @@ export interface IDECommand {
|
|
|
24
28
|
file: string;
|
|
25
29
|
description: string;
|
|
26
30
|
}
|
|
31
|
+
export interface ErrorPattern {
|
|
32
|
+
className: string;
|
|
33
|
+
extendsFrom: string;
|
|
34
|
+
file: string;
|
|
35
|
+
}
|
|
36
|
+
export interface TestPatternInfo {
|
|
37
|
+
framework: string;
|
|
38
|
+
coverageThreshold: number | null;
|
|
39
|
+
unitFilePattern: string;
|
|
40
|
+
integrationFilePattern: string | null;
|
|
41
|
+
testDir: string;
|
|
42
|
+
assertionStyle: string | null;
|
|
43
|
+
}
|
|
44
|
+
export interface CodeExample {
|
|
45
|
+
file: string;
|
|
46
|
+
label: string;
|
|
47
|
+
code: string;
|
|
48
|
+
category: string;
|
|
49
|
+
}
|
|
27
50
|
export declare function scanCodePatterns(rootPath: string, allFiles: string[], deps: DependencyEntry[], frameworks: FrameworkInfo[]): Promise<CodePatterns>;
|
|
28
51
|
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/scanner/patterns.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGlE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,WAAW,EAAE,UAAU,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/scanner/patterns.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGlE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,EAAE,eAAe,EAAE,EACvB,UAAU,EAAE,aAAa,EAAE,GAC1B,OAAO,CAAC,YAAY,CAAC,CAoBvB"}
|
package/dist/scanner/patterns.js
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { readTextFile, readFilesMatching } from "../utils/files.js";
|
|
3
3
|
export async function scanCodePatterns(rootPath, allFiles, deps, frameworks) {
|
|
4
|
-
const [di, imports, naming, workflows, codeConventions, ideSkills, ideCommands] = await Promise.all([
|
|
4
|
+
const [di, imports, naming, workflows, codeConventions, ideSkills, ideCommands, errorHandling, testPatterns, architecturalRules, codeExamples] = await Promise.all([
|
|
5
5
|
detectDI(rootPath, allFiles, deps),
|
|
6
6
|
detectImportPatterns(rootPath, allFiles),
|
|
7
|
-
detectNaming(allFiles),
|
|
7
|
+
detectNaming(rootPath, allFiles),
|
|
8
8
|
detectWorkflows(rootPath, allFiles, deps, frameworks),
|
|
9
9
|
detectCodeConventions(rootPath, allFiles),
|
|
10
10
|
scanIDESkills(rootPath, allFiles),
|
|
11
11
|
scanIDECommands(rootPath, allFiles),
|
|
12
|
+
detectErrorHandling(rootPath, allFiles),
|
|
13
|
+
detectTestPatterns(rootPath, allFiles, deps, frameworks),
|
|
14
|
+
detectArchitecturalRules(rootPath, allFiles),
|
|
15
|
+
extractCodeExamples(rootPath, allFiles, deps),
|
|
12
16
|
]);
|
|
13
|
-
return {
|
|
17
|
+
return {
|
|
18
|
+
di, imports, naming, workflows, codeConventions, ideSkills, ideCommands,
|
|
19
|
+
errorHandling, testPatterns, architecturalRules, codeExamples,
|
|
20
|
+
};
|
|
14
21
|
}
|
|
15
22
|
// ─── Dependency Injection ─────────────────────────────────
|
|
16
23
|
async function detectDI(rootPath, allFiles, deps) {
|
|
17
24
|
const depNames = deps.map((d) => d.name);
|
|
18
|
-
// Known DI frameworks
|
|
19
25
|
if (depNames.includes("@nestjs/core"))
|
|
20
26
|
return "NestJS built-in DI (@Injectable, @Inject)";
|
|
21
27
|
if (depNames.includes("tsyringe"))
|
|
@@ -28,7 +34,6 @@ async function detectDI(rootPath, allFiles, deps) {
|
|
|
28
34
|
return "TypeDI (Container.get, @Service)";
|
|
29
35
|
if (depNames.includes("awilix"))
|
|
30
36
|
return "Awilix (createContainer, asClass, asFunction)";
|
|
31
|
-
// Detect custom DI patterns from code
|
|
32
37
|
const sourceFiles = await readFilesMatching(rootPath, allFiles, {
|
|
33
38
|
extensions: [".ts", ".js"],
|
|
34
39
|
maxFiles: 50,
|
|
@@ -76,25 +81,21 @@ async function detectImportPatterns(rootPath, allFiles) {
|
|
|
76
81
|
patterns.push("Scoped package aliases (@/)");
|
|
77
82
|
if (hasBarrelImports)
|
|
78
83
|
patterns.push("Barrel exports (index.ts re-exports)");
|
|
79
|
-
// Check tsconfig for path aliases
|
|
80
84
|
const tsconfig = await readTextFile(join(rootPath, "tsconfig.json"));
|
|
81
|
-
if (tsconfig) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
patterns.push(`Path aliases: ${aliases.map((a) => a.replace(/"/g, "").replace(":", "")).join(", ")}`);
|
|
88
|
-
}
|
|
85
|
+
if (tsconfig?.includes('"paths"')) {
|
|
86
|
+
const pathsMatch = tsconfig.match(/"paths"\s*:\s*\{([^}]+)\}/);
|
|
87
|
+
if (pathsMatch) {
|
|
88
|
+
const aliases = pathsMatch[1].match(/"(@?\w[^"]*)":/g);
|
|
89
|
+
if (aliases) {
|
|
90
|
+
patterns.push(`Path aliases: ${aliases.map((a) => a.replace(/"/g, "").replace(":", "")).join(", ")}`);
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
return patterns;
|
|
93
95
|
}
|
|
94
96
|
// ─── Naming Conventions ───────────────────────────────────
|
|
95
|
-
async function detectNaming(allFiles) {
|
|
97
|
+
async function detectNaming(rootPath, allFiles) {
|
|
96
98
|
const tsFiles = allFiles.filter((f) => f.match(/\.(ts|tsx|js|jsx)$/) && !f.includes("node_modules"));
|
|
97
|
-
// File naming
|
|
98
99
|
const fileNames = tsFiles.map((f) => f.split("/").pop() || "").filter(Boolean);
|
|
99
100
|
let kebabCount = 0;
|
|
100
101
|
let camelCount = 0;
|
|
@@ -103,9 +104,9 @@ async function detectNaming(allFiles) {
|
|
|
103
104
|
const baseName = name.replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
104
105
|
if (baseName.includes("-"))
|
|
105
106
|
kebabCount++;
|
|
106
|
-
else if (baseName[0] === baseName[0].toUpperCase() &&
|
|
107
|
+
else if (baseName[0] === baseName[0].toUpperCase() && /[a-z]/.test(baseName))
|
|
107
108
|
pascalCount++;
|
|
108
|
-
else if (
|
|
109
|
+
else if (/[a-z]/.test(baseName))
|
|
109
110
|
camelCount++;
|
|
110
111
|
}
|
|
111
112
|
const maxCount = Math.max(kebabCount, camelCount, pascalCount);
|
|
@@ -116,82 +117,286 @@ async function detectNaming(allFiles) {
|
|
|
116
117
|
fileNaming = "PascalCase (MyComponent.ts)";
|
|
117
118
|
else if (camelCount === maxCount && camelCount > kebabCount + pascalCount)
|
|
118
119
|
fileNaming = "camelCase (myComponent.ts)";
|
|
119
|
-
// DB column naming —
|
|
120
|
+
// DB column naming — read actual schema/migrations
|
|
120
121
|
let dbColumns = "unknown";
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
122
|
+
const prismaFile = allFiles.find((f) => f.endsWith("schema.prisma"));
|
|
123
|
+
if (prismaFile) {
|
|
124
|
+
const content = await readTextFile(join(rootPath, prismaFile));
|
|
125
|
+
if (content) {
|
|
126
|
+
const fieldNames = [];
|
|
127
|
+
const fieldRegex = /^\s+(\w+)\s+\w+/gm;
|
|
128
|
+
let match;
|
|
129
|
+
while ((match = fieldRegex.exec(content)) !== null) {
|
|
130
|
+
const name = match[1];
|
|
131
|
+
if (!["model", "enum", "datasource", "generator"].includes(name))
|
|
132
|
+
fieldNames.push(name);
|
|
133
|
+
}
|
|
134
|
+
const snakeCount = fieldNames.filter((n) => n.includes("_")).length;
|
|
135
|
+
const camelFieldCount = fieldNames.filter((n) => !n.includes("_") && n !== n.toLowerCase()).length;
|
|
136
|
+
if (snakeCount > camelFieldCount)
|
|
137
|
+
dbColumns = "snake_case";
|
|
138
|
+
else if (fieldNames.length > 0)
|
|
139
|
+
dbColumns = "camelCase";
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (dbColumns === "unknown") {
|
|
143
|
+
const migrationFiles = allFiles.filter((f) => f.includes("migration") && f.match(/\.(ts|js|sql)$/));
|
|
144
|
+
if (migrationFiles.length > 0) {
|
|
145
|
+
const content = await readTextFile(join(rootPath, migrationFiles[0]));
|
|
146
|
+
if (content) {
|
|
147
|
+
const snakeMatches = content.match(/["'`]\w+_\w+["'`]/g);
|
|
148
|
+
if (snakeMatches && snakeMatches.length > 3)
|
|
149
|
+
dbColumns = "snake_case";
|
|
150
|
+
const camelMatches = content.match(/["'`][a-z]+[A-Z]\w+["'`]/g);
|
|
151
|
+
if (camelMatches && camelMatches.length > 3)
|
|
152
|
+
dbColumns = "camelCase (quote in raw SQL)";
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return { files: fileNaming, variables: "camelCase", dbColumns };
|
|
157
|
+
}
|
|
158
|
+
// ─── Error Handling ───────────────────────────────────────
|
|
159
|
+
async function detectErrorHandling(rootPath, allFiles) {
|
|
160
|
+
const patterns = [];
|
|
161
|
+
const sourceFiles = await readFilesMatching(rootPath, allFiles, {
|
|
162
|
+
extensions: [".ts", ".js"],
|
|
163
|
+
maxFiles: 100,
|
|
164
|
+
maxFileSize: 10240,
|
|
165
|
+
});
|
|
166
|
+
for (const { file, content } of sourceFiles) {
|
|
167
|
+
const regex = /class\s+(\w+)\s+extends\s+(Error|BaseError|DomainError|AppError|HttpException|CustomError|BusinessError|NotFound|BadRequest|Unauthorized|Forbidden)\b/g;
|
|
168
|
+
let match;
|
|
169
|
+
while ((match = regex.exec(content)) !== null) {
|
|
170
|
+
patterns.push({ className: match[1], extendsFrom: match[2], file });
|
|
171
|
+
}
|
|
172
|
+
if (patterns.length >= 30)
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
// Dedupe by className
|
|
176
|
+
const seen = new Set();
|
|
177
|
+
return patterns.filter((p) => {
|
|
178
|
+
if (seen.has(p.className))
|
|
179
|
+
return false;
|
|
180
|
+
seen.add(p.className);
|
|
181
|
+
return true;
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
// ─── Test Patterns ────────────────────────────────────────
|
|
185
|
+
async function detectTestPatterns(rootPath, allFiles, deps, frameworks) {
|
|
186
|
+
const depNames = deps.map((d) => d.name);
|
|
187
|
+
const fwNames = frameworks.map((f) => f.name);
|
|
188
|
+
let framework = "";
|
|
189
|
+
if (depNames.includes("vitest") || fwNames.includes("Vitest"))
|
|
190
|
+
framework = "Vitest";
|
|
191
|
+
else if (depNames.includes("jest") || depNames.includes("ts-jest") || fwNames.includes("Jest"))
|
|
192
|
+
framework = "Jest";
|
|
193
|
+
else if (depNames.includes("mocha"))
|
|
194
|
+
framework = "Mocha";
|
|
195
|
+
if (!framework)
|
|
196
|
+
return null;
|
|
197
|
+
// Coverage threshold
|
|
198
|
+
let coverageThreshold = null;
|
|
199
|
+
const configFiles = allFiles.filter((f) => f.match(/(jest|vitest)\..*config\.(ts|js|mjs|cjs|json)$/));
|
|
200
|
+
for (const cf of configFiles.slice(0, 3)) {
|
|
201
|
+
const content = await readTextFile(join(rootPath, cf));
|
|
202
|
+
if (!content)
|
|
203
|
+
continue;
|
|
204
|
+
const thresholdMatch = content.match(/(?:branches|lines|functions|statements)\s*:\s*(\d+)/);
|
|
205
|
+
if (thresholdMatch) {
|
|
206
|
+
coverageThreshold = parseInt(thresholdMatch[1], 10);
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// File patterns
|
|
211
|
+
const testFiles = allFiles.filter((f) => f.match(/\.(test|spec)\.(ts|tsx|js|jsx)$/));
|
|
212
|
+
const specCount = testFiles.filter((f) => f.includes(".spec.")).length;
|
|
213
|
+
const testCount = testFiles.filter((f) => f.includes(".test.")).length;
|
|
214
|
+
const unitFilePattern = specCount > testCount ? "*.spec.ts" : "*.test.ts";
|
|
215
|
+
let integrationFilePattern = null;
|
|
216
|
+
if (allFiles.some((f) => f.includes("__tests__/")))
|
|
217
|
+
integrationFilePattern = "__tests__/**/*.test.ts";
|
|
218
|
+
else if (allFiles.some((f) => f.includes("e2e/")))
|
|
219
|
+
integrationFilePattern = "e2e/**/*.test.ts";
|
|
220
|
+
let testDir = "src/";
|
|
221
|
+
if (allFiles.some((f) => f.includes("__tests__/")))
|
|
222
|
+
testDir = "__tests__/";
|
|
223
|
+
else if (allFiles.some((f) => f.match(/^tests?\//)))
|
|
224
|
+
testDir = "tests/";
|
|
225
|
+
// Assertion style
|
|
226
|
+
let assertionStyle = null;
|
|
227
|
+
if (testFiles.length > 0) {
|
|
228
|
+
const content = await readTextFile(join(rootPath, testFiles[0]));
|
|
229
|
+
if (content) {
|
|
230
|
+
if (content.includes("expect("))
|
|
231
|
+
assertionStyle = "expect() (Jest/Vitest)";
|
|
232
|
+
else if (content.includes("assert."))
|
|
233
|
+
assertionStyle = "assert (Node.js/Chai)";
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return { framework, coverageThreshold, unitFilePattern, integrationFilePattern, testDir, assertionStyle };
|
|
237
|
+
}
|
|
238
|
+
// ─── Architectural Rules ──────────────────────────────────
|
|
239
|
+
async function detectArchitecturalRules(rootPath, allFiles) {
|
|
240
|
+
const rules = [];
|
|
241
|
+
// 1. dependency-cruiser config
|
|
242
|
+
const dcFile = allFiles.find((f) => f.match(/\.dependency-cruiser\.(cjs|js|json)$/));
|
|
243
|
+
if (dcFile) {
|
|
244
|
+
const content = await readTextFile(join(rootPath, dcFile));
|
|
245
|
+
if (content) {
|
|
246
|
+
const nameRegex = /name\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
247
|
+
let match;
|
|
248
|
+
while ((match = nameRegex.exec(content)) !== null) {
|
|
249
|
+
rules.push(`Dependency rule: ${match[1]}`);
|
|
250
|
+
if (rules.length >= 10)
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// 2. ESLint boundary rules
|
|
256
|
+
const eslintFiles = allFiles.filter((f) => f.match(/eslint/i) && !f.includes("node_modules"));
|
|
257
|
+
for (const ef of eslintFiles.slice(0, 2)) {
|
|
258
|
+
const content = await readTextFile(join(rootPath, ef));
|
|
259
|
+
if (!content)
|
|
260
|
+
continue;
|
|
261
|
+
if (content.includes("import/no-restricted-paths") || content.includes("boundaries/element-types")) {
|
|
262
|
+
rules.push("ESLint enforced import boundaries between layers");
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// 3. Infer from structure — check if domain doesn't import from infra
|
|
266
|
+
const hasDomain = allFiles.some((f) => f.match(/src\/(domain|core)\//));
|
|
267
|
+
const hasInfra = allFiles.some((f) => f.match(/src\/(infra|infrastructure)\//));
|
|
268
|
+
const hasApp = allFiles.some((f) => f.match(/src\/(application|use-?cases)\//));
|
|
269
|
+
if (hasDomain && hasInfra) {
|
|
270
|
+
const domainFiles = await readFilesMatching(rootPath, allFiles, {
|
|
271
|
+
extensions: [".ts", ".js"],
|
|
272
|
+
maxFiles: 20,
|
|
273
|
+
maxFileSize: 5120,
|
|
274
|
+
pathPatterns: [/src\/(domain|core)\//],
|
|
275
|
+
});
|
|
276
|
+
let domainImportsInfra = false;
|
|
277
|
+
for (const { content } of domainFiles) {
|
|
278
|
+
if (content.match(/from\s+['"].*\/(infra|infrastructure)\//)) {
|
|
279
|
+
domainImportsInfra = true;
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (!domainImportsInfra) {
|
|
284
|
+
rules.push("Domain/Core layer does NOT import from Infrastructure (Clean Architecture)");
|
|
285
|
+
}
|
|
286
|
+
if (hasApp) {
|
|
287
|
+
rules.push("Layers: Domain → Application → Infrastructure");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return rules;
|
|
291
|
+
}
|
|
292
|
+
// ─── Code Examples ────────────────────────────────────────
|
|
293
|
+
async function extractCodeExamples(rootPath, allFiles, deps) {
|
|
294
|
+
const examples = [];
|
|
295
|
+
const depNames = deps.map((d) => d.name);
|
|
296
|
+
const categories = [
|
|
297
|
+
{ category: "service", patterns: [/services?\//i], label: "Service pattern" },
|
|
298
|
+
{ category: "controller", patterns: [/controllers?\//i], label: "Controller pattern" },
|
|
299
|
+
{ category: "repository", patterns: [/repositor/i], label: "Repository pattern" },
|
|
300
|
+
{ category: "middleware", patterns: [/middleware/i], label: "Middleware pattern" },
|
|
301
|
+
{ category: "error-handling", patterns: [/(errors|exceptions)\//i], label: "Error handling" },
|
|
302
|
+
];
|
|
303
|
+
for (const cat of categories) {
|
|
304
|
+
const candidates = allFiles.filter((f) => f.match(/\.(ts|js)$/) &&
|
|
305
|
+
cat.patterns.some((p) => p.test(f)) &&
|
|
306
|
+
!f.includes(".test.") && !f.includes(".spec.") &&
|
|
307
|
+
!f.includes("index.") && !f.includes("generated/"));
|
|
308
|
+
if (candidates.length === 0)
|
|
309
|
+
continue;
|
|
310
|
+
const content = await readTextFile(join(rootPath, candidates[0]));
|
|
311
|
+
if (!content)
|
|
312
|
+
continue;
|
|
313
|
+
const lines = content.split("\n").slice(0, 40);
|
|
314
|
+
// Extract meaningful code: class definition or function
|
|
315
|
+
const snippet = lines.join("\n");
|
|
316
|
+
const classMatch = snippet.match(/((?:export\s+)?(?:abstract\s+)?class\s+\w+[^{]*\{[^}]*(?:\n[^}]*){0,8})/);
|
|
317
|
+
const fnMatch = snippet.match(/((?:export\s+)?(?:async\s+)?function\s+\w+[^{]*\{[^}]*(?:\n[^}]*){0,5})/);
|
|
318
|
+
const code = classMatch?.[1] || fnMatch?.[1] || lines.slice(0, 15).join("\n");
|
|
319
|
+
if (code.trim().length > 30) {
|
|
320
|
+
examples.push({
|
|
321
|
+
file: candidates[0],
|
|
322
|
+
label: cat.label,
|
|
323
|
+
code: code.trim().slice(0, 500),
|
|
324
|
+
category: cat.category,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
if (examples.length >= 6)
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
// DI example
|
|
331
|
+
if (depNames.includes("@cubos/inject") || depNames.includes("tsyringe") || depNames.includes("inversify")) {
|
|
332
|
+
const diFiles = await readFilesMatching(rootPath, allFiles, {
|
|
333
|
+
extensions: [".ts"],
|
|
334
|
+
maxFiles: 10,
|
|
335
|
+
maxFileSize: 5120,
|
|
336
|
+
pathPatterns: [/(services?|controllers?|use-?cases?)\//],
|
|
337
|
+
});
|
|
338
|
+
for (const { file, content } of diFiles) {
|
|
339
|
+
const useMatch = content.match(/.*use\(\w+\).*/);
|
|
340
|
+
const injectMatch = content.match(/.*@Inject.*|.*@injectable.*/i);
|
|
341
|
+
const line = useMatch?.[0] || injectMatch?.[0];
|
|
342
|
+
if (line) {
|
|
343
|
+
examples.push({ file, label: "DI usage", code: line.trim(), category: "di" });
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return examples;
|
|
132
349
|
}
|
|
133
350
|
// ─── Workflows ────────────────────────────────────────────
|
|
134
351
|
async function detectWorkflows(rootPath, allFiles, deps, frameworks) {
|
|
135
352
|
const workflows = [];
|
|
136
353
|
const depNames = deps.map((d) => d.name);
|
|
137
|
-
// SDKGEN
|
|
138
354
|
if (allFiles.some((f) => f.endsWith(".sdkgen"))) {
|
|
139
|
-
workflows.push("SDKGEN: .sdkgen
|
|
355
|
+
workflows.push("SDKGEN: define .sdkgen schema → `pnpm run sdkgen` → implement controllers");
|
|
140
356
|
}
|
|
141
|
-
// GraphQL codegen
|
|
142
357
|
if (depNames.includes("@graphql-codegen/cli") || allFiles.some((f) => f.includes("codegen"))) {
|
|
143
358
|
workflows.push("GraphQL Codegen: .graphql schema → generated types/resolvers");
|
|
144
359
|
}
|
|
145
|
-
// Prisma workflow
|
|
146
360
|
if (allFiles.some((f) => f.endsWith("schema.prisma"))) {
|
|
147
|
-
workflows.push("Prisma: schema.prisma → prisma generate → prisma migrate");
|
|
361
|
+
workflows.push("Prisma: edit schema.prisma → `prisma generate` → `prisma migrate dev`");
|
|
148
362
|
}
|
|
149
|
-
// Drizzle
|
|
150
363
|
if (depNames.includes("drizzle-kit")) {
|
|
151
|
-
workflows.push("Drizzle: schema
|
|
364
|
+
workflows.push("Drizzle: edit schema → `drizzle-kit generate` → `drizzle-kit migrate`");
|
|
152
365
|
}
|
|
153
|
-
// Knex migrations
|
|
154
366
|
if (allFiles.some((f) => f.includes("knexfile"))) {
|
|
155
|
-
workflows.push("Knex:
|
|
367
|
+
workflows.push("Knex migrations: `knex migrate:make <name>` → edit → `knex migrate:latest`");
|
|
156
368
|
}
|
|
157
|
-
// OpenAPI / Swagger
|
|
158
369
|
if (allFiles.some((f) => f.match(/openapi|swagger/i) && f.match(/\.(json|yaml|yml)$/))) {
|
|
159
|
-
workflows.push("OpenAPI/Swagger
|
|
370
|
+
workflows.push("OpenAPI/Swagger spec → generated client/types");
|
|
160
371
|
}
|
|
161
|
-
// Monorepo
|
|
162
372
|
if (depNames.includes("turbo"))
|
|
163
|
-
workflows.push("Turborepo: turbo run <task
|
|
373
|
+
workflows.push("Turborepo: `turbo run <task>` across packages");
|
|
164
374
|
if (depNames.includes("lerna"))
|
|
165
|
-
workflows.push("Lerna: lerna run <task
|
|
375
|
+
workflows.push("Lerna: `lerna run <task>` across packages");
|
|
166
376
|
if (allFiles.includes("nx.json"))
|
|
167
|
-
workflows.push("Nx: nx run <project>:<task
|
|
168
|
-
// CI/CD
|
|
377
|
+
workflows.push("Nx: `nx run <project>:<task>`");
|
|
169
378
|
if (allFiles.some((f) => f.includes(".github/workflows/")))
|
|
170
379
|
workflows.push("GitHub Actions CI/CD");
|
|
171
380
|
if (allFiles.some((f) => f.includes(".gitlab-ci")))
|
|
172
381
|
workflows.push("GitLab CI/CD");
|
|
173
382
|
if (allFiles.includes("Jenkinsfile"))
|
|
174
383
|
workflows.push("Jenkins CI/CD");
|
|
175
|
-
// Husky / commitizen
|
|
176
384
|
if (depNames.includes("husky"))
|
|
177
385
|
workflows.push("Husky: pre-commit hooks for linting/formatting");
|
|
178
386
|
if (depNames.includes("commitizen") || depNames.includes("git-cz"))
|
|
179
|
-
workflows.push("Commitizen: standardized commit messages");
|
|
180
|
-
// Docker
|
|
387
|
+
workflows.push("Commitizen: standardized commit messages (`git cz`)");
|
|
181
388
|
if (allFiles.includes("Dockerfile"))
|
|
182
389
|
workflows.push("Docker: containerized deployment");
|
|
183
|
-
if (allFiles.some((f) => f.match(/docker-compose\.(yml|yaml)$/)))
|
|
184
|
-
workflows.push("Docker Compose: multi-service local
|
|
185
|
-
// Electron
|
|
390
|
+
if (allFiles.some((f) => f.match(/(docker-)?compose\.(yml|yaml)$/)))
|
|
391
|
+
workflows.push("Docker Compose: multi-service local dev");
|
|
186
392
|
if (depNames.includes("electron") || depNames.includes("electron-builder")) {
|
|
187
|
-
workflows.push("Electron: build
|
|
393
|
+
workflows.push("Electron: build → bundle → `electron-builder` dist");
|
|
188
394
|
}
|
|
189
395
|
return workflows;
|
|
190
396
|
}
|
|
191
397
|
// ─── Code Conventions ─────────────────────────────────────
|
|
192
398
|
async function detectCodeConventions(rootPath, allFiles) {
|
|
193
399
|
const conventions = [];
|
|
194
|
-
// Check for strict mode / noAny
|
|
195
400
|
const tsconfig = await readTextFile(join(rootPath, "tsconfig.json"));
|
|
196
401
|
if (tsconfig) {
|
|
197
402
|
if (tsconfig.includes('"strict": true') || tsconfig.includes('"strict":true')) {
|
|
@@ -201,7 +406,6 @@ async function detectCodeConventions(rootPath, allFiles) {
|
|
|
201
406
|
conventions.push("No implicit any types");
|
|
202
407
|
}
|
|
203
408
|
}
|
|
204
|
-
// ESLint config
|
|
205
409
|
const eslintFiles = allFiles.filter((f) => f.match(/eslint/i) && !f.includes("node_modules"));
|
|
206
410
|
if (eslintFiles.length > 0) {
|
|
207
411
|
const content = await readTextFile(join(rootPath, eslintFiles[0]));
|
|
@@ -214,20 +418,6 @@ async function detectCodeConventions(rootPath, allFiles) {
|
|
|
214
418
|
}
|
|
215
419
|
}
|
|
216
420
|
}
|
|
217
|
-
// Error handling patterns
|
|
218
|
-
const sourceFiles = await readFilesMatching(rootPath, allFiles, {
|
|
219
|
-
extensions: [".ts", ".js"],
|
|
220
|
-
maxFiles: 30,
|
|
221
|
-
maxFileSize: 5120,
|
|
222
|
-
pathPatterns: [/(errors|exceptions|shared|utils)/],
|
|
223
|
-
});
|
|
224
|
-
for (const { content } of sourceFiles) {
|
|
225
|
-
if (content.match(/class\s+\w+\s+extends\s+(Error|BaseError|DomainError|AppError)/)) {
|
|
226
|
-
conventions.push("Custom error classes extending base errors");
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
// Check for isDeleted / soft delete pattern
|
|
231
421
|
const repoFiles = await readFilesMatching(rootPath, allFiles, {
|
|
232
422
|
extensions: [".ts", ".js"],
|
|
233
423
|
maxFiles: 20,
|
|
@@ -236,35 +426,21 @@ async function detectCodeConventions(rootPath, allFiles) {
|
|
|
236
426
|
});
|
|
237
427
|
for (const { content } of repoFiles) {
|
|
238
428
|
if (content.includes("isDeleted") || content.includes("is_deleted") || content.includes("deletedAt")) {
|
|
239
|
-
conventions.push("Soft delete pattern (isDeleted
|
|
429
|
+
conventions.push("Soft delete pattern (filter `isDeleted`/`deletedAt`)");
|
|
240
430
|
break;
|
|
241
431
|
}
|
|
242
432
|
}
|
|
243
|
-
// Base repository pattern
|
|
244
433
|
for (const { content } of repoFiles) {
|
|
245
434
|
if (content.match(/class\s+\w+\s+extends\s+Base(Repository|Repo)/)) {
|
|
246
435
|
conventions.push("BaseRepository pattern for data access");
|
|
247
436
|
break;
|
|
248
437
|
}
|
|
249
438
|
}
|
|
250
|
-
// Test coverage config
|
|
251
|
-
const jestConfigs = allFiles.filter((f) => f.match(/jest\..*config/));
|
|
252
|
-
for (const configFile of jestConfigs.slice(0, 3)) {
|
|
253
|
-
const content = await readTextFile(join(rootPath, configFile));
|
|
254
|
-
if (content) {
|
|
255
|
-
const thresholdMatch = content.match(/branches.*?(\d+)/);
|
|
256
|
-
if (thresholdMatch) {
|
|
257
|
-
conventions.push(`Test coverage threshold: ${thresholdMatch[1]}%`);
|
|
258
|
-
break;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
439
|
return conventions;
|
|
263
440
|
}
|
|
264
|
-
// ─── IDE Skills
|
|
441
|
+
// ─── IDE Skills ───────────────────────────────────────────
|
|
265
442
|
async function scanIDESkills(rootPath, allFiles) {
|
|
266
443
|
const skills = [];
|
|
267
|
-
// .claude/skills/*.mdc or *.md
|
|
268
444
|
const skillFiles = allFiles.filter((f) => f.match(/\.claude\/skills\/.*\.(mdc|md)$/) ||
|
|
269
445
|
f.match(/\.cursor\/rules\/.*\.(md|mdc)$/) ||
|
|
270
446
|
f.match(/\.trae\/rules\/.*\.(md|mdc)$/));
|
|
@@ -273,10 +449,8 @@ async function scanIDESkills(rootPath, allFiles) {
|
|
|
273
449
|
if (!content)
|
|
274
450
|
continue;
|
|
275
451
|
const name = file.split("/").pop()?.replace(/\.(mdc|md)$/, "") || file;
|
|
276
|
-
// Try to extract frontmatter info
|
|
277
452
|
let activatesOn = "";
|
|
278
453
|
let description = "";
|
|
279
|
-
// YAML frontmatter
|
|
280
454
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
281
455
|
if (frontmatterMatch) {
|
|
282
456
|
const fm = frontmatterMatch[1];
|
|
@@ -287,7 +461,6 @@ async function scanIDESkills(rootPath, allFiles) {
|
|
|
287
461
|
if (descMatch)
|
|
288
462
|
description = descMatch[1].trim().replace(/^["']|["']$/g, "");
|
|
289
463
|
}
|
|
290
|
-
// Fallback: first heading or first paragraph
|
|
291
464
|
if (!description) {
|
|
292
465
|
const headingMatch = content.match(/^#\s+(.+)$/m);
|
|
293
466
|
if (headingMatch)
|
|
@@ -302,7 +475,7 @@ async function scanIDESkills(rootPath, allFiles) {
|
|
|
302
475
|
}
|
|
303
476
|
return skills;
|
|
304
477
|
}
|
|
305
|
-
// ─── IDE Commands
|
|
478
|
+
// ─── IDE Commands ─────────────────────────────────────────
|
|
306
479
|
async function scanIDECommands(rootPath, allFiles) {
|
|
307
480
|
const commands = [];
|
|
308
481
|
const cmdFiles = allFiles.filter((f) => f.match(/\.claude\/commands\/.*\.(md|mdc|txt)$/));
|
|
@@ -311,12 +484,10 @@ async function scanIDECommands(rootPath, allFiles) {
|
|
|
311
484
|
if (!content)
|
|
312
485
|
continue;
|
|
313
486
|
const name = file.split("/").pop()?.replace(/\.(md|mdc|txt)$/, "") || file;
|
|
314
|
-
// Extract description from first line or heading
|
|
315
487
|
let description = "";
|
|
316
488
|
const headingMatch = content.match(/^#\s+(.+)$/m);
|
|
317
|
-
if (headingMatch)
|
|
489
|
+
if (headingMatch)
|
|
318
490
|
description = headingMatch[1].trim();
|
|
319
|
-
}
|
|
320
491
|
else {
|
|
321
492
|
const firstLine = content.split("\n").find((l) => l.trim() && !l.startsWith("---"));
|
|
322
493
|
if (firstLine)
|