@merlean/analyzer 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/analyzer.js +77 -3
  2. package/package.json +1 -1
package/lib/analyzer.js CHANGED
@@ -67,12 +67,19 @@ async function scanCodebase(codebasePath) {
67
67
  const content = fs.readFileSync(file, 'utf-8');
68
68
  const relativePath = path.relative(codebasePath, file);
69
69
 
70
- // Limit content per file
71
- const truncatedContent = content.slice(0, 3000);
70
+ // Smart extraction: if file is large, extract route-like patterns
71
+ let extractedContent;
72
+ if (content.length > 8000) {
73
+ // For large files, extract route definitions and API patterns
74
+ extractedContent = extractRoutePatterns(content, relativePath);
75
+ } else {
76
+ // For smaller files, include more content
77
+ extractedContent = content.slice(0, 8000);
78
+ }
72
79
 
73
80
  fileContents.push({
74
81
  path: relativePath,
75
- content: truncatedContent
82
+ content: extractedContent
76
83
  });
77
84
  } catch (error) {
78
85
  // Skip files that can't be read
@@ -82,6 +89,73 @@ async function scanCodebase(codebasePath) {
82
89
  return fileContents;
83
90
  }
84
91
 
92
+ /**
93
+ * Extract route patterns from large files
94
+ */
95
+ function extractRoutePatterns(content, filePath) {
96
+ const lines = content.split('\n');
97
+ const relevantLines = [];
98
+
99
+ // Patterns that indicate API routes/endpoints
100
+ const routePatterns = [
101
+ /app\.(get|post|put|patch|delete|use)\s*\(/i,
102
+ /router\.(get|post|put|patch|delete|use)\s*\(/i,
103
+ /Route::(get|post|put|patch|delete)\s*\(/i,
104
+ /@(Get|Post|Put|Patch|Delete|RequestMapping)/i,
105
+ /def\s+(get|post|put|patch|delete|index|create|update|destroy)/i,
106
+ /function\s+\w+\s*\(\s*(req|request)/i,
107
+ /fetch\s*\(/i,
108
+ /axios\./i,
109
+ /api['"]\s*:/i,
110
+ /endpoint/i,
111
+ /\/api\//i
112
+ ];
113
+
114
+ let inRouteBlock = false;
115
+ let braceCount = 0;
116
+
117
+ for (let i = 0; i < lines.length; i++) {
118
+ const line = lines[i];
119
+
120
+ // Check if line matches any route pattern
121
+ const isRouteLine = routePatterns.some(pattern => pattern.test(line));
122
+
123
+ if (isRouteLine) {
124
+ // Include context: 2 lines before
125
+ for (let j = Math.max(0, i - 2); j < i; j++) {
126
+ if (!relevantLines.includes(lines[j])) {
127
+ relevantLines.push(`// Line ${j + 1}: ${lines[j]}`);
128
+ }
129
+ }
130
+ relevantLines.push(`// Line ${i + 1}: ${line}`);
131
+ inRouteBlock = true;
132
+ braceCount = (line.match(/{/g) || []).length - (line.match(/}/g) || []).length;
133
+ } else if (inRouteBlock) {
134
+ // Continue capturing the route handler
135
+ relevantLines.push(line);
136
+ braceCount += (line.match(/{/g) || []).length - (line.match(/}/g) || []).length;
137
+
138
+ // End of route block
139
+ if (braceCount <= 0) {
140
+ inRouteBlock = false;
141
+ relevantLines.push('// ---');
142
+ }
143
+
144
+ // Safety limit per block
145
+ if (relevantLines.length > 200) {
146
+ inRouteBlock = false;
147
+ }
148
+ }
149
+ }
150
+
151
+ // If we found relevant lines, return them; otherwise return truncated content
152
+ if (relevantLines.length > 10) {
153
+ return `// Extracted route patterns from ${filePath} (${lines.length} lines total)\n\n${relevantLines.join('\n')}`;
154
+ }
155
+
156
+ return content.slice(0, 8000);
157
+ }
158
+
85
159
  /**
86
160
  * Prioritize files based on keywords in path/name
87
161
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@merlean/analyzer",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "AI Bot codebase analyzer - generates site maps for AI assistant integration",
5
5
  "keywords": ["ai", "bot", "analyzer", "claude", "anthropic", "widget"],
6
6
  "author": "zmaren",