@lakindu_perera/toren 1.0.5 → 1.0.8
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 +19 -0
- package/README.md +172 -63
- package/bin/toren.js +66 -44
- package/package.json +7 -3
- package/src/detectors/health-detector.js +72 -0
- package/src/detectors/important-files-detector.js +515 -0
- package/src/detectors/package-manager-detector.js +112 -0
- package/src/detectors/project-info-detector.js +89 -0
- package/src/detectors/script-detector.js +226 -10
- package/src/focused-output.js +161 -41
- package/src/renderers/console-renderer.js +170 -53
- package/src/renderers/html-renderer.js +212 -73
- package/src/renderers/json-renderer.js +133 -23
- package/src/renderers/markdown-renderer.js +127 -104
- package/src/scanner/scan.js +51 -10
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.7] - 2026-08-29
|
|
9
|
+
### Added
|
|
10
|
+
- **Project Intelligence Upgrade**: Added Package Manager detection, project metadata extraction (name, language, runtime, architecture), and important file detection.
|
|
11
|
+
- **Project Health Checks**: New `--health` flag to evaluate repository health (checking for README, License, linting, tests, docker files).
|
|
12
|
+
- **Richer Output Formats**: Expanded HTML and Markdown renderers to include the newly extracted project details, ensuring a highly readable and comprehensive project overview.
|
|
13
|
+
- **Enhanced JSON schema**: Output JSON schema has been substantially updated to support these rich data properties in a deterministic order.
|
|
14
|
+
- **New CLI flags**: `--summary`, `--important-files`, and `--health`.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Refactored `ScanResult` object with `packageManager`, `projectInfo`, `health`, and `importantFiles`.
|
|
18
|
+
- Updated test suite for new CLI flags and deterministic JSON output.
|
|
19
|
+
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Toren —
|
|
1
|
+
# Toren — Fast Repository Discovery CLI
|
|
2
2
|
|
|
3
3
|
> The fastest way to understand any project structure. A zero-dependency codebase scanner CLI for modern developers.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@lakindudev/toren)
|
|
6
6
|
[](https://nodejs.org)
|
|
7
7
|
[](package.json)
|
|
8
8
|
[](LICENSE)
|
|
@@ -23,6 +23,8 @@ Built with zero external dependencies, this **Node.js repository explorer** is t
|
|
|
23
23
|
- **Framework Detection**: Instantly identifies Node.js, React, Next.js, Vue, Nuxt, Angular, Svelte, Python, Go, Rust, Spring Boot, Ruby, PHP, Elixir and more.
|
|
24
24
|
- **Entry Point Detection**: Automatically pinpoints where execution begins (e.g., `index.js`, `main.ts`, `App.tsx`, `main.go`).
|
|
25
25
|
- **Project Structure Visualizer**: Generates clean, hierarchical file trees.
|
|
26
|
+
- **Project Health Diagnostics**: Provides observations and warnings for common project health issues.
|
|
27
|
+
- **Package Manager Detection**: Identifies whether a project uses npm, pnpm, yarn, bun, etc.
|
|
26
28
|
- **Multiple Output Formats**: Choose between `console` (default), `json`, `markdown`, or `html` reports.
|
|
27
29
|
- **Zero Dependencies**: A pure Node.js CLI tool with no external runtime packages. Lightning fast install, infinitely secure.
|
|
28
30
|
- **CLI Lifecycle Tools**: Native diagnostic and uninstallation tools (`--doctor`, `--uninstall`).
|
|
@@ -34,7 +36,7 @@ Built with zero external dependencies, this **Node.js repository explorer** is t
|
|
|
34
36
|
Install Toren globally via npm to make the **repository inspection CLI** available anywhere on your machine:
|
|
35
37
|
|
|
36
38
|
```bash
|
|
37
|
-
npm install -g @
|
|
39
|
+
npm install -g @lakindudev/toren
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
**Requirements:** Node.js 18.0.0 or higher.
|
|
@@ -69,6 +71,9 @@ toren --entry-points
|
|
|
69
71
|
toren --structure
|
|
70
72
|
toren --configs
|
|
71
73
|
toren --scripts
|
|
74
|
+
toren --summary
|
|
75
|
+
toren --important-files
|
|
76
|
+
toren --health
|
|
72
77
|
|
|
73
78
|
# Lifecycle & Help Commands
|
|
74
79
|
toren --help
|
|
@@ -77,10 +82,10 @@ toren --doctor
|
|
|
77
82
|
toren --uninstall
|
|
78
83
|
```
|
|
79
84
|
|
|
80
|
-
###
|
|
85
|
+
### CLI Reference
|
|
81
86
|
|
|
82
|
-
| Flag | Description |
|
|
83
|
-
|
|
87
|
+
| Command / Flag | Description |
|
|
88
|
+
|----------------|-------------|
|
|
84
89
|
| `[path]` | Directory to scan. Defaults to the current directory (`.`). |
|
|
85
90
|
| `--project-type` | Show detected project type only. |
|
|
86
91
|
| `--frameworks` | Show detected frameworks only. |
|
|
@@ -88,70 +93,46 @@ toren --uninstall
|
|
|
88
93
|
| `--structure` | Show repository structure only. |
|
|
89
94
|
| `--configs` | Show detected project configuration files. |
|
|
90
95
|
| `--scripts` | Show available package scripts only. |
|
|
96
|
+
| `--summary` | Show project summary only. |
|
|
97
|
+
| `--important-files` | Show important files only. |
|
|
98
|
+
| `--health` | Show project health observations only. |
|
|
91
99
|
| `--format <type>` | Output format: `console` (default), `json`, `markdown`, `html`. |
|
|
92
100
|
| `--include-hidden` | Include hidden files and dot-directories in the scan. |
|
|
93
|
-
| `--max-files <
|
|
94
|
-
| `--help
|
|
95
|
-
| `--version
|
|
101
|
+
| `--max-files <n>` | Override the default 50,000-file scan limit. |
|
|
102
|
+
| `--help`, `-h` | Show usage and help message. |
|
|
103
|
+
| `--version`, `-v` | Print the installed version number. |
|
|
96
104
|
| `--doctor` | Diagnose the global installation health. |
|
|
97
105
|
| `--uninstall` | Safely remove Toren from the global npm environment. |
|
|
98
106
|
|
|
99
107
|
> **Note:** `--format md` is not a valid alias. Use `--format markdown` in full.
|
|
100
|
-
> **Note:** Focused output flags
|
|
108
|
+
> **Note:** Focused output flags are mutually exclusive.
|
|
101
109
|
|
|
102
110
|
---
|
|
103
111
|
|
|
104
|
-
## Output Examples
|
|
112
|
+
## Screenshots & Output Examples
|
|
105
113
|
|
|
106
|
-
###
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
$ toren --project-type
|
|
111
|
-
Project Type: Node.js / JavaScript
|
|
114
|
+
### Console Output Example
|
|
115
|
+
The default `console` format renders a beautiful summary directly in your terminal:
|
|
112
116
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
- React
|
|
117
|
+
```text
|
|
118
|
+
Toren v1.0.7 — Fast Repository Discovery CLI
|
|
116
119
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
- src/main.tsx
|
|
120
|
+
Project Summary
|
|
121
|
+
───────────────
|
|
120
122
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
Path: ./my-react-app
|
|
124
|
+
Project type: React
|
|
125
|
+
Total files: 32
|
|
126
|
+
Total folders: 6
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
Entry Points
|
|
129
|
+
────────────
|
|
127
130
|
|
|
128
|
-
|
|
129
|
-
Available Scripts
|
|
131
|
+
src/main.tsx
|
|
130
132
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
```
|
|
133
|
+
Folder Structure (first 20 files)
|
|
134
|
+
──────────────────────────────────
|
|
134
135
|
|
|
135
|
-
### Console Output Example
|
|
136
|
-
The default `console` format renders a beautiful summary directly in your terminal:
|
|
137
|
-
|
|
138
|
-
```text
|
|
139
|
-
Toren v1.0.4 — Codebase Onboarding Intelligence
|
|
140
|
-
|
|
141
|
-
Project Summary
|
|
142
|
-
────────────────────────────────────────────────────────────────────────────────
|
|
143
|
-
Path: ./my-react-app
|
|
144
|
-
Project type: React
|
|
145
|
-
Total files: 32
|
|
146
|
-
Total folders: 6
|
|
147
|
-
Scan duration: 4 ms
|
|
148
|
-
|
|
149
|
-
Entry Points
|
|
150
|
-
────────────────────────────────────────────────────────────────────────────────
|
|
151
|
-
→ src/main.tsx
|
|
152
|
-
|
|
153
|
-
Folder Structure (first 20 files)
|
|
154
|
-
────────────────────────────────────────────────────────────────────────────────
|
|
155
136
|
my-react-app/
|
|
156
137
|
├── public/
|
|
157
138
|
│ └── vite.svg
|
|
@@ -165,10 +146,27 @@ my-react-app/
|
|
|
165
146
|
├── index.html
|
|
166
147
|
├── package.json
|
|
167
148
|
└── vite.config.ts
|
|
168
|
-
|
|
149
|
+
… and 21 more file(s) not shown
|
|
150
|
+
|
|
151
|
+
Scan completed in 4 ms
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Focused Output Examples
|
|
155
|
+
Sometimes you only need a specific piece of intelligence for use in a script or a quick lookup. Use the focused output flags to bypass the full report:
|
|
169
156
|
|
|
170
|
-
|
|
171
|
-
|
|
157
|
+
```bash
|
|
158
|
+
$ toren --project-type
|
|
159
|
+
Project Type
|
|
160
|
+
────────────
|
|
161
|
+
|
|
162
|
+
Node.js / JavaScript
|
|
163
|
+
|
|
164
|
+
$ toren --scripts
|
|
165
|
+
Package Scripts
|
|
166
|
+
───────────────
|
|
167
|
+
|
|
168
|
+
start vite
|
|
169
|
+
test vitest
|
|
172
170
|
```
|
|
173
171
|
|
|
174
172
|
### JSON Output Example
|
|
@@ -176,19 +174,54 @@ Generate machine-readable output for scripts, toolchains, or AI context windows
|
|
|
176
174
|
|
|
177
175
|
```json
|
|
178
176
|
{
|
|
177
|
+
"meta": {
|
|
178
|
+
"version": "1.0.7",
|
|
179
|
+
"scanDurationMs": 4,
|
|
180
|
+
"timestamp": "2026-08-29T23:51:00.000Z"
|
|
181
|
+
},
|
|
179
182
|
"project": {
|
|
183
|
+
"name": "my-react-app",
|
|
180
184
|
"path": "./my-react-app",
|
|
181
185
|
"type": "React",
|
|
182
|
-
"framework": "React"
|
|
183
|
-
|
|
184
|
-
"summary": {
|
|
185
|
-
"totalFiles": 32,
|
|
186
|
-
"totalFolders": 6,
|
|
187
|
-
"scanDurationMs": 4
|
|
186
|
+
"framework": "React",
|
|
187
|
+
"packageManager": "npm"
|
|
188
188
|
},
|
|
189
|
+
"frameworks": [
|
|
190
|
+
"React"
|
|
191
|
+
],
|
|
189
192
|
"entryPoints": [
|
|
190
193
|
"src/main.tsx"
|
|
191
194
|
],
|
|
195
|
+
"configs": [
|
|
196
|
+
"package.json",
|
|
197
|
+
"vite.config.ts"
|
|
198
|
+
],
|
|
199
|
+
"scripts": [
|
|
200
|
+
{
|
|
201
|
+
"name": "start",
|
|
202
|
+
"command": "vite",
|
|
203
|
+
"description": "Start the development server",
|
|
204
|
+
"category": "development",
|
|
205
|
+
"usage": "npm start"
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
"importantFiles": [
|
|
209
|
+
{
|
|
210
|
+
"path": "package.json",
|
|
211
|
+
"reason": "Defines dependencies"
|
|
212
|
+
}
|
|
213
|
+
],
|
|
214
|
+
"health": [
|
|
215
|
+
{
|
|
216
|
+
"id": "readme",
|
|
217
|
+
"status": "pass",
|
|
218
|
+
"message": "README file is present"
|
|
219
|
+
}
|
|
220
|
+
],
|
|
221
|
+
"statistics": {
|
|
222
|
+
"totalFiles": 32,
|
|
223
|
+
"totalFolders": 6
|
|
224
|
+
},
|
|
192
225
|
"structure": [
|
|
193
226
|
{
|
|
194
227
|
"type": "folder",
|
|
@@ -199,7 +232,12 @@ Generate machine-readable output for scripts, toolchains, or AI context windows
|
|
|
199
232
|
]
|
|
200
233
|
},
|
|
201
234
|
{ "type": "file", "name": "package.json" }
|
|
202
|
-
]
|
|
235
|
+
],
|
|
236
|
+
"summary": {
|
|
237
|
+
"totalFiles": 32,
|
|
238
|
+
"totalFolders": 6,
|
|
239
|
+
"scanDurationMs": 4
|
|
240
|
+
}
|
|
203
241
|
}
|
|
204
242
|
```
|
|
205
243
|
|
|
@@ -207,6 +245,23 @@ Generate machine-readable output for scripts, toolchains, or AI context windows
|
|
|
207
245
|
|
|
208
246
|
---
|
|
209
247
|
|
|
248
|
+
## Release Notes
|
|
249
|
+
|
|
250
|
+
### v1.0.7 - Intelligence Upgrade
|
|
251
|
+
- **Project Intelligence Upgrade**: Added Package Manager detection, project metadata extraction (name, language, runtime, architecture), and important file detection.
|
|
252
|
+
- **Project Health Checks**: New `--health` flag to evaluate repository health (checking for README, License, linting, tests, docker files).
|
|
253
|
+
- **Richer Output Formats**: Expanded HTML and Markdown renderers to include the newly extracted project details, ensuring a highly readable and comprehensive project overview.
|
|
254
|
+
- **Enhanced JSON schema**: Output JSON schema has been substantially updated to support these rich data properties in a deterministic order.
|
|
255
|
+
|
|
256
|
+
### v1.0.6 - CLI Experience Update
|
|
257
|
+
- **Redesigned CLI Output**: Completely revamped the console layout to use minimal typography, bold section titles, and dynamic divider lines matching the title width.
|
|
258
|
+
- **Improved Error Handling**: Transformed raw exceptions into user-friendly error messages outlining the issue and potential fixes, ensuring consistent exit codes.
|
|
259
|
+
- **Enhanced Focused Modes**: Focused output flags (`--configs`, `--entry-points`, `--structure`, etc.) now strictly mirror the design tokens of the full console renderer, providing identical spacing and layouts.
|
|
260
|
+
- **Streamlined Help & Version**: The `--help` interface was fully redesigned for faster reading, and `-v` / `--version` flags were added to output the exact binary version directly from `package.json`.
|
|
261
|
+
- **Accurate Timing Metrics**: Scan duration logic was improved to utilize native timing APIs, precisely measuring execution and printing results natively as "Scan completed in X ms" without clogging the project summary.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
210
265
|
## Architecture
|
|
211
266
|
|
|
212
267
|
Toren's internal architecture emphasizes modular design, separation of concerns, and a strict **zero dependency** philosophy.
|
|
@@ -253,6 +308,60 @@ Contributions to improve this codebase analyzer CLI are always welcome!
|
|
|
253
308
|
|
|
254
309
|
---
|
|
255
310
|
|
|
311
|
+
## Maintainer: Releasing a New Version
|
|
312
|
+
|
|
313
|
+
Toren uses **automated npm publishing via GitHub Actions** and [npm Trusted Publishing (OIDC)](https://docs.npmjs.com/generating-provenance-statements).
|
|
314
|
+
**Do not run `npm publish` manually** — GitHub Actions owns the publish step.
|
|
315
|
+
|
|
316
|
+
### Release checklist
|
|
317
|
+
|
|
318
|
+
```text
|
|
319
|
+
1. Implement changes on a feature branch.
|
|
320
|
+
|
|
321
|
+
2. Update the version in package.json:
|
|
322
|
+
"version": "1.0.8"
|
|
323
|
+
|
|
324
|
+
3. Run tests and lint locally:
|
|
325
|
+
npm test
|
|
326
|
+
npm run lint
|
|
327
|
+
|
|
328
|
+
4. Commit the version bump and any other changes:
|
|
329
|
+
git commit -m "chore: release v1.0.8"
|
|
330
|
+
|
|
331
|
+
5. Open a Pull Request → merge to main.
|
|
332
|
+
|
|
333
|
+
6. On GitHub, create a new Release:
|
|
334
|
+
Tag: v1.0.8 ← must match package.json exactly (with leading v)
|
|
335
|
+
Title: v1.0.8
|
|
336
|
+
Body: paste CHANGELOG.md entry
|
|
337
|
+
|
|
338
|
+
7. Click "Publish Release".
|
|
339
|
+
|
|
340
|
+
8. GitHub Actions runs automatically:
|
|
341
|
+
✔ npm ci
|
|
342
|
+
✔ npm test (all 233+ tests must pass)
|
|
343
|
+
✔ npm run lint
|
|
344
|
+
✔ tag format validated (vX.Y.Z)
|
|
345
|
+
✔ tag v1.0.8 == package.json 1.0.8
|
|
346
|
+
✔ npm pack --dry-run
|
|
347
|
+
✔ npm publish --access public --provenance
|
|
348
|
+
|
|
349
|
+
9. @lakindudev/toren@1.0.8 is live on npmjs.com.
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### If the workflow fails
|
|
353
|
+
|
|
354
|
+
| Failure step | Cause | Fix |
|
|
355
|
+
|---|---|---|
|
|
356
|
+
| Run tests | A test is failing | Fix the test, push, re-create release |
|
|
357
|
+
| Run lint | Syntax error in source | Fix lint error, push, re-create release |
|
|
358
|
+
| Validate tag format | Tag is not `vX.Y.Z` | Delete the release, re-create with correct tag |
|
|
359
|
+
| Verify version matches | `package.json` not bumped | Update `package.json`, push, re-create release |
|
|
360
|
+
| Verify package contents | `files` array misconfigured | Fix `package.json`, push, re-create release |
|
|
361
|
+
| Publish to npm | Trusted Publisher not configured | Follow the npm Trusted Publisher setup in `.github/workflows/publish.yml` header |
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
256
365
|
## License
|
|
257
366
|
|
|
258
367
|
Distributed under the MIT License. See `LICENSE` for more information.
|
package/bin/toren.js
CHANGED
|
@@ -38,43 +38,59 @@ const DEFAULT_FORMAT = 'console';
|
|
|
38
38
|
const SUPPORTED_FORMATS = Object.keys(renderers);
|
|
39
39
|
|
|
40
40
|
// ---------------------------------------------------------------------------
|
|
41
|
-
//
|
|
41
|
+
// Helpers
|
|
42
42
|
// ---------------------------------------------------------------------------
|
|
43
43
|
|
|
44
|
+
function printError(title, message, detailLabel, detailValue) {
|
|
45
|
+
console.error(`\x1b[31m✖ ${title}\x1b[0m\n`);
|
|
46
|
+
console.error(`${message}\n`);
|
|
47
|
+
if (detailLabel && detailValue) {
|
|
48
|
+
console.error(`${detailLabel}:\n`);
|
|
49
|
+
console.error(`${detailValue}\n`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
44
53
|
function printHelp() {
|
|
45
|
-
const formatList = SUPPORTED_FORMATS.map(f =>
|
|
54
|
+
const formatList = SUPPORTED_FORMATS.map(f => {
|
|
55
|
+
const suffix = f === DEFAULT_FORMAT ? ' (default)' : '';
|
|
56
|
+
return ` --format ${f.padEnd(10)}${suffix}`;
|
|
57
|
+
}).join('\n');
|
|
58
|
+
|
|
46
59
|
console.log(`
|
|
47
|
-
\x1b[
|
|
60
|
+
\x1b[1mToren\x1b[0m v${pkg.version}
|
|
61
|
+
Fast Repository Discovery CLI
|
|
62
|
+
|
|
63
|
+
\x1b[1mUSAGE\x1b[0m
|
|
48
64
|
toren [path] [options]
|
|
49
65
|
|
|
50
|
-
\x1b[
|
|
66
|
+
\x1b[1mCOMMANDS\x1b[0m
|
|
51
67
|
--project-type Show detected project type only
|
|
52
68
|
--frameworks Show detected frameworks only
|
|
53
69
|
--entry-points Show detected entry points only
|
|
54
70
|
--structure Show repository structure only
|
|
55
71
|
--configs Show detected project configuration files
|
|
56
72
|
--scripts Show available package scripts only
|
|
57
|
-
--
|
|
73
|
+
--summary Show project summary only
|
|
74
|
+
--important-files Show important files only
|
|
75
|
+
--health Show project health observations only
|
|
58
76
|
--include-hidden Include hidden files and folders
|
|
59
77
|
--max-files <n> Set scan file limit
|
|
60
|
-
--help Show this help message
|
|
61
|
-
--version Show version number
|
|
62
78
|
--doctor Run CLI diagnostics
|
|
63
79
|
--uninstall Remove Toren global installation
|
|
80
|
+
--help Show this help message
|
|
81
|
+
--version Show version number
|
|
64
82
|
|
|
65
|
-
\x1b[
|
|
83
|
+
\x1b[1mOUTPUT FORMATS\x1b[0m
|
|
66
84
|
${formatList}
|
|
67
85
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
\x1b[1mExamples:\x1b[0m
|
|
86
|
+
\x1b[1mEXAMPLES\x1b[0m
|
|
71
87
|
toren . Scan the current directory
|
|
72
88
|
toren ./my-project Scan a specific project folder
|
|
73
89
|
toren --format json . Output results as JSON
|
|
74
90
|
toren --format markdown . > out.md Save a Markdown report to a file
|
|
75
91
|
toren --format html . > out.html Save an HTML report to a file
|
|
76
|
-
toren --
|
|
77
|
-
toren
|
|
92
|
+
toren . --configs Show project configuration files
|
|
93
|
+
toren . --frameworks Show detected frameworks
|
|
78
94
|
`);
|
|
79
95
|
}
|
|
80
96
|
|
|
@@ -110,7 +126,7 @@ function parseArgs() {
|
|
|
110
126
|
}
|
|
111
127
|
|
|
112
128
|
if (args.includes('--version') || args.includes('-V') || args.includes('-v')) {
|
|
113
|
-
console.log(pkg.version);
|
|
129
|
+
console.log(`Toren ${pkg.version}`);
|
|
114
130
|
return { action: 'exit', code: 0 };
|
|
115
131
|
}
|
|
116
132
|
|
|
@@ -135,13 +151,12 @@ function parseArgs() {
|
|
|
135
151
|
const nextToken = args[formatIdx + 1];
|
|
136
152
|
// If the next token is missing or starts with '-', the user omitted the value.
|
|
137
153
|
if (nextToken === undefined || nextToken.startsWith('-')) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
console.error('');
|
|
154
|
+
printError(
|
|
155
|
+
'Missing value',
|
|
156
|
+
'The --format flag requires a valid output format.',
|
|
157
|
+
'Supported formats',
|
|
158
|
+
SUPPORTED_FORMATS.join(', ')
|
|
159
|
+
);
|
|
145
160
|
return { action: 'exit', code: 1 };
|
|
146
161
|
}
|
|
147
162
|
format = nextToken;
|
|
@@ -153,7 +168,7 @@ function parseArgs() {
|
|
|
153
168
|
const focusedInfo = getFocusedModeInfo(args);
|
|
154
169
|
|
|
155
170
|
if (focusedInfo.error) {
|
|
156
|
-
|
|
171
|
+
printError(focusedInfo.title, focusedInfo.message, focusedInfo.detailLabel, focusedInfo.detailValue);
|
|
157
172
|
return { action: 'exit', code: 1 };
|
|
158
173
|
}
|
|
159
174
|
|
|
@@ -176,17 +191,22 @@ function parseArgs() {
|
|
|
176
191
|
if (maxFilesIdx !== -1) {
|
|
177
192
|
const rawVal = args[maxFilesIdx + 1];
|
|
178
193
|
if (rawVal === undefined || rawVal.startsWith('-')) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
194
|
+
printError(
|
|
195
|
+
'Missing value',
|
|
196
|
+
'The --max-files flag requires a numeric value.',
|
|
197
|
+
'Example',
|
|
198
|
+
'toren --max-files 100000'
|
|
199
|
+
);
|
|
183
200
|
return { action: 'exit', code: 1 };
|
|
184
201
|
}
|
|
185
202
|
maxFiles = parseInt(rawVal, 10);
|
|
186
203
|
if (isNaN(maxFiles) || maxFiles < 1) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
204
|
+
printError(
|
|
205
|
+
'Invalid value',
|
|
206
|
+
'The --max-files flag must be a positive integer.',
|
|
207
|
+
'Provided value',
|
|
208
|
+
rawVal
|
|
209
|
+
);
|
|
190
210
|
return { action: 'exit', code: 1 };
|
|
191
211
|
}
|
|
192
212
|
consumedValues.add(rawVal);
|
|
@@ -213,8 +233,12 @@ function parseArgs() {
|
|
|
213
233
|
);
|
|
214
234
|
|
|
215
235
|
if (unknownFlag) {
|
|
216
|
-
|
|
217
|
-
|
|
236
|
+
printError(
|
|
237
|
+
'Unknown option',
|
|
238
|
+
'An unrecognized flag was provided.',
|
|
239
|
+
'Flag',
|
|
240
|
+
unknownFlag
|
|
241
|
+
);
|
|
218
242
|
return { action: 'exit', code: 1 };
|
|
219
243
|
}
|
|
220
244
|
|
|
@@ -234,16 +258,12 @@ function parseArgs() {
|
|
|
234
258
|
function assertValidFormat(format) {
|
|
235
259
|
if (renderers[format]) return;
|
|
236
260
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
console.error(list);
|
|
244
|
-
console.error('');
|
|
245
|
-
console.error(' Run \x1b[36mtoren --help\x1b[0m for usage.');
|
|
246
|
-
console.error('');
|
|
261
|
+
printError(
|
|
262
|
+
'Unsupported output format',
|
|
263
|
+
'The requested output format is not supported.',
|
|
264
|
+
'Format',
|
|
265
|
+
format
|
|
266
|
+
);
|
|
247
267
|
process.exit(1);
|
|
248
268
|
}
|
|
249
269
|
|
|
@@ -280,9 +300,11 @@ function assertValidFormat(format) {
|
|
|
280
300
|
if (parsed.format === 'json') {
|
|
281
301
|
console.error(JSON.stringify({ error: err.message }, null, 2));
|
|
282
302
|
} else {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
303
|
+
if (err.title) {
|
|
304
|
+
printError(err.title, err.message, err.detailLabel, err.detailValue);
|
|
305
|
+
} else {
|
|
306
|
+
printError('Scan failed', err.message);
|
|
307
|
+
}
|
|
286
308
|
}
|
|
287
309
|
process.exit(1);
|
|
288
310
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lakindu_perera/toren",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "A powerful codebase scanner CLI tool for project analysis, framework detection, and understanding repository structure instantly.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,12 +10,16 @@
|
|
|
10
10
|
"bin",
|
|
11
11
|
"src",
|
|
12
12
|
"LICENSE",
|
|
13
|
-
"README.md"
|
|
13
|
+
"README.md",
|
|
14
|
+
"CHANGELOG.md"
|
|
14
15
|
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
15
19
|
"scripts": {
|
|
16
20
|
"start": "node bin/toren.js",
|
|
17
21
|
"test": "node --test",
|
|
18
|
-
"lint": "node --check bin/toren.js src/scanner/scan.js src/lifecycle.js src/renderers/index.js src/renderers/console-renderer.js src/renderers/json-renderer.js src/renderers/markdown-renderer.js src/renderers/html-renderer.js"
|
|
22
|
+
"lint": "node --check bin/toren.js src/scanner/scan.js src/lifecycle.js src/renderers/index.js src/renderers/console-renderer.js src/renderers/json-renderer.js src/renderers/markdown-renderer.js src/renderers/html-renderer.js src/detectors/config-detector.js src/detectors/script-detector.js src/detectors/package-manager-detector.js"
|
|
19
23
|
},
|
|
20
24
|
"keywords": [
|
|
21
25
|
"cli tool",
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect project health observations.
|
|
3
|
+
*/
|
|
4
|
+
export function detectHealth({
|
|
5
|
+
flatFiles,
|
|
6
|
+
configs,
|
|
7
|
+
importantFiles,
|
|
8
|
+
scripts,
|
|
9
|
+
projectType
|
|
10
|
+
}) {
|
|
11
|
+
const health = [];
|
|
12
|
+
const fileSet = new Set(flatFiles);
|
|
13
|
+
|
|
14
|
+
// README
|
|
15
|
+
if (fileSet.has('README.md') || fileSet.has('README') || fileSet.has('readme.md')) {
|
|
16
|
+
health.push({ id: 'readme', status: 'pass', message: 'README found' });
|
|
17
|
+
} else {
|
|
18
|
+
health.push({ id: 'readme', status: 'warning', message: 'README not found' });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// LICENSE
|
|
22
|
+
if (fileSet.has('LICENSE') || fileSet.has('LICENSE.md') || fileSet.has('LICENSE.txt')) {
|
|
23
|
+
health.push({ id: 'license', status: 'pass', message: 'LICENSE found' });
|
|
24
|
+
} else {
|
|
25
|
+
health.push({ id: 'license', status: 'warning', message: 'LICENSE not found' });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ENVIRONMENT EXAMPLE
|
|
29
|
+
if (fileSet.has('.env.example') || fileSet.has('.env.sample')) {
|
|
30
|
+
health.push({ id: 'env-example', status: 'pass', message: 'Environment example found' });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// TESTS
|
|
34
|
+
const hasTestFiles = flatFiles.some(f =>
|
|
35
|
+
f.startsWith('test/') ||
|
|
36
|
+
f.startsWith('tests/') ||
|
|
37
|
+
f.startsWith('__tests__/') ||
|
|
38
|
+
f.includes('.test.') ||
|
|
39
|
+
f.includes('.spec.')
|
|
40
|
+
);
|
|
41
|
+
const hasTestScripts = (scripts || []).some(s => s.category === 'testing' || s.name === 'test');
|
|
42
|
+
if (hasTestFiles || hasTestScripts) {
|
|
43
|
+
health.push({ id: 'tests', status: 'pass', message: 'Tests detected' });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// LINTER
|
|
47
|
+
const hasLinter = (configs || []).some(c =>
|
|
48
|
+
c.includes('eslint') ||
|
|
49
|
+
c.includes('biome') ||
|
|
50
|
+
c.includes('stylelint')
|
|
51
|
+
) || (scripts || []).some(s => s.category === 'quality' || s.name === 'lint');
|
|
52
|
+
if (hasLinter) {
|
|
53
|
+
health.push({ id: 'lint', status: 'pass', message: 'Linter detected' });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// TYPESCRIPT
|
|
57
|
+
if (fileSet.has('tsconfig.json')) {
|
|
58
|
+
health.push({ id: 'typescript', status: 'pass', message: 'TypeScript configuration found' });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// GIT
|
|
62
|
+
if (fileSet.has('.gitignore')) {
|
|
63
|
+
health.push({ id: 'git', status: 'info', message: '.gitignore found' });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// DOCKER
|
|
67
|
+
if (fileSet.has('Dockerfile') || fileSet.has('docker-compose.yml') || fileSet.has('compose.yml')) {
|
|
68
|
+
health.push({ id: 'docker', status: 'info', message: 'Docker configuration found' });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { health };
|
|
72
|
+
}
|