@lakindu_perera/toren 1.0.7 → 1.0.9
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/CHANGELOG.md +26 -0
- package/README.md +120 -31
- package/dist/cli/toren.d.ts +24 -0
- package/dist/cli/toren.js +254 -0
- package/dist/cli/toren.js.map +1 -0
- package/dist/detectors/config-detector.d.ts +3 -0
- package/dist/detectors/config-detector.js +58 -0
- package/dist/detectors/config-detector.js.map +1 -0
- package/dist/detectors/health-detector.d.ts +12 -0
- package/dist/detectors/health-detector.js +53 -0
- package/dist/detectors/health-detector.js.map +1 -0
- package/dist/detectors/important-files-detector.d.ts +51 -0
- package/dist/detectors/important-files-detector.js +455 -0
- package/dist/detectors/important-files-detector.js.map +1 -0
- package/dist/detectors/package-manager-detector.d.ts +7 -0
- package/dist/detectors/package-manager-detector.js +35 -0
- package/dist/detectors/package-manager-detector.js.map +1 -0
- package/dist/detectors/project-info-detector.d.ts +13 -0
- package/dist/detectors/project-info-detector.js +97 -0
- package/dist/detectors/project-info-detector.js.map +1 -0
- package/dist/detectors/script-detector.d.ts +42 -0
- package/dist/detectors/script-detector.js +199 -0
- package/dist/detectors/script-detector.js.map +1 -0
- package/dist/focused-output.d.ts +27 -0
- package/dist/focused-output.js +201 -0
- package/dist/focused-output.js.map +1 -0
- package/dist/lifecycle.d.ts +2 -0
- package/dist/lifecycle.js +114 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/renderers/console-renderer.d.ts +19 -0
- package/dist/renderers/console-renderer.js +361 -0
- package/dist/renderers/console-renderer.js.map +1 -0
- package/dist/renderers/html-renderer.d.ts +14 -0
- package/{src → dist}/renderers/html-renderer.js +263 -201
- package/dist/renderers/html-renderer.js.map +1 -0
- package/dist/renderers/index.d.ts +6 -0
- package/dist/renderers/index.js +12 -0
- package/dist/renderers/index.js.map +1 -0
- package/dist/renderers/json-renderer.d.ts +10 -0
- package/dist/renderers/json-renderer.js +127 -0
- package/dist/renderers/json-renderer.js.map +1 -0
- package/dist/renderers/markdown-renderer.d.ts +13 -0
- package/dist/renderers/markdown-renderer.js +360 -0
- package/dist/renderers/markdown-renderer.js.map +1 -0
- package/dist/scanner/scan.d.ts +2 -0
- package/dist/scanner/scan.js +573 -0
- package/dist/scanner/scan.js.map +1 -0
- package/dist/types/index.d.ts +85 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +16 -7
- package/bin/toren.js +0 -308
- package/src/detectors/config-detector.js +0 -81
- package/src/detectors/script-detector.js +0 -32
- package/src/focused-output.js +0 -146
- package/src/lifecycle.js +0 -124
- package/src/renderers/console-renderer.js +0 -350
- package/src/renderers/index.js +0 -41
- package/src/renderers/json-renderer.js +0 -154
- package/src/renderers/markdown-renderer.js +0 -337
- package/src/scanner/scan.js +0 -532
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Toren CLI — Codebase Scanner (Core Logic)
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Recursively walk a project directory
|
|
6
|
+
* - Ignore irrelevant paths (node_modules, .git, dist, build, etc.)
|
|
7
|
+
* - Build an in-memory file-tree representation
|
|
8
|
+
* - Detect the project type from marker files
|
|
9
|
+
* - Identify known entry-point files
|
|
10
|
+
*
|
|
11
|
+
* This module is intentionally free of side-effects (no console.log),
|
|
12
|
+
* except for warnings about unreadable directories.
|
|
13
|
+
* All output concerns live in bin/toren.js.
|
|
14
|
+
*
|
|
15
|
+
* Designed to scale into:
|
|
16
|
+
* - Module / dependency graph analysis
|
|
17
|
+
* - Architecture visualisation layers
|
|
18
|
+
* - AI explanation integrations
|
|
19
|
+
*/
|
|
20
|
+
import fs from 'node:fs';
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import { detectConfigs } from '../detectors/config-detector.js';
|
|
23
|
+
import { detectScripts } from '../detectors/script-detector.js';
|
|
24
|
+
import { detectPackageManager } from '../detectors/package-manager-detector.js';
|
|
25
|
+
import { detectImportantFiles } from '../detectors/important-files-detector.js';
|
|
26
|
+
import { detectProjectInfo } from '../detectors/project-info-detector.js';
|
|
27
|
+
import { detectHealth } from '../detectors/health-detector.js';
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Constants
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/**
|
|
32
|
+
* Directory / file names that are never walked.
|
|
33
|
+
* Stored as a Set for O(1) membership checks.
|
|
34
|
+
* @type {Set<string>}
|
|
35
|
+
*/
|
|
36
|
+
const IGNORED_DIRS = new Set([
|
|
37
|
+
'node_modules',
|
|
38
|
+
'.git',
|
|
39
|
+
'dist',
|
|
40
|
+
'build',
|
|
41
|
+
'.cache',
|
|
42
|
+
'.next',
|
|
43
|
+
'.nuxt',
|
|
44
|
+
'out',
|
|
45
|
+
'coverage',
|
|
46
|
+
'__pycache__',
|
|
47
|
+
'.venv',
|
|
48
|
+
'venv',
|
|
49
|
+
'.idea',
|
|
50
|
+
'.vscode',
|
|
51
|
+
'.svelte-kit',
|
|
52
|
+
'.turbo',
|
|
53
|
+
'.parcel-cache',
|
|
54
|
+
'.DS_Store'
|
|
55
|
+
]);
|
|
56
|
+
/**
|
|
57
|
+
* Mapping from a marker filename to a human-readable project-type label.
|
|
58
|
+
* Evaluated in iteration order — more specific entries should come first.
|
|
59
|
+
* @type {Array<{ marker: string, label: string }>}
|
|
60
|
+
*/
|
|
61
|
+
const PROJECT_TYPE_MARKERS = [
|
|
62
|
+
{ marker: 'package.json', label: 'Node.js / JavaScript' },
|
|
63
|
+
{ marker: 'pom.xml', label: 'Java / Spring Boot' },
|
|
64
|
+
{ marker: 'build.gradle', label: 'Java / Gradle' },
|
|
65
|
+
{ marker: 'requirements.txt', label: 'Python' },
|
|
66
|
+
{ marker: 'Pipfile', label: 'Python (Pipenv)' },
|
|
67
|
+
{ marker: 'pyproject.toml', label: 'Python (pyproject)' },
|
|
68
|
+
{ marker: 'go.mod', label: 'Go' },
|
|
69
|
+
{ marker: 'Cargo.toml', label: 'Rust' },
|
|
70
|
+
{ marker: 'composer.json', label: 'PHP / Composer' },
|
|
71
|
+
{ marker: 'Gemfile', label: 'Ruby' },
|
|
72
|
+
{ marker: 'mix.exs', label: 'Elixir' },
|
|
73
|
+
];
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Types (JSDoc — no TypeScript dependency required)
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
/**
|
|
78
|
+
* @typedef {Object} FileNode
|
|
79
|
+
* @property {'file'} type
|
|
80
|
+
* @property {string} name - Basename of the file
|
|
81
|
+
* @property {string} fullPath - Absolute path
|
|
82
|
+
* @property {string} relPath - Path relative to the scanned root (POSIX style)
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* @typedef {Object} DirNode
|
|
86
|
+
* @property {'directory'} type
|
|
87
|
+
* @property {string} name - Basename of the directory
|
|
88
|
+
* @property {string} fullPath - Absolute path
|
|
89
|
+
* @property {string} relPath - Path relative to the scanned root (POSIX style)
|
|
90
|
+
* @property {Array<FileNode|DirNode>} children
|
|
91
|
+
*/
|
|
92
|
+
/**
|
|
93
|
+
* @typedef {Object} ScanResult
|
|
94
|
+
* @property {string} rootPath - Absolute path that was scanned
|
|
95
|
+
* @property {string} projectType - Detected project type label
|
|
96
|
+
* @property {Array<string>} entryPoints - Relative paths of detected entry points
|
|
97
|
+
* @property {Array<string>} configs - Relative paths of detected config files
|
|
98
|
+
* @property {Array<{name: string, command: string, category: string|null, description: string|null, usage: string}>} scripts - Parsed and enriched package scripts
|
|
99
|
+
* @property {string|null} packageManager - Detected package manager, or null if none/ambiguous
|
|
100
|
+
* @property {DirNode} tree - Full in-memory file tree
|
|
101
|
+
* @property {Array<string>} flatFiles - All relative file paths (flat list)
|
|
102
|
+
* @property {number} totalFolders - Total number of directories walked
|
|
103
|
+
* @property {number} scanDurationMs - Wall-clock time of the scan in milliseconds
|
|
104
|
+
*/
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
// Internal helpers
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
/**
|
|
109
|
+
* Normalize a path to use POSIX separators ('/').
|
|
110
|
+
*/
|
|
111
|
+
function toPosix(p) {
|
|
112
|
+
return p.replace(/\\/g, '/');
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Determine whether a directory entry should be skipped.
|
|
116
|
+
*
|
|
117
|
+
* @param {string} name - Basename of the entry
|
|
118
|
+
* @param {fs.Dirent} dirent
|
|
119
|
+
* @param {boolean} includeHidden
|
|
120
|
+
* @returns {boolean}
|
|
121
|
+
*/
|
|
122
|
+
function shouldIgnore(name, dirent, includeHidden) {
|
|
123
|
+
if (!includeHidden && name.startsWith('.'))
|
|
124
|
+
return true;
|
|
125
|
+
return IGNORED_DIRS.has(name);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Recursively walk `dirPath`, building a DirNode tree.
|
|
129
|
+
* Also populates `flatFiles` array by reference.
|
|
130
|
+
*
|
|
131
|
+
* @param {string} dirPath - Absolute path of the current directory
|
|
132
|
+
* @param {string} rootPath - Absolute path of the scan root (for relative paths)
|
|
133
|
+
* @param {Array<string>} flatFiles - Accumulator for all relative file paths
|
|
134
|
+
* @param {boolean} includeHidden - Whether to include hidden files
|
|
135
|
+
* @param {number} maxFiles - Maximum number of files to scan before aborting
|
|
136
|
+
* @returns {DirNode}
|
|
137
|
+
*/
|
|
138
|
+
function walkDirectory(dirPath, rootPath, flatFiles, includeHidden, maxFiles) {
|
|
139
|
+
const name = path.basename(dirPath);
|
|
140
|
+
let rawRelPath = path.relative(rootPath, dirPath) || '.';
|
|
141
|
+
const relPath = toPosix(rawRelPath);
|
|
142
|
+
/** @type {DirNode} */
|
|
143
|
+
const node = {
|
|
144
|
+
type: 'directory',
|
|
145
|
+
name,
|
|
146
|
+
fullPath: dirPath,
|
|
147
|
+
relPath,
|
|
148
|
+
children: [],
|
|
149
|
+
};
|
|
150
|
+
let entries;
|
|
151
|
+
try {
|
|
152
|
+
entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Permission-denied or unreadable directory — skip silently.
|
|
156
|
+
// Write to stderr so stdout remains clean for piped/redirected output.
|
|
157
|
+
process.stderr.write(`[toren] warning: skipping unreadable directory: ${dirPath}\n`);
|
|
158
|
+
return node;
|
|
159
|
+
}
|
|
160
|
+
// Sort: directories first, then files — both alphabetically.
|
|
161
|
+
entries.sort((a, b) => {
|
|
162
|
+
const aIsDir = a.isDirectory() ? 0 : 1;
|
|
163
|
+
const bIsDir = b.isDirectory() ? 0 : 1;
|
|
164
|
+
if (aIsDir !== bIsDir)
|
|
165
|
+
return aIsDir - bIsDir;
|
|
166
|
+
return a.name.localeCompare(b.name);
|
|
167
|
+
});
|
|
168
|
+
for (const dirent of entries) {
|
|
169
|
+
if (shouldIgnore(dirent.name, dirent, includeHidden))
|
|
170
|
+
continue;
|
|
171
|
+
const childPath = path.join(dirPath, dirent.name);
|
|
172
|
+
// Explicitly skip symbolic links to prevent infinite loops and unsafe traversals
|
|
173
|
+
if (dirent.isSymbolicLink())
|
|
174
|
+
continue;
|
|
175
|
+
if (dirent.isDirectory()) {
|
|
176
|
+
const childNode = walkDirectory(childPath, rootPath, flatFiles, includeHidden, maxFiles);
|
|
177
|
+
node.children.push(childNode);
|
|
178
|
+
}
|
|
179
|
+
else if (dirent.isFile()) {
|
|
180
|
+
if (flatFiles.length >= maxFiles) {
|
|
181
|
+
const err = new Error(`Max file scan limit exceeded (${maxFiles} files).`);
|
|
182
|
+
err.title = 'Scan limit exceeded';
|
|
183
|
+
err.detailLabel = 'Hint';
|
|
184
|
+
err.detailValue = 'Use --max-files <number> to increase the limit.';
|
|
185
|
+
throw err;
|
|
186
|
+
}
|
|
187
|
+
const relFilePath = toPosix(path.relative(rootPath, childPath));
|
|
188
|
+
/** @type {FileNode} */
|
|
189
|
+
const fileNode = {
|
|
190
|
+
type: 'file',
|
|
191
|
+
name: dirent.name,
|
|
192
|
+
fullPath: childPath,
|
|
193
|
+
relPath: relFilePath,
|
|
194
|
+
};
|
|
195
|
+
node.children.push(fileNode);
|
|
196
|
+
flatFiles.push(relFilePath);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return node;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Detect the project type by checking for known marker files in `rootPath`.
|
|
203
|
+
*
|
|
204
|
+
* Returns the label of the first matched marker, or `'Unknown'` if none match.
|
|
205
|
+
*
|
|
206
|
+
* @param {string} rootPath - Absolute path to the project root
|
|
207
|
+
* @returns {string}
|
|
208
|
+
*/
|
|
209
|
+
function detectProjectType(rootPath) {
|
|
210
|
+
for (const { marker, label } of PROJECT_TYPE_MARKERS) {
|
|
211
|
+
const markerPath = path.join(rootPath, marker);
|
|
212
|
+
if (fs.existsSync(markerPath)) {
|
|
213
|
+
// Refine Node.js projects by inspecting package.json dependencies.
|
|
214
|
+
if (marker === 'package.json') {
|
|
215
|
+
return refineNodeProjectType(markerPath);
|
|
216
|
+
}
|
|
217
|
+
return label;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return 'Unknown';
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Read `package.json` and return a more specific label when React / Next / Vue
|
|
224
|
+
* etc. are listed as dependencies.
|
|
225
|
+
*
|
|
226
|
+
* @param {string} pkgPath - Absolute path to package.json
|
|
227
|
+
* @returns {string}
|
|
228
|
+
*/
|
|
229
|
+
function refineNodeProjectType(pkgPath) {
|
|
230
|
+
try {
|
|
231
|
+
const raw = fs.readFileSync(pkgPath, 'utf8');
|
|
232
|
+
const pkg = JSON.parse(raw);
|
|
233
|
+
const deps = {
|
|
234
|
+
...pkg.dependencies,
|
|
235
|
+
...pkg.devDependencies,
|
|
236
|
+
...pkg.peerDependencies,
|
|
237
|
+
};
|
|
238
|
+
if (deps['next'])
|
|
239
|
+
return 'Next.js';
|
|
240
|
+
if (deps['nuxt'] || deps['nuxt3'])
|
|
241
|
+
return 'Nuxt.js';
|
|
242
|
+
if (deps['react'])
|
|
243
|
+
return 'React';
|
|
244
|
+
if (deps['vue'])
|
|
245
|
+
return 'Vue.js';
|
|
246
|
+
if (deps['@angular/core'])
|
|
247
|
+
return 'Angular';
|
|
248
|
+
if (deps['svelte'])
|
|
249
|
+
return 'Svelte';
|
|
250
|
+
if (deps['express'])
|
|
251
|
+
return 'Node.js / Express';
|
|
252
|
+
if (deps['fastify'])
|
|
253
|
+
return 'Node.js / Fastify';
|
|
254
|
+
if (deps['koa'])
|
|
255
|
+
return 'Node.js / Koa';
|
|
256
|
+
if (deps['typescript'])
|
|
257
|
+
return 'Node.js / TypeScript';
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
// Malformed package.json — fall through.
|
|
261
|
+
}
|
|
262
|
+
return 'Node.js / JavaScript';
|
|
263
|
+
}
|
|
264
|
+
// ---------------------------------------------------------------------------
|
|
265
|
+
// Entry Point Heuristics
|
|
266
|
+
// ---------------------------------------------------------------------------
|
|
267
|
+
const FALSE_POSITIVES = [
|
|
268
|
+
'/internal/', '/renderer/', '/renderers/', '/dist/', '/build/', '/generated/', '/node_modules/'
|
|
269
|
+
];
|
|
270
|
+
function isFalsePositive(relPath) {
|
|
271
|
+
const normalized = '/' + relPath + '/'; // relPath is already POSIX
|
|
272
|
+
if (FALSE_POSITIVES.some(fp => normalized.includes(fp)))
|
|
273
|
+
return true;
|
|
274
|
+
if (relPath.includes('.test.') || relPath.includes('.spec.'))
|
|
275
|
+
return true;
|
|
276
|
+
// Exclude config files usually not entry points
|
|
277
|
+
if (relPath.endsWith('.config.js') || relPath.endsWith('.config.ts'))
|
|
278
|
+
return true;
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
function findEntryPoints(projectType, flatFiles, rootPath) {
|
|
282
|
+
let entries = [];
|
|
283
|
+
const validFiles = flatFiles.filter(f => !isFalsePositive(f));
|
|
284
|
+
const validSet = new Set(validFiles);
|
|
285
|
+
if (projectType === 'Node.js / JavaScript' || projectType.startsWith('Node.js')) {
|
|
286
|
+
try {
|
|
287
|
+
const pkgPath = path.join(rootPath, 'package.json');
|
|
288
|
+
if (fs.existsSync(pkgPath)) {
|
|
289
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
290
|
+
if (pkg.bin) {
|
|
291
|
+
if (typeof pkg.bin === 'string')
|
|
292
|
+
entries.push(pkg.bin);
|
|
293
|
+
else
|
|
294
|
+
Object.values(pkg.bin).forEach(b => entries.push(b));
|
|
295
|
+
}
|
|
296
|
+
if (pkg.main)
|
|
297
|
+
entries.push(pkg.main);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch { }
|
|
301
|
+
// Normalize and filter package.json entries to ensure they exist
|
|
302
|
+
entries = entries.map(e => toPosix(e).replace(/^\.\//, '')).filter(e => validSet.has(e));
|
|
303
|
+
if (entries.length === 0) {
|
|
304
|
+
const fallbacks = ['src/index.ts', 'src/index.js', 'lib/index.js', 'index.js'];
|
|
305
|
+
for (const f of fallbacks) {
|
|
306
|
+
if (validSet.has(f)) {
|
|
307
|
+
entries.push(f);
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else if (projectType === 'React' || projectType === 'Next.js' ||
|
|
314
|
+
projectType === 'Nuxt.js' || projectType === 'Vue.js' ||
|
|
315
|
+
projectType === 'Angular' || projectType === 'Svelte') {
|
|
316
|
+
const priorities = [
|
|
317
|
+
'src/main.tsx', 'src/main.jsx', 'src/main.ts', 'src/main.js',
|
|
318
|
+
'pages/_app.tsx', 'pages/_app.js',
|
|
319
|
+
'app/layout.tsx', 'app/layout.js',
|
|
320
|
+
'src/App.tsx', 'src/App.jsx',
|
|
321
|
+
'index.html',
|
|
322
|
+
];
|
|
323
|
+
for (const p of priorities) {
|
|
324
|
+
if (validSet.has(p)) {
|
|
325
|
+
entries.push(p);
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else if (projectType.includes('Java')) {
|
|
331
|
+
const applicationJava = validFiles.filter(f => f.endsWith('Application.java'));
|
|
332
|
+
if (applicationJava.length > 0) {
|
|
333
|
+
entries.push(...applicationJava);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
for (const f of validFiles) {
|
|
337
|
+
if (f.endsWith('.java')) {
|
|
338
|
+
try {
|
|
339
|
+
const content = fs.readFileSync(path.join(rootPath, f), 'utf8');
|
|
340
|
+
if (content.includes('public static void main')) {
|
|
341
|
+
entries.push(f);
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch { }
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
else if (projectType.includes('Python')) {
|
|
351
|
+
const priorities = ['main.py', 'app.py', '__main__.py', 'manage.py', 'run.py'];
|
|
352
|
+
for (const p of priorities) {
|
|
353
|
+
if (validSet.has(p)) {
|
|
354
|
+
entries.push(p);
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (entries.length === 0) {
|
|
359
|
+
for (const f of validFiles) {
|
|
360
|
+
if (f.endsWith('.py')) {
|
|
361
|
+
try {
|
|
362
|
+
const content = fs.readFileSync(path.join(rootPath, f), 'utf8');
|
|
363
|
+
if (content.includes('if __name__ == "__main__":') || content.includes("if __name__ == '__main__':")) {
|
|
364
|
+
entries.push(f);
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
catch { }
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
else if (projectType === 'Go') {
|
|
374
|
+
const priorities = ['main.go', 'cmd/main.go', 'cmd/api/main.go'];
|
|
375
|
+
for (const p of priorities) {
|
|
376
|
+
if (validSet.has(p)) {
|
|
377
|
+
entries.push(p);
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else if (projectType === 'Rust') {
|
|
383
|
+
const priorities = ['src/main.rs', 'src/lib.rs'];
|
|
384
|
+
for (const p of priorities) {
|
|
385
|
+
if (validSet.has(p)) {
|
|
386
|
+
entries.push(p);
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
else if (projectType === 'Ruby') {
|
|
392
|
+
const priorities = ['app.rb', 'main.rb', 'config.ru', 'Rakefile'];
|
|
393
|
+
for (const p of priorities) {
|
|
394
|
+
if (validSet.has(p)) {
|
|
395
|
+
entries.push(p);
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
else if (projectType === 'PHP / Composer') {
|
|
401
|
+
const priorities = ['index.php', 'public/index.php', 'src/index.php', 'artisan'];
|
|
402
|
+
for (const p of priorities) {
|
|
403
|
+
if (validSet.has(p)) {
|
|
404
|
+
entries.push(p);
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
else if (projectType === 'Elixir') {
|
|
410
|
+
const priorities = ['lib/mix/tasks/run.ex', 'mix.exs'];
|
|
411
|
+
for (const p of priorities) {
|
|
412
|
+
if (validSet.has(p)) {
|
|
413
|
+
entries.push(p);
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (entries.length === 0) {
|
|
419
|
+
// Fallbacks for Unknown or unrecognised projects.
|
|
420
|
+
// First try well-known index file patterns.
|
|
421
|
+
for (const f of validFiles) {
|
|
422
|
+
if (/^(src\/)?index\.[a-z]+$/.test(f)) {
|
|
423
|
+
entries.push(f);
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
// If still empty, pick the file with the highest import/export density.
|
|
428
|
+
if (entries.length === 0) {
|
|
429
|
+
let best = null;
|
|
430
|
+
let maxScore = -1;
|
|
431
|
+
for (const f of validFiles) {
|
|
432
|
+
if (f.match(/\.(js|ts|jsx|tsx|py|java|go|rs|rb|php)$/)) {
|
|
433
|
+
try {
|
|
434
|
+
const content = fs.readFileSync(path.join(rootPath, f), 'utf8');
|
|
435
|
+
const score = (content.match(/import /g) || []).length +
|
|
436
|
+
(content.match(/export /g) || []).length +
|
|
437
|
+
(content.match(/require\(/g) || []).length;
|
|
438
|
+
if (score > maxScore) {
|
|
439
|
+
maxScore = score;
|
|
440
|
+
best = f;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
catch { }
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (best)
|
|
447
|
+
entries.push(best);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return Array.from(new Set(entries));
|
|
451
|
+
}
|
|
452
|
+
// ---------------------------------------------------------------------------
|
|
453
|
+
// Tree helpers
|
|
454
|
+
// ---------------------------------------------------------------------------
|
|
455
|
+
/**
|
|
456
|
+
* Count the total number of directory nodes in a tree (including the root).
|
|
457
|
+
*
|
|
458
|
+
* @param {DirNode} node
|
|
459
|
+
* @returns {number}
|
|
460
|
+
*/
|
|
461
|
+
function countFolders(node) {
|
|
462
|
+
let count = 1; // count this directory
|
|
463
|
+
for (const child of node.children ?? []) {
|
|
464
|
+
if (child.type === 'directory') {
|
|
465
|
+
count += countFolders(child);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return count;
|
|
469
|
+
}
|
|
470
|
+
// ---------------------------------------------------------------------------
|
|
471
|
+
// Public API
|
|
472
|
+
// ---------------------------------------------------------------------------
|
|
473
|
+
export function scan(targetPath, options = {}) {
|
|
474
|
+
const rootPath = path.resolve(targetPath);
|
|
475
|
+
const includeHidden = !!options.includeHidden;
|
|
476
|
+
const maxFiles = options.maxFiles || 50000; // Default cap of 50k files for huge repos
|
|
477
|
+
// Validate target
|
|
478
|
+
let stat;
|
|
479
|
+
try {
|
|
480
|
+
stat = fs.statSync(rootPath);
|
|
481
|
+
}
|
|
482
|
+
catch (err) {
|
|
483
|
+
const error = new Error(`Path does not exist: ${rootPath}`);
|
|
484
|
+
if (err.code === 'EACCES' || err.code === 'EPERM') {
|
|
485
|
+
error.title = 'Permission denied';
|
|
486
|
+
error.message = 'You do not have permission to access the specified path.';
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
error.title = 'Invalid directory';
|
|
490
|
+
error.message = 'The specified path does not exist.';
|
|
491
|
+
}
|
|
492
|
+
error.detailLabel = 'Path';
|
|
493
|
+
error.detailValue = rootPath;
|
|
494
|
+
throw error;
|
|
495
|
+
}
|
|
496
|
+
/** @type {Array<string>} */
|
|
497
|
+
const flatFiles = [];
|
|
498
|
+
/** @type {Array<string>} */
|
|
499
|
+
let entryPoints = [];
|
|
500
|
+
/** @type {Array<string>} */
|
|
501
|
+
let configs = [];
|
|
502
|
+
/** @type {Array<{name: string, command: string}>} */
|
|
503
|
+
let scripts = [];
|
|
504
|
+
/** @type {string|null} */
|
|
505
|
+
let packageManager = null;
|
|
506
|
+
let importantFiles = [];
|
|
507
|
+
let projectInfo = null;
|
|
508
|
+
let health = [];
|
|
509
|
+
const startTime = performance.now();
|
|
510
|
+
let tree;
|
|
511
|
+
let projectType = 'Unknown';
|
|
512
|
+
let totalFolders = 0;
|
|
513
|
+
if (stat.isDirectory()) {
|
|
514
|
+
tree = walkDirectory(rootPath, rootPath, flatFiles, includeHidden, maxFiles);
|
|
515
|
+
projectType = detectProjectType(rootPath);
|
|
516
|
+
// Count all directory nodes in the tree (excluding root itself).
|
|
517
|
+
totalFolders = countFolders(tree) - 1;
|
|
518
|
+
entryPoints = findEntryPoints(projectType, flatFiles, rootPath);
|
|
519
|
+
configs = detectConfigs(flatFiles).configs;
|
|
520
|
+
packageManager = detectPackageManager(flatFiles).packageManager;
|
|
521
|
+
scripts = detectScripts(rootPath, packageManager).scripts;
|
|
522
|
+
importantFiles = detectImportantFiles({ flatFiles, projectType, entryPoints, configs }).importantFiles;
|
|
523
|
+
projectInfo = detectProjectInfo({ rootPath, projectType, flatFiles, entryPoints, packageManager, scripts }).projectInfo;
|
|
524
|
+
health = detectHealth({ flatFiles, configs, importantFiles, scripts, projectType }).health;
|
|
525
|
+
}
|
|
526
|
+
else if (stat.isFile()) {
|
|
527
|
+
const relFilePath = toPosix(path.basename(rootPath));
|
|
528
|
+
tree = { type: 'directory',
|
|
529
|
+
name: path.basename(path.dirname(rootPath)),
|
|
530
|
+
fullPath: path.dirname(rootPath),
|
|
531
|
+
relPath: '.',
|
|
532
|
+
children: [{
|
|
533
|
+
type: 'file',
|
|
534
|
+
name: relFilePath,
|
|
535
|
+
fullPath: rootPath,
|
|
536
|
+
relPath: relFilePath
|
|
537
|
+
}]
|
|
538
|
+
};
|
|
539
|
+
flatFiles.push(relFilePath);
|
|
540
|
+
entryPoints = [relFilePath]; // A single file is its own entry point
|
|
541
|
+
configs = detectConfigs(flatFiles).configs;
|
|
542
|
+
packageManager = detectPackageManager(flatFiles).packageManager;
|
|
543
|
+
scripts = detectScripts(path.dirname(rootPath), packageManager).scripts;
|
|
544
|
+
importantFiles = detectImportantFiles({ flatFiles, projectType, entryPoints, configs }).importantFiles;
|
|
545
|
+
projectInfo = detectProjectInfo({ rootPath, projectType, flatFiles, entryPoints, packageManager, scripts }).projectInfo;
|
|
546
|
+
health = detectHealth({ flatFiles, configs, importantFiles, scripts, projectType }).health;
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
const err = new Error(`Path is neither a file nor a directory: ${rootPath}`);
|
|
550
|
+
err.title = 'Unsupported path type';
|
|
551
|
+
err.message = 'The specified path is neither a file nor a directory.';
|
|
552
|
+
err.detailLabel = 'Path';
|
|
553
|
+
err.detailValue = rootPath;
|
|
554
|
+
throw err;
|
|
555
|
+
}
|
|
556
|
+
const scanDurationMs = performance.now() - startTime;
|
|
557
|
+
return {
|
|
558
|
+
rootPath,
|
|
559
|
+
projectType,
|
|
560
|
+
entryPoints,
|
|
561
|
+
configs,
|
|
562
|
+
scripts,
|
|
563
|
+
packageManager,
|
|
564
|
+
importantFiles,
|
|
565
|
+
projectInfo,
|
|
566
|
+
health,
|
|
567
|
+
tree,
|
|
568
|
+
flatFiles,
|
|
569
|
+
totalFolders,
|
|
570
|
+
scanDurationMs,
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/scanner/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export interface DirectoryNode {
|
|
2
|
+
type: "directory";
|
|
3
|
+
name: string;
|
|
4
|
+
fullPath: string;
|
|
5
|
+
relPath: string;
|
|
6
|
+
children: TreeNode[];
|
|
7
|
+
}
|
|
8
|
+
export interface FileNode {
|
|
9
|
+
type: "file";
|
|
10
|
+
name: string;
|
|
11
|
+
fullPath: string;
|
|
12
|
+
relPath: string;
|
|
13
|
+
}
|
|
14
|
+
export type TreeNode = DirectoryNode | FileNode;
|
|
15
|
+
export type DirNode = DirectoryNode;
|
|
16
|
+
export interface ScriptInfo {
|
|
17
|
+
name: string;
|
|
18
|
+
command: string;
|
|
19
|
+
usage: string | null;
|
|
20
|
+
description: string | null;
|
|
21
|
+
category: string | null;
|
|
22
|
+
}
|
|
23
|
+
export type PackageManager = "npm" | "pnpm" | "yarn" | "bun";
|
|
24
|
+
export type ImportantFileType = "manifest" | "documentation" | "entry-point" | "configuration" | "environment" | "container" | "framework" | "build" | "testing" | "database";
|
|
25
|
+
export interface ImportantFile {
|
|
26
|
+
path: string;
|
|
27
|
+
type: ImportantFileType | string;
|
|
28
|
+
reason: string;
|
|
29
|
+
priority: number;
|
|
30
|
+
}
|
|
31
|
+
export interface ProjectInfo {
|
|
32
|
+
name: string | null;
|
|
33
|
+
projectType: string;
|
|
34
|
+
runtime: string | null;
|
|
35
|
+
language: string | null;
|
|
36
|
+
framework: string | null;
|
|
37
|
+
architecture: string | null;
|
|
38
|
+
packageManager: PackageManager | null;
|
|
39
|
+
entryPoint: string | null;
|
|
40
|
+
sourceDirectory: string | null;
|
|
41
|
+
}
|
|
42
|
+
export type HealthStatus = "pass" | "warning" | "info" | "fail";
|
|
43
|
+
export interface HealthObservation {
|
|
44
|
+
id: string;
|
|
45
|
+
status: HealthStatus;
|
|
46
|
+
message: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ScanResult {
|
|
49
|
+
rootPath: string;
|
|
50
|
+
projectType: string;
|
|
51
|
+
entryPoints: string[];
|
|
52
|
+
configs: string[];
|
|
53
|
+
scripts: ScriptInfo[];
|
|
54
|
+
tree: DirNode;
|
|
55
|
+
flatFiles: string[];
|
|
56
|
+
totalFolders: number;
|
|
57
|
+
scanDurationMs: number;
|
|
58
|
+
packageManager: PackageManager | null;
|
|
59
|
+
importantFiles: ImportantFile[];
|
|
60
|
+
projectInfo: ProjectInfo;
|
|
61
|
+
health: HealthObservation[];
|
|
62
|
+
}
|
|
63
|
+
export type OutputFormat = "console" | "json" | "markdown" | "html";
|
|
64
|
+
export interface CliOptions {
|
|
65
|
+
targetPath: string;
|
|
66
|
+
format: OutputFormat;
|
|
67
|
+
maxFiles?: number;
|
|
68
|
+
includeHidden?: boolean;
|
|
69
|
+
projectTypeOnly?: boolean;
|
|
70
|
+
frameworksOnly?: boolean;
|
|
71
|
+
entryPointsOnly?: boolean;
|
|
72
|
+
configsOnly?: boolean;
|
|
73
|
+
structureOnly?: boolean;
|
|
74
|
+
summaryOnly?: boolean;
|
|
75
|
+
importantFilesOnly?: boolean;
|
|
76
|
+
healthOnly?: boolean;
|
|
77
|
+
scriptsOnly?: boolean;
|
|
78
|
+
}
|
|
79
|
+
declare global {
|
|
80
|
+
interface Error {
|
|
81
|
+
title?: string;
|
|
82
|
+
detailLabel?: string;
|
|
83
|
+
detailValue?: string;
|
|
84
|
+
}
|
|
85
|
+
}
|