@eloquence98/ctx 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -30
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +13 -5
- package/dist/formatter.d.ts +13 -0
- package/dist/formatter.js +20 -3
- package/dist/parser.d.ts +11 -0
- package/dist/parser.js +180 -4
- package/dist/scanner.d.ts +11 -0
- package/dist/scanner.js +13 -1
- package/dist/types.d.ts +11 -0
- package/dist/types.js +0 -0
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -4,9 +4,9 @@ Dump a truthful structural index of a codebase.
|
|
|
4
4
|
|
|
5
5
|
No analysis. No opinions. No guessing.
|
|
6
6
|
|
|
7
|
-
ctx scans a directory and prints a map of folders, files, and
|
|
7
|
+
ctx scans a directory and prints a map of folders, files, and trivially detectable exported symbols. It tells you exactly what exists — nothing more, nothing less.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Quick Start
|
|
10
10
|
|
|
11
11
|
No installation required. Run it directly with npx:
|
|
12
12
|
|
|
@@ -14,13 +14,15 @@ No installation required. Run it directly with npx:
|
|
|
14
14
|
npx @eloquence98/ctx ./path-to-project
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## What It Does
|
|
18
18
|
|
|
19
19
|
ctx provides a high-level map of a project. It identifies:
|
|
20
20
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
21
|
+
- Folders
|
|
22
|
+
- Files
|
|
23
|
+
- Exported symbols (both ES modules and CommonJS, when trivially detectable)
|
|
24
|
+
|
|
25
|
+
Exports that cannot be statically determined from source text are silently ignored.
|
|
24
26
|
|
|
25
27
|
## Example Output
|
|
26
28
|
|
|
@@ -34,11 +36,21 @@ src/
|
|
|
34
36
|
└─ styles.css
|
|
35
37
|
```
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
Files whose exports cannot be determined are listed without symbols.
|
|
40
|
+
|
|
41
|
+
## Supported Export Patterns
|
|
42
|
+
|
|
43
|
+
#### ES Modules:
|
|
44
|
+
|
|
45
|
+
`export function`, `export const/let/var`, `export class`, `export type`, `export interface`, `export default function/class`
|
|
38
46
|
|
|
39
|
-
|
|
47
|
+
#### CommonJS:
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
`exports.name = ...`, `module.exports.name = ...`, `module.exports = { name1, name2 }`, `module.exports = function/class`
|
|
50
|
+
|
|
51
|
+
## Why This Exists
|
|
52
|
+
|
|
53
|
+
When working with LLMs, new contributors, or legacy codebases, you don't always need the content of the files immediately, you need to understand the topology of the project first.
|
|
42
54
|
|
|
43
55
|
ctx gives you that map.
|
|
44
56
|
|
|
@@ -46,43 +58,45 @@ ctx gives you that map.
|
|
|
46
58
|
2. Paste it into an LLM context window.
|
|
47
59
|
3. Ask informed questions about the architecture before dumping raw code.
|
|
48
60
|
|
|
49
|
-
##
|
|
50
|
-
|
|
51
|
-
ctx is intentionally dumb. That is why it is reliable.
|
|
61
|
+
## What It Does Not Do
|
|
52
62
|
|
|
53
|
-
|
|
63
|
+
ctx is intentionally shallow. That is why it is reliable.
|
|
54
64
|
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
65
|
+
- Does not interpret architecture or infer domains
|
|
66
|
+
- Does not explain code intent
|
|
67
|
+
- Does not refactor or execute code
|
|
68
|
+
- Does not read `node_modules`, `.git`, or environment files
|
|
69
|
+
- Does not parse re-exports, barrel files, or computed names
|
|
60
70
|
|
|
61
|
-
|
|
71
|
+
See [LIMITATIONS.md](https://github.com/Eloquence98/ctx/blob/main/limitation.md) for detailed edge cases.
|
|
62
72
|
|
|
63
|
-
##
|
|
73
|
+
## Configuration
|
|
64
74
|
|
|
65
75
|
No configuration required.
|
|
66
76
|
|
|
67
77
|
ctx automatically ignores:
|
|
68
78
|
|
|
69
|
-
- node_modules
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
79
|
+
- `node_modules`, `.git`
|
|
80
|
+
- Build outputs (`dist`, `build`, `.next`)
|
|
81
|
+
- Environment files (`.env`)
|
|
82
|
+
- Test files (`.test`., `.spec`.)
|
|
83
|
+
- Hidden files and directories
|
|
74
84
|
|
|
75
|
-
|
|
85
|
+
Only `.ts`, `.tsx`, `.js`, `.jsx` files are scanned. Both ES module and CommonJS exports are detected.
|
|
76
86
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
## ⚡️ Install (optional)
|
|
87
|
+
## Install (optional)
|
|
80
88
|
|
|
81
89
|
```bash
|
|
82
90
|
npm install -g @eloquence98/ctx
|
|
83
91
|
ctx ./src
|
|
84
92
|
```
|
|
85
93
|
|
|
94
|
+
## Philosophy
|
|
95
|
+
|
|
96
|
+
Don't explain the code. Show the codebase as it exists.
|
|
97
|
+
|
|
98
|
+
ctx prefers truthful omission over incorrect inference. If something cannot be determined reliably, it is excluded.
|
|
99
|
+
|
|
86
100
|
## License
|
|
87
101
|
|
|
88
|
-
[MIT](https://choosealicense.com/licenses/mit/)
|
|
102
|
+
[MIT ](https://choosealicense.com/licenses/mit/)
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI entry point for ctx.
|
|
4
|
+
* Scans a directory, parses exports, and prints a formatted tree.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* npx ctx ./src
|
|
8
|
+
*/
|
|
2
9
|
import path from "path";
|
|
3
|
-
import { scan } from "./scanner.js";
|
|
4
|
-
import { parse } from "./parser.js";
|
|
5
10
|
import { format } from "./formatter.js";
|
|
11
|
+
import { parse } from "./parser.js";
|
|
12
|
+
import { scan } from "./scanner.js";
|
|
6
13
|
const args = process.argv.slice(2);
|
|
7
14
|
const targetPath = args[0] || ".";
|
|
15
|
+
/**
|
|
16
|
+
* Main CLI execution flow.
|
|
17
|
+
* Orchestrates scanning → parsing → formatting.
|
|
18
|
+
*/
|
|
8
19
|
async function main() {
|
|
9
20
|
const dir = path.resolve(process.cwd(), targetPath);
|
|
10
|
-
// Scan
|
|
11
21
|
const files = await scan(dir);
|
|
12
22
|
if (files.length === 0) {
|
|
13
23
|
console.log("No files found.");
|
|
14
24
|
process.exit(1);
|
|
15
25
|
}
|
|
16
|
-
// Parse
|
|
17
26
|
const parsed = await Promise.all(files.map(parse));
|
|
18
|
-
// Format and print
|
|
19
27
|
console.log(format(parsed, dir));
|
|
20
28
|
}
|
|
21
29
|
main().catch(console.error);
|
package/dist/formatter.d.ts
CHANGED
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
import type { ParsedFile } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Formats parsed files into a tree-style string representation.
|
|
4
|
+
*
|
|
5
|
+
* @param files - Array of parsed files
|
|
6
|
+
* @param baseDir - Root directory path for relative path calculation
|
|
7
|
+
* @returns Formatted tree string
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const output = format(parsedFiles, "/project/src");
|
|
11
|
+
* // src/
|
|
12
|
+
* // ├─ index.ts → main
|
|
13
|
+
* // └─ utils.ts → format, parse
|
|
14
|
+
*/
|
|
2
15
|
export declare function format(files: ParsedFile[], baseDir: string): string;
|
package/dist/formatter.js
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
+
/**
|
|
3
|
+
* Formats parsed files into a tree-style string representation.
|
|
4
|
+
*
|
|
5
|
+
* @param files - Array of parsed files
|
|
6
|
+
* @param baseDir - Root directory path for relative path calculation
|
|
7
|
+
* @returns Formatted tree string
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const output = format(parsedFiles, "/project/src");
|
|
11
|
+
* // src/
|
|
12
|
+
* // ├─ index.ts → main
|
|
13
|
+
* // └─ utils.ts → format, parse
|
|
14
|
+
*/
|
|
2
15
|
export function format(files, baseDir) {
|
|
3
|
-
// Build tree structure
|
|
4
16
|
const root = { name: path.basename(baseDir), children: new Map() };
|
|
5
17
|
for (const file of files) {
|
|
6
18
|
const rel = path.relative(baseDir, file.path);
|
|
@@ -22,12 +34,18 @@ export function format(files, baseDir) {
|
|
|
22
34
|
current = current.children.get(part);
|
|
23
35
|
}
|
|
24
36
|
}
|
|
25
|
-
// Render tree
|
|
26
37
|
const lines = [];
|
|
27
38
|
lines.push(root.name + "/");
|
|
28
39
|
renderTree(root, "", lines);
|
|
29
40
|
return lines.join("\n");
|
|
30
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Recursively renders tree nodes into formatted lines.
|
|
44
|
+
*
|
|
45
|
+
* @param node - Current tree node
|
|
46
|
+
* @param prefix - Indentation prefix for current depth
|
|
47
|
+
* @param lines - Output array to append lines to
|
|
48
|
+
*/
|
|
31
49
|
function renderTree(node, prefix, lines) {
|
|
32
50
|
const children = [...node.children.values()];
|
|
33
51
|
for (let i = 0; i < children.length; i++) {
|
|
@@ -35,7 +53,6 @@ function renderTree(node, prefix, lines) {
|
|
|
35
53
|
const isLast = i === children.length - 1;
|
|
36
54
|
const connector = isLast ? "└─ " : "├─ ";
|
|
37
55
|
const extension = isLast ? " " : "│ ";
|
|
38
|
-
// Is it a file (has exports defined) or folder?
|
|
39
56
|
const isFile = child.exports !== undefined;
|
|
40
57
|
if (isFile) {
|
|
41
58
|
const exportsStr = child.exports.length > 0 ? ` → ${child.exports.join(", ")}` : "";
|
package/dist/parser.d.ts
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
import type { ParsedFile } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parses a source file and extracts exported symbol names.
|
|
4
|
+
* Supports both ES modules and CommonJS exports.
|
|
5
|
+
*
|
|
6
|
+
* @param filePath - Absolute path to the file
|
|
7
|
+
* @returns Parsed file object with export names
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const result = await parse("./src/utils.ts");
|
|
11
|
+
* // { path: "./src/utils.ts", name: "utils.ts", exports: ["format", "parse"] }
|
|
12
|
+
*/
|
|
2
13
|
export declare function parse(filePath: string): Promise<ParsedFile>;
|
package/dist/parser.js
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
import fs from "fs/promises";
|
|
2
2
|
import path from "path";
|
|
3
|
+
/**
|
|
4
|
+
* Parses a source file and extracts exported symbol names.
|
|
5
|
+
* Supports both ES modules and CommonJS exports.
|
|
6
|
+
*
|
|
7
|
+
* @param filePath - Absolute path to the file
|
|
8
|
+
* @returns Parsed file object with export names
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const result = await parse("./src/utils.ts");
|
|
12
|
+
* // { path: "./src/utils.ts", name: "utils.ts", exports: ["format", "parse"] }
|
|
13
|
+
*/
|
|
3
14
|
export async function parse(filePath) {
|
|
4
|
-
|
|
15
|
+
let content = await fs.readFile(filePath, "utf-8");
|
|
5
16
|
const name = path.basename(filePath);
|
|
6
17
|
const exports = [];
|
|
18
|
+
// Remove comments to avoid false positives from commented-out code
|
|
19
|
+
content = stripComments(content);
|
|
20
|
+
// === ES Module Exports ===
|
|
7
21
|
// export function Name
|
|
8
22
|
for (const match of content.matchAll(/export\s+(?:async\s+)?function\s+(\w+)/g)) {
|
|
9
23
|
exports.push(match[1]);
|
|
10
24
|
}
|
|
11
|
-
// export const Name
|
|
12
|
-
for (const match of content.matchAll(/export\s+const\s+(\w+)/g)) {
|
|
25
|
+
// export const/let/var Name
|
|
26
|
+
for (const match of content.matchAll(/export\s+(?:const|let|var)\s+(\w+)/g)) {
|
|
13
27
|
exports.push(match[1]);
|
|
14
28
|
}
|
|
15
29
|
// export type/interface Name
|
|
@@ -24,5 +38,167 @@ export async function parse(filePath) {
|
|
|
24
38
|
for (const match of content.matchAll(/export\s+default\s+(?:function|class)\s+(\w+)/g)) {
|
|
25
39
|
exports.push(match[1]);
|
|
26
40
|
}
|
|
27
|
-
|
|
41
|
+
// === CommonJS Exports ===
|
|
42
|
+
// module.exports.name = ...
|
|
43
|
+
for (const match of content.matchAll(/module\.exports\.(\w+)\s*=/g)) {
|
|
44
|
+
exports.push(match[1]);
|
|
45
|
+
}
|
|
46
|
+
// exports.name = ... (but not module.exports.name)
|
|
47
|
+
for (const match of content.matchAll(/(?<!module\.)exports\.(\w+)\s*=/g)) {
|
|
48
|
+
exports.push(match[1]);
|
|
49
|
+
}
|
|
50
|
+
// module.exports = { name1, name2: value, ... }
|
|
51
|
+
for (const match of content.matchAll(/module\.exports\s*=\s*\{/g)) {
|
|
52
|
+
const startIdx = match.index + match[0].length;
|
|
53
|
+
const objectExports = parseExportsObject(content, startIdx);
|
|
54
|
+
exports.push(...objectExports);
|
|
55
|
+
}
|
|
56
|
+
// module.exports = function name() {} or async function name() {}
|
|
57
|
+
for (const match of content.matchAll(/module\.exports\s*=\s*(?:async\s+)?function\s+(\w+)/g)) {
|
|
58
|
+
exports.push(match[1]);
|
|
59
|
+
}
|
|
60
|
+
// module.exports = class Name {}
|
|
61
|
+
for (const match of content.matchAll(/module\.exports\s*=\s*class\s+(\w+)/g)) {
|
|
62
|
+
exports.push(match[1]);
|
|
63
|
+
}
|
|
64
|
+
// module.exports = Identifier (e.g., module.exports = MyClass;)
|
|
65
|
+
for (const match of content.matchAll(/module\.exports\s*=\s*([A-Z]\w*)\s*;?\s*$/gm)) {
|
|
66
|
+
exports.push(match[1]);
|
|
67
|
+
}
|
|
68
|
+
return { path: filePath, name, exports: [...new Set(exports)] };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Removes single-line (//) and multi-line (/* *\/) comments from source code.
|
|
72
|
+
* Preserves string literals to avoid breaking code structure.
|
|
73
|
+
*
|
|
74
|
+
* @param code - Raw source code
|
|
75
|
+
* @returns Code with comments removed
|
|
76
|
+
*/
|
|
77
|
+
function stripComments(code) {
|
|
78
|
+
let result = "";
|
|
79
|
+
let i = 0;
|
|
80
|
+
while (i < code.length) {
|
|
81
|
+
// Handle string literals - don't strip inside strings
|
|
82
|
+
if (code[i] === '"' || code[i] === "'" || code[i] === "`") {
|
|
83
|
+
const quote = code[i];
|
|
84
|
+
result += code[i++];
|
|
85
|
+
while (i < code.length && code[i] !== quote) {
|
|
86
|
+
if (code[i] === "\\") {
|
|
87
|
+
result += code[i++];
|
|
88
|
+
}
|
|
89
|
+
if (i < code.length) {
|
|
90
|
+
result += code[i++];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (i < code.length) {
|
|
94
|
+
result += code[i++];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Single-line comment
|
|
98
|
+
else if (code[i] === "/" && code[i + 1] === "/") {
|
|
99
|
+
while (i < code.length && code[i] !== "\n") {
|
|
100
|
+
i++;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Multi-line comment
|
|
104
|
+
else if (code[i] === "/" && code[i + 1] === "*") {
|
|
105
|
+
i += 2;
|
|
106
|
+
while (i < code.length && !(code[i] === "*" && code[i + 1] === "/")) {
|
|
107
|
+
i++;
|
|
108
|
+
}
|
|
109
|
+
i += 2;
|
|
110
|
+
}
|
|
111
|
+
// Regular character
|
|
112
|
+
else {
|
|
113
|
+
result += code[i++];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Parses a CommonJS exports object literal and extracts property names.
|
|
120
|
+
* Handles nested objects/arrays by tracking bracket depth.
|
|
121
|
+
*
|
|
122
|
+
* @param content - Source code content
|
|
123
|
+
* @param startIdx - Index where the object literal begins (after opening brace)
|
|
124
|
+
* @returns Array of exported property names
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* // For: module.exports = { foo, bar: value }
|
|
128
|
+
* parseExportsObject(content, indexAfterBrace);
|
|
129
|
+
* // Returns: ["foo", "bar"]
|
|
130
|
+
*/
|
|
131
|
+
function parseExportsObject(content, startIdx) {
|
|
132
|
+
const exports = [];
|
|
133
|
+
let depth = 0;
|
|
134
|
+
let i = startIdx;
|
|
135
|
+
let token = "";
|
|
136
|
+
let afterColon = false;
|
|
137
|
+
const keywords = new Set([
|
|
138
|
+
"function",
|
|
139
|
+
"async",
|
|
140
|
+
"class",
|
|
141
|
+
"return",
|
|
142
|
+
"const",
|
|
143
|
+
"let",
|
|
144
|
+
"var",
|
|
145
|
+
"true",
|
|
146
|
+
"false",
|
|
147
|
+
"null",
|
|
148
|
+
"undefined",
|
|
149
|
+
"new",
|
|
150
|
+
"require",
|
|
151
|
+
"await",
|
|
152
|
+
]);
|
|
153
|
+
while (i < content.length) {
|
|
154
|
+
const char = content[i];
|
|
155
|
+
if (char === "{" || char === "[" || char === "(") {
|
|
156
|
+
depth++;
|
|
157
|
+
token = "";
|
|
158
|
+
}
|
|
159
|
+
else if (char === "}") {
|
|
160
|
+
if (depth === 0) {
|
|
161
|
+
if (token && !afterColon && !keywords.has(token)) {
|
|
162
|
+
exports.push(token);
|
|
163
|
+
}
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
depth--;
|
|
167
|
+
token = "";
|
|
168
|
+
}
|
|
169
|
+
else if (char === "]" || char === ")") {
|
|
170
|
+
depth--;
|
|
171
|
+
token = "";
|
|
172
|
+
}
|
|
173
|
+
else if (depth === 0) {
|
|
174
|
+
if (/[a-zA-Z_$]/.test(char)) {
|
|
175
|
+
token += char;
|
|
176
|
+
}
|
|
177
|
+
else if (/[0-9]/.test(char) && token) {
|
|
178
|
+
token += char;
|
|
179
|
+
}
|
|
180
|
+
else if (char === ":") {
|
|
181
|
+
if (token && !keywords.has(token)) {
|
|
182
|
+
exports.push(token);
|
|
183
|
+
}
|
|
184
|
+
token = "";
|
|
185
|
+
afterColon = true;
|
|
186
|
+
}
|
|
187
|
+
else if (char === ",") {
|
|
188
|
+
if (token && !afterColon && !keywords.has(token)) {
|
|
189
|
+
exports.push(token);
|
|
190
|
+
}
|
|
191
|
+
token = "";
|
|
192
|
+
afterColon = false;
|
|
193
|
+
}
|
|
194
|
+
else if (/\s/.test(char)) {
|
|
195
|
+
// continue
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
token = "";
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
i++;
|
|
202
|
+
}
|
|
203
|
+
return exports;
|
|
28
204
|
}
|
package/dist/scanner.d.ts
CHANGED
|
@@ -1 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursively scans a directory for JavaScript/TypeScript files.
|
|
3
|
+
* Ignores node_modules, build outputs, hidden files, and test files.
|
|
4
|
+
*
|
|
5
|
+
* @param dir - The directory path to scan
|
|
6
|
+
* @returns Array of absolute file paths
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const files = await scan("./src");
|
|
10
|
+
* // ["/project/src/index.ts", "/project/src/utils.ts", ...]
|
|
11
|
+
*/
|
|
1
12
|
export declare function scan(dir: string): Promise<string[]>;
|
package/dist/scanner.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from "fs/promises";
|
|
2
2
|
import path from "path";
|
|
3
|
+
/** Directories and files to ignore during scanning */
|
|
3
4
|
const IGNORE = [
|
|
4
5
|
"node_modules",
|
|
5
6
|
".git",
|
|
@@ -14,7 +15,19 @@ const IGNORE = [
|
|
|
14
15
|
".idea",
|
|
15
16
|
"coverage",
|
|
16
17
|
];
|
|
18
|
+
/** File extensions to include in scan results */
|
|
17
19
|
const EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"];
|
|
20
|
+
/**
|
|
21
|
+
* Recursively scans a directory for JavaScript/TypeScript files.
|
|
22
|
+
* Ignores node_modules, build outputs, hidden files, and test files.
|
|
23
|
+
*
|
|
24
|
+
* @param dir - The directory path to scan
|
|
25
|
+
* @returns Array of absolute file paths
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* const files = await scan("./src");
|
|
29
|
+
* // ["/project/src/index.ts", "/project/src/utils.ts", ...]
|
|
30
|
+
*/
|
|
18
31
|
export async function scan(dir) {
|
|
19
32
|
const files = [];
|
|
20
33
|
async function walk(current) {
|
|
@@ -26,7 +39,6 @@ export async function scan(dir) {
|
|
|
26
39
|
return;
|
|
27
40
|
}
|
|
28
41
|
for (const entry of entries) {
|
|
29
|
-
// Skip ignored
|
|
30
42
|
if (IGNORE.includes(entry.name))
|
|
31
43
|
continue;
|
|
32
44
|
if (entry.name.startsWith("."))
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a parsed source file with its exported symbols.
|
|
3
|
+
*/
|
|
1
4
|
export interface ParsedFile {
|
|
5
|
+
/** Absolute path to the file */
|
|
2
6
|
path: string;
|
|
7
|
+
/** Base filename (e.g., "parser.ts") */
|
|
3
8
|
name: string;
|
|
9
|
+
/** List of exported symbol names */
|
|
4
10
|
exports: string[];
|
|
5
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Represents a folder and its parsed files.
|
|
14
|
+
*/
|
|
6
15
|
export interface FolderContent {
|
|
16
|
+
/** Folder path */
|
|
7
17
|
folder: string;
|
|
18
|
+
/** Parsed files within this folder */
|
|
8
19
|
files: ParsedFile[];
|
|
9
20
|
}
|
package/dist/types.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eloquence98/ctx",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Generate a truthful structural map of your codebase for AI and humans.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"ctx": "dist/cli.js"
|
|
@@ -15,17 +15,15 @@
|
|
|
15
15
|
"ai",
|
|
16
16
|
"context",
|
|
17
17
|
"codebase",
|
|
18
|
-
"documentation",
|
|
19
18
|
"cli",
|
|
20
19
|
"typescript",
|
|
21
|
-
"
|
|
22
|
-
"react"
|
|
20
|
+
"javascript"
|
|
23
21
|
],
|
|
24
22
|
"author": "Eloquence98",
|
|
25
23
|
"license": "MIT",
|
|
26
24
|
"repository": {
|
|
27
25
|
"type": "git",
|
|
28
|
-
"url": "https://github.com/Eloquence98/ctx.git"
|
|
26
|
+
"url": "git+https://github.com/Eloquence98/ctx.git"
|
|
29
27
|
},
|
|
30
28
|
"homepage": "https://github.com/Eloquence98/ctx",
|
|
31
29
|
"files": [
|
|
@@ -35,5 +33,8 @@
|
|
|
35
33
|
"@types/node": "^20.0.0",
|
|
36
34
|
"tsx": "^4.0.0",
|
|
37
35
|
"typescript": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@eloquence98/ctx": "file:eloquence98-ctx-0.4.0.tgz"
|
|
38
39
|
}
|
|
39
|
-
}
|
|
40
|
+
}
|