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.
Files changed (72) hide show
  1. package/README.md +198 -0
  2. package/bin/mustard.js +5 -0
  3. package/dist/analyzers/llm.d.ts +13 -0
  4. package/dist/analyzers/llm.js +339 -0
  5. package/dist/analyzers/llm.js.map +1 -0
  6. package/dist/analyzers/semantic.d.ts +13 -0
  7. package/dist/analyzers/semantic.js +215 -0
  8. package/dist/analyzers/semantic.js.map +1 -0
  9. package/dist/cli.d.ts +1 -0
  10. package/dist/cli.js +42 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/init.d.ts +5 -0
  13. package/dist/commands/init.js +377 -0
  14. package/dist/commands/init.js.map +1 -0
  15. package/dist/commands/sync.d.ts +5 -0
  16. package/dist/commands/sync.js +235 -0
  17. package/dist/commands/sync.js.map +1 -0
  18. package/dist/commands/update.d.ts +8 -0
  19. package/dist/commands/update.js +237 -0
  20. package/dist/commands/update.js.map +1 -0
  21. package/dist/generators/claude-md-llm.d.ts +5 -0
  22. package/dist/generators/claude-md-llm.js +101 -0
  23. package/dist/generators/claude-md-llm.js.map +1 -0
  24. package/dist/generators/claude-md-template.d.ts +5 -0
  25. package/dist/generators/claude-md-template.js +273 -0
  26. package/dist/generators/claude-md-template.js.map +1 -0
  27. package/dist/generators/commands.d.ts +17 -0
  28. package/dist/generators/commands.js +845 -0
  29. package/dist/generators/commands.js.map +1 -0
  30. package/dist/generators/context.d.ts +11 -0
  31. package/dist/generators/context.js +621 -0
  32. package/dist/generators/context.js.map +1 -0
  33. package/dist/generators/hooks.d.ts +5 -0
  34. package/dist/generators/hooks.js +128 -0
  35. package/dist/generators/hooks.js.map +1 -0
  36. package/dist/generators/index.d.ts +11 -0
  37. package/dist/generators/index.js +541 -0
  38. package/dist/generators/index.js.map +1 -0
  39. package/dist/generators/prompts.d.ts +13 -0
  40. package/dist/generators/prompts.js +579 -0
  41. package/dist/generators/prompts.js.map +1 -0
  42. package/dist/generators/registry.d.ts +5 -0
  43. package/dist/generators/registry.js +93 -0
  44. package/dist/generators/registry.js.map +1 -0
  45. package/dist/scanners/dependencies.d.ts +7 -0
  46. package/dist/scanners/dependencies.js +195 -0
  47. package/dist/scanners/dependencies.js.map +1 -0
  48. package/dist/scanners/index.d.ts +6 -0
  49. package/dist/scanners/index.js +37 -0
  50. package/dist/scanners/index.js.map +1 -0
  51. package/dist/scanners/samples.d.ts +8 -0
  52. package/dist/scanners/samples.js +193 -0
  53. package/dist/scanners/samples.js.map +1 -0
  54. package/dist/scanners/stack.d.ts +5 -0
  55. package/dist/scanners/stack.js +294 -0
  56. package/dist/scanners/stack.js.map +1 -0
  57. package/dist/scanners/structure.d.ts +5 -0
  58. package/dist/scanners/structure.js +274 -0
  59. package/dist/scanners/structure.js.map +1 -0
  60. package/dist/services/grepai.d.ts +25 -0
  61. package/dist/services/grepai.js +89 -0
  62. package/dist/services/grepai.js.map +1 -0
  63. package/dist/services/ollama.d.ts +22 -0
  64. package/dist/services/ollama.js +86 -0
  65. package/dist/services/ollama.js.map +1 -0
  66. package/dist/services/package-manager.d.ts +95 -0
  67. package/dist/services/package-manager.js +164 -0
  68. package/dist/services/package-manager.js.map +1 -0
  69. package/dist/types.d.ts +233 -0
  70. package/dist/types.js +5 -0
  71. package/dist/types.js.map +1 -0
  72. 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,5 @@
1
+ import type { StructureInfo, ScanOptions } from '../types.js';
2
+ /**
3
+ * Scan project structure
4
+ */
5
+ export declare function scanStructure(projectPath: string, options?: ScanOptions): Promise<StructureInfo>;
@@ -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":"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"}
@@ -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>;