@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,114 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
import readline from 'node:readline';
|
|
4
|
+
const C = {
|
|
5
|
+
reset: '\x1b[0m',
|
|
6
|
+
cyan: '\x1b[36m',
|
|
7
|
+
green: '\x1b[32m',
|
|
8
|
+
yellow: '\x1b[33m',
|
|
9
|
+
red: '\x1b[31m',
|
|
10
|
+
};
|
|
11
|
+
function paint(text, ...codes) {
|
|
12
|
+
return `${codes.join('')}${text}${C.reset}`;
|
|
13
|
+
}
|
|
14
|
+
function getGlobalNpmRoot() {
|
|
15
|
+
try {
|
|
16
|
+
return execSync('npm root -g', { encoding: 'utf8', stdio: 'pipe' }).trim();
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function getInstallStatus() {
|
|
23
|
+
const status = {
|
|
24
|
+
isGlobal: false,
|
|
25
|
+
method: 'unknown',
|
|
26
|
+
binaryPath: process.argv[1] || 'unknown',
|
|
27
|
+
isBroken: false,
|
|
28
|
+
};
|
|
29
|
+
try {
|
|
30
|
+
if (!status.binaryPath || !fs.existsSync(status.binaryPath)) {
|
|
31
|
+
status.isBroken = true;
|
|
32
|
+
return status;
|
|
33
|
+
}
|
|
34
|
+
const realPath = fs.realpathSync(status.binaryPath);
|
|
35
|
+
const globalRoot = getGlobalNpmRoot();
|
|
36
|
+
if (globalRoot) {
|
|
37
|
+
if (realPath.includes(globalRoot)) {
|
|
38
|
+
status.isGlobal = true;
|
|
39
|
+
status.method = 'npm install -g';
|
|
40
|
+
}
|
|
41
|
+
else if (status.binaryPath !== realPath) {
|
|
42
|
+
status.isGlobal = true;
|
|
43
|
+
status.method = 'npm link';
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
status.isGlobal = false;
|
|
47
|
+
status.method = 'local';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (status.binaryPath !== realPath) {
|
|
52
|
+
status.isGlobal = true;
|
|
53
|
+
status.method = 'npm link';
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
status.isGlobal = false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
status.isBroken = true;
|
|
62
|
+
}
|
|
63
|
+
return status;
|
|
64
|
+
}
|
|
65
|
+
export function runDoctor(pkgVersion) {
|
|
66
|
+
const status = getInstallStatus();
|
|
67
|
+
if (status.isBroken) {
|
|
68
|
+
console.log(paint('⚠ Broken installation detected', C.red));
|
|
69
|
+
console.log(`→ Run: ${paint('npm uninstall -g toren', C.cyan)}`);
|
|
70
|
+
console.log('');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (status.isGlobal) {
|
|
74
|
+
console.log(`${paint('✔', C.green)} Toren installed globally`);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
console.log(`${paint('✔', C.green)} Toren installed locally`);
|
|
78
|
+
}
|
|
79
|
+
console.log(`${paint('✔', C.green)} Binary path valid`);
|
|
80
|
+
console.log(`${paint('✔', C.green)} Version match confirmed`);
|
|
81
|
+
console.log('');
|
|
82
|
+
}
|
|
83
|
+
export function runUninstall() {
|
|
84
|
+
const status = getInstallStatus();
|
|
85
|
+
if (status.isBroken) {
|
|
86
|
+
console.log(paint('⚠ Toren installation is corrupted. Please reinstall using npm install -g toren', C.yellow));
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
|
89
|
+
const rl = readline.createInterface({
|
|
90
|
+
input: process.stdin,
|
|
91
|
+
output: process.stdout
|
|
92
|
+
});
|
|
93
|
+
rl.question('Are you sure you want to remove Toren from global environment? (y/n) ', (answer) => {
|
|
94
|
+
rl.close();
|
|
95
|
+
if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {
|
|
96
|
+
process.exit(0);
|
|
97
|
+
}
|
|
98
|
+
console.log('');
|
|
99
|
+
console.log('Uninstalling Toren...');
|
|
100
|
+
try {
|
|
101
|
+
execSync('npm uninstall -g toren', { stdio: 'inherit' });
|
|
102
|
+
console.log('');
|
|
103
|
+
console.log(paint('✔ Successfully removed Toren from the global environment.', C.green));
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
console.log('');
|
|
107
|
+
console.log(paint('❌ Failed to uninstall Toren.', C.red));
|
|
108
|
+
console.log('Please try manually: npm uninstall -g toren');
|
|
109
|
+
}
|
|
110
|
+
console.log('');
|
|
111
|
+
process.exit(0);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ScanResult } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Render a ScanResult to the terminal.
|
|
4
|
+
*
|
|
5
|
+
* All sections read from the ScanResult. Presentation-level derivations
|
|
6
|
+
* (e.g. frameworks list) are computed here; no business logic is added.
|
|
7
|
+
*
|
|
8
|
+
* @param {import('../scanner/scan.js').ScanResult} result
|
|
9
|
+
* @param {{ cwd?: string }} [options]
|
|
10
|
+
*/
|
|
11
|
+
export declare function render(result: ScanResult, options?: {
|
|
12
|
+
cwd?: string;
|
|
13
|
+
}): void;
|
|
14
|
+
/**
|
|
15
|
+
* Render only the project structure for the --structure flag.
|
|
16
|
+
*
|
|
17
|
+
* @param {import('../scanner/scan.js').ScanResult} result
|
|
18
|
+
*/
|
|
19
|
+
export declare function renderStructure(result: ScanResult): void;
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Toren — Console Renderer
|
|
3
|
+
*
|
|
4
|
+
* Consumes a {@link ScanResult} and produces styled terminal output.
|
|
5
|
+
*
|
|
6
|
+
* Design contract:
|
|
7
|
+
* - Presentation-only. Every value rendered comes from ScanResult.
|
|
8
|
+
* Presentation-level derivations (e.g. frameworks list from projectType) are
|
|
9
|
+
* permitted here; business logic is not.
|
|
10
|
+
* - No imports from the scanner or any domain module.
|
|
11
|
+
* - Stateless: render() may be called multiple times safely.
|
|
12
|
+
* - The shape expected here matches the ScanResult typedef in scan.js.
|
|
13
|
+
* When ScanResult grows new fields, add new render sections; never mutate data.
|
|
14
|
+
*
|
|
15
|
+
* Adding a new output format (JSON, Markdown, HTML …):
|
|
16
|
+
* - Create src/renderers/<format>-renderer.js
|
|
17
|
+
* - Export a render(result, options?) function with the same signature
|
|
18
|
+
* - Import and call it from bin/toren.js based on a --format flag
|
|
19
|
+
*/
|
|
20
|
+
import path from 'node:path';
|
|
21
|
+
import { createRequire } from 'node:module';
|
|
22
|
+
const require = createRequire(import.meta.url);
|
|
23
|
+
const pkg = require('../../package.json');
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// ANSI palette — zero external dependencies
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
const C = {
|
|
28
|
+
reset: '\x1b[0m',
|
|
29
|
+
bold: '\x1b[1m',
|
|
30
|
+
dim: '\x1b[2m',
|
|
31
|
+
cyan: '\x1b[36m',
|
|
32
|
+
green: '\x1b[32m',
|
|
33
|
+
yellow: '\x1b[33m',
|
|
34
|
+
blue: '\x1b[34m',
|
|
35
|
+
magenta: '\x1b[35m',
|
|
36
|
+
red: '\x1b[31m',
|
|
37
|
+
white: '\x1b[97m',
|
|
38
|
+
};
|
|
39
|
+
/** Maximum files shown in the structure preview. */
|
|
40
|
+
const PREVIEW_LIMIT = 20;
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Cross-platform capability detection
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
function shouldEnableColors() {
|
|
45
|
+
if ('FORCE_COLOR' in process.env) {
|
|
46
|
+
return process.env.FORCE_COLOR !== '0' && process.env.FORCE_COLOR !== 'false';
|
|
47
|
+
}
|
|
48
|
+
if ('NO_COLOR' in process.env)
|
|
49
|
+
return false;
|
|
50
|
+
if (!process.stdout || !process.stdout.isTTY)
|
|
51
|
+
return false;
|
|
52
|
+
if (process.env.TERM === 'dumb')
|
|
53
|
+
return false;
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
function isUnicodeSupported() {
|
|
57
|
+
if (process.platform !== 'win32') {
|
|
58
|
+
return process.env.TERM !== 'linux';
|
|
59
|
+
}
|
|
60
|
+
return Boolean(process.env.CI ||
|
|
61
|
+
process.env.WT_SESSION ||
|
|
62
|
+
process.env.TERMINUS_SUBLIME ||
|
|
63
|
+
process.env.ConEmuTask === '{cmd::Cmder}' ||
|
|
64
|
+
process.env.TERM_PROGRAM === 'Terminus-Sublime' ||
|
|
65
|
+
process.env.TERM_PROGRAM === 'vscode' ||
|
|
66
|
+
process.env.TERM === 'xterm-256color' ||
|
|
67
|
+
process.env.TERM === 'alacritty' ||
|
|
68
|
+
process.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm');
|
|
69
|
+
}
|
|
70
|
+
const useColors = shouldEnableColors();
|
|
71
|
+
const useUnicode = isUnicodeSupported();
|
|
72
|
+
const CHARS = {
|
|
73
|
+
dash: useUnicode ? '─' : '-',
|
|
74
|
+
corner: useUnicode ? '└── ' : '\\-- ',
|
|
75
|
+
tee: useUnicode ? '├── ' : '+-- ',
|
|
76
|
+
pipe: useUnicode ? '│ ' : '| ',
|
|
77
|
+
};
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Low-level paint / layout helpers (private to this module)
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
/**
|
|
82
|
+
* Wrap `text` with one or more ANSI codes, resetting after.
|
|
83
|
+
* @param {string} text
|
|
84
|
+
* @param {...string} codes
|
|
85
|
+
* @returns {string}
|
|
86
|
+
*/
|
|
87
|
+
function paint(text, ...codes) {
|
|
88
|
+
if (!useColors)
|
|
89
|
+
return text;
|
|
90
|
+
return `${codes.join('')}${text}${C.reset}`;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Print a titled section header followed by a matched-length divider.
|
|
94
|
+
* @param {string} title
|
|
95
|
+
*/
|
|
96
|
+
function section(title) {
|
|
97
|
+
const cleanTitle = title.replace(/\x1b\[[0-9;]*m/g, '');
|
|
98
|
+
console.log(paint(title, C.bold, C.white));
|
|
99
|
+
console.log(paint(CHARS.dash.repeat(cleanTitle.length), C.dim));
|
|
100
|
+
console.log('');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Print a single labelled key-value row.
|
|
104
|
+
* @param {string} label - Left-hand label (dim)
|
|
105
|
+
* @param {string} value - Right-hand value
|
|
106
|
+
* @param {string} [valueColor] - Optional ANSI code(s) for the value
|
|
107
|
+
*/
|
|
108
|
+
function row(label, value, ...valueCodes) {
|
|
109
|
+
const coloured = valueCodes.length ? paint(value, ...valueCodes) : value;
|
|
110
|
+
console.log(`${paint(label, C.dim)} ${coloured}`);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Format a scan duration into a human-readable string.
|
|
114
|
+
* Mirrors the formatDuration helpers in markdown-renderer and html-renderer.
|
|
115
|
+
* @param {number} ms
|
|
116
|
+
* @returns {string}
|
|
117
|
+
*/
|
|
118
|
+
function formatDuration(ms) {
|
|
119
|
+
if (ms < 1)
|
|
120
|
+
return '< 1 ms';
|
|
121
|
+
if (ms >= 1000)
|
|
122
|
+
return `${(ms / 1000).toFixed(2)} s`;
|
|
123
|
+
return `${Math.round(ms)} ms`;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Derive a frameworks array from the projectType string.
|
|
127
|
+
* Returns [] when no specific framework is detected (projectType is falsy or 'Unknown').
|
|
128
|
+
* Mirrors the identical derivation in json-renderer.js — both must stay in sync.
|
|
129
|
+
*
|
|
130
|
+
* @param {string} projectType
|
|
131
|
+
* @returns {string[]}
|
|
132
|
+
*/
|
|
133
|
+
function deriveFrameworks(projectType) {
|
|
134
|
+
if (!projectType || projectType === 'Unknown')
|
|
135
|
+
return [];
|
|
136
|
+
return [projectType];
|
|
137
|
+
}
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
// File-tree renderer (private)
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
/**
|
|
142
|
+
* Recursively print a file tree with classic tree connectors.
|
|
143
|
+
* Stops after PREVIEW_LIMIT files have been printed.
|
|
144
|
+
*
|
|
145
|
+
* @param {import('../scanner/scan.js').DirNode | import('../scanner/scan.js').FileNode} node
|
|
146
|
+
* @param {string} prefix - Accumulated indentation
|
|
147
|
+
* @param {boolean} isLast - Whether this is the last sibling
|
|
148
|
+
* @param {{ count: number, maxReached: boolean }} counter - Shared mutable file counter
|
|
149
|
+
* @param {number} limit - Max files to render
|
|
150
|
+
* @param {number} depth - Current depth
|
|
151
|
+
* @param {number} maxDepth - Max recursion depth
|
|
152
|
+
*/
|
|
153
|
+
function renderTree(node, prefix, isLast, counter, limit = PREVIEW_LIMIT, depth = 0, maxDepth = 4) {
|
|
154
|
+
if (counter.maxReached)
|
|
155
|
+
return;
|
|
156
|
+
if (depth >= maxDepth)
|
|
157
|
+
return;
|
|
158
|
+
const connector = isLast ? CHARS.corner : CHARS.tee;
|
|
159
|
+
const extension = isLast ? ' ' : CHARS.pipe;
|
|
160
|
+
if (node.type === 'directory') {
|
|
161
|
+
console.log(`${prefix}${connector}${paint(`${node.name}${path.sep}`, C.bold, C.blue)}`);
|
|
162
|
+
const children = node.children ?? [];
|
|
163
|
+
if (depth === maxDepth - 1 && children.length > 0) {
|
|
164
|
+
console.log(`${prefix}${extension}${CHARS.corner}${paint('...', C.dim)}`);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
for (let i = 0; i < children.length; i++) {
|
|
168
|
+
if (counter.count >= limit) {
|
|
169
|
+
console.log(`${prefix}${extension}${CHARS.corner}${paint('...', C.dim)}`);
|
|
170
|
+
counter.maxReached = true;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
// Check if this child will be the last one we render due to limits
|
|
174
|
+
let willBeLast = i === children.length - 1;
|
|
175
|
+
renderTree(children[i], prefix + extension, willBeLast, counter, limit, depth + 1, maxDepth);
|
|
176
|
+
if (counter.maxReached)
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.log(`${prefix}${connector}${paint(node.name, C.white)}`);
|
|
182
|
+
counter.count += 1;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
// Banner (private)
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
function printBanner() {
|
|
189
|
+
const name = paint('Toren', C.bold, C.cyan);
|
|
190
|
+
const version = paint(`v${pkg.version}`, C.dim);
|
|
191
|
+
const tagline = paint('Codebase Onboarding Intelligence', C.dim);
|
|
192
|
+
console.log(`${name} ${version} — ${tagline}`);
|
|
193
|
+
}
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// Public API
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
/**
|
|
198
|
+
* Render a ScanResult to the terminal.
|
|
199
|
+
*
|
|
200
|
+
* All sections read from the ScanResult. Presentation-level derivations
|
|
201
|
+
* (e.g. frameworks list) are computed here; no business logic is added.
|
|
202
|
+
*
|
|
203
|
+
* @param {import('../scanner/scan.js').ScanResult} result
|
|
204
|
+
* @param {{ cwd?: string }} [options]
|
|
205
|
+
*/
|
|
206
|
+
export function render(result, options = {}) {
|
|
207
|
+
const { rootPath, projectType, entryPoints, configs = [], scripts = [], packageManager, importantFiles = [], projectInfo = null, health = [], tree, flatFiles, totalFolders, scanDurationMs, } = result;
|
|
208
|
+
const cwd = options.cwd ?? process.cwd();
|
|
209
|
+
const relRoot = path.relative(cwd, rootPath) || '.';
|
|
210
|
+
// ── Banner ────────────────────────────────────────────────────────────────
|
|
211
|
+
printBanner();
|
|
212
|
+
console.log('');
|
|
213
|
+
// ── Summary ───────────────────────────────────────────────────────────────
|
|
214
|
+
section('Project Summary');
|
|
215
|
+
row('Path: ', paint(relRoot, C.cyan));
|
|
216
|
+
if (projectInfo && projectInfo.name) {
|
|
217
|
+
row('Name: ', paint(projectInfo.name, C.white));
|
|
218
|
+
}
|
|
219
|
+
row('Project type: ', paint(projectType, C.bold, C.green));
|
|
220
|
+
if (packageManager) {
|
|
221
|
+
row('Pkg manager: ', paint(packageManager, C.white));
|
|
222
|
+
}
|
|
223
|
+
row('Total files: ', paint(String(flatFiles.length), C.yellow));
|
|
224
|
+
row('Total folders:', paint(String(totalFolders), C.yellow));
|
|
225
|
+
console.log('');
|
|
226
|
+
// ── Project Health ────────────────────────────────────────────────────────
|
|
227
|
+
section('Project Health');
|
|
228
|
+
if (health.length === 0) {
|
|
229
|
+
console.log(paint('No project health observations available.', C.dim));
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
for (const h of health) {
|
|
233
|
+
let icon = 'ℹ';
|
|
234
|
+
let color = C.white;
|
|
235
|
+
if (h.status === 'pass') {
|
|
236
|
+
icon = '✓';
|
|
237
|
+
color = C.green;
|
|
238
|
+
}
|
|
239
|
+
else if (h.status === 'warning') {
|
|
240
|
+
icon = '⚠';
|
|
241
|
+
color = C.yellow;
|
|
242
|
+
}
|
|
243
|
+
console.log(`${paint(icon, color)} ${h.message}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
console.log('');
|
|
247
|
+
// ── Important Files ───────────────────────────────────────────────────────
|
|
248
|
+
section('Important Files');
|
|
249
|
+
if (importantFiles.length === 0) {
|
|
250
|
+
console.log(paint('No important files detected.', C.dim));
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
importantFiles.forEach((f, idx) => {
|
|
254
|
+
console.log(`${idx + 1}. ${paint(f.path, C.white)}`);
|
|
255
|
+
console.log(` ${paint(f.reason, C.dim)}`);
|
|
256
|
+
if (idx < importantFiles.length - 1)
|
|
257
|
+
console.log('');
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
console.log('');
|
|
261
|
+
// ── Frameworks ────────────────────────────────────────────────────────────
|
|
262
|
+
section('Frameworks');
|
|
263
|
+
const frameworks = deriveFrameworks(projectType);
|
|
264
|
+
if (frameworks.length === 0) {
|
|
265
|
+
console.log(paint('No frameworks detected.', C.dim));
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
for (const fw of frameworks) {
|
|
269
|
+
console.log(paint(fw, C.white));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
console.log('');
|
|
273
|
+
// ── Entry Points ──────────────────────────────────────────────────────────
|
|
274
|
+
section('Entry Points');
|
|
275
|
+
if (entryPoints.length === 0) {
|
|
276
|
+
console.log(paint('No entry points detected.', C.dim));
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
for (const ep of entryPoints) {
|
|
280
|
+
console.log(paint(ep, C.white));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
console.log('');
|
|
284
|
+
// ── Configuration Files ───────────────────────────────────────────────────
|
|
285
|
+
section('Configuration Files');
|
|
286
|
+
if (configs.length === 0) {
|
|
287
|
+
console.log(paint('No configuration files detected.', C.dim));
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
for (const c of configs) {
|
|
291
|
+
console.log(paint(c, C.white));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
console.log('');
|
|
295
|
+
// ── Package Scripts ───────────────────────────────────────────────────────
|
|
296
|
+
section('Package Scripts');
|
|
297
|
+
if (scripts.length === 0) {
|
|
298
|
+
console.log(paint('No package scripts detected.', C.dim));
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
for (let i = 0; i < scripts.length; i++) {
|
|
302
|
+
const s = scripts[i];
|
|
303
|
+
const usage = s.usage || `npm run ${s.name}`;
|
|
304
|
+
console.log(paint(usage, C.white));
|
|
305
|
+
if (s.description) {
|
|
306
|
+
console.log(` ${paint(s.description, C.dim)}`);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
console.log(` ${paint(s.command, C.dim)}`);
|
|
310
|
+
}
|
|
311
|
+
if (i < scripts.length - 1)
|
|
312
|
+
console.log('');
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
console.log('');
|
|
316
|
+
// ── Structure Preview ─────────────────────────────────────────────────────
|
|
317
|
+
section('Folder Structure');
|
|
318
|
+
console.log(paint(`${tree.name || '.'}${path.sep}`, C.bold, C.blue));
|
|
319
|
+
const counter = { count: 0, maxReached: false };
|
|
320
|
+
const children = tree.children ?? [];
|
|
321
|
+
for (let i = 0; i < children.length; i++) {
|
|
322
|
+
if (counter.count >= PREVIEW_LIMIT) {
|
|
323
|
+
console.log(`${CHARS.corner}${paint('...', C.dim)}`);
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
renderTree(children[i], '', i === children.length - 1, counter);
|
|
327
|
+
if (counter.maxReached)
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
if (flatFiles.length > PREVIEW_LIMIT) {
|
|
331
|
+
const hidden = flatFiles.length - PREVIEW_LIMIT;
|
|
332
|
+
console.log(paint(`… ${hidden} more file(s) not shown`, C.dim));
|
|
333
|
+
}
|
|
334
|
+
// ── Footer ────────────────────────────────────────────────────────────────
|
|
335
|
+
console.log('');
|
|
336
|
+
console.log(paint(`Scan completed in ${formatDuration(scanDurationMs)}`, C.green));
|
|
337
|
+
console.log('');
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Render only the project structure for the --structure flag.
|
|
341
|
+
*
|
|
342
|
+
* @param {import('../scanner/scan.js').ScanResult} result
|
|
343
|
+
*/
|
|
344
|
+
export function renderStructure(result) {
|
|
345
|
+
const { tree, flatFiles } = result;
|
|
346
|
+
section('Folder Structure');
|
|
347
|
+
console.log(paint(`${tree.name || '.'}${path.sep}`, C.bold, C.blue));
|
|
348
|
+
const counter = { count: 0, maxReached: false };
|
|
349
|
+
const children = tree.children ?? [];
|
|
350
|
+
const limit = flatFiles.length; // No preview limit for focused --structure
|
|
351
|
+
for (let i = 0; i < children.length; i++) {
|
|
352
|
+
if (counter.count >= limit) {
|
|
353
|
+
console.log(`${CHARS.corner}${paint('...', C.dim)}`);
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
renderTree(children[i], '', i === children.length - 1, counter, limit, 0, Infinity);
|
|
357
|
+
if (counter.maxReached)
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
//# sourceMappingURL=console-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console-renderer.js","sourceRoot":"","sources":["../../src/renderers/console-renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ScanResult } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Render a ScanResult as a self-contained HTML5 report to stdout.
|
|
4
|
+
*
|
|
5
|
+
* The entire document is assembled into a single string before writing —
|
|
6
|
+
* one console.log call keeps stdout writes atomic and avoids partial output
|
|
7
|
+
* if the process is terminated early.
|
|
8
|
+
*
|
|
9
|
+
* @param {import('../scanner/scan.js').ScanResult} result
|
|
10
|
+
* @param {{ cwd?: string }} [options]
|
|
11
|
+
*/
|
|
12
|
+
export declare function render(result: ScanResult, options?: {
|
|
13
|
+
cwd?: string;
|
|
14
|
+
}): void;
|