mustard-claude 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +198 -0
- package/bin/mustard.js +5 -0
- package/dist/analyzers/llm.d.ts +13 -0
- package/dist/analyzers/llm.js +339 -0
- package/dist/analyzers/llm.js.map +1 -0
- package/dist/analyzers/semantic.d.ts +13 -0
- package/dist/analyzers/semantic.js +215 -0
- package/dist/analyzers/semantic.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +42 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.js +377 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/sync.d.ts +5 -0
- package/dist/commands/sync.js +235 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/update.d.ts +8 -0
- package/dist/commands/update.js +237 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/generators/claude-md-llm.d.ts +5 -0
- package/dist/generators/claude-md-llm.js +101 -0
- package/dist/generators/claude-md-llm.js.map +1 -0
- package/dist/generators/claude-md-template.d.ts +5 -0
- package/dist/generators/claude-md-template.js +273 -0
- package/dist/generators/claude-md-template.js.map +1 -0
- package/dist/generators/commands.d.ts +17 -0
- package/dist/generators/commands.js +845 -0
- package/dist/generators/commands.js.map +1 -0
- package/dist/generators/context.d.ts +11 -0
- package/dist/generators/context.js +621 -0
- package/dist/generators/context.js.map +1 -0
- package/dist/generators/hooks.d.ts +5 -0
- package/dist/generators/hooks.js +128 -0
- package/dist/generators/hooks.js.map +1 -0
- package/dist/generators/index.d.ts +11 -0
- package/dist/generators/index.js +541 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/prompts.d.ts +13 -0
- package/dist/generators/prompts.js +579 -0
- package/dist/generators/prompts.js.map +1 -0
- package/dist/generators/registry.d.ts +5 -0
- package/dist/generators/registry.js +93 -0
- package/dist/generators/registry.js.map +1 -0
- package/dist/scanners/dependencies.d.ts +7 -0
- package/dist/scanners/dependencies.js +195 -0
- package/dist/scanners/dependencies.js.map +1 -0
- package/dist/scanners/index.d.ts +6 -0
- package/dist/scanners/index.js +37 -0
- package/dist/scanners/index.js.map +1 -0
- package/dist/scanners/samples.d.ts +8 -0
- package/dist/scanners/samples.js +193 -0
- package/dist/scanners/samples.js.map +1 -0
- package/dist/scanners/stack.d.ts +5 -0
- package/dist/scanners/stack.js +294 -0
- package/dist/scanners/stack.js.map +1 -0
- package/dist/scanners/structure.d.ts +5 -0
- package/dist/scanners/structure.js +274 -0
- package/dist/scanners/structure.js.map +1 -0
- package/dist/services/grepai.d.ts +25 -0
- package/dist/services/grepai.js +89 -0
- package/dist/services/grepai.js.map +1 -0
- package/dist/services/ollama.d.ts +22 -0
- package/dist/services/ollama.js +86 -0
- package/dist/services/ollama.js.map +1 -0
- package/dist/services/package-manager.d.ts +95 -0
- package/dist/services/package-manager.js +164 -0
- package/dist/services/package-manager.js.map +1 -0
- package/dist/types.d.ts +233 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { glob } from 'glob';
|
|
2
|
+
import { readFile } from 'fs/promises';
|
|
3
|
+
import { join, basename } from 'path';
|
|
4
|
+
/**
|
|
5
|
+
* Stack detection patterns
|
|
6
|
+
*/
|
|
7
|
+
const STACK_PATTERNS = {
|
|
8
|
+
dotnet: {
|
|
9
|
+
indicators: ['**/*.csproj', '**/*.sln', '**/*.cs'],
|
|
10
|
+
configFiles: ['*.csproj', 'Directory.Build.props'],
|
|
11
|
+
versionExtractor: async (path) => {
|
|
12
|
+
const csprojFiles = await glob('**/*.csproj', { cwd: path, nodir: true });
|
|
13
|
+
if (csprojFiles.length > 0) {
|
|
14
|
+
try {
|
|
15
|
+
const firstCsproj = csprojFiles[0];
|
|
16
|
+
if (firstCsproj) {
|
|
17
|
+
const content = await readFile(join(path, firstCsproj), 'utf-8');
|
|
18
|
+
const match = content.match(/<TargetFramework>net(\d+\.\d+|\d+)<\/TargetFramework>/);
|
|
19
|
+
return match?.[1] ?? 'unknown';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch { /* ignored */ }
|
|
23
|
+
}
|
|
24
|
+
return 'unknown';
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
react: {
|
|
28
|
+
indicators: ['**/package.json'],
|
|
29
|
+
configFiles: ['package.json', 'vite.config.*', 'next.config.*'],
|
|
30
|
+
// Custom scanner for react to check all package.json files
|
|
31
|
+
customScanner: async (projectPath) => {
|
|
32
|
+
const results = [];
|
|
33
|
+
const pkgFiles = await glob('**/package.json', {
|
|
34
|
+
cwd: projectPath,
|
|
35
|
+
nodir: true,
|
|
36
|
+
ignore: ['**/node_modules/**']
|
|
37
|
+
});
|
|
38
|
+
for (const pkgFile of pkgFiles) {
|
|
39
|
+
try {
|
|
40
|
+
const fullPath = join(projectPath, pkgFile);
|
|
41
|
+
const pkg = JSON.parse(await readFile(fullPath, 'utf-8'));
|
|
42
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
43
|
+
if ('react' in deps || 'react-dom' in deps) {
|
|
44
|
+
const subPath = pkgFile.replace(/\/package\.json$/, '').replace(/\\package\.json$/, '') || '.';
|
|
45
|
+
const version = deps['react']?.replace('^', '').replace('~', '') ?? 'unknown';
|
|
46
|
+
results.push({
|
|
47
|
+
name: 'react',
|
|
48
|
+
version,
|
|
49
|
+
path: subPath,
|
|
50
|
+
files: [pkgFile]
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch { /* ignored */ }
|
|
55
|
+
}
|
|
56
|
+
return results;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
nextjs: {
|
|
60
|
+
indicators: ['**/next.config.*', '**/package.json'],
|
|
61
|
+
detector: async (path) => {
|
|
62
|
+
try {
|
|
63
|
+
const pkgPath = join(path, 'package.json');
|
|
64
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
65
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
66
|
+
return 'next' in deps;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
versionExtractor: async (path) => {
|
|
73
|
+
try {
|
|
74
|
+
const pkgPath = join(path, 'package.json');
|
|
75
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
76
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
77
|
+
return deps['next']?.replace('^', '').replace('~', '') ?? 'unknown';
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return 'unknown';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
node: {
|
|
85
|
+
indicators: ['**/package.json'],
|
|
86
|
+
configFiles: ['package.json', 'tsconfig.json'],
|
|
87
|
+
detector: async (path) => {
|
|
88
|
+
const hasPackageJson = await glob('package.json', { cwd: path }).then(f => f.length > 0);
|
|
89
|
+
return hasPackageJson;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
python: {
|
|
93
|
+
indicators: ['**/requirements.txt', '**/pyproject.toml', '**/*.py'],
|
|
94
|
+
configFiles: ['requirements.txt', 'pyproject.toml', 'setup.py'],
|
|
95
|
+
versionExtractor: async (path) => {
|
|
96
|
+
try {
|
|
97
|
+
const pyprojectPath = join(path, 'pyproject.toml');
|
|
98
|
+
const content = await readFile(pyprojectPath, 'utf-8');
|
|
99
|
+
const match = content.match(/python\s*=\s*"[><=^~]*(\d+\.\d+)/);
|
|
100
|
+
return match?.[1] ?? 'unknown';
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return 'unknown';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
java: {
|
|
108
|
+
indicators: ['**/pom.xml', '**/build.gradle', '**/*.java'],
|
|
109
|
+
configFiles: ['pom.xml', 'build.gradle', 'build.gradle.kts']
|
|
110
|
+
},
|
|
111
|
+
rust: {
|
|
112
|
+
indicators: ['**/Cargo.toml', '**/*.rs'],
|
|
113
|
+
configFiles: ['Cargo.toml']
|
|
114
|
+
},
|
|
115
|
+
go: {
|
|
116
|
+
indicators: ['**/go.mod', '**/*.go'],
|
|
117
|
+
configFiles: ['go.mod']
|
|
118
|
+
},
|
|
119
|
+
drizzle: {
|
|
120
|
+
indicators: ['**/drizzle.config.*', '**/schema/*.ts'],
|
|
121
|
+
// Custom scanner for drizzle to check all package.json files
|
|
122
|
+
customScanner: async (projectPath) => {
|
|
123
|
+
const results = [];
|
|
124
|
+
const pkgFiles = await glob('**/package.json', {
|
|
125
|
+
cwd: projectPath,
|
|
126
|
+
nodir: true,
|
|
127
|
+
ignore: ['**/node_modules/**']
|
|
128
|
+
});
|
|
129
|
+
for (const pkgFile of pkgFiles) {
|
|
130
|
+
try {
|
|
131
|
+
const fullPath = join(projectPath, pkgFile);
|
|
132
|
+
const pkg = JSON.parse(await readFile(fullPath, 'utf-8'));
|
|
133
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
134
|
+
if ('drizzle-orm' in deps) {
|
|
135
|
+
const subPath = pkgFile.replace(/\/package\.json$/, '').replace(/\\package\.json$/, '') || '.';
|
|
136
|
+
results.push({
|
|
137
|
+
name: 'drizzle',
|
|
138
|
+
version: deps['drizzle-orm']?.replace('^', '').replace('~', '') ?? 'unknown',
|
|
139
|
+
path: subPath,
|
|
140
|
+
files: [pkgFile]
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch { /* ignored */ }
|
|
145
|
+
}
|
|
146
|
+
return results;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Package manager detection
|
|
152
|
+
*/
|
|
153
|
+
const PACKAGE_MANAGERS = {
|
|
154
|
+
pnpm: ['pnpm-lock.yaml', 'pnpm-workspace.yaml'],
|
|
155
|
+
yarn: ['yarn.lock', '.yarnrc.yml'],
|
|
156
|
+
npm: ['package-lock.json'],
|
|
157
|
+
bun: ['bun.lockb']
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Scan project for stacks (languages and frameworks)
|
|
161
|
+
*/
|
|
162
|
+
export async function scanStack(projectPath, options = {}) {
|
|
163
|
+
const { verbose = false } = options;
|
|
164
|
+
const stacks = [];
|
|
165
|
+
const detectedPaths = new Map();
|
|
166
|
+
// Check each stack
|
|
167
|
+
for (const [stackName, config] of Object.entries(STACK_PATTERNS)) {
|
|
168
|
+
// Use custom scanner if available (for stacks that need to check multiple package.json)
|
|
169
|
+
if (config.customScanner) {
|
|
170
|
+
const customResults = await config.customScanner(projectPath);
|
|
171
|
+
for (const result of customResults) {
|
|
172
|
+
const key = `${result.name}-${result.path}`;
|
|
173
|
+
if (!detectedPaths.has(key)) {
|
|
174
|
+
detectedPaths.set(key, true);
|
|
175
|
+
stacks.push(result);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
// Standard detection via indicators
|
|
181
|
+
for (const pattern of config.indicators) {
|
|
182
|
+
const matches = await glob(pattern, {
|
|
183
|
+
cwd: projectPath,
|
|
184
|
+
nodir: true,
|
|
185
|
+
ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**', '**/.next/**', '**/dist/**']
|
|
186
|
+
});
|
|
187
|
+
if (matches.length > 0) {
|
|
188
|
+
// If there's a custom detector, use it
|
|
189
|
+
if (config.detector) {
|
|
190
|
+
const detected = await config.detector(projectPath);
|
|
191
|
+
if (!detected)
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
// Get version if extractor exists
|
|
195
|
+
let version = 'unknown';
|
|
196
|
+
if (config.versionExtractor) {
|
|
197
|
+
version = await config.versionExtractor(projectPath);
|
|
198
|
+
}
|
|
199
|
+
// Determine subpath
|
|
200
|
+
const firstMatch = matches[0];
|
|
201
|
+
const subPath = firstMatch?.includes('/') ? firstMatch.split('/')[0] ?? '.' : '.';
|
|
202
|
+
// Avoid duplicates
|
|
203
|
+
if (!detectedPaths.has(`${stackName}-${subPath}`)) {
|
|
204
|
+
detectedPaths.set(`${stackName}-${subPath}`, true);
|
|
205
|
+
stacks.push({
|
|
206
|
+
name: stackName,
|
|
207
|
+
version,
|
|
208
|
+
path: subPath,
|
|
209
|
+
files: matches.slice(0, 5) // Sample files
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Detect package manager
|
|
216
|
+
const packageManager = await detectPackageManager(projectPath);
|
|
217
|
+
// Infer naming conventions from files
|
|
218
|
+
const naming = await inferNamingConventions(projectPath, stacks);
|
|
219
|
+
return {
|
|
220
|
+
stacks,
|
|
221
|
+
packageManager,
|
|
222
|
+
naming
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Detect package manager from lock files
|
|
227
|
+
*/
|
|
228
|
+
async function detectPackageManager(projectPath) {
|
|
229
|
+
for (const [manager, lockFiles] of Object.entries(PACKAGE_MANAGERS)) {
|
|
230
|
+
for (const lockFile of lockFiles) {
|
|
231
|
+
const matches = await glob(lockFile, { cwd: projectPath });
|
|
232
|
+
if (matches.length > 0) {
|
|
233
|
+
return manager;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return 'npm'; // Default
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Infer naming conventions from existing files
|
|
241
|
+
*/
|
|
242
|
+
async function inferNamingConventions(projectPath, stacks) {
|
|
243
|
+
const naming = {
|
|
244
|
+
classes: 'PascalCase',
|
|
245
|
+
files: {},
|
|
246
|
+
variables: 'camelCase'
|
|
247
|
+
};
|
|
248
|
+
// Check .cs files for class naming
|
|
249
|
+
const csFiles = await glob('**/*.cs', {
|
|
250
|
+
cwd: projectPath,
|
|
251
|
+
nodir: true,
|
|
252
|
+
ignore: ['**/bin/**', '**/obj/**']
|
|
253
|
+
});
|
|
254
|
+
if (csFiles.length > 0) {
|
|
255
|
+
naming.files['cs'] = 'PascalCase'; // .NET convention
|
|
256
|
+
}
|
|
257
|
+
// Check .ts/.tsx files
|
|
258
|
+
const tsFiles = await glob('**/*.{ts,tsx}', {
|
|
259
|
+
cwd: projectPath,
|
|
260
|
+
nodir: true,
|
|
261
|
+
ignore: ['**/node_modules/**', '**/.next/**', '**/dist/**']
|
|
262
|
+
});
|
|
263
|
+
if (tsFiles.length > 0) {
|
|
264
|
+
// Analyze file names
|
|
265
|
+
const sample = tsFiles.slice(0, 20);
|
|
266
|
+
const kebabCount = sample.filter(f => /[a-z]+-[a-z]+/.test(basename(f))).length;
|
|
267
|
+
const pascalCount = sample.filter(f => /^[A-Z][a-zA-Z]+\.tsx?$/.test(basename(f))).length;
|
|
268
|
+
const camelCount = sample.filter(f => /^[a-z][a-zA-Z]+\.tsx?$/.test(basename(f))).length;
|
|
269
|
+
const filesObj = naming.files;
|
|
270
|
+
if (kebabCount > pascalCount && kebabCount > camelCount) {
|
|
271
|
+
filesObj['ts'] = 'kebab-case';
|
|
272
|
+
filesObj['tsx'] = 'kebab-case';
|
|
273
|
+
}
|
|
274
|
+
else if (pascalCount > camelCount) {
|
|
275
|
+
filesObj['ts'] = 'PascalCase';
|
|
276
|
+
filesObj['tsx'] = 'PascalCase';
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
filesObj['ts'] = 'camelCase';
|
|
280
|
+
filesObj['tsx'] = 'camelCase';
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Check Python files
|
|
284
|
+
const pyFiles = await glob('**/*.py', {
|
|
285
|
+
cwd: projectPath,
|
|
286
|
+
nodir: true,
|
|
287
|
+
ignore: ['**/venv/**', '**/.venv/**', '**/__pycache__/**']
|
|
288
|
+
});
|
|
289
|
+
if (pyFiles.length > 0) {
|
|
290
|
+
naming.files['py'] = 'snake_case'; // Python convention
|
|
291
|
+
}
|
|
292
|
+
return naming;
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack.js","sourceRoot":"","sources":["../../src/scanners/stack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { glob } from 'glob';
|
|
2
|
+
import { readFile, readdir } from 'fs/promises';
|
|
3
|
+
import { join, basename } from 'path';
|
|
4
|
+
/**
|
|
5
|
+
* Architecture patterns to detect
|
|
6
|
+
*/
|
|
7
|
+
const ARCHITECTURE_PATTERNS = {
|
|
8
|
+
mvc: {
|
|
9
|
+
folders: ['Controllers', 'Models', 'Views'],
|
|
10
|
+
confidence: 'high'
|
|
11
|
+
},
|
|
12
|
+
clean: {
|
|
13
|
+
folders: ['Domain', 'Application', 'Infrastructure', 'Presentation'],
|
|
14
|
+
confidence: 'high'
|
|
15
|
+
},
|
|
16
|
+
featureBased: {
|
|
17
|
+
patterns: [/Modules\/\w+\/Endpoints/, /features\/\w+\/components/],
|
|
18
|
+
confidence: 'high'
|
|
19
|
+
},
|
|
20
|
+
reactStandard: {
|
|
21
|
+
folders: ['components', 'hooks', 'pages'],
|
|
22
|
+
confidence: 'medium'
|
|
23
|
+
},
|
|
24
|
+
layered: {
|
|
25
|
+
folders: ['Services', 'Repositories', 'Entities'],
|
|
26
|
+
confidence: 'medium'
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Scan project structure
|
|
31
|
+
*/
|
|
32
|
+
export async function scanStructure(projectPath, options = {}) {
|
|
33
|
+
const { verbose = false } = options;
|
|
34
|
+
// Get project name from directory or package.json
|
|
35
|
+
const name = await getProjectName(projectPath);
|
|
36
|
+
// Check if monorepo
|
|
37
|
+
const isMonorepo = await detectMonorepo(projectPath);
|
|
38
|
+
// Get top-level directories
|
|
39
|
+
const directories = await getDirectories(projectPath);
|
|
40
|
+
// Detect architecture pattern
|
|
41
|
+
const architecture = await detectArchitecture(projectPath, directories);
|
|
42
|
+
// Detect folder naming style
|
|
43
|
+
const folderStyle = detectFolderStyle(directories);
|
|
44
|
+
// Get subprojects if monorepo
|
|
45
|
+
const subprojects = isMonorepo ? await getSubprojects(projectPath) : [];
|
|
46
|
+
return {
|
|
47
|
+
name,
|
|
48
|
+
type: isMonorepo ? 'monorepo' : 'single',
|
|
49
|
+
architecture,
|
|
50
|
+
directories,
|
|
51
|
+
folderStyle,
|
|
52
|
+
subprojects
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get project name from package.json or directory name
|
|
57
|
+
*/
|
|
58
|
+
async function getProjectName(projectPath) {
|
|
59
|
+
try {
|
|
60
|
+
const pkgPath = join(projectPath, 'package.json');
|
|
61
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
62
|
+
return pkg.name ?? basename(projectPath);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return basename(projectPath);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Detect if project is a monorepo
|
|
70
|
+
*/
|
|
71
|
+
async function detectMonorepo(projectPath) {
|
|
72
|
+
// Check for common monorepo indicators
|
|
73
|
+
const indicators = [
|
|
74
|
+
'pnpm-workspace.yaml',
|
|
75
|
+
'lerna.json',
|
|
76
|
+
'nx.json',
|
|
77
|
+
'turbo.json',
|
|
78
|
+
'rush.json'
|
|
79
|
+
];
|
|
80
|
+
for (const indicator of indicators) {
|
|
81
|
+
const matches = await glob(indicator, { cwd: projectPath });
|
|
82
|
+
if (matches.length > 0)
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
// Check for workspaces in package.json
|
|
86
|
+
try {
|
|
87
|
+
const pkgPath = join(projectPath, 'package.json');
|
|
88
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
89
|
+
if (pkg.workspaces)
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
catch { /* ignored */ }
|
|
93
|
+
// Check for multiple package.json files in subdirectories
|
|
94
|
+
const packageJsons = await glob('*/package.json', { cwd: projectPath });
|
|
95
|
+
if (packageJsons.length >= 2)
|
|
96
|
+
return true;
|
|
97
|
+
// Check for .NET solution with multiple projects
|
|
98
|
+
const slnFiles = await glob('*.sln', { cwd: projectPath });
|
|
99
|
+
if (slnFiles.length > 0) {
|
|
100
|
+
const csprojFiles = await glob('**/*.csproj', {
|
|
101
|
+
cwd: projectPath,
|
|
102
|
+
ignore: ['**/bin/**', '**/obj/**']
|
|
103
|
+
});
|
|
104
|
+
if (csprojFiles.length >= 2)
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get top-level directories
|
|
111
|
+
*/
|
|
112
|
+
async function getDirectories(projectPath) {
|
|
113
|
+
const entries = await readdir(projectPath, { withFileTypes: true });
|
|
114
|
+
return entries
|
|
115
|
+
.filter(entry => entry.isDirectory())
|
|
116
|
+
.filter(entry => !entry.name.startsWith('.'))
|
|
117
|
+
.filter(entry => !['node_modules', 'bin', 'obj', 'dist', '.next', '__pycache__', 'venv', '.venv'].includes(entry.name))
|
|
118
|
+
.map(entry => entry.name);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Detect architecture pattern
|
|
122
|
+
*/
|
|
123
|
+
async function detectArchitecture(projectPath, directories) {
|
|
124
|
+
const allPaths = await glob('**/', {
|
|
125
|
+
cwd: projectPath,
|
|
126
|
+
ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**', '**/.next/**', '**/dist/**']
|
|
127
|
+
});
|
|
128
|
+
const detectedPatterns = [];
|
|
129
|
+
for (const [patternName, config] of Object.entries(ARCHITECTURE_PATTERNS)) {
|
|
130
|
+
if (config.folders) {
|
|
131
|
+
// Check if all required folders exist
|
|
132
|
+
const hasAll = config.folders.every(folder => directories.some(d => d.toLowerCase() === folder.toLowerCase()) ||
|
|
133
|
+
allPaths.some(p => p.toLowerCase().includes(folder.toLowerCase())));
|
|
134
|
+
if (hasAll) {
|
|
135
|
+
detectedPatterns.push({
|
|
136
|
+
type: patternName,
|
|
137
|
+
confidence: config.confidence
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (config.patterns) {
|
|
142
|
+
// Check regex patterns
|
|
143
|
+
const matchesAny = config.patterns.some(pattern => allPaths.some(p => pattern.test(p)));
|
|
144
|
+
if (matchesAny) {
|
|
145
|
+
detectedPatterns.push({
|
|
146
|
+
type: patternName,
|
|
147
|
+
confidence: config.confidence
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Return the highest confidence match
|
|
153
|
+
if (detectedPatterns.length > 0) {
|
|
154
|
+
const highConfidence = detectedPatterns.find(p => p.confidence === 'high');
|
|
155
|
+
return highConfidence ?? detectedPatterns[0];
|
|
156
|
+
}
|
|
157
|
+
return { type: 'unknown', confidence: 'low' };
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Detect folder naming style (singular vs plural)
|
|
161
|
+
*/
|
|
162
|
+
function detectFolderStyle(directories) {
|
|
163
|
+
const pluralIndicators = ['Controllers', 'Models', 'Services', 'Repositories', 'Entities', 'Modules', 'components', 'hooks', 'pages', 'features'];
|
|
164
|
+
const singularIndicators = ['Controller', 'Model', 'Service', 'Repository', 'Entity', 'Module', 'component', 'hook', 'page', 'feature'];
|
|
165
|
+
let pluralCount = 0;
|
|
166
|
+
let singularCount = 0;
|
|
167
|
+
for (const dir of directories) {
|
|
168
|
+
if (pluralIndicators.some(p => dir.toLowerCase() === p.toLowerCase())) {
|
|
169
|
+
pluralCount++;
|
|
170
|
+
}
|
|
171
|
+
if (singularIndicators.some(s => dir.toLowerCase() === s.toLowerCase())) {
|
|
172
|
+
singularCount++;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return pluralCount >= singularCount ? 'plural' : 'singular';
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Parse workspaces field from package.json
|
|
179
|
+
* Supports npm, yarn (both array and object formats), and bun workspaces
|
|
180
|
+
*/
|
|
181
|
+
async function parsePackageJsonWorkspaces(projectPath) {
|
|
182
|
+
try {
|
|
183
|
+
const pkgPath = join(projectPath, 'package.json');
|
|
184
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
185
|
+
if (!pkg.workspaces) {
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
// Handle array format (npm, bun, yarn classic)
|
|
189
|
+
if (Array.isArray(pkg.workspaces)) {
|
|
190
|
+
return pkg.workspaces;
|
|
191
|
+
}
|
|
192
|
+
// Handle object format with packages key (yarn berry)
|
|
193
|
+
if (typeof pkg.workspaces === 'object' && pkg.workspaces.packages) {
|
|
194
|
+
return pkg.workspaces.packages;
|
|
195
|
+
}
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
return [];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Resolve workspace patterns to actual subprojects
|
|
204
|
+
*/
|
|
205
|
+
async function resolveWorkspacePatterns(projectPath, patterns) {
|
|
206
|
+
const subprojects = [];
|
|
207
|
+
for (const pattern of patterns) {
|
|
208
|
+
const matches = await glob(pattern, { cwd: projectPath });
|
|
209
|
+
for (const match of matches) {
|
|
210
|
+
const pkgJsonPath = join(projectPath, match, 'package.json');
|
|
211
|
+
try {
|
|
212
|
+
const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));
|
|
213
|
+
subprojects.push({
|
|
214
|
+
name: pkgJson.name ?? match,
|
|
215
|
+
path: match
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
subprojects.push({ name: match, path: match });
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return subprojects;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get subprojects in monorepo
|
|
227
|
+
*/
|
|
228
|
+
async function getSubprojects(projectPath) {
|
|
229
|
+
const subprojects = [];
|
|
230
|
+
// Check for pnpm workspace first
|
|
231
|
+
let pnpmWorkspaceFound = false;
|
|
232
|
+
try {
|
|
233
|
+
const workspaceFile = join(projectPath, 'pnpm-workspace.yaml');
|
|
234
|
+
const content = await readFile(workspaceFile, 'utf-8');
|
|
235
|
+
// Simple yaml parsing for packages field
|
|
236
|
+
const packagesMatch = content.match(/packages:\s*\n((?:\s+-\s*.+\n?)+)/);
|
|
237
|
+
if (packagesMatch) {
|
|
238
|
+
pnpmWorkspaceFound = true;
|
|
239
|
+
const packages = packagesMatch[1]
|
|
240
|
+
.split('\n')
|
|
241
|
+
.map(line => line.replace(/^\s*-\s*['"]?/, '').replace(/['"]?\s*$/, ''))
|
|
242
|
+
.filter(Boolean);
|
|
243
|
+
const resolved = await resolveWorkspacePatterns(projectPath, packages);
|
|
244
|
+
subprojects.push(...resolved);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
catch { /* ignored */ }
|
|
248
|
+
// If no pnpm workspace, try package.json workspaces (npm, yarn, bun)
|
|
249
|
+
if (!pnpmWorkspaceFound) {
|
|
250
|
+
const workspacePatterns = await parsePackageJsonWorkspaces(projectPath);
|
|
251
|
+
if (workspacePatterns.length > 0) {
|
|
252
|
+
const resolved = await resolveWorkspacePatterns(projectPath, workspacePatterns);
|
|
253
|
+
subprojects.push(...resolved);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Check for .NET projects
|
|
257
|
+
const csprojFiles = await glob('**/*.csproj', {
|
|
258
|
+
cwd: projectPath,
|
|
259
|
+
ignore: ['**/bin/**', '**/obj/**']
|
|
260
|
+
});
|
|
261
|
+
for (const csproj of csprojFiles) {
|
|
262
|
+
const projectDir = csproj.replace(/\/[^/]+\.csproj$/, '').replace(/\\[^\\]+\.csproj$/, '');
|
|
263
|
+
const projectName = basename(csproj, '.csproj');
|
|
264
|
+
// Avoid duplicates
|
|
265
|
+
if (!subprojects.find(s => s.path === projectDir)) {
|
|
266
|
+
subprojects.push({
|
|
267
|
+
name: projectName,
|
|
268
|
+
path: projectDir || '.'
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return subprojects;
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=structure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structure.js","sourceRoot":"","sources":["../../src/scanners/structure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAGtC;;GAEG;AACH,MAAM,qBAAqB,GAA8C;IACvE,GAAG,EAAE;QACH,OAAO,EAAE,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC;QAC3C,UAAU,EAAE,MAAM;KACnB;IACD,KAAK,EAAE;QACL,OAAO,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,CAAC;QACpE,UAAU,EAAE,MAAM;KACnB;IACD,YAAY,EAAE;QACZ,QAAQ,EAAE,CAAC,yBAAyB,EAAE,2BAA2B,CAAC;QAClE,UAAU,EAAE,MAAM;KACnB;IACD,aAAa,EAAE;QACb,OAAO,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC;QACzC,UAAU,EAAE,QAAQ;KACrB;IACD,OAAO,EAAE;QACP,OAAO,EAAE,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC;QACjD,UAAU,EAAE,QAAQ;KACrB;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,UAAuB,EAAE;IAChF,MAAM,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEpC,kDAAkD;IAClD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;IAE/C,oBAAoB;IACpB,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;IAErD,4BAA4B;IAC5B,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;IAEtD,8BAA8B;IAC9B,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAExE,6BAA6B;IAC7B,MAAM,WAAW,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAEnD,8BAA8B;IAC9B,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAExE,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;QACxC,YAAY;QACZ,WAAW;QACX,WAAW;QACX,WAAW;KACZ,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,WAAmB;IAC/C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAsB,CAAC;QAC9E,OAAO,GAAG,CAAC,IAAI,IAAI,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,WAAmB;IAC/C,uCAAuC;IACvC,MAAM,UAAU,GAAG;QACjB,qBAAqB;QACrB,YAAY;QACZ,SAAS;QACT,YAAY;QACZ,WAAW;KACZ,CAAC;IAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAC5D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACtC,CAAC;IAED,uCAAuC;IACvC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAA8B,CAAC;QACtF,IAAI,GAAG,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;IAEzB,0DAA0D;IAC1D,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IACxE,IAAI,YAAY,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1C,iDAAiD;IACjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE;YAC5C,GAAG,EAAE,WAAW;YAChB,MAAM,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC;SACnC,CAAC,CAAC;QACH,IAAI,WAAW,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAC3C,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,WAAmB;IAC/C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,OAAO,OAAO;SACX,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;SACpC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SAC5C,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SACtH,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,kBAAkB,CAAC,WAAmB,EAAE,WAAqB;IAC1E,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE;QACjC,GAAG,EAAE,WAAW;QAChB,MAAM,EAAE,CAAC,oBAAoB,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,CAAC;KACtF,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAuB,EAAE,CAAC;IAEhD,KAAK,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC;QAC1E,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,sCAAsC;YACtC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAC3C,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC/D,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CACnE,CAAC;YAEF,IAAI,MAAM,EAAE,CAAC;gBACX,gBAAgB,CAAC,IAAI,CAAC;oBACpB,IAAI,EAAE,WAAW;oBACjB,UAAU,EAAE,MAAM,CAAC,UAAU;iBAC9B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,uBAAuB;YACvB,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAChD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CACpC,CAAC;YAEF,IAAI,UAAU,EAAE,CAAC;gBACf,gBAAgB,CAAC,IAAI,CAAC;oBACpB,IAAI,EAAE,WAAW;oBACjB,UAAU,EAAE,MAAM,CAAC,UAAU;iBAC9B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC;QAC3E,OAAO,cAAc,IAAI,gBAAgB,CAAC,CAAC,CAAE,CAAC;IAChD,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,WAAqB;IAC9C,MAAM,gBAAgB,GAAG,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAClJ,MAAM,kBAAkB,GAAG,CAAC,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAExI,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,aAAa,GAAG,CAAC,CAAC;IAEtB,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACtE,WAAW,EAAE,CAAC;QAChB,CAAC;QACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACxE,aAAa,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,WAAW,IAAI,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,0BAA0B,CAAC,WAAmB;IAC3D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAEtD,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,+CAA+C;QAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,OAAO,GAAG,CAAC,UAAU,CAAC;QACxB,CAAC;QAED,sDAAsD;QACtD,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;YAClE,OAAO,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;QACjC,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,wBAAwB,CAAC,WAAmB,EAAE,QAAkB;IAC7E,MAAM,WAAW,GAAiB,EAAE,CAAC;IAErC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAC1D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;YAC7D,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAsB,CAAC;gBACtF,WAAW,CAAC,IAAI,CAAC;oBACf,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;oBAC3B,IAAI,EAAE,KAAK;iBACZ,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,WAAmB;IAC/C,MAAM,WAAW,GAAiB,EAAE,CAAC;IAErC,iCAAiC;IACjC,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACvD,yCAAyC;QACzC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACzE,IAAI,aAAa,EAAE,CAAC;YAClB,kBAAkB,GAAG,IAAI,CAAC;YAC1B,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAE;iBAC/B,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;iBACvE,MAAM,CAAC,OAAO,CAAC,CAAC;YAEnB,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACvE,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;IAEzB,qEAAqE;IACrE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,MAAM,iBAAiB,GAAG,MAAM,0BAA0B,CAAC,WAAW,CAAC,CAAC;QACxE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;YAChF,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE;QAC5C,GAAG,EAAE,WAAW;QAChB,MAAM,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC;KACnC,CAAC,CAAC;IAEH,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QAC3F,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAEhD,mBAAmB;QACnB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC;YAClD,WAAW,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,UAAU,IAAI,GAAG;aACxB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SearchOptions, TraceOptions, SearchResponse, TraceResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Check if grepai CLI is available
|
|
4
|
+
*/
|
|
5
|
+
export declare function checkGrepaiAvailable(): Promise<boolean>;
|
|
6
|
+
/**
|
|
7
|
+
* Get grepai index status
|
|
8
|
+
*/
|
|
9
|
+
export declare function indexStatus(): Promise<Record<string, unknown> | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Search using grepai semantic search
|
|
12
|
+
*/
|
|
13
|
+
export declare function search(query: string, options?: SearchOptions): Promise<SearchResponse>;
|
|
14
|
+
/**
|
|
15
|
+
* Find all functions that call the specified symbol
|
|
16
|
+
*/
|
|
17
|
+
export declare function traceCallers(symbol: string, options?: TraceOptions): Promise<TraceResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Find all functions called by the specified symbol
|
|
20
|
+
*/
|
|
21
|
+
export declare function traceCallees(symbol: string, options?: TraceOptions): Promise<TraceResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Build a complete call graph around a symbol
|
|
24
|
+
*/
|
|
25
|
+
export declare function traceGraph(symbol: string, options?: TraceOptions): Promise<TraceResult>;
|