@yoinkingfish/codecarto 0.1.1
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/LICENSE +21 -0
- package/dist/browser/index.d.ts +6 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +32 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/commands/default.d.ts +9 -0
- package/dist/commands/default.d.ts.map +1 -0
- package/dist/commands/default.js +103 -0
- package/dist/commands/default.js.map +1 -0
- package/dist/commands/export.d.ts +9 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +62 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/scan.d.ts +8 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +81 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/serve.d.ts +8 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +47 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +105 -0
- package/dist/index.js.map +1 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +115 -0
- package/dist/server/index.js.map +1 -0
- package/dist/utils/banner.d.ts +2 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +17 -0
- package/dist/utils/banner.js.map +1 -0
- package/dist/utils/logger.d.ts +12 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +34 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.d.ts +6 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +27 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/pipeline.d.ts +28 -0
- package/dist/utils/pipeline.d.ts.map +1 -0
- package/dist/utils/pipeline.js +234 -0
- package/dist/utils/pipeline.js.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CodeCarto Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser launcher — uses `open` but waits until server is ready.
|
|
3
|
+
*/
|
|
4
|
+
export declare function openBrowser(url: string): Promise<void>;
|
|
5
|
+
export declare function waitForServer(url: string, timeoutMs?: number): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS5D;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAahF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser launcher — uses `open` but waits until server is ready.
|
|
3
|
+
*/
|
|
4
|
+
import { logger } from "../utils/logger.js";
|
|
5
|
+
export async function openBrowser(url) {
|
|
6
|
+
try {
|
|
7
|
+
const { default: open } = await import("open");
|
|
8
|
+
await open(url, { wait: false });
|
|
9
|
+
logger.verbose(`Opened browser: ${url}`);
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
logger.warn(`Could not open browser automatically. Please open ${url} manually.`);
|
|
13
|
+
logger.verbose(String(err));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export async function waitForServer(url, timeoutMs = 5000) {
|
|
17
|
+
const start = Date.now();
|
|
18
|
+
const healthUrl = new URL("/api/health", url).toString();
|
|
19
|
+
while (Date.now() - start < timeoutMs) {
|
|
20
|
+
try {
|
|
21
|
+
const res = await fetch(healthUrl);
|
|
22
|
+
if (res.ok)
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// retry
|
|
27
|
+
}
|
|
28
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
29
|
+
}
|
|
30
|
+
logger.verbose(`Health check timed out for ${healthUrl}`);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACjC,MAAM,CAAC,OAAO,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,qDAAqD,GAAG,YAAY,CAAC,CAAC;QAClF,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,SAAS,GAAG,IAAI;IAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;IACzD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;YACnC,IAAI,GAAG,CAAC,EAAE;gBAAE,OAAO;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ;QACV,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,CAAC,OAAO,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/commands/default.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA+GxE"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import { runPipeline } from "../utils/pipeline.js";
|
|
6
|
+
import { logger, setLogLevel } from "../utils/logger.js";
|
|
7
|
+
import { resolveRoot } from "../utils/paths.js";
|
|
8
|
+
import { printBanner } from "../utils/banner.js";
|
|
9
|
+
import { startServer } from "../server/index.js";
|
|
10
|
+
import { openBrowser, waitForServer } from "../browser/index.js";
|
|
11
|
+
export async function defaultCommand(opts) {
|
|
12
|
+
setLogLevel(opts.verbose ? "verbose" : "info");
|
|
13
|
+
printBanner();
|
|
14
|
+
const root = resolveRoot("."); // Use current working directory
|
|
15
|
+
const preferredPort = Number(opts.port);
|
|
16
|
+
if (!Number.isFinite(preferredPort) || preferredPort < 1 || preferredPort > 65535) {
|
|
17
|
+
console.error(chalk.red(`\n✗ Invalid port: ${opts.port}\n`));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const st = await fs.stat(root);
|
|
22
|
+
if (!st.isDirectory())
|
|
23
|
+
throw new Error(`Not a directory: ${root}`);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
console.error(chalk.red(`\n✗ Could not read repository\n\n Path:\n ${root}\n\n Reason:\n ${err.message}\n\n Try:\n codecarto --path <directory>\n`));
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const spinner = ora({ text: "Discovering repository...", color: "cyan" }).start();
|
|
30
|
+
logger.verbose("CodeCarto analyzes your project locally. Your source code is not uploaded.");
|
|
31
|
+
try {
|
|
32
|
+
spinner.text = "Scanning files...";
|
|
33
|
+
const { graph, diagnostics } = await runPipeline({
|
|
34
|
+
root,
|
|
35
|
+
ignore: opts.ignore,
|
|
36
|
+
verbose: opts.verbose,
|
|
37
|
+
});
|
|
38
|
+
spinner.text = `Analyzing ${graph.stats.totalFiles} files...`;
|
|
39
|
+
await new Promise((r) => setTimeout(r, 30));
|
|
40
|
+
spinner.text = "Building architecture graph...";
|
|
41
|
+
spinner.succeed(chalk.green("Repository scanned"));
|
|
42
|
+
console.log(chalk.dim(` Root: ${root}`));
|
|
43
|
+
console.log(chalk.dim(` Files: ${graph.stats.totalFiles} Links: ${graph.stats.totalLinks} Dirs: ${graph.stats.totalDirectories} Isolated: ${graph.stats.isolatedFiles}`));
|
|
44
|
+
if (Object.keys(graph.stats.languages).length) {
|
|
45
|
+
const langStr = Object.entries(graph.stats.languages)
|
|
46
|
+
.sort((a, b) => b[1] - a[1])
|
|
47
|
+
.map(([k, v]) => `${k} ${v}`)
|
|
48
|
+
.join(" · ");
|
|
49
|
+
logger.info(chalk.dim(` Languages: ${langStr}`));
|
|
50
|
+
}
|
|
51
|
+
if (graph.stats.totalFiles > 0) {
|
|
52
|
+
console.log("");
|
|
53
|
+
const langs = Object.entries(graph.stats.languages).sort((a, b) => b[1] - a[1]);
|
|
54
|
+
const maxCount = Math.max(...langs.map(([, c]) => c));
|
|
55
|
+
for (const [lang, count] of langs) {
|
|
56
|
+
const pct = Math.round((count / graph.stats.totalFiles) * 100);
|
|
57
|
+
const width = Math.max(2, Math.round((count / maxCount) * 16));
|
|
58
|
+
const bar = "█".repeat(width);
|
|
59
|
+
const label = lang.padEnd(12);
|
|
60
|
+
console.log(` ${label} ${chalk.cyan(bar)} ${pct}%`);
|
|
61
|
+
}
|
|
62
|
+
console.log("");
|
|
63
|
+
}
|
|
64
|
+
if (diagnostics.parseFailures.length) {
|
|
65
|
+
logger.warn(`${diagnostics.parseFailures.length} parse failures`);
|
|
66
|
+
if (opts.verbose)
|
|
67
|
+
for (const f of diagnostics.parseFailures.slice(0, 5))
|
|
68
|
+
logger.dim(` ! ${f.path}: ${f.reason}`);
|
|
69
|
+
}
|
|
70
|
+
if (opts.output) {
|
|
71
|
+
const outPath = path.resolve(opts.output);
|
|
72
|
+
await fs.mkdir(path.dirname(outPath), { recursive: true });
|
|
73
|
+
await fs.writeFile(outPath, JSON.stringify(graph, null, 2), "utf-8");
|
|
74
|
+
logger.success(`Graph written to ${outPath}`);
|
|
75
|
+
console.log(chalk.dim("\n Tip: codecarto serve --input <file> to visualize the exported graph.\n"));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
console.log(chalk.dim(" Starting visualization...\n"));
|
|
79
|
+
const { url, server } = await startServer({ graph, preferredPort });
|
|
80
|
+
console.log(chalk.green(`✓ Visualization running\n`));
|
|
81
|
+
console.log(` ${chalk.bold.cyan(url)}\n`);
|
|
82
|
+
console.log(chalk.dim(" Press Ctrl+C to stop.\n"));
|
|
83
|
+
await waitForServer(url);
|
|
84
|
+
if (opts.open)
|
|
85
|
+
await openBrowser(url);
|
|
86
|
+
await new Promise((resolve) => {
|
|
87
|
+
const close = () => server.close(() => resolve());
|
|
88
|
+
process.on("SIGINT", close);
|
|
89
|
+
process.on("SIGTERM", close);
|
|
90
|
+
});
|
|
91
|
+
logger.info("Server stopped.");
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
spinner.fail(chalk.red("Failed to analyze repository"));
|
|
95
|
+
console.error(chalk.red(err.message));
|
|
96
|
+
if (opts.verbose)
|
|
97
|
+
console.error(err);
|
|
98
|
+
else
|
|
99
|
+
console.error(chalk.dim(" Run with --verbose for details.\n"));
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=default.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/commands/default.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDtE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import { runPipeline } from "../utils/pipeline.js";
|
|
6
|
+
import { logger, setLogLevel } from "../utils/logger.js";
|
|
7
|
+
import { resolveRoot } from "../utils/paths.js";
|
|
8
|
+
export async function exportCommand(opts) {
|
|
9
|
+
setLogLevel(opts.verbose ? "verbose" : "info");
|
|
10
|
+
const root = resolveRoot(opts.path);
|
|
11
|
+
const format = opts.format.toLowerCase();
|
|
12
|
+
if (!["json", "html"].includes(format)) {
|
|
13
|
+
console.error(chalk.red(`\n✗ Unknown format: ${opts.format} (expected json | html)\n`));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const spinner = ora("Exporting architecture...").start();
|
|
17
|
+
try {
|
|
18
|
+
await fs.stat(root);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
spinner.fail(chalk.red("Could not read repository"));
|
|
22
|
+
console.error(chalk.dim(err.message));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const { graph } = await runPipeline({ root, ignore: opts.ignore, verbose: opts.verbose });
|
|
27
|
+
if (format === "json") {
|
|
28
|
+
const json = JSON.stringify(graph, null, 2);
|
|
29
|
+
const outPath = path.resolve(opts.output);
|
|
30
|
+
await fs.mkdir(path.dirname(outPath), { recursive: true });
|
|
31
|
+
await fs.writeFile(outPath, json, "utf-8");
|
|
32
|
+
spinner.succeed(chalk.green(`Exported JSON -> ${outPath}`));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const statsLine = `${graph.stats.totalFiles} files · ${graph.stats.totalLinks} links · ${Object.keys(graph.stats.languages).length} languages`;
|
|
36
|
+
const html = `<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>CodeCarto - ${escapeHtml(path.basename(root))}</title><style>body{margin:0;background:#050505;color:#e6e8ec;font-family:system-ui;padding:32px}pre{background:#0f0f12;border:1px solid #1e1e24;padding:16px;border-radius:8px;overflow:auto;max-width:960px}a{color:#00d9ff}</style></head><body><h1 style="color:#00d9ff">CodeCarto</h1><p>Architecture of <strong>${escapeHtml(root)}</strong></p><p>${statsLine}</p><pre>${escapeHtml(JSON.stringify(graph, null, 2))}</pre><p><a href="#" onclick="navigator.clipboard.writeText(document.querySelector('pre').textContent);return false">Copy JSON</a></p></body></html>`;
|
|
37
|
+
const out = opts.output.endsWith(".html")
|
|
38
|
+
? opts.output
|
|
39
|
+
: opts.output.replace(/\.json$/, "") + ".html";
|
|
40
|
+
const outPath = path.resolve(out);
|
|
41
|
+
await fs.mkdir(path.dirname(outPath), { recursive: true });
|
|
42
|
+
await fs.writeFile(outPath, html, "utf-8");
|
|
43
|
+
spinner.succeed(chalk.green(`Exported HTML -> ${outPath}`));
|
|
44
|
+
}
|
|
45
|
+
logger.dim(" Tip: codecarto serve --input <file> to visualize an exported graph.\n");
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
spinner.fail(chalk.red("Export failed"));
|
|
49
|
+
console.error(chalk.red(err.message));
|
|
50
|
+
if (opts.verbose)
|
|
51
|
+
console.error(err);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function escapeHtml(s) {
|
|
56
|
+
return s
|
|
57
|
+
.replaceAll("&", "&")
|
|
58
|
+
.replaceAll("<", "<")
|
|
59
|
+
.replaceAll(">", ">")
|
|
60
|
+
.replaceAll('"', """);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFlE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import { runPipeline } from "../utils/pipeline.js";
|
|
6
|
+
import { logger, setLogLevel } from "../utils/logger.js";
|
|
7
|
+
import { resolveRoot } from "../utils/paths.js";
|
|
8
|
+
export async function scanCommand(opts) {
|
|
9
|
+
setLogLevel(opts.verbose ? "verbose" : "info");
|
|
10
|
+
const root = resolveRoot(opts.path);
|
|
11
|
+
try {
|
|
12
|
+
const st = await fs.stat(root);
|
|
13
|
+
if (!st.isDirectory())
|
|
14
|
+
throw new Error(`Not a directory: ${root}`);
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
console.error(chalk.red(`\n✗ Could not read repository\n\n Path:\n ${root}\n\n Reason:\n ${err.message}\n\n Try:\n codecarto --path <directory>\n`));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
const spinner = ora({ text: "Discovering repository...", color: "cyan" }).start();
|
|
21
|
+
try {
|
|
22
|
+
spinner.text = "Scanning files...";
|
|
23
|
+
const { graph, diagnostics } = await runPipeline({
|
|
24
|
+
root,
|
|
25
|
+
ignore: opts.ignore,
|
|
26
|
+
verbose: opts.verbose,
|
|
27
|
+
});
|
|
28
|
+
spinner.text = `Analyzing ${graph.stats.totalFiles} files...`;
|
|
29
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
30
|
+
spinner.text = "Building architecture graph...";
|
|
31
|
+
spinner.succeed(chalk.green("Repository scanned"));
|
|
32
|
+
logger.info(chalk.dim(` Root: ${root}`));
|
|
33
|
+
logger.info(chalk.dim(` Files: ${graph.stats.totalFiles} Links: ${graph.stats.totalLinks} Dirs: ${graph.stats.totalDirectories} Isolated: ${graph.stats.isolatedFiles}`));
|
|
34
|
+
if (Object.keys(graph.stats.languages).length) {
|
|
35
|
+
const langStr = Object.entries(graph.stats.languages)
|
|
36
|
+
.sort((a, b) => b[1] - a[1])
|
|
37
|
+
.map(([k, v]) => `${k} ${v}`)
|
|
38
|
+
.join(" · ");
|
|
39
|
+
logger.info(chalk.dim(` Languages: ${langStr}`));
|
|
40
|
+
}
|
|
41
|
+
if (diagnostics.parseFailures.length) {
|
|
42
|
+
logger.warn(`${diagnostics.parseFailures.length} parse failures (see --verbose)`);
|
|
43
|
+
if (opts.verbose) {
|
|
44
|
+
for (const f of diagnostics.parseFailures.slice(0, 10))
|
|
45
|
+
logger.dim(` ! ${f.path}: ${f.reason}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (diagnostics.unsupported)
|
|
49
|
+
logger.dim(` Unsupported: ${diagnostics.unsupported} files (parser unavailable)`);
|
|
50
|
+
console.log("");
|
|
51
|
+
if (graph.stats.totalFiles > 0) {
|
|
52
|
+
const langs = Object.entries(graph.stats.languages).sort((a, b) => b[1] - a[1]);
|
|
53
|
+
for (const [lang, count] of langs) {
|
|
54
|
+
const pct = Math.round((count / graph.stats.totalFiles) * 100);
|
|
55
|
+
const bar = "█".repeat(Math.max(1, Math.round(pct / 5)));
|
|
56
|
+
logger.info(` ${lang.padEnd(12)} ${bar} ${pct}%`);
|
|
57
|
+
}
|
|
58
|
+
console.log("");
|
|
59
|
+
}
|
|
60
|
+
const json = JSON.stringify(graph, null, 2);
|
|
61
|
+
if (opts.output) {
|
|
62
|
+
const outPath = path.resolve(opts.output);
|
|
63
|
+
await fs.mkdir(path.dirname(outPath), { recursive: true });
|
|
64
|
+
await fs.writeFile(outPath, json, "utf-8");
|
|
65
|
+
logger.success(`Graph written to ${outPath}`);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(json);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
spinner.fail(chalk.red("Scan failed"));
|
|
73
|
+
console.error(chalk.red(err.message));
|
|
74
|
+
if (opts.verbose)
|
|
75
|
+
console.error(err);
|
|
76
|
+
else
|
|
77
|
+
console.error(chalk.dim(" Run with --verbose for details.\n"));
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAShD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAiB;IACjD,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC;IACrE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CACP,+CAA+C,IAAI,oBAAqB,GAAa,CAAC,OAAO,8CAA8C,CAC5I,CACF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IAElF,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,GAAG,mBAAmB,CAAC;QACnC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,WAAW,CAAC;YAC/C,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,GAAG,aAAa,KAAK,CAAC,KAAK,CAAC,UAAU,WAAW,CAAC;QAC9D,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,GAAG,gCAAgC,CAAC;QAEhD,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAEnD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CACT,KAAK,CAAC,GAAG,CACP,YAAY,KAAK,CAAC,KAAK,CAAC,UAAU,YAAY,KAAK,CAAC,KAAK,CAAC,UAAU,WAAW,KAAK,CAAC,KAAK,CAAC,gBAAgB,eAAe,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,CACtJ,CACF,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC;YAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,SAAmC,CAAC;iBAC5E,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;iBAC3B,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;iBAC5B,IAAI,CAAC,KAAK,CAAC,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,iCAAiC,CAAC,CAAC;YAClF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;oBACpD,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QACD,IAAI,WAAW,CAAC,WAAW;YACzB,MAAM,CAAC,GAAG,CAAC,kBAAkB,WAAW,CAAC,WAAW,6BAA6B,CAAC,CAAC;QACrF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,SAAmC,CAAC,CAAC,IAAI,CAChF,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CACtB,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;gBAClC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;gBAC/D,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzD,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;YACrD,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAC3C,MAAM,CAAC,OAAO,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;;YAChC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CpE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { parseCodeGraph } from "@yoinkingfish/shared";
|
|
4
|
+
import { logger, setLogLevel } from "../utils/logger.js";
|
|
5
|
+
import { startServer } from "../server/index.js";
|
|
6
|
+
import { openBrowser, waitForServer } from "../browser/index.js";
|
|
7
|
+
export async function serveCommand(opts) {
|
|
8
|
+
setLogLevel(opts.verbose ? "verbose" : "info");
|
|
9
|
+
const port = Number(opts.port);
|
|
10
|
+
if (!Number.isFinite(port) || port < 1 || port > 65535) {
|
|
11
|
+
console.error(chalk.red(`\n✗ Invalid port: ${opts.port}\n`));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
let raw;
|
|
15
|
+
try {
|
|
16
|
+
raw = await fs.readFile(opts.input, "utf-8");
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
console.error(chalk.red(`\n✗ Could not read graph file\n\n Path: ${opts.input}\n Reason: ${err.message}\n`));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
let graph;
|
|
23
|
+
try {
|
|
24
|
+
graph = parseCodeGraph(JSON.parse(raw));
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
console.error(chalk.red(`\n✗ Invalid graph JSON: ${err.message}\n`));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const { url, server } = await startServer({ graph, preferredPort: port });
|
|
31
|
+
console.log(chalk.green(`\n✓ Visualization running\n`));
|
|
32
|
+
console.log(` ${chalk.bold(url)}\n`);
|
|
33
|
+
console.log(chalk.dim(" Press Ctrl+C to stop.\n"));
|
|
34
|
+
await waitForServer(url);
|
|
35
|
+
if (opts.open)
|
|
36
|
+
await openBrowser(url);
|
|
37
|
+
// Keep process alive until SIGINT
|
|
38
|
+
await new Promise((resolve) => {
|
|
39
|
+
const close = () => {
|
|
40
|
+
server.close(() => resolve());
|
|
41
|
+
};
|
|
42
|
+
process.on("SIGINT", close);
|
|
43
|
+
process.on("SIGTERM", close);
|
|
44
|
+
});
|
|
45
|
+
logger.info("Server stopped.");
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CodeCarto CLI entry point.
|
|
4
|
+
* Local-first, offline-capable. Never executes repository code.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import { createRequire } from "node:module";
|
|
9
|
+
import { scanCommand } from "./commands/scan.js";
|
|
10
|
+
import { serveCommand } from "./commands/serve.js";
|
|
11
|
+
import { exportCommand } from "./commands/export.js";
|
|
12
|
+
import { defaultCommand } from "./commands/default.js";
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
14
|
+
// Read version without importing JSON with assertions (Node 18 compat)
|
|
15
|
+
let version = "0.1.0";
|
|
16
|
+
try {
|
|
17
|
+
const pkg = require("../../package.json");
|
|
18
|
+
if (pkg.version)
|
|
19
|
+
version = pkg.version;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// fallback — will be replaced by workspace package version at build time
|
|
23
|
+
try {
|
|
24
|
+
const cliPkg = require("../package.json");
|
|
25
|
+
if (cliPkg.version)
|
|
26
|
+
version = cliPkg.version;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
/* noop */
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const program = new Command();
|
|
33
|
+
program
|
|
34
|
+
.name("codecarto")
|
|
35
|
+
.description("See your codebase — local-first 3D architecture visualization")
|
|
36
|
+
.version(version, "-V, --version", "output the version number")
|
|
37
|
+
.helpOption("-h, --help", "display help for command");
|
|
38
|
+
// Default: scan + serve + open browser
|
|
39
|
+
program
|
|
40
|
+
.option("--port <number>", "preferred port (auto-increments if busy)", String(3000))
|
|
41
|
+
.option("--no-open", "do not automatically open browser")
|
|
42
|
+
.option("--verbose", "verbose logging", false)
|
|
43
|
+
.option("--ignore <pattern>", "additional ignore glob (repeatable)", collect, [])
|
|
44
|
+
.option("--output <file>", "write graph JSON to file instead of serving")
|
|
45
|
+
.action(defaultCommand);
|
|
46
|
+
// Subcommands
|
|
47
|
+
program
|
|
48
|
+
.command("scan")
|
|
49
|
+
.description("scan repository and print graph JSON to stdout or file")
|
|
50
|
+
.option("--path <dir>", "repository root", ".")
|
|
51
|
+
.option("--output <file>", "write graph JSON to file")
|
|
52
|
+
.option("--verbose", "verbose logging", false)
|
|
53
|
+
.option("--ignore <pattern>", "additional ignore glob (repeatable)", collect, [])
|
|
54
|
+
.action(scanCommand);
|
|
55
|
+
program
|
|
56
|
+
.command("serve")
|
|
57
|
+
.description("serve an existing graph JSON file in the visualizer")
|
|
58
|
+
.option("--input <file>", "graph JSON file to serve", "codecarto-data.json")
|
|
59
|
+
.option("--port <number>", "preferred port", String(3000))
|
|
60
|
+
.option("--no-open", "do not automatically open browser")
|
|
61
|
+
.option("--verbose", "verbose logging", false)
|
|
62
|
+
.action(serveCommand);
|
|
63
|
+
program
|
|
64
|
+
.command("export")
|
|
65
|
+
.description("export portable architecture artifact (JSON / HTML)")
|
|
66
|
+
.option("--path <dir>", "repository root", ".")
|
|
67
|
+
.option("--output <file>", "output file", "codecarto-data.json")
|
|
68
|
+
.option("--format <format>", "export format: json | html", "json")
|
|
69
|
+
.option("--verbose", "verbose logging", false)
|
|
70
|
+
.option("--ignore <pattern>", "additional ignore glob (repeatable)", collect, [])
|
|
71
|
+
.action(exportCommand);
|
|
72
|
+
function collect(value, previous) {
|
|
73
|
+
return previous.concat([value]);
|
|
74
|
+
}
|
|
75
|
+
// Friendly error handling — never dump stack in normal mode
|
|
76
|
+
program.exitOverride();
|
|
77
|
+
try {
|
|
78
|
+
await program.parseAsync(process.argv);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
const e = err;
|
|
82
|
+
// Commander help/version exits with code 0 — pass through
|
|
83
|
+
if (e.code === "commander.helpDisplayed" || e.code === "commander.version") {
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
86
|
+
if (e.message) {
|
|
87
|
+
console.error(chalk.red(`\n✗ ${e.message}\n`));
|
|
88
|
+
if (process.argv.includes("--verbose")) {
|
|
89
|
+
console.error(e);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
console.error(chalk.dim(" Run with --verbose for details. See --help.\n"));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
process.exit(e.exitCode ?? 1);
|
|
96
|
+
}
|
|
97
|
+
// Graceful termination
|
|
98
|
+
process.on("SIGINT", () => {
|
|
99
|
+
console.log(chalk.dim("\n Shutting down…\n"));
|
|
100
|
+
process.exit(0);
|
|
101
|
+
});
|
|
102
|
+
process.on("SIGTERM", () => {
|
|
103
|
+
process.exit(0);
|
|
104
|
+
});
|
|
105
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local HTTP server — serves visualizer static assets + graph JSON.
|
|
3
|
+
* Binds to 127.0.0.1 only. Tries ports incrementally.
|
|
4
|
+
*/
|
|
5
|
+
import http from "node:http";
|
|
6
|
+
import type { CodeGraph } from "@yoinkingfish/shared";
|
|
7
|
+
export interface ServeOptions {
|
|
8
|
+
graph: CodeGraph;
|
|
9
|
+
preferredPort?: number;
|
|
10
|
+
verbose?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface ServeResult {
|
|
13
|
+
url: string;
|
|
14
|
+
port: number;
|
|
15
|
+
server: http.Server;
|
|
16
|
+
}
|
|
17
|
+
export declare function startServer(options: ServeOptions): Promise<ServeResult>;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAiCtD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;CACrB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAwF7E"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local HTTP server — serves visualizer static assets + graph JSON.
|
|
3
|
+
* Binds to 127.0.0.1 only. Tries ports incrementally.
|
|
4
|
+
*/
|
|
5
|
+
import http from "node:http";
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { DEFAULT_PORT, MAX_PORT_ATTEMPTS } from "@yoinkingfish/shared";
|
|
10
|
+
import { logger } from "../utils/logger.js";
|
|
11
|
+
function findVisualizerDist() {
|
|
12
|
+
const base = path.dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const candidates = [
|
|
14
|
+
// monorepo dev: packages/cli/dist/server -> apps/visualizer/dist (4 levels up)
|
|
15
|
+
path.resolve(base, "../../../../apps/visualizer/dist"),
|
|
16
|
+
// alternative dev layout
|
|
17
|
+
path.resolve(base, "../../../apps/visualizer/dist"),
|
|
18
|
+
// published npm: node_modules/codecarto/dist/server -> node_modules/codecarto/visualizer
|
|
19
|
+
path.resolve(base, "../../visualizer"),
|
|
20
|
+
path.resolve(base, "../visualizer"),
|
|
21
|
+
path.resolve(base, "../../visualizer/dist"),
|
|
22
|
+
];
|
|
23
|
+
for (const c of candidates) {
|
|
24
|
+
if (fs.existsSync(c))
|
|
25
|
+
return c;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const MIME = {
|
|
30
|
+
".html": "text/html; charset=utf-8",
|
|
31
|
+
".js": "text/javascript; charset=utf-8",
|
|
32
|
+
".css": "text/css; charset=utf-8",
|
|
33
|
+
".json": "application/json; charset=utf-8",
|
|
34
|
+
".svg": "image/svg+xml",
|
|
35
|
+
".png": "image/png",
|
|
36
|
+
".ico": "image/x-icon",
|
|
37
|
+
".woff": "font/woff",
|
|
38
|
+
".woff2": "font/woff2",
|
|
39
|
+
};
|
|
40
|
+
export async function startServer(options) {
|
|
41
|
+
const { graph, preferredPort = DEFAULT_PORT } = options;
|
|
42
|
+
const graphJson = JSON.stringify(graph);
|
|
43
|
+
// Inline fallback HTML if visualizer not yet built — still proves server works
|
|
44
|
+
const fallbackHtml = `<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>CodeCarto</title><style>body{margin:0;background:#050505;color:#e6e8ec;font-family:ui-monospace,monospace;display:grid;place-items:center;height:100vh}pre{background:#0f0f12;border:1px solid #1e1e24;padding:24px;border-radius:12px;max-width:720px;overflow:auto}a{color:#00d9ff}</style></head><body><div><h1>CodeCarto</h1><p>Visualizer build not found. Run <code>pnpm build</code> in <code>apps/visualizer</code>.</p><p>Graph API: <a href="/api/graph">/api/graph</a></p><pre id="stats"></pre><script>fetch('/api/graph').then(r=>r.json()).then(g=>{document.getElementById('stats').textContent=JSON.stringify(g.stats,null,2)}).catch(e=>{document.getElementById('stats').textContent=String(e)})</script></div></body></html>`;
|
|
45
|
+
const distDir = findVisualizerDist();
|
|
46
|
+
const handler = (req, res) => {
|
|
47
|
+
const url = new URL(req.url ?? "/", `http://127.0.0.1`);
|
|
48
|
+
const pathname = url.pathname;
|
|
49
|
+
// CORS locked to localhost — no wildcard
|
|
50
|
+
res.setHeader("X-Content-Type-Options", "nosniff");
|
|
51
|
+
res.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;");
|
|
52
|
+
if (pathname === "/api/graph") {
|
|
53
|
+
res.writeHead(200, { "Content-Type": MIME[".json"] });
|
|
54
|
+
res.end(graphJson);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (pathname === "/api/health") {
|
|
58
|
+
res.writeHead(200, { "Content-Type": MIME[".json"] });
|
|
59
|
+
res.end(JSON.stringify({ ok: true, version: graph.version }));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (distDir) {
|
|
63
|
+
const filePath = path.join(distDir, pathname === "/" ? "index.html" : pathname.replace(/^\//, ""));
|
|
64
|
+
// Prevent traversal
|
|
65
|
+
if (!filePath.startsWith(distDir)) {
|
|
66
|
+
res.writeHead(403);
|
|
67
|
+
res.end("Forbidden");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
|
|
71
|
+
const ext = path.extname(filePath);
|
|
72
|
+
res.writeHead(200, { "Content-Type": MIME[ext] ?? "application/octet-stream" });
|
|
73
|
+
fs.createReadStream(filePath).pipe(res);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// SPA fallback
|
|
77
|
+
const indexHtml = path.join(distDir, "index.html");
|
|
78
|
+
if (fs.existsSync(indexHtml)) {
|
|
79
|
+
res.writeHead(200, { "Content-Type": MIME[".html"] });
|
|
80
|
+
fs.createReadStream(indexHtml).pipe(res);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Fallback
|
|
85
|
+
res.writeHead(200, { "Content-Type": MIME[".html"] });
|
|
86
|
+
res.end(fallbackHtml);
|
|
87
|
+
};
|
|
88
|
+
let lastError = null;
|
|
89
|
+
for (let attempt = 0; attempt < MAX_PORT_ATTEMPTS; attempt++) {
|
|
90
|
+
const port = preferredPort + attempt;
|
|
91
|
+
const server = http.createServer(handler);
|
|
92
|
+
try {
|
|
93
|
+
await new Promise((resolve, reject) => {
|
|
94
|
+
server.once("error", reject);
|
|
95
|
+
server.listen(port, "127.0.0.1", () => {
|
|
96
|
+
server.off("error", reject);
|
|
97
|
+
resolve();
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
const url = `http://localhost:${port}`;
|
|
101
|
+
logger.verbose(`Server listening on ${url} (distDir=${distDir ?? "fallback"})`);
|
|
102
|
+
return { url, port, server };
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
lastError = err;
|
|
106
|
+
const code = err.code;
|
|
107
|
+
if (code !== "EADDRINUSE" && code !== "EACCES")
|
|
108
|
+
throw err;
|
|
109
|
+
logger.verbose(`Port ${port} unavailable (${code}), trying next…`);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
throw new Error(`Could not bind to any port from ${preferredPort} to ${preferredPort + MAX_PORT_ATTEMPTS - 1}. Last error: ${lastError?.message}`);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/utils/banner.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,SAiB1B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
export function printBanner() {
|
|
3
|
+
// CODECARTO — ANSI Shadow figlet, verified spelling (last char is O, not P/D)
|
|
4
|
+
// Generated via `figlet -f 'ANSI Shadow' CODECARTO` — do not edit manually
|
|
5
|
+
const art = `
|
|
6
|
+
██████╗ ██████╗ ██████╗ ███████╗ ██████╗ █████╗ ██████╗ ████████╗ ██████╗
|
|
7
|
+
██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔════╝██╔══██╗██╔══██╗╚══██╔══╝██╔═══██╗
|
|
8
|
+
██║ ██║ ██║██║ ██║█████╗ ██║ ███████║██████╔╝ ██║ ██║ ██║
|
|
9
|
+
██║ ██║ ██║██║ ██║██╔══╝ ██║ ██╔══██║██╔══██╗ ██║ ██║ ██║
|
|
10
|
+
╚██████╗╚██████╔╝██████╔╝███████╗╚██████╗██║ ██║██║ ██║ ██║ ╚██████╔╝
|
|
11
|
+
╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═════╝`;
|
|
12
|
+
console.log(chalk.cyan(art));
|
|
13
|
+
console.log(chalk.bold(" CodeCarto"));
|
|
14
|
+
console.log(chalk.dim(" See your codebase. ") +
|
|
15
|
+
chalk.dim.italic("Local \u00b7 Fast \u00b7 Private \u00b7 Visual\n"));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/utils/banner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,WAAW;IACzB,8EAA8E;IAC9E,2EAA2E;IAC3E,MAAM,GAAG,GAAG;;;;;;2EAM6D,CAAC;IAE1E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC;QACjC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,kDAAkD,CAAC,CACvE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type LogLevel = "silent" | "info" | "verbose";
|
|
2
|
+
export declare function setLogLevel(l: LogLevel): void;
|
|
3
|
+
export declare function getLogLevel(): LogLevel;
|
|
4
|
+
export declare const logger: {
|
|
5
|
+
info(msg: string): void;
|
|
6
|
+
verbose(msg: string): void;
|
|
7
|
+
success(msg: string): void;
|
|
8
|
+
warn(msg: string): void;
|
|
9
|
+
error(msg: string): void;
|
|
10
|
+
dim(msg: string): void;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAIrD,wBAAgB,WAAW,CAAC,CAAC,EAAE,QAAQ,QAEtC;AAED,wBAAgB,WAAW,IAAI,QAAQ,CAEtC;AAED,eAAO,MAAM,MAAM;cACP,MAAM;iBAGH,MAAM;iBAGN,MAAM;cAGT,MAAM;eAGL,MAAM;aAGR,MAAM;CAGhB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
let level = "info";
|
|
3
|
+
export function setLogLevel(l) {
|
|
4
|
+
level = l;
|
|
5
|
+
}
|
|
6
|
+
export function getLogLevel() {
|
|
7
|
+
return level;
|
|
8
|
+
}
|
|
9
|
+
export const logger = {
|
|
10
|
+
info(msg) {
|
|
11
|
+
if (level !== "silent")
|
|
12
|
+
console.log(msg);
|
|
13
|
+
},
|
|
14
|
+
verbose(msg) {
|
|
15
|
+
if (level === "verbose")
|
|
16
|
+
console.log(chalk.dim(msg));
|
|
17
|
+
},
|
|
18
|
+
success(msg) {
|
|
19
|
+
if (level !== "silent")
|
|
20
|
+
console.log(chalk.green(msg));
|
|
21
|
+
},
|
|
22
|
+
warn(msg) {
|
|
23
|
+
if (level !== "silent")
|
|
24
|
+
console.warn(chalk.yellow(`⚠ ${msg}`));
|
|
25
|
+
},
|
|
26
|
+
error(msg) {
|
|
27
|
+
console.error(chalk.red(`✗ ${msg}`));
|
|
28
|
+
},
|
|
29
|
+
dim(msg) {
|
|
30
|
+
if (level !== "silent")
|
|
31
|
+
console.log(chalk.dim(msg));
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,IAAI,KAAK,GAAa,MAAM,CAAC;AAE7B,MAAM,UAAU,WAAW,CAAC,CAAW;IACrC,KAAK,GAAG,CAAC,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,CAAC,GAAW;QACd,IAAI,KAAK,KAAK,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,CAAC,GAAW;QACjB,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,CAAC,GAAW;QACjB,IAAI,KAAK,KAAK,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,CAAC,GAAW;QACd,IAAI,KAAK,KAAK,QAAQ;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;IACD,KAAK,CAAC,GAAW;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,GAAG,CAAC,GAAW;QACb,IAAI,KAAK,KAAK,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Normalize to POSIX, prevent traversal outside root */
|
|
2
|
+
export declare function sanitizePath(root: string, p: string): string;
|
|
3
|
+
export declare function ensureDirectoryExists(dir: string): Promise<void>;
|
|
4
|
+
export declare function toPosix(p: string): string;
|
|
5
|
+
export declare function resolveRoot(input: string): string;
|
|
6
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAGA,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtE;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
/** Normalize to POSIX, prevent traversal outside root */
|
|
4
|
+
export function sanitizePath(root, p) {
|
|
5
|
+
const normalized = path.posix.normalize(p.replaceAll("\\", "/"));
|
|
6
|
+
if (normalized.includes("..")) {
|
|
7
|
+
throw new Error(`Invalid path traversal: ${p}`);
|
|
8
|
+
}
|
|
9
|
+
return normalized;
|
|
10
|
+
}
|
|
11
|
+
export async function ensureDirectoryExists(dir) {
|
|
12
|
+
// Validate that parent is accessible and dir is inside allowed root — caller checks existence
|
|
13
|
+
const abs = path.resolve(dir);
|
|
14
|
+
try {
|
|
15
|
+
await fs.access(path.dirname(abs));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
throw new Error(`Parent directory does not exist: ${path.dirname(abs)}\n Try: codecarto --path <existing-directory>`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function toPosix(p) {
|
|
22
|
+
return p.split(path.sep).join(path.posix.sep);
|
|
23
|
+
}
|
|
24
|
+
export function resolveRoot(input) {
|
|
25
|
+
return path.resolve(input);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,yDAAyD;AACzD,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,CAAS;IAClD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IACjE,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAW;IACrD,8FAA8F;IAC9F,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,oCAAoC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,gDAAgD,CACtG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,CAAS;IAC/B,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline — orchestrates scan → parse → resolve → graph.
|
|
3
|
+
* This is the core that CLI `scan` and `default` commands use.
|
|
4
|
+
*/
|
|
5
|
+
import type { CodeGraph } from "@yoinkingfish/shared";
|
|
6
|
+
export interface PipelineOptions {
|
|
7
|
+
root: string;
|
|
8
|
+
ignore?: string[];
|
|
9
|
+
verbose?: boolean;
|
|
10
|
+
maxFileSizeBytes?: number;
|
|
11
|
+
concurrency?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface PipelineResult {
|
|
14
|
+
graph: CodeGraph;
|
|
15
|
+
diagnostics: {
|
|
16
|
+
scanned: number;
|
|
17
|
+
parsed: number;
|
|
18
|
+
unsupported: number;
|
|
19
|
+
parseFailures: Array<{
|
|
20
|
+
path: string;
|
|
21
|
+
reason: string;
|
|
22
|
+
}>;
|
|
23
|
+
unresolvedLocals: number;
|
|
24
|
+
externals: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare function runPipeline(options: PipelineOptions): Promise<PipelineResult>;
|
|
28
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/utils/pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,sBAAsB,CAAC;AAGhE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACvD,gBAAgB,EAAE,MAAM,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA+MnF"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline — orchestrates scan → parse → resolve → graph.
|
|
3
|
+
* This is the core that CLI `scan` and `default` commands use.
|
|
4
|
+
*/
|
|
5
|
+
import fs from "node:fs/promises";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { scanRepositoryDetailed, getParserForExtension, resolveImport, parseTsconfigPaths, } from "@yoinkingfish/parser";
|
|
8
|
+
import { buildGraph } from "@yoinkingfish/graph";
|
|
9
|
+
import { LANGUAGE_BY_EXTENSION } from "@yoinkingfish/shared";
|
|
10
|
+
export async function runPipeline(options) {
|
|
11
|
+
const root = path.resolve(options.root);
|
|
12
|
+
const ignore = options.ignore ?? [];
|
|
13
|
+
// Load tsconfig paths if present
|
|
14
|
+
const { tsConfigPaths, tsConfigBaseUrl } = await loadTsconfig(root);
|
|
15
|
+
// 1. Scan
|
|
16
|
+
const scan = await scanRepositoryDetailed({
|
|
17
|
+
root,
|
|
18
|
+
ignore,
|
|
19
|
+
maxFileSizeBytes: options.maxFileSizeBytes,
|
|
20
|
+
concurrency: options.concurrency,
|
|
21
|
+
});
|
|
22
|
+
const files = scan.files;
|
|
23
|
+
const existingFilesSet = new Set(files.map((f) => f.relativePath));
|
|
24
|
+
const existingAbsSet = new Set(files.map((f) => f.absolutePath));
|
|
25
|
+
// 2. Parse + build nodes + collect raw dependencies
|
|
26
|
+
const nodes = [];
|
|
27
|
+
const rawEdges = [];
|
|
28
|
+
const parseFailures = [];
|
|
29
|
+
const unsupported = [];
|
|
30
|
+
let externals = 0;
|
|
31
|
+
let unresolvedLocals = 0;
|
|
32
|
+
// Read files concurrently with limit
|
|
33
|
+
const concurrency = options.concurrency ?? 32;
|
|
34
|
+
const queue = [...files];
|
|
35
|
+
const workers = [];
|
|
36
|
+
async function worker() {
|
|
37
|
+
while (queue.length) {
|
|
38
|
+
const file = queue.pop();
|
|
39
|
+
let source;
|
|
40
|
+
try {
|
|
41
|
+
source = await fs.readFile(file.absolutePath, "utf-8");
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
parseFailures.push({ path: file.relativePath, reason: err.message });
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const parser = getParserForExtension(file.extension);
|
|
48
|
+
if (!parser) {
|
|
49
|
+
unsupported.push({ path: file.relativePath, reason: `no parser for .${file.extension}` });
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
let result;
|
|
53
|
+
try {
|
|
54
|
+
result = await parser.parseFile(source, {
|
|
55
|
+
filePath: file.absolutePath,
|
|
56
|
+
relativePath: file.relativePath,
|
|
57
|
+
root,
|
|
58
|
+
tsConfigPaths,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
parseFailures.push({ path: file.relativePath, reason: err.message });
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (result.parseError) {
|
|
66
|
+
parseFailures.push({ path: file.relativePath, reason: result.parseError });
|
|
67
|
+
}
|
|
68
|
+
// Build node
|
|
69
|
+
const dir = path.posix.dirname(file.relativePath);
|
|
70
|
+
const depth = dir === "." ? 0 : dir.split("/").length;
|
|
71
|
+
const lines = source.split("\n").length;
|
|
72
|
+
const category = inferCategory(file.relativePath);
|
|
73
|
+
nodes.push({
|
|
74
|
+
id: file.relativePath,
|
|
75
|
+
type: "file",
|
|
76
|
+
path: file.relativePath,
|
|
77
|
+
name: path.posix.basename(file.relativePath),
|
|
78
|
+
extension: file.extension,
|
|
79
|
+
language: file.language ?? LANGUAGE_BY_EXTENSION[file.extension],
|
|
80
|
+
category,
|
|
81
|
+
sizeBytes: file.sizeBytes,
|
|
82
|
+
linesOfCode: lines,
|
|
83
|
+
directory: dir,
|
|
84
|
+
depth,
|
|
85
|
+
inboundDependencies: 0,
|
|
86
|
+
outboundDependencies: 0,
|
|
87
|
+
});
|
|
88
|
+
// Collect dependencies for later resolution
|
|
89
|
+
for (const dep of result.dependencies) {
|
|
90
|
+
const resolved = resolveImport(dep.specifier, {
|
|
91
|
+
importerPath: file.absolutePath,
|
|
92
|
+
importerRelative: file.relativePath,
|
|
93
|
+
root,
|
|
94
|
+
existingFiles: existingFilesSet,
|
|
95
|
+
existingAbsFiles: existingAbsSet,
|
|
96
|
+
tsConfigPaths,
|
|
97
|
+
tsConfigBaseUrl,
|
|
98
|
+
});
|
|
99
|
+
if (resolved.resolved && resolved.resolvedPath) {
|
|
100
|
+
// Will be added as link after nodes built
|
|
101
|
+
rawEdges.push({
|
|
102
|
+
source: file.relativePath,
|
|
103
|
+
specifier: dep.specifier,
|
|
104
|
+
type: dep.type,
|
|
105
|
+
resolved: false,
|
|
106
|
+
});
|
|
107
|
+
// Store resolved mapping for later
|
|
108
|
+
dep._resolvedPath = resolved.resolvedPath;
|
|
109
|
+
// Keep dep for link creation
|
|
110
|
+
file._deps ??= [];
|
|
111
|
+
file._deps.push({
|
|
112
|
+
...dep,
|
|
113
|
+
_resolvedPath: resolved.resolvedPath,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
if (resolved.external)
|
|
118
|
+
externals++;
|
|
119
|
+
else
|
|
120
|
+
unresolvedLocals++;
|
|
121
|
+
// Still track unresolved? MVP omits external nodes, but we could keep meta
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Attach deps to file object for link phase
|
|
125
|
+
file._rawDeps = result.dependencies;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const workerCount = Math.min(concurrency, Math.max(1, Math.ceil(files.length / 16)));
|
|
129
|
+
for (let i = 0; i < workerCount; i++)
|
|
130
|
+
workers.push(worker());
|
|
131
|
+
await Promise.all(workers);
|
|
132
|
+
// If any unsupported files from scan, merge
|
|
133
|
+
for (const s of scan.skipped) {
|
|
134
|
+
if (s.reason.startsWith("unsupported"))
|
|
135
|
+
unsupported.push(s);
|
|
136
|
+
}
|
|
137
|
+
// 3. Build links from resolved deps
|
|
138
|
+
// We need to re-derive links from file._rawDeps that had resolved path
|
|
139
|
+
const links = [];
|
|
140
|
+
for (const file of files) {
|
|
141
|
+
const rawDeps = file._rawDeps;
|
|
142
|
+
if (!rawDeps)
|
|
143
|
+
continue;
|
|
144
|
+
for (const dep of rawDeps) {
|
|
145
|
+
const depWithResolved = dep;
|
|
146
|
+
const resolvedPath = depWithResolved._resolvedPath;
|
|
147
|
+
if (!resolvedPath)
|
|
148
|
+
continue;
|
|
149
|
+
// Only include if target exists (we already checked)
|
|
150
|
+
links.push({
|
|
151
|
+
source: file.relativePath,
|
|
152
|
+
target: resolvedPath,
|
|
153
|
+
type: dep.type,
|
|
154
|
+
resolved: true,
|
|
155
|
+
rawSpecifier: dep.specifier,
|
|
156
|
+
weight: 1,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Deduplicate links (A->B may appear multiple times via multiple imports)
|
|
161
|
+
const linkMap = new Map();
|
|
162
|
+
for (const l of links) {
|
|
163
|
+
const key = `${l.source}::${l.target}::${l.type}`;
|
|
164
|
+
const existing = linkMap.get(key);
|
|
165
|
+
if (existing) {
|
|
166
|
+
existing.weight = (existing.weight ?? 1) + 1;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
linkMap.set(key, { ...l });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const dedupedLinks = [...linkMap.values()];
|
|
173
|
+
// 4. Build graph
|
|
174
|
+
const graph = buildGraph({ root, nodes, links: dedupedLinks });
|
|
175
|
+
// Enrich stats with scan/parse diagnostics
|
|
176
|
+
graph.stats.parseFailures = parseFailures;
|
|
177
|
+
graph.stats.unsupportedFiles = unsupported.map((s) => ({
|
|
178
|
+
path: s.path,
|
|
179
|
+
language: s.reason.includes(".") ? s.reason.split(".").pop() : undefined,
|
|
180
|
+
}));
|
|
181
|
+
// Recompute isolated after dedupe? buildGraph already does
|
|
182
|
+
return {
|
|
183
|
+
graph,
|
|
184
|
+
diagnostics: {
|
|
185
|
+
scanned: scan.stats.totalDiscovered,
|
|
186
|
+
parsed: nodes.length,
|
|
187
|
+
unsupported: unsupported.length,
|
|
188
|
+
parseFailures,
|
|
189
|
+
unresolvedLocals,
|
|
190
|
+
externals,
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async function loadTsconfig(root) {
|
|
195
|
+
const candidates = ["tsconfig.json", "jsconfig.json"];
|
|
196
|
+
for (const name of candidates) {
|
|
197
|
+
const p = path.join(root, name);
|
|
198
|
+
try {
|
|
199
|
+
const content = await fs.readFile(p, "utf-8");
|
|
200
|
+
const parsed = parseTsconfigPaths(content, root);
|
|
201
|
+
if (parsed.paths || parsed.baseUrl)
|
|
202
|
+
return { tsConfigPaths: parsed.paths, tsConfigBaseUrl: parsed.baseUrl };
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Also check for tsconfig via workspaces? For monorepo, check root + packages/*/tsconfig
|
|
209
|
+
return {};
|
|
210
|
+
}
|
|
211
|
+
function inferCategory(relPath) {
|
|
212
|
+
const p = relPath.toLowerCase();
|
|
213
|
+
if (p.includes("__tests__") ||
|
|
214
|
+
p.endsWith(".test.ts") ||
|
|
215
|
+
p.endsWith(".test.tsx") ||
|
|
216
|
+
p.endsWith(".spec.ts") ||
|
|
217
|
+
p.includes("/test/"))
|
|
218
|
+
return "test";
|
|
219
|
+
if (p.includes("/components/") || p.includes("/ui/") || p.endsWith(".css") || p.endsWith(".scss"))
|
|
220
|
+
return p.endsWith(".css") || p.endsWith(".scss") ? "style" : "ui";
|
|
221
|
+
if (p.includes("/api/") ||
|
|
222
|
+
p.includes("/routes/") ||
|
|
223
|
+
p.includes("/pages/api/") ||
|
|
224
|
+
p.startsWith("api/"))
|
|
225
|
+
return "api";
|
|
226
|
+
if (p.includes("/config/") || p.endsWith(".config.ts") || p.endsWith(".config.js"))
|
|
227
|
+
return "config";
|
|
228
|
+
if (p.includes("/utils/") || p.includes("/helpers/") || p.includes("/lib/"))
|
|
229
|
+
return "util";
|
|
230
|
+
if (p.includes("/data/") || p.includes("/db/") || p.includes("/models/"))
|
|
231
|
+
return "data";
|
|
232
|
+
return "other";
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/utils/pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAsB7D,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAwB;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IAEpC,iCAAiC;IACjC,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IAEpE,UAAU;IACV,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC;QACxC,IAAI;QACJ,MAAM;QACN,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACzB,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IACnE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IAEjE,oDAAoD;IACpD,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAKT,EAAE,CAAC;IACR,MAAM,aAAa,GAA4C,EAAE,CAAC;IAClE,MAAM,WAAW,GAAwB,EAAE,CAAC;IAC5C,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IAEzB,qCAAqC;IACrC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;IAC9C,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IACzB,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,KAAK,UAAU,MAAM;QACnB,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;YAC1B,IAAI,MAAc,CAAC;YACnB,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACzD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;gBAChF,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACrD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,kBAAkB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;gBAC1F,SAAS;YACX,CAAC;YAED,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE;oBACtC,QAAQ,EAAE,IAAI,CAAC,YAAY;oBAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,IAAI;oBACJ,aAAa;iBACd,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;gBAChF,SAAS;YACX,CAAC;YAED,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtB,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YAC7E,CAAC;YAED,aAAa;YACb,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;YACtD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YACxC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAElD,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,IAAI,CAAC,YAAY;gBACrB,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,YAAY;gBACvB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;gBAC5C,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC;gBAChE,QAAQ;gBACR,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,WAAW,EAAE,KAAK;gBAClB,SAAS,EAAE,GAAG;gBACd,KAAK;gBACL,mBAAmB,EAAE,CAAC;gBACtB,oBAAoB,EAAE,CAAC;aACxB,CAAC,CAAC;YAEH,4CAA4C;YAC5C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACtC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE;oBAC5C,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,gBAAgB,EAAE,IAAI,CAAC,YAAY;oBACnC,IAAI;oBACJ,aAAa,EAAE,gBAAgB;oBAC/B,gBAAgB,EAAE,cAAc;oBAChC,aAAa;oBACb,eAAe;iBAChB,CAAC,CAAC;gBAEH,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;oBAC/C,0CAA0C;oBAC1C,QAAQ,CAAC,IAAI,CAAC;wBACZ,MAAM,EAAE,IAAI,CAAC,YAAY;wBACzB,SAAS,EAAE,GAAG,CAAC,SAAS;wBACxB,IAAI,EAAE,GAAG,CAAC,IAAa;wBACvB,QAAQ,EAAE,KAAK;qBAChB,CAAC,CAAC;oBACH,mCAAmC;oBAClC,GAA6C,CAAC,aAAa,GAAG,QAAQ,CAAC,YAAY,CAAC;oBACrF,6BAA6B;oBAC5B,IAAyC,CAAC,KAAK,KAAK,EAAE,CAAC;oBACtD,IAAwC,CAAC,KAAmB,CAAC,IAAI,CAAC;wBAClE,GAAG,GAAG;wBACN,aAAa,EAAE,QAAQ,CAAC,YAAY;qBACrC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,IAAI,QAAQ,CAAC,QAAQ;wBAAE,SAAS,EAAE,CAAC;;wBAC9B,gBAAgB,EAAE,CAAC;oBACxB,2EAA2E;gBAC7E,CAAC;YACH,CAAC;YAED,4CAA4C;YAC3C,IAA6D,CAAC,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC;QAChG,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACrF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE;QAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7D,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAE3B,4CAA4C;IAC5C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,oCAAoC;IACpC,uEAAuE;IACvE,MAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GACX,IAGD,CAAC,QAAQ,CAAC;QACX,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,eAAe,GAAG,GAIvB,CAAC;YACF,MAAM,YAAY,GAAG,eAAe,CAAC,aAAa,CAAC;YACnD,IAAI,CAAC,YAAY;gBAAE,SAAS;YAC5B,qDAAqD;YACrD,KAAK,CAAC,IAAI,CAAC;gBACT,MAAM,EAAE,IAAI,CAAC,YAAY;gBACzB,MAAM,EAAE,YAAY;gBACpB,IAAI,EAAE,GAAG,CAAC,IAA0C;gBACpD,QAAQ,EAAE,IAAI;gBACd,YAAY,EAAE,GAAG,CAAC,SAAS;gBAC3B,MAAM,EAAE,CAAC;aACV,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsC,CAAC;IAC9D,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,MAAM,YAAY,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE3C,iBAAiB;IACjB,MAAM,KAAK,GAAG,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;IAE/D,2CAA2C;IAC3C,KAAK,CAAC,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;IAC1C,KAAK,CAAC,KAAK,CAAC,gBAAgB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrD,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;KACzE,CAAC,CAAC,CAAC;IAEJ,2DAA2D;IAC3D,OAAO;QACL,KAAK;QACL,WAAW,EAAE;YACX,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe;YACnC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,WAAW,EAAE,WAAW,CAAC,MAAM;YAC/B,aAAa;YACb,gBAAgB;YAChB,SAAS;SACV;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,IAAY;IAEZ,MAAM,UAAU,GAAG,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IACtD,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9C,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACjD,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO;gBAChC,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAC5E,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,yFAAyF;IACzF,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAChC,IACE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;QACvB,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QACtB,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;QACvB,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QACtB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAEpB,OAAO,MAAM,CAAC;IAChB,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC/F,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,IACE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QACnB,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QACtB,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;QACzB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QAEpB,OAAO,KAAK,CAAC;IACf,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;QAChF,OAAO,QAAQ,CAAC;IAClB,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3F,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,MAAM,CAAC;IACxF,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yoinkingfish/codecarto",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "See your codebase — local-first 3D architecture visualization",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"codecarto": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"chalk": "^5.3.0",
|
|
22
|
+
"commander": "^12.1.0",
|
|
23
|
+
"fast-glob": "^3.3.2",
|
|
24
|
+
"open": "^10.1.0",
|
|
25
|
+
"ora": "^8.0.1",
|
|
26
|
+
"zod": "^3.23.8",
|
|
27
|
+
"@yoinkingfish/graph": "0.1.1",
|
|
28
|
+
"@yoinkingfish/parser": "0.1.1",
|
|
29
|
+
"@yoinkingfish/shared": "0.1.1"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^22.7.4",
|
|
33
|
+
"rimraf": "^6.0.1",
|
|
34
|
+
"typescript": "^5.6.3",
|
|
35
|
+
"vitest": "^2.1.8"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18.0.0"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"architecture",
|
|
42
|
+
"visualization",
|
|
43
|
+
"3d",
|
|
44
|
+
"ast",
|
|
45
|
+
"graph",
|
|
46
|
+
"cli",
|
|
47
|
+
"developer-tools"
|
|
48
|
+
],
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/OpKnock/codecarto.git"
|
|
53
|
+
},
|
|
54
|
+
"author": "Mehul Wagde <yoinkingfish@gmail.com>",
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "tsc -p tsconfig.json",
|
|
57
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
58
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
59
|
+
"clean": "rimraf dist",
|
|
60
|
+
"test": "vitest run"
|
|
61
|
+
}
|
|
62
|
+
}
|