@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.
Files changed (61) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +120 -31
  3. package/dist/cli/toren.d.ts +24 -0
  4. package/dist/cli/toren.js +254 -0
  5. package/dist/cli/toren.js.map +1 -0
  6. package/dist/detectors/config-detector.d.ts +3 -0
  7. package/dist/detectors/config-detector.js +58 -0
  8. package/dist/detectors/config-detector.js.map +1 -0
  9. package/dist/detectors/health-detector.d.ts +12 -0
  10. package/dist/detectors/health-detector.js +53 -0
  11. package/dist/detectors/health-detector.js.map +1 -0
  12. package/dist/detectors/important-files-detector.d.ts +51 -0
  13. package/dist/detectors/important-files-detector.js +455 -0
  14. package/dist/detectors/important-files-detector.js.map +1 -0
  15. package/dist/detectors/package-manager-detector.d.ts +7 -0
  16. package/dist/detectors/package-manager-detector.js +35 -0
  17. package/dist/detectors/package-manager-detector.js.map +1 -0
  18. package/dist/detectors/project-info-detector.d.ts +13 -0
  19. package/dist/detectors/project-info-detector.js +97 -0
  20. package/dist/detectors/project-info-detector.js.map +1 -0
  21. package/dist/detectors/script-detector.d.ts +42 -0
  22. package/dist/detectors/script-detector.js +199 -0
  23. package/dist/detectors/script-detector.js.map +1 -0
  24. package/dist/focused-output.d.ts +27 -0
  25. package/dist/focused-output.js +201 -0
  26. package/dist/focused-output.js.map +1 -0
  27. package/dist/lifecycle.d.ts +2 -0
  28. package/dist/lifecycle.js +114 -0
  29. package/dist/lifecycle.js.map +1 -0
  30. package/dist/renderers/console-renderer.d.ts +19 -0
  31. package/dist/renderers/console-renderer.js +361 -0
  32. package/dist/renderers/console-renderer.js.map +1 -0
  33. package/dist/renderers/html-renderer.d.ts +14 -0
  34. package/{src → dist}/renderers/html-renderer.js +263 -201
  35. package/dist/renderers/html-renderer.js.map +1 -0
  36. package/dist/renderers/index.d.ts +6 -0
  37. package/dist/renderers/index.js +12 -0
  38. package/dist/renderers/index.js.map +1 -0
  39. package/dist/renderers/json-renderer.d.ts +10 -0
  40. package/dist/renderers/json-renderer.js +127 -0
  41. package/dist/renderers/json-renderer.js.map +1 -0
  42. package/dist/renderers/markdown-renderer.d.ts +13 -0
  43. package/dist/renderers/markdown-renderer.js +360 -0
  44. package/dist/renderers/markdown-renderer.js.map +1 -0
  45. package/dist/scanner/scan.d.ts +2 -0
  46. package/dist/scanner/scan.js +573 -0
  47. package/dist/scanner/scan.js.map +1 -0
  48. package/dist/types/index.d.ts +85 -0
  49. package/dist/types/index.js +2 -0
  50. package/dist/types/index.js.map +1 -0
  51. package/package.json +16 -7
  52. package/bin/toren.js +0 -308
  53. package/src/detectors/config-detector.js +0 -81
  54. package/src/detectors/script-detector.js +0 -32
  55. package/src/focused-output.js +0 -146
  56. package/src/lifecycle.js +0 -124
  57. package/src/renderers/console-renderer.js +0 -350
  58. package/src/renderers/index.js +0 -41
  59. package/src/renderers/json-renderer.js +0 -154
  60. package/src/renderers/markdown-renderer.js +0 -337
  61. package/src/scanner/scan.js +0 -532
