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,93 @@
1
+ /**
2
+ * Generate entity-registry.json
3
+ */
4
+ export function generateRegistry(projectInfo, analysis) {
5
+ const registry = {
6
+ _meta: {
7
+ version: '2.1',
8
+ generated: new Date().toISOString().split('T')[0],
9
+ tool: 'mustard-cli'
10
+ },
11
+ _p: generatePatterns(projectInfo),
12
+ e: generateEntities(projectInfo, analysis)
13
+ };
14
+ return registry;
15
+ }
16
+ /**
17
+ * Generate path patterns based on detected stacks
18
+ */
19
+ function generatePatterns(projectInfo) {
20
+ const patterns = {};
21
+ // Find database stack
22
+ const dbStack = projectInfo.stacks.find(s => ['drizzle', 'prisma', 'typeorm', 'sequelize'].includes(s.name));
23
+ if (dbStack) {
24
+ const basePath = dbStack.path === '.' ? '' : `${dbStack.path}/`;
25
+ if (dbStack.name === 'drizzle') {
26
+ patterns.db = `${basePath}src/schema/{e}.ts`;
27
+ }
28
+ else if (dbStack.name === 'prisma') {
29
+ patterns.db = `${basePath}prisma/schema.prisma`;
30
+ }
31
+ else {
32
+ patterns.db = `${basePath}src/entities/{e}.ts`;
33
+ }
34
+ }
35
+ // Find backend stack
36
+ const beStack = projectInfo.stacks.find(s => ['dotnet', 'node', 'python', 'java', 'go', 'rust'].includes(s.name));
37
+ if (beStack) {
38
+ const basePath = beStack.path === '.' ? '' : `${beStack.path}/`;
39
+ if (beStack.name === 'dotnet') {
40
+ patterns.be = `${basePath}Modules/{E}/`;
41
+ }
42
+ else if (beStack.name === 'python') {
43
+ patterns.be = `${basePath}app/modules/{e}/`;
44
+ }
45
+ else {
46
+ patterns.be = `${basePath}src/modules/{e}/`;
47
+ }
48
+ }
49
+ // Find frontend stack
50
+ const feStack = projectInfo.stacks.find(s => ['react', 'nextjs', 'vue', 'angular', 'svelte'].includes(s.name));
51
+ if (feStack) {
52
+ const basePath = feStack.path === '.' ? '' : `${feStack.path}/`;
53
+ if (feStack.name === 'nextjs') {
54
+ patterns.fe = `${basePath}src/features/{e}/`;
55
+ }
56
+ else {
57
+ patterns.fe = `${basePath}src/features/{e}/`;
58
+ }
59
+ }
60
+ return patterns;
61
+ }
62
+ /**
63
+ * Generate entities map from analysis
64
+ */
65
+ function generateEntities(projectInfo, analysis) {
66
+ const entities = {};
67
+ // Add entities discovered by semantic analyzer
68
+ if (analysis.entities && Array.isArray(analysis.entities)) {
69
+ for (const entity of analysis.entities) {
70
+ // Normalize entity name to PascalCase
71
+ const name = toPascalCase(typeof entity === 'string' ? entity : entity.name);
72
+ if (name && !entities[name]) {
73
+ entities[name] = 1;
74
+ }
75
+ }
76
+ }
77
+ // If no entities found, add placeholder
78
+ if (Object.keys(entities).length === 0) {
79
+ entities['_placeholder'] = 0;
80
+ }
81
+ return entities;
82
+ }
83
+ /**
84
+ * Convert string to PascalCase
85
+ */
86
+ function toPascalCase(str) {
87
+ if (!str)
88
+ return '';
89
+ return str
90
+ .replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))
91
+ .replace(/^(.)/, (_, c) => c.toUpperCase());
92
+ }
93
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/generators/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { DependencyInfo } from '../types.js';
2
+ /**
3
+ * Scan all package.json and .csproj files to extract real dependencies
4
+ */
5
+ export declare function scanDependencies(projectPath: string, options?: {
6
+ verbose?: boolean;
7
+ }): Promise<DependencyInfo>;
@@ -0,0 +1,195 @@
1
+ import { readFile } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { glob } from 'glob';
4
+ /** Notable npm packages grouped by category */
5
+ const NPM_CATEGORIES = {
6
+ frontend: [
7
+ 'react', 'react-dom', 'next', 'vue', 'nuxt', 'svelte', '@sveltejs/kit',
8
+ 'angular', '@angular/core',
9
+ // UI
10
+ '@radix-ui', 'shadcn', '@headlessui', '@mui/material', 'antd',
11
+ 'tailwindcss', 'styled-components', '@emotion/react',
12
+ 'lucide-react', '@heroicons/react', 'react-icons',
13
+ // State
14
+ '@tanstack/react-query', 'swr', 'zustand', 'jotai', 'recoil',
15
+ 'redux', '@reduxjs/toolkit', 'mobx', 'pinia', 'vuex',
16
+ // Forms
17
+ 'react-hook-form', '@hookform/resolvers', 'formik',
18
+ // Tables
19
+ '@tanstack/react-table', '@tanstack/react-virtual', 'ag-grid-react',
20
+ // Validation (shared)
21
+ 'zod', 'yup', 'joi', 'valibot',
22
+ // Charts
23
+ 'recharts', 'chart.js', 'd3', 'visx', 'nivo',
24
+ // Date
25
+ 'date-fns', 'dayjs', 'moment', 'luxon',
26
+ // Animation
27
+ 'framer-motion', 'lottie-react', 'gsap',
28
+ // Notifications
29
+ 'sonner', 'react-toastify', 'react-hot-toast', 'notistack',
30
+ ],
31
+ backend: [
32
+ 'express', 'fastify', 'koa', 'hapi', 'nest', '@nestjs/core',
33
+ 'graphql', '@apollo/server', 'mercurius',
34
+ 'trpc', '@trpc/server',
35
+ 'passport', 'jsonwebtoken', 'bcrypt', 'argon2',
36
+ 'nodemailer', 'bullmq', 'agenda',
37
+ 'winston', 'pino',
38
+ 'swagger-jsdoc', 'swagger-ui-express',
39
+ ],
40
+ database: [
41
+ 'drizzle-orm', 'drizzle-kit',
42
+ 'prisma', '@prisma/client',
43
+ 'typeorm', 'sequelize', 'knex', 'kysely',
44
+ 'mongoose', 'mongodb',
45
+ 'pg', 'mysql2', 'better-sqlite3', 'redis', 'ioredis',
46
+ ],
47
+ testing: [
48
+ 'jest', 'vitest', '@testing-library/react', '@testing-library/jest-dom',
49
+ 'playwright', '@playwright/test', 'cypress',
50
+ 'supertest', 'msw', 'nock',
51
+ ],
52
+ tooling: [
53
+ 'typescript', 'eslint', 'prettier', 'biome',
54
+ 'vite', 'turbo', 'nx', 'webpack', 'esbuild', 'tsup', 'tsx',
55
+ 'husky', 'lint-staged', 'commitlint',
56
+ '@kubb/cli', 'openapi-typescript',
57
+ ],
58
+ };
59
+ /** Notable NuGet packages grouped by category */
60
+ const NUGET_CATEGORIES = {
61
+ backend: [
62
+ 'Microsoft.AspNetCore', 'FastEndpoints',
63
+ 'MediatR', 'AutoMapper', 'Mapster',
64
+ 'FluentValidation', 'FluentResults',
65
+ 'Serilog', 'NLog',
66
+ 'Swashbuckle', 'NSwag',
67
+ 'MassTransit', 'Rebus',
68
+ 'Hangfire', 'Quartz',
69
+ 'HotChocolate', 'GraphQL',
70
+ 'IdentityServer', 'Duende',
71
+ 'Polly', 'Refit',
72
+ ],
73
+ database: [
74
+ 'Microsoft.EntityFrameworkCore', 'Npgsql',
75
+ 'Dapper', 'SqlKata',
76
+ 'MongoDB.Driver', 'StackExchange.Redis',
77
+ ],
78
+ testing: [
79
+ 'xunit', 'NUnit', 'MSTest',
80
+ 'Moq', 'NSubstitute', 'FakeItEasy',
81
+ 'FluentAssertions', 'Shouldly',
82
+ 'Bogus', 'AutoFixture',
83
+ 'WireMock', 'Testcontainers',
84
+ ],
85
+ };
86
+ /**
87
+ * Scan all package.json and .csproj files to extract real dependencies
88
+ */
89
+ export async function scanDependencies(projectPath, options = {}) {
90
+ const result = {};
91
+ // Scan npm packages
92
+ const pkgFiles = await glob('**/package.json', {
93
+ cwd: projectPath,
94
+ nodir: true,
95
+ ignore: ['**/node_modules/**', '**/dist/**', '**/.next/**']
96
+ });
97
+ for (const pkgFile of pkgFiles) {
98
+ try {
99
+ const fullPath = join(projectPath, pkgFile);
100
+ const pkg = JSON.parse(await readFile(fullPath, 'utf-8'));
101
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
102
+ const subPath = pkgFile.replace(/[/\\]package\.json$/, '') || '.';
103
+ const categorized = categorizeNpmDeps(allDeps);
104
+ if (hasAnyDeps(categorized)) {
105
+ result[subPath] = categorized;
106
+ if (options.verbose) {
107
+ const total = Object.values(categorized).reduce((sum, arr) => sum + (arr?.length ?? 0), 0);
108
+ console.log(` Found ${total} notable dependencies in ${subPath}/package.json`);
109
+ }
110
+ }
111
+ }
112
+ catch { /* skip unreadable */ }
113
+ }
114
+ // Scan .csproj files for NuGet packages
115
+ const csprojFiles = await glob('**/*.csproj', {
116
+ cwd: projectPath,
117
+ nodir: true,
118
+ ignore: ['**/bin/**', '**/obj/**']
119
+ });
120
+ for (const csprojFile of csprojFiles) {
121
+ try {
122
+ const fullPath = join(projectPath, csprojFile);
123
+ const content = await readFile(fullPath, 'utf-8');
124
+ const subPath = csprojFile.replace(/[/\\][^/\\]+\.csproj$/, '') || '.';
125
+ const categorized = categorizeNugetDeps(content);
126
+ if (hasAnyDeps(categorized)) {
127
+ // Merge with existing entry for this path
128
+ const existing = result[subPath] ?? {};
129
+ for (const [cat, libs] of Object.entries(categorized)) {
130
+ const key = cat;
131
+ if (libs && libs.length > 0) {
132
+ existing[key] = [...(existing[key] ?? []), ...libs];
133
+ }
134
+ }
135
+ result[subPath] = existing;
136
+ if (options.verbose) {
137
+ const total = Object.values(categorized).reduce((sum, arr) => sum + (arr?.length ?? 0), 0);
138
+ console.log(` Found ${total} notable packages in ${csprojFile}`);
139
+ }
140
+ }
141
+ }
142
+ catch { /* skip */ }
143
+ }
144
+ return result;
145
+ }
146
+ function categorizeNpmDeps(deps) {
147
+ const result = {};
148
+ const depNames = Object.keys(deps);
149
+ for (const [category, patterns] of Object.entries(NPM_CATEGORIES)) {
150
+ const found = [];
151
+ for (const pattern of patterns) {
152
+ // Match exact name or prefix (e.g., '@radix-ui' matches '@radix-ui/react-dialog')
153
+ const matches = depNames.filter(d => d === pattern || d.startsWith(pattern + '/'));
154
+ for (const match of matches) {
155
+ const version = deps[match]?.replace(/[\^~>=<]*/g, '') ?? '';
156
+ // For scoped packages that match a prefix, just note the prefix once
157
+ if (pattern.startsWith('@') && match !== pattern && match.startsWith(pattern + '/')) {
158
+ if (!found.some(f => f.startsWith(pattern))) {
159
+ found.push(`${pattern}/* ${version}`);
160
+ }
161
+ }
162
+ else {
163
+ found.push(`${match} ${version}`);
164
+ }
165
+ }
166
+ }
167
+ if (found.length > 0) {
168
+ result[category] = [...new Set(found)];
169
+ }
170
+ }
171
+ return result;
172
+ }
173
+ function categorizeNugetDeps(csprojContent) {
174
+ const result = {};
175
+ // Extract PackageReference elements
176
+ const packageRefs = [...csprojContent.matchAll(/<PackageReference\s+Include="([^"]+)"(?:\s+Version="([^"]+)")?/g)];
177
+ const packages = packageRefs.map(m => ({ name: m[1] ?? '', version: m[2] ?? '' }));
178
+ for (const [category, patterns] of Object.entries(NUGET_CATEGORIES)) {
179
+ const found = [];
180
+ for (const pattern of patterns) {
181
+ const matches = packages.filter(p => p.name === pattern || p.name.startsWith(pattern + '.'));
182
+ for (const match of matches) {
183
+ found.push(`${match.name} ${match.version}`);
184
+ }
185
+ }
186
+ if (found.length > 0) {
187
+ result[category] = [...new Set(found)];
188
+ }
189
+ }
190
+ return result;
191
+ }
192
+ function hasAnyDeps(categorized) {
193
+ return Object.values(categorized).some(arr => arr && arr.length > 0);
194
+ }
195
+ //# sourceMappingURL=dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/scanners/dependencies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { ProjectInfo, ScanOptions } from '../types.js';
2
+ /**
3
+ * Main scanner orchestrator
4
+ * Scans the project directory and returns comprehensive project info
5
+ */
6
+ export declare function scanProject(projectPath: string, options?: ScanOptions): Promise<ProjectInfo>;
@@ -0,0 +1,37 @@
1
+ import { scanStack } from './stack.js';
2
+ import { scanStructure } from './structure.js';
3
+ import { scanDependencies } from './dependencies.js';
4
+ /**
5
+ * Main scanner orchestrator
6
+ * Scans the project directory and returns comprehensive project info
7
+ */
8
+ export async function scanProject(projectPath, options = {}) {
9
+ const { verbose = false } = options;
10
+ // Scan stack (languages, frameworks)
11
+ const stackInfo = await scanStack(projectPath, { verbose });
12
+ // Scan structure (monorepo, folders)
13
+ const structureInfo = await scanStructure(projectPath, { verbose });
14
+ // Scan dependencies from package.json and .csproj
15
+ const dependencies = await scanDependencies(projectPath, { verbose });
16
+ // Combine results
17
+ return {
18
+ name: structureInfo.name,
19
+ path: projectPath,
20
+ type: structureInfo.type, // 'monorepo' | 'single'
21
+ stacks: stackInfo.stacks,
22
+ patterns: {
23
+ classes: stackInfo.naming.classes,
24
+ files: stackInfo.naming.files,
25
+ folders: structureInfo.folderStyle
26
+ },
27
+ structure: structureInfo,
28
+ packageManager: stackInfo.packageManager,
29
+ entities: [], // Will be populated by semantic analyzer
30
+ dependencies,
31
+ raw: {
32
+ stack: stackInfo,
33
+ structure: structureInfo
34
+ }
35
+ };
36
+ }
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanners/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,WAAmB,EAAE,UAAuB,EAAE;IAC9E,MAAM,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEpC,qCAAqC;IACrC,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAE5D,qCAAqC;IACrC,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAEpE,kDAAkD;IAClD,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAEtE,kBAAkB;IAClB,OAAO;QACL,IAAI,EAAE,aAAa,CAAC,IAAI;QACxB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,wBAAwB;QAClD,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,QAAQ,EAAE;YACR,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,OAAO;YACjC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK;YAC7B,OAAO,EAAE,aAAa,CAAC,WAAW;SACnC;QACD,SAAS,EAAE,aAAa;QACxB,cAAc,EAAE,SAAS,CAAC,cAAc;QACxC,QAAQ,EAAE,EAAE,EAAE,yCAAyC;QACvD,YAAY;QACZ,GAAG,EAAE;YACH,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,aAAa;SACzB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { Stack, CodeSamples } from '../types.js';
2
+ /**
3
+ * Scan the project for real code samples without grepai
4
+ * Returns up to 1 sample per type (service, endpoint, component, hook)
5
+ */
6
+ export declare function scanCodeSamples(projectPath: string, stacks: Stack[], options?: {
7
+ verbose?: boolean;
8
+ }): Promise<CodeSamples>;
@@ -0,0 +1,193 @@
1
+ import { readFile, readdir, stat } from 'fs/promises';
2
+ import { join, relative, extname, basename } from 'path';
3
+ const SAMPLE_PATTERNS = {
4
+ dotnet: [
5
+ {
6
+ type: 'service',
7
+ pathPatterns: [/Services?[/\\]/i, /Service\.cs$/i],
8
+ extensions: ['.cs'],
9
+ maxLines: 120,
10
+ },
11
+ {
12
+ type: 'endpoint',
13
+ pathPatterns: [/EndPoints?[/\\]/i, /Controller\.cs$/i, /EndPoint\.cs$/i, /EndPoints\.cs$/i],
14
+ extensions: ['.cs'],
15
+ maxLines: 120,
16
+ },
17
+ ],
18
+ node: [
19
+ {
20
+ type: 'service',
21
+ pathPatterns: [/\.service\.(ts|js)$/i, /services?[/\\]/i],
22
+ extensions: ['.ts', '.js'],
23
+ maxLines: 100,
24
+ },
25
+ {
26
+ type: 'endpoint',
27
+ pathPatterns: [/\.controller\.(ts|js)$/i, /\.route\.(ts|js)$/i, /controllers?[/\\]/i, /routes?[/\\]/i],
28
+ extensions: ['.ts', '.js'],
29
+ maxLines: 100,
30
+ },
31
+ ],
32
+ react: [
33
+ {
34
+ type: 'component',
35
+ pathPatterns: [/components?[/\\].*\.tsx$/i, /_components[/\\].*\.tsx$/i],
36
+ extensions: ['.tsx'],
37
+ maxLines: 100,
38
+ },
39
+ {
40
+ type: 'hook',
41
+ pathPatterns: [/hooks?[/\\]use.*\.(ts|tsx)$/i, /use[A-Z].*\.(ts|tsx)$/i],
42
+ extensions: ['.ts', '.tsx'],
43
+ maxLines: 100,
44
+ },
45
+ ],
46
+ nextjs: [
47
+ {
48
+ type: 'component',
49
+ pathPatterns: [/_components[/\\].*\.tsx$/i, /components?[/\\].*\.tsx$/i],
50
+ extensions: ['.tsx'],
51
+ maxLines: 100,
52
+ },
53
+ {
54
+ type: 'hook',
55
+ pathPatterns: [/hooks?[/\\]use.*\.(ts|tsx)$/i],
56
+ extensions: ['.ts', '.tsx'],
57
+ maxLines: 100,
58
+ },
59
+ ],
60
+ drizzle: [
61
+ {
62
+ type: 'service',
63
+ pathPatterns: [/schema[/\\](?!index\.).*\.ts$/i],
64
+ extensions: ['.ts'],
65
+ maxLines: 120,
66
+ },
67
+ ],
68
+ prisma: [
69
+ {
70
+ type: 'service',
71
+ pathPatterns: [/schema\.prisma$/i],
72
+ extensions: ['.prisma'],
73
+ maxLines: 120,
74
+ },
75
+ ],
76
+ };
77
+ /** Directories to always skip */
78
+ const SKIP_DIRS = new Set([
79
+ 'node_modules', '.git', '.next', 'dist', 'build', 'bin', 'obj',
80
+ '.claude', '.vs', '.vscode', 'coverage', '__pycache__', '.nuxt',
81
+ 'migrations', 'backup', 'backups', '.angular',
82
+ ]);
83
+ /**
84
+ * Scan the project for real code samples without grepai
85
+ * Returns up to 1 sample per type (service, endpoint, component, hook)
86
+ */
87
+ export async function scanCodeSamples(projectPath, stacks, options = {}) {
88
+ const samples = {};
89
+ const stackNames = stacks.map(s => s.name);
90
+ // Collect patterns for detected stacks
91
+ const patterns = [];
92
+ for (const name of stackNames) {
93
+ const stackPatterns = SAMPLE_PATTERNS[name];
94
+ if (stackPatterns) {
95
+ patterns.push(...stackPatterns);
96
+ }
97
+ }
98
+ if (patterns.length === 0)
99
+ return samples;
100
+ // Walk the project tree looking for matching files
101
+ const candidates = new Map();
102
+ await walkDir(projectPath, projectPath, patterns, candidates, 0, 6);
103
+ // Pick the best candidate for each type
104
+ for (const [type, files] of candidates) {
105
+ if (files.length === 0)
106
+ continue;
107
+ // Prefer files with more content (not too small) and specific names
108
+ files.sort((a, b) => b.score - a.score);
109
+ const best = files[0];
110
+ if (!best)
111
+ continue;
112
+ const pattern = patterns.find(p => p.type === type);
113
+ const maxLines = pattern?.maxLines ?? 100;
114
+ try {
115
+ const content = await readFileTruncated(best.file, maxLines);
116
+ if (content.length > 50) { // Skip very small files
117
+ samples[type] = {
118
+ file: relative(projectPath, best.file).replace(/\\/g, '/'),
119
+ content,
120
+ type,
121
+ };
122
+ if (options.verbose) {
123
+ console.log(` Found ${type} sample: ${relative(projectPath, best.file)}`);
124
+ }
125
+ }
126
+ }
127
+ catch {
128
+ // Skip unreadable files
129
+ }
130
+ }
131
+ return samples;
132
+ }
133
+ /**
134
+ * Recursively walk directory to find matching files
135
+ */
136
+ async function walkDir(dir, rootPath, patterns, candidates, depth, maxDepth) {
137
+ if (depth > maxDepth)
138
+ return;
139
+ let entries;
140
+ try {
141
+ entries = await readdir(dir, { withFileTypes: true });
142
+ }
143
+ catch {
144
+ return;
145
+ }
146
+ for (const entry of entries) {
147
+ const fullPath = join(dir, entry.name);
148
+ if (entry.isDirectory()) {
149
+ if (SKIP_DIRS.has(entry.name) || entry.name.startsWith('.'))
150
+ continue;
151
+ await walkDir(fullPath, rootPath, patterns, candidates, depth + 1, maxDepth);
152
+ }
153
+ else if (entry.isFile()) {
154
+ const relPath = relative(rootPath, fullPath);
155
+ const ext = extname(entry.name);
156
+ for (const pattern of patterns) {
157
+ if (!pattern.extensions.includes(ext))
158
+ continue;
159
+ const matched = pattern.pathPatterns.some(rx => rx.test(relPath));
160
+ if (!matched)
161
+ continue;
162
+ // Check file size (skip huge files)
163
+ try {
164
+ const info = await stat(fullPath);
165
+ if (info.size > (pattern.maxSize ?? 50000))
166
+ continue;
167
+ if (info.size < 100)
168
+ continue;
169
+ // Score: prefer medium-sized files with descriptive names
170
+ const nameLen = basename(entry.name, ext).length;
171
+ const score = Math.min(info.size, 5000) + (nameLen > 5 ? 100 : 0);
172
+ const list = candidates.get(pattern.type) ?? [];
173
+ list.push({ file: fullPath, score });
174
+ candidates.set(pattern.type, list);
175
+ }
176
+ catch {
177
+ // Skip
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+ /**
184
+ * Read a file, returning only the first N lines
185
+ */
186
+ async function readFileTruncated(filePath, maxLines) {
187
+ const content = await readFile(filePath, 'utf-8');
188
+ const lines = content.split('\n');
189
+ if (lines.length <= maxLines)
190
+ return content;
191
+ return lines.slice(0, maxLines).join('\n') + '\n// ... (truncated)';
192
+ }
193
+ //# sourceMappingURL=samples.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"samples.js","sourceRoot":"","sources":["../../src/scanners/samples.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAezD,MAAM,eAAe,GAAoC;IACvD,MAAM,EAAE;QACN;YACE,IAAI,EAAE,SAAS;YACf,YAAY,EAAE,CAAC,iBAAiB,EAAE,eAAe,CAAC;YAClD,UAAU,EAAE,CAAC,KAAK,CAAC;YACnB,QAAQ,EAAE,GAAG;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,YAAY,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,CAAC;YAC3F,UAAU,EAAE,CAAC,KAAK,CAAC;YACnB,QAAQ,EAAE,GAAG;SACd;KACF;IACD,IAAI,EAAE;QACJ;YACE,IAAI,EAAE,SAAS;YACf,YAAY,EAAE,CAAC,sBAAsB,EAAE,iBAAiB,CAAC;YACzD,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;YAC1B,QAAQ,EAAE,GAAG;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,YAAY,EAAE,CAAC,yBAAyB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,eAAe,CAAC;YACtG,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;YAC1B,QAAQ,EAAE,GAAG;SACd;KACF;IACD,KAAK,EAAE;QACL;YACE,IAAI,EAAE,WAAW;YACjB,YAAY,EAAE,CAAC,2BAA2B,EAAE,2BAA2B,CAAC;YACxE,UAAU,EAAE,CAAC,MAAM,CAAC;YACpB,QAAQ,EAAE,GAAG;SACd;QACD;YACE,IAAI,EAAE,MAAM;YACZ,YAAY,EAAE,CAAC,8BAA8B,EAAE,wBAAwB,CAAC;YACxE,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC;YAC3B,QAAQ,EAAE,GAAG;SACd;KACF;IACD,MAAM,EAAE;QACN;YACE,IAAI,EAAE,WAAW;YACjB,YAAY,EAAE,CAAC,2BAA2B,EAAE,2BAA2B,CAAC;YACxE,UAAU,EAAE,CAAC,MAAM,CAAC;YACpB,QAAQ,EAAE,GAAG;SACd;QACD;YACE,IAAI,EAAE,MAAM;YACZ,YAAY,EAAE,CAAC,8BAA8B,CAAC;YAC9C,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC;YAC3B,QAAQ,EAAE,GAAG;SACd;KACF;IACD,OAAO,EAAE;QACP;YACE,IAAI,EAAE,SAA8B;YACpC,YAAY,EAAE,CAAC,gCAAgC,CAAC;YAChD,UAAU,EAAE,CAAC,KAAK,CAAC;YACnB,QAAQ,EAAE,GAAG;SACd;KACF;IACD,MAAM,EAAE;QACN;YACE,IAAI,EAAE,SAA8B;YACpC,YAAY,EAAE,CAAC,kBAAkB,CAAC;YAClC,UAAU,EAAE,CAAC,SAAS,CAAC;YACvB,QAAQ,EAAE,GAAG;SACd;KACF;CACF,CAAC;AAEF,iCAAiC;AACjC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK;IAC9D,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO;IAC/D,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU;CAC9C,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAmB,EACnB,MAAe,EACf,UAAiC,EAAE;IAEnC,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE3C,uCAAuC;IACvC,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,aAAa,EAAE,CAAC;YAClB,QAAQ,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAE1C,mDAAmD;IACnD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAwD,CAAC;IAEnF,MAAM,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAEpE,wCAAwC;IACxC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACjC,oEAAoE;QACpE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,GAAG,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC7D,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC,wBAAwB;gBACjD,OAAO,CAAC,IAAI,CAAC,GAAG;oBACd,IAAI,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;oBAC1D,OAAO;oBACP,IAAI;iBACL,CAAC;gBACF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBACpB,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,YAAY,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC7E,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,OAAO,CACpB,GAAW,EACX,QAAgB,EAChB,QAAyB,EACzB,UAAqE,EACrE,KAAa,EACb,QAAgB;IAEhB,IAAI,KAAK,GAAG,QAAQ;QAAE,OAAO;IAE7B,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAEvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACtE,MAAM,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC/E,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEhC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAEhD,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClE,IAAI,CAAC,OAAO;oBAAE,SAAS;gBAEvB,oCAAoC;gBACpC,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAClC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;wBAAE,SAAS;oBACrD,IAAI,IAAI,CAAC,IAAI,GAAG,GAAG;wBAAE,SAAS;oBAE9B,0DAA0D;oBAC1D,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC;oBACjD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAElE,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBAChD,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;oBACrC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACrC,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,iBAAiB,CAAC,QAAgB,EAAE,QAAgB;IACjE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,OAAO,CAAC;IAC7C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC;AACtE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StackScanResult, ScanOptions } from '../types.js';
2
+ /**
3
+ * Scan project for stacks (languages and frameworks)
4
+ */
5
+ export declare function scanStack(projectPath: string, options?: ScanOptions): Promise<StackScanResult>;