@merlean/analyzer 2.1.0 → 2.3.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/bin/cli.js +47 -12
- package/lib/analyzer.js +1231 -123
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -23,7 +23,8 @@ function parseArgs() {
|
|
|
23
23
|
path: null,
|
|
24
24
|
name: null,
|
|
25
25
|
backend: DEFAULT_BACKEND,
|
|
26
|
-
output: null
|
|
26
|
+
output: null,
|
|
27
|
+
mergeWith: null // Existing siteId to merge into
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -35,6 +36,8 @@ function parseArgs() {
|
|
|
35
36
|
options.backend = args[++i];
|
|
36
37
|
} else if (arg === '--output' || arg === '-o') {
|
|
37
38
|
options.output = args[++i];
|
|
39
|
+
} else if (arg === '--merge-with' || arg === '-m') {
|
|
40
|
+
options.mergeWith = args[++i];
|
|
38
41
|
} else if (arg === '--help' || arg === '-h') {
|
|
39
42
|
printHelp();
|
|
40
43
|
process.exit(0);
|
|
@@ -58,7 +61,8 @@ Arguments:
|
|
|
58
61
|
<path> Path to codebase (default: current directory)
|
|
59
62
|
|
|
60
63
|
Options:
|
|
61
|
-
--name, -n <name> Site name (required)
|
|
64
|
+
--name, -n <name> Site name (required for new analysis)
|
|
65
|
+
--merge-with, -m <siteId> Merge into existing site map (appends routes/forms/actions)
|
|
62
66
|
--backend, -b <url> Backend URL (default: ${DEFAULT_BACKEND})
|
|
63
67
|
--output, -o <file> Save site map locally (optional)
|
|
64
68
|
--help, -h Show this help
|
|
@@ -70,6 +74,9 @@ Examples:
|
|
|
70
74
|
# Analyze specific path
|
|
71
75
|
npx @merlean/analyzer ./my-app --name "My App"
|
|
72
76
|
|
|
77
|
+
# Merge another frontend into existing site map
|
|
78
|
+
npx @merlean/analyzer ./admin-panel --merge-with site_abc123
|
|
79
|
+
|
|
73
80
|
# Use custom backend (for local dev)
|
|
74
81
|
npx @merlean/analyzer --name "My App" --backend http://localhost:3004
|
|
75
82
|
`);
|
|
@@ -81,8 +88,8 @@ async function main() {
|
|
|
81
88
|
const options = parseArgs();
|
|
82
89
|
|
|
83
90
|
// Validate required args
|
|
84
|
-
if (!options.name) {
|
|
85
|
-
console.error('❌ Error: --name is required');
|
|
91
|
+
if (!options.name && !options.mergeWith) {
|
|
92
|
+
console.error('❌ Error: --name is required (or use --merge-with to merge into existing site)');
|
|
86
93
|
console.log(' Run with --help for usage');
|
|
87
94
|
process.exit(1);
|
|
88
95
|
}
|
|
@@ -96,22 +103,41 @@ async function main() {
|
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
console.log(`📁 Scanning: ${codebasePath}`);
|
|
99
|
-
|
|
106
|
+
if (options.mergeWith) {
|
|
107
|
+
console.log(`🔗 Merging into: ${options.mergeWith}`);
|
|
108
|
+
if (options.name) {
|
|
109
|
+
console.log(`📛 Site name: ${options.name} (will update existing)`);
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
console.log(`📛 Site name: ${options.name}`);
|
|
113
|
+
}
|
|
100
114
|
|
|
101
115
|
try {
|
|
102
116
|
// Scan codebase locally
|
|
103
|
-
const
|
|
117
|
+
const scanResult = await scanCodebase(codebasePath);
|
|
118
|
+
// Handle both old format (array) and new format (object with files + preExtractedRoutes)
|
|
119
|
+
const fileContents = Array.isArray(scanResult) ? scanResult : scanResult.files;
|
|
120
|
+
const preExtractedRoutes = Array.isArray(scanResult) ? [] : (scanResult.preExtractedRoutes || []);
|
|
104
121
|
|
|
105
122
|
console.log(`\n📤 Uploading to backend for analysis...`);
|
|
106
123
|
|
|
124
|
+
// Build request body
|
|
125
|
+
const requestBody = {
|
|
126
|
+
siteName: options.name,
|
|
127
|
+
files: fileContents,
|
|
128
|
+
preExtractedRoutes // Include convention-based routes
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Add merge parameter if specified
|
|
132
|
+
if (options.mergeWith) {
|
|
133
|
+
requestBody.mergeWithSiteId = options.mergeWith;
|
|
134
|
+
}
|
|
135
|
+
|
|
107
136
|
// Send to backend for LLM analysis
|
|
108
137
|
const response = await fetch(`${options.backend}/api/analyze`, {
|
|
109
138
|
method: 'POST',
|
|
110
139
|
headers: { 'Content-Type': 'application/json' },
|
|
111
|
-
body: JSON.stringify(
|
|
112
|
-
siteName: options.name,
|
|
113
|
-
files: fileContents
|
|
114
|
-
})
|
|
140
|
+
body: JSON.stringify(requestBody)
|
|
115
141
|
});
|
|
116
142
|
|
|
117
143
|
if (!response.ok) {
|
|
@@ -121,13 +147,22 @@ async function main() {
|
|
|
121
147
|
|
|
122
148
|
const result = await response.json();
|
|
123
149
|
|
|
124
|
-
|
|
125
|
-
|
|
150
|
+
if (options.mergeWith) {
|
|
151
|
+
console.log('\n✅ Merge complete!');
|
|
152
|
+
console.log('\n📊 Updated Summary:');
|
|
153
|
+
} else {
|
|
154
|
+
console.log('\n✅ Analysis complete!');
|
|
155
|
+
console.log('\n📊 Summary:');
|
|
156
|
+
}
|
|
126
157
|
console.log(` Site ID: ${result.siteId}`);
|
|
127
158
|
console.log(` Framework: ${result.framework || 'Unknown'}`);
|
|
128
159
|
console.log(` Routes: ${result.routes?.length || 0}`);
|
|
129
160
|
console.log(` Forms: ${result.forms?.length || 0}`);
|
|
130
161
|
console.log(` Actions: ${result.actions?.length || 0}`);
|
|
162
|
+
|
|
163
|
+
if (result.merged) {
|
|
164
|
+
console.log(`\n 📎 Merged from: ${result.merged.sourcesCount} source(s)`);
|
|
165
|
+
}
|
|
131
166
|
|
|
132
167
|
// Save locally if requested
|
|
133
168
|
if (options.output) {
|