package/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
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
+ ## [1.0.9] - 2026-08-31
8
+ ### Changed
9
+ - **TypeScript Foundation**: Completely migrated the entire Torén codebase from JavaScript to TypeScript.
10
+ - **Zero Runtime Dependencies**: The CLI continues to operate natively on Node.js without needing ts-node or any other runtime bundlers. Source code is compiled to `.js` files using ES2022 targets.
11
+ - **Build & CI Improvements**: Set up robust static type-checking and automated build steps using `tsc`.
12
+
13
+
14
+
15
+ ## [1.0.7] - 2026-08-29
16
+ ### Added
17
+ - **Project Intelligence Upgrade**: Added Package Manager detection, project metadata extraction (name, language, runtime, architecture), and important file detection.
18
+ - **Project Health Checks**: New `--health` flag to evaluate repository health (checking for README, License, linting, tests, docker files).
19
+ - **Richer Output Formats**: Expanded HTML and Markdown renderers to include the newly extracted project details, ensuring a highly readable and comprehensive project overview.
20
+ - **Enhanced JSON schema**: Output JSON schema has been substantially updated to support these rich data properties in a deterministic order.
21
+ - **New CLI flags**: `--summary`, `--important-files`, and `--health`.
22
+
23
+ ### Changed
24
+ - Refactored `ScanResult` object with `packageManager`, `projectInfo`, `health`, and `importantFiles`.
25
+ - Updated test suite for new CLI flags and deterministic JSON output.
26
+
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Toren — Codebase Analyzer CLI
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
- [![npm version](https://img.shields.io/npm/v/@lakindu_perera/toren.svg)](https://www.npmjs.com/package/@lakindu_perera/toren)
5
+ [![npm version](https://img.shields.io/npm/v/@lakindudev/toren.svg)](https://www.npmjs.com/package/@lakindudev/toren)
6
6
  [![Node.js Version](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org)
7
7
  [![Zero Dependencies](https://img.shields.io/badge/dependencies-zero-success.svg)](package.json)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](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 @lakindu_perera/toren
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
@@ -88,6 +93,9 @@ 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
101
  | `--max-files <n>` | Override the default 50,000-file scan limit. |
@@ -97,7 +105,7 @@ toren --uninstall
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 (`--project-type`, `--frameworks`, `--entry-points`, `--structure`, `--configs`, `--scripts`) are mutually exclusive.
108
+ > **Note:** Focused output flags are mutually exclusive.
101
109
 
102
110
  ---
103
111
 
@@ -107,7 +115,7 @@ toren --uninstall
107
115
  The default `console` format renders a beautiful summary directly in your terminal:
108
116
 
109
117
  ```text
110
- Toren v1.0.6Codebase Onboarding Intelligence
118
+ Toren v1.0.7Fast Repository Discovery CLI
111
119
 
112
120
  Project Summary
113
121
  ───────────────
@@ -153,25 +161,6 @@ Project Type
153
161
 
154
162
  Node.js / JavaScript
155
163
 
156
- $ toren --frameworks
157
- Frameworks
158
- ──────────
159
-
160
- React
161
-
162
- $ toren --entry-points
163
- Entry Points
164
- ────────────
165
-
166
- src/main.tsx
167
-
168
- $ toren --configs
169
- Configuration Files
170
- ───────────────────
171
-
172
- package.json
173
- vite.config.ts
174
-
175
164
  $ toren --scripts
176
165
  Package Scripts
177
166
  ───────────────
@@ -185,19 +174,54 @@ Generate machine-readable output for scripts, toolchains, or AI context windows
185
174
 
186
175
  ```json
187
176
  {
177
+ "meta": {
178
+ "version": "1.0.7",
179
+ "scanDurationMs": 4,
180
+ "timestamp": "2026-08-29T23:51:00.000Z"
181
+ },
188
182
  "project": {
183
+ "name": "my-react-app",
189
184
  "path": "./my-react-app",
190
185
  "type": "React",
191
- "framework": "React"
192
- },
193
- "summary": {
194
- "totalFiles": 32,
195
- "totalFolders": 6,
196
- "scanDurationMs": 4
186
+ "framework": "React",
187
+ "packageManager": "npm"
197
188
  },
189
+ "frameworks": [
190
+ "React"
191
+ ],
198
192
  "entryPoints": [
199
193
  "src/main.tsx"
200
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
+ },
201
225
  "structure": [
202
226
  {
203
227
  "type": "folder",
@@ -208,7 +232,12 @@ Generate machine-readable output for scripts, toolchains, or AI context windows
208
232
  ]
209
233
  },
210
234
  { "type": "file", "name": "package.json" }
211
- ]
235
+ ],
236
+ "summary": {
237
+ "totalFiles": 32,
238
+ "totalFolders": 6,
239
+ "scanDurationMs": 4
240
+ }
212
241
  }
213
242
  ```
214
243
 
@@ -218,6 +247,12 @@ Generate machine-readable output for scripts, toolchains, or AI context windows
218
247
 
219
248
  ## Release Notes
220
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
+
221
256
  ### v1.0.6 - CLI Experience Update
222
257
  - **Redesigned CLI Output**: Completely revamped the console layout to use minimal typography, bold section titles, and dynamic divider lines matching the title width.
223
258
  - **Improved Error Handling**: Transformed raw exceptions into user-friendly error messages outlining the issue and potential fixes, ensuring consistent exit codes.
@@ -273,6 +308,60 @@ Contributions to improve this codebase analyzer CLI are always welcome!
273
308
 
274
309
  ---
275
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
+
276
365
  ## License
277
366
 
278
367
  Distributed under the MIT License. See `LICENSE` for more information.
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview Toren CLI — Entry Point
4
+ *
5
+ * Usage:
6
+ * toren [path] Scan <path> (defaults to current directory)
7
+ * toren --format <type> Select output format (default: console)
8
+ * toren --json Legacy alias for --format json
9
+ * toren --version Print version
10
+ * toren --help Print usage
11
+ * toren --doctor Check global installation health
12
+ * toren --uninstall Safely remove global installation
13
+ * toren --include-hidden Include hidden files (dot-files) in scan
14
+ * toren --max-files <N> Override the max file scan limit
15
+ *
16
+ * Adding a new output format
17
+ * ──────────────────────────
18
+ * 1. Create src/renderers/<format>-renderer.js
19
+ * and export: render(result, options?) => void
20
+ * 2. Register it in src/renderers/index.js
21
+ *
22
+ * No changes to this file are required.
23
+ */
24
+ export {};
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview Toren CLI — Entry Point
4
+ *
5
+ * Usage:
6
+ * toren [path] Scan <path> (defaults to current directory)
7
+ * toren --format <type> Select output format (default: console)
8
+ * toren --json Legacy alias for --format json
9
+ * toren --version Print version
10
+ * toren --help Print usage
11
+ * toren --doctor Check global installation health
12
+ * toren --uninstall Safely remove global installation
13
+ * toren --include-hidden Include hidden files (dot-files) in scan
14
+ * toren --max-files <N> Override the max file scan limit
15
+ *
16
+ * Adding a new output format
17
+ * ──────────────────────────
18
+ * 1. Create src/renderers/<format>-renderer.js
19
+ * and export: render(result, options?) => void
20
+ * 2. Register it in src/renderers/index.js
21
+ *
22
+ * No changes to this file are required.
23
+ */
24
+ import { createRequire } from 'node:module';
25
+ import { scan } from '../scanner/scan.js';
26
+ import renderers from '../renderers/index.js';
27
+ import { getFocusedModeInfo, renderFocusedMode, FOCUSED_FLAGS } from '../focused-output.js';
28
+ import { runDoctor, runUninstall } from '../lifecycle.js';
29
+ const require = createRequire(import.meta.url);
30
+ const pkg = require('../../package.json');
31
+ /** Format used when no --format flag is supplied. */
32
+ const DEFAULT_FORMAT = 'console';
33
+ /** Derived from the registry — always in sync with available renderers. */
34
+ const SUPPORTED_FORMATS = Object.keys(renderers);
35
+ // ---------------------------------------------------------------------------
36
+ // Helpers
37
+ // ---------------------------------------------------------------------------
38
+ function printError(title, message, detailLabel, detailValue) {
39
+ console.error(`\x1b[31m✖ ${title}\x1b[0m\n`);
40
+ console.error(`${message}\n`);
41
+ if (detailLabel && detailValue) {
42
+ console.error(`${detailLabel}:\n`);
43
+ console.error(`${detailValue}\n`);
44
+ }
45
+ }
46
+ function printHelp() {
47
+ const formatList = SUPPORTED_FORMATS.map(f => {
48
+ const suffix = f === DEFAULT_FORMAT ? ' (default)' : '';
49
+ return ` --format ${f.padEnd(10)}${suffix}`;
50
+ }).join('\n');
51
+ console.log(`
52
+ \x1b[1mToren\x1b[0m v${pkg.version}
53
+ Fast Repository Discovery CLI
54
+
55
+ \x1b[1mUSAGE\x1b[0m
56
+ toren [path] [options]
57
+
58
+ \x1b[1mCOMMANDS\x1b[0m
59
+ --project-type Show detected project type only
60
+ --frameworks Show detected frameworks only
61
+ --entry-points Show detected entry points only
62
+ --structure Show repository structure only
63
+ --configs Show detected project configuration files
64
+ --scripts Show available package scripts only
65
+ --summary Show project summary only
66
+ --important-files Show important files only
67
+ --health Show project health observations only
68
+ --include-hidden Include hidden files and folders
69
+ --max-files <n> Set scan file limit
70
+ --doctor Run CLI diagnostics
71
+ --uninstall Remove Toren global installation
72
+ --help Show this help message
73
+ --version Show version number
74
+
75
+ \x1b[1mOUTPUT FORMATS\x1b[0m
76
+ ${formatList}
77
+
78
+ \x1b[1mEXAMPLES\x1b[0m
79
+ toren . Scan the current directory
80
+ toren ./my-project Scan a specific project folder
81
+ toren --format json . Output results as JSON
82
+ toren --format markdown . > out.md Save a Markdown report to a file
83
+ toren --format html . > out.html Save an HTML report to a file
84
+ toren . --configs Show project configuration files
85
+ toren . --frameworks Show detected frameworks
86
+ `);
87
+ }
88
+ // ---------------------------------------------------------------------------
89
+ // Argument parsing
90
+ // ---------------------------------------------------------------------------
91
+ /**
92
+ * @typedef {Object} ParsedArgs
93
+ * @property {'exit'|'wait'|'scan'} action
94
+ * @property {string} [target] - Resolved path to scan
95
+ * @property {string} [format] - Renderer format name
96
+ * @property {boolean} [includeHidden] - Whether to include hidden files
97
+ * @property {number} [maxFiles] - Max files to scan
98
+ */
99
+ /**
100
+ * Parse process.argv into a structured options object.
101
+ *
102
+ * Returns { action: 'exit' } when the process should exit immediately.
103
+ * Returns { action: 'wait' } when an async interactive command is running.
104
+ * Returns { action: 'scan', target, format } for normal scan operations.
105
+ *
106
+ * @returns {ParsedArgs}
107
+ */
108
+ function parseArgs() {
109
+ const args = process.argv.slice(2);
110
+ // ── Informational flags ─────────────────────────────────────────────────
111
+ if (args.includes('--help') || args.includes('-h')) {
112
+ printHelp();
113
+ return { action: 'exit', code: 0 };
114
+ }
115
+ if (args.includes('--version') || args.includes('-V') || args.includes('-v')) {
116
+ console.log(`Toren ${pkg.version}`);
117
+ return { action: 'exit', code: 0 };
118
+ }
119
+ // ── Lifecycle commands ──────────────────────────────────────────────────
120
+ if (args.includes('--doctor')) {
121
+ runDoctor(pkg.version);
122
+ return { action: 'exit', code: 0 };
123
+ }
124
+ if (args.includes('--uninstall')) {
125
+ runUninstall();
126
+ return { action: 'wait' };
127
+ }
128
+ // ── Output format ───────────────────────────────────────────────────────
129
+ // --json is a legacy alias for --format json, kept for backwards
130
+ // compatibility. It will be removed in a future major version.
131
+ let format = DEFAULT_FORMAT;
132
+ const formatIdx = args.indexOf('--format');
133
+ if (formatIdx !== -1) {
134
+ const nextToken = args[formatIdx + 1];
135
+ // If the next token is missing or starts with '-', the user omitted the value.
136
+ if (nextToken === undefined || nextToken.startsWith('-')) {
137
+ printError('Missing value', 'The --format flag requires a valid output format.', 'Supported formats', SUPPORTED_FORMATS.join(', '));
138
+ return { action: 'exit', code: 1 };
139
+ }
140
+ format = nextToken;
141
+ }
142
+ else if (args.includes('--json')) {
143
+ format = 'json';
144
+ }
145
+ // ── Focused Output Flags ────────────────────────────────────────────────
146
+ const focusedInfo = getFocusedModeInfo(args);
147
+ if (focusedInfo.error) {
148
+ printError(focusedInfo.title, focusedInfo.message, focusedInfo.detailLabel, focusedInfo.detailValue);
149
+ return { action: 'exit', code: 1 };
150
+ }
151
+ const focusedMode = focusedInfo.mode;
152
+ // ── Hidden files ────────────────────────────────────────────────────────
153
+ const includeHidden = args.includes('--include-hidden');
154
+ // ── Target path ─────────────────────────────────────────────────────────
155
+ // Build the set of tokens that are consumed as values by named flags so
156
+ // we don't accidentally treat them as the positional path argument.
157
+ const consumedValues = new Set();
158
+ if (formatIdx !== -1 && args[formatIdx + 1] !== undefined && !args[formatIdx + 1].startsWith('-')) {
159
+ consumedValues.add(args[formatIdx + 1]);
160
+ }
161
+ // ── Max files ───────────────────────────────────────────────────────────
162
+ let maxFiles = undefined;
163
+ const maxFilesIdx = args.indexOf('--max-files');
164
+ if (maxFilesIdx !== -1) {
165
+ const rawVal = args[maxFilesIdx + 1];
166
+ if (rawVal === undefined || rawVal.startsWith('-')) {
167
+ printError('Missing value', 'The --max-files flag requires a numeric value.', 'Example', 'toren --max-files 100000');
168
+ return { action: 'exit', code: 1 };
169
+ }
170
+ maxFiles = parseInt(rawVal, 10);
171
+ if (isNaN(maxFiles) || maxFiles < 1) {
172
+ printError('Invalid value', 'The --max-files flag must be a positive integer.', 'Provided value', rawVal);
173
+ return { action: 'exit', code: 1 };
174
+ }
175
+ consumedValues.add(rawVal);
176
+ }
177
+ // First non-flag, non-consumed token is the target path; default to cwd.
178
+ const target = args.find(a => !a.startsWith('-') && !consumedValues.has(a)) ?? '.';
179
+ // ── Unknown flag check ──────────────────────────────────────────────────
180
+ const knownFlags = new Set([
181
+ '--help', '-h',
182
+ '--version', '-V', '-v',
183
+ '--doctor',
184
+ '--uninstall',
185
+ '--format',
186
+ '--json',
187
+ ...FOCUSED_FLAGS,
188
+ '--include-hidden',
189
+ '--max-files',
190
+ ]);
191
+ const unknownFlag = args.find(a => a.startsWith('-') && !knownFlags.has(a) && !consumedValues.has(a));
192
+ if (unknownFlag) {
193
+ printError('Unknown option', 'An unrecognized flag was provided.', 'Flag', unknownFlag);
194
+ return { action: 'exit', code: 1 };
195
+ }
196
+ return { action: 'scan', target, format, includeHidden, maxFiles, focusedMode };
197
+ }
198
+ // ---------------------------------------------------------------------------
199
+ // Format validation
200
+ // ---------------------------------------------------------------------------
201
+ /**
202
+ * Assert that `format` has a registered renderer.
203
+ * Prints a descriptive error message and exits with code 1 if not found.
204
+ *
205
+ * @param {string} format
206
+ */
207
+ function assertValidFormat(format) {
208
+ if (renderers[format])
209
+ return;
210
+ printError('Unsupported output format', 'The requested output format is not supported.', 'Format', format);
211
+ process.exit(1);
212
+ }
213
+ // ---------------------------------------------------------------------------
214
+ // Main
215
+ // ---------------------------------------------------------------------------
216
+ (function main() {
217
+ const parsed = parseArgs();
218
+ if (parsed.action === 'exit') {
219
+ process.exit(parsed.code ?? 0);
220
+ }
221
+ if (parsed.action === 'wait')
222
+ return;
223
+ // Validate before scanning — fail fast on bad format names.
224
+ assertValidFormat(parsed.format);
225
+ const render = renderers[parsed.format];
226
+ try {
227
+ const result = scan(parsed.target, {
228
+ includeHidden: parsed.includeHidden,
229
+ maxFiles: parsed.maxFiles,
230
+ });
231
+ if (parsed.focusedMode) {
232
+ renderFocusedMode(parsed.focusedMode, result);
233
+ }
234
+ else {
235
+ render(result, { cwd: process.cwd() });
236
+ }
237
+ }
238
+ catch (err) {
239
+ // Render errors in the requested format where possible.
240
+ if (parsed.format === 'json') {
241
+ console.error(JSON.stringify({ error: err.message }, null, 2));
242
+ }
243
+ else {
244
+ if (err.title) {
245
+ printError(err.title, err.message, err.detailLabel, err.detailValue);
246
+ }
247
+ else {
248
+ printError('Scan failed', err.message);
249
+ }
250
+ }
251
+ process.exit(1);
252
+ }
253
+ })();
254
+ //# sourceMappingURL=toren.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toren.js","sourceRoot":"","sources":["../../src/cli/toren.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function detectConfigs(flatFiles: string[]): {
2
+ configs: string[];
3
+ };
@@ -0,0 +1,58 @@
1
+ export function detectConfigs(flatFiles) {
2
+ const configPatterns = [
3
+ // Package
4
+ /^package\.json$/,
5
+ /^package-lock\.json$/,
6
+ /^pnpm-lock\.yaml$/,
7
+ /^yarn\.lock$/,
8
+ /^bun\.lockb$/,
9
+ // TypeScript
10
+ /^tsconfig\.json$/,
11
+ /^jsconfig\.json$/,
12
+ // Frontend
13
+ /^vite\.config\.[a-zA-Z0-9]+$/,
14
+ /^next\.config\.[a-zA-Z0-9]+$/,
15
+ /^nuxt\.config\.[a-zA-Z0-9]+$/,
16
+ /^astro\.config\.[a-zA-Z0-9]+$/,
17
+ /^angular\.json$/,
18
+ // Build
19
+ /^webpack\.config\.[a-zA-Z0-9]+$/,
20
+ /^rollup\.config\.[a-zA-Z0-9]+$/,
21
+ /^turbo\.json$/,
22
+ /^nx\.json$/,
23
+ // Styling
24
+ /^tailwind\.config\.[a-zA-Z0-9]+$/,
25
+ /^postcss\.config\.[a-zA-Z0-9]+$/,
26
+ // Lint
27
+ /^eslint\.config\.[a-zA-Z0-9]+$/,
28
+ /^\.eslintrc.*$/,
29
+ /^prettier\.config\.[a-zA-Z0-9]+$/,
30
+ /^\.prettierrc.*$/,
31
+ // Backend
32
+ /^pom\.xml$/,
33
+ /^build\.gradle$/,
34
+ /^build\.gradle\.kts$/,
35
+ // Languages
36
+ /^requirements\.txt$/,
37
+ /^pyproject\.toml$/,
38
+ /^Cargo\.toml$/,
39
+ /^go\.mod$/,
40
+ // Deployment
41
+ /^Dockerfile$/,
42
+ /^docker-compose\.ya?ml$/
43
+ ];
44
+ const matchedSet = new Set();
45
+ for (const file of flatFiles) {
46
+ if (file.includes('/'))
47
+ continue;
48
+ for (const pattern of configPatterns) {
49
+ if (pattern.test(file)) {
50
+ matchedSet.add(file);
51
+ break;
52
+ }
53
+ }
54
+ }
55
+ const configs = Array.from(matchedSet).sort();
56
+ return { configs };
57
+ }
58
+ //# sourceMappingURL=config-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-detector.js","sourceRoot":"","sources":["../../src/detectors/config-detector.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,SAAmB;IAC/C,MAAM,cAAc,GAAa;QAC/B,UAAU;QACV,iBAAiB;QACjB,sBAAsB;QACtB,mBAAmB;QACnB,cAAc;QACd,cAAc;QAEd,aAAa;QACb,kBAAkB;QAClB,kBAAkB;QAElB,WAAW;QACX,8BAA8B;QAC9B,8BAA8B;QAC9B,8BAA8B;QAC9B,+BAA+B;QAC/B,iBAAiB;QAEjB,QAAQ;QACR,iCAAiC;QACjC,gCAAgC;QAChC,eAAe;QACf,YAAY;QAEZ,UAAU;QACV,kCAAkC;QAClC,iCAAiC;QAEjC,OAAO;QACP,gCAAgC;QAChC,gBAAgB;QAChB,kCAAkC;QAClC,kBAAkB;QAElB,UAAU;QACV,YAAY;QACZ,iBAAiB;QACjB,sBAAsB;QAEtB,YAAY;QACZ,qBAAqB;QACrB,mBAAmB;QACnB,eAAe;QACf,WAAW;QAEX,aAAa;QACb,cAAc;QACd,yBAAyB;KAC1B,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QAEjC,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;YACrC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACrB,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { HealthObservation, ScriptInfo, ImportantFile } from '../types/index.js';
2
+ interface DetectHealthOptions {
3
+ flatFiles: string[];
4
+ configs: string[];
5
+ importantFiles: ImportantFile[];
6
+ scripts: ScriptInfo[];
7
+ projectType: string;
8
+ }
9
+ export declare function detectHealth({ flatFiles, configs, importantFiles, scripts, projectType }: DetectHealthOptions): {
10
+ health: HealthObservation[];
11
+ };
12
+ export {};