depwire-cli 0.3.1 → 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/dist/{chunk-LOX5NEND.js → chunk-X2DOGIIG.js} +98 -68
- package/dist/index.js +6 -6
- package/dist/mcpb-entry.js +2 -2
- package/dist/parser/grammars/tree-sitter-go.wasm +0 -0
- package/dist/parser/grammars/tree-sitter-javascript.wasm +0 -0
- package/dist/parser/grammars/tree-sitter-python.wasm +0 -0
- package/dist/parser/grammars/tree-sitter-tsx.wasm +0 -0
- package/dist/parser/grammars/tree-sitter-typescript.wasm +0 -0
- package/package.json +4 -8
|
@@ -54,9 +54,50 @@ function fileExists(filePath) {
|
|
|
54
54
|
// src/parser/detect.ts
|
|
55
55
|
import { extname as extname3 } from "path";
|
|
56
56
|
|
|
57
|
-
// src/parser/
|
|
58
|
-
import Parser from "tree-sitter";
|
|
59
|
-
import
|
|
57
|
+
// src/parser/wasm-init.ts
|
|
58
|
+
import { Parser, Language } from "web-tree-sitter";
|
|
59
|
+
import path from "path";
|
|
60
|
+
import { fileURLToPath } from "url";
|
|
61
|
+
import { existsSync as existsSync2 } from "fs";
|
|
62
|
+
var initialized = false;
|
|
63
|
+
var languages = /* @__PURE__ */ new Map();
|
|
64
|
+
async function initParser() {
|
|
65
|
+
if (initialized) return;
|
|
66
|
+
await Parser.init();
|
|
67
|
+
const __dirname3 = path.dirname(fileURLToPath(import.meta.url));
|
|
68
|
+
let grammarsDir = path.join(__dirname3, "parser", "grammars");
|
|
69
|
+
if (!existsSync2(grammarsDir)) {
|
|
70
|
+
grammarsDir = path.join(path.dirname(__dirname3), "parser", "grammars");
|
|
71
|
+
}
|
|
72
|
+
if (!existsSync2(grammarsDir)) {
|
|
73
|
+
grammarsDir = path.join(__dirname3, "grammars");
|
|
74
|
+
}
|
|
75
|
+
const grammarFiles = {
|
|
76
|
+
"typescript": "tree-sitter-typescript.wasm",
|
|
77
|
+
"tsx": "tree-sitter-tsx.wasm",
|
|
78
|
+
"javascript": "tree-sitter-javascript.wasm",
|
|
79
|
+
"python": "tree-sitter-python.wasm",
|
|
80
|
+
"go": "tree-sitter-go.wasm"
|
|
81
|
+
};
|
|
82
|
+
for (const [name, file] of Object.entries(grammarFiles)) {
|
|
83
|
+
const wasmPath = path.join(grammarsDir, file);
|
|
84
|
+
const lang = await Language.load(wasmPath);
|
|
85
|
+
languages.set(name, lang);
|
|
86
|
+
}
|
|
87
|
+
initialized = true;
|
|
88
|
+
}
|
|
89
|
+
function getParser(language) {
|
|
90
|
+
if (!initialized) {
|
|
91
|
+
throw new Error("Parser not initialized. Call initParser() first.");
|
|
92
|
+
}
|
|
93
|
+
const lang = languages.get(language);
|
|
94
|
+
if (!lang) {
|
|
95
|
+
throw new Error(`Language '${language}' not loaded.`);
|
|
96
|
+
}
|
|
97
|
+
const parser = new Parser();
|
|
98
|
+
parser.setLanguage(lang);
|
|
99
|
+
return parser;
|
|
100
|
+
}
|
|
60
101
|
|
|
61
102
|
// src/parser/resolver.ts
|
|
62
103
|
import { join as join2, dirname, resolve, relative as relative2 } from "path";
|
|
@@ -152,13 +193,10 @@ function resolveImportPath(importPath, fromFile, projectRoot) {
|
|
|
152
193
|
}
|
|
153
194
|
|
|
154
195
|
// src/parser/typescript.ts
|
|
155
|
-
var tsParser = new Parser();
|
|
156
|
-
tsParser.setLanguage(TypeScript.typescript);
|
|
157
|
-
var tsxParser = new Parser();
|
|
158
|
-
tsxParser.setLanguage(TypeScript.tsx);
|
|
159
196
|
function parseTypeScriptFile(filePath, sourceCode, projectRoot) {
|
|
160
|
-
const
|
|
161
|
-
const
|
|
197
|
+
const languageType = filePath.endsWith(".tsx") ? "tsx" : "typescript";
|
|
198
|
+
const parser = getParser(languageType);
|
|
199
|
+
const tree = parser.parse(sourceCode, null, { bufferSize: 1024 * 1024 });
|
|
162
200
|
const context = {
|
|
163
201
|
filePath,
|
|
164
202
|
projectRoot,
|
|
@@ -613,14 +651,11 @@ var typescriptParser = {
|
|
|
613
651
|
};
|
|
614
652
|
|
|
615
653
|
// src/parser/python.ts
|
|
616
|
-
import Parser2 from "tree-sitter";
|
|
617
|
-
import Python from "tree-sitter-python";
|
|
618
654
|
import { dirname as dirname2, join as join3 } from "path";
|
|
619
|
-
import { existsSync as
|
|
620
|
-
var pyParser = new Parser2();
|
|
621
|
-
pyParser.setLanguage(Python);
|
|
655
|
+
import { existsSync as existsSync3 } from "fs";
|
|
622
656
|
function parsePythonFile(filePath, sourceCode, projectRoot) {
|
|
623
|
-
const
|
|
657
|
+
const parser = getParser("python");
|
|
658
|
+
const tree = parser.parse(sourceCode, null, { bufferSize: 1024 * 1024 });
|
|
624
659
|
const context = {
|
|
625
660
|
filePath,
|
|
626
661
|
projectRoot,
|
|
@@ -907,13 +942,13 @@ function resolveImportPath2(moduleName, currentFile, projectRoot) {
|
|
|
907
942
|
join3(targetDir, modulePath2, "__init__.py")
|
|
908
943
|
];
|
|
909
944
|
for (const candidate of candidates2) {
|
|
910
|
-
if (
|
|
945
|
+
if (existsSync3(candidate)) {
|
|
911
946
|
return candidate.substring(projectRoot.length + 1);
|
|
912
947
|
}
|
|
913
948
|
}
|
|
914
949
|
} else {
|
|
915
950
|
const initPath = join3(targetDir, "__init__.py");
|
|
916
|
-
if (
|
|
951
|
+
if (existsSync3(initPath)) {
|
|
917
952
|
return initPath.substring(projectRoot.length + 1);
|
|
918
953
|
}
|
|
919
954
|
}
|
|
@@ -925,7 +960,7 @@ function resolveImportPath2(moduleName, currentFile, projectRoot) {
|
|
|
925
960
|
join3(projectRoot, modulePath, "__init__.py")
|
|
926
961
|
];
|
|
927
962
|
for (const candidate of candidates) {
|
|
928
|
-
if (
|
|
963
|
+
if (existsSync3(candidate)) {
|
|
929
964
|
return candidate.substring(projectRoot.length + 1);
|
|
930
965
|
}
|
|
931
966
|
}
|
|
@@ -982,14 +1017,11 @@ var pythonParser = {
|
|
|
982
1017
|
};
|
|
983
1018
|
|
|
984
1019
|
// src/parser/javascript.ts
|
|
985
|
-
import
|
|
986
|
-
import JavaScript from "tree-sitter-javascript";
|
|
987
|
-
import { existsSync as existsSync3 } from "fs";
|
|
1020
|
+
import { existsSync as existsSync4 } from "fs";
|
|
988
1021
|
import { join as join4, dirname as dirname3, extname as extname2 } from "path";
|
|
989
|
-
var jsParser = new Parser3();
|
|
990
|
-
jsParser.setLanguage(JavaScript);
|
|
991
1022
|
function parseJavaScriptFile(filePath, sourceCode, projectRoot) {
|
|
992
|
-
const
|
|
1023
|
+
const parser = getParser("javascript");
|
|
1024
|
+
const tree = parser.parse(sourceCode, null, { bufferSize: 1024 * 1024 });
|
|
993
1025
|
const context = {
|
|
994
1026
|
filePath,
|
|
995
1027
|
projectRoot,
|
|
@@ -1402,20 +1434,20 @@ function resolveJavaScriptImport(importPath, currentFile, projectRoot) {
|
|
|
1402
1434
|
const indexFiles = ["index.js", "index.jsx", "index.mjs"];
|
|
1403
1435
|
if (extname2(importPath)) {
|
|
1404
1436
|
const fullPath = targetPath;
|
|
1405
|
-
if (
|
|
1437
|
+
if (existsSync4(fullPath)) {
|
|
1406
1438
|
return fullPath.substring(projectRoot.length + 1);
|
|
1407
1439
|
}
|
|
1408
1440
|
return null;
|
|
1409
1441
|
}
|
|
1410
1442
|
for (const ext of extensions) {
|
|
1411
1443
|
const candidate = `${targetPath}${ext}`;
|
|
1412
|
-
if (
|
|
1444
|
+
if (existsSync4(candidate)) {
|
|
1413
1445
|
return candidate.substring(projectRoot.length + 1);
|
|
1414
1446
|
}
|
|
1415
1447
|
}
|
|
1416
1448
|
for (const indexFile of indexFiles) {
|
|
1417
1449
|
const candidate = join4(targetPath, indexFile);
|
|
1418
|
-
if (
|
|
1450
|
+
if (existsSync4(candidate)) {
|
|
1419
1451
|
return candidate.substring(projectRoot.length + 1);
|
|
1420
1452
|
}
|
|
1421
1453
|
}
|
|
@@ -1486,13 +1518,10 @@ var javascriptParser = {
|
|
|
1486
1518
|
};
|
|
1487
1519
|
|
|
1488
1520
|
// src/parser/go.ts
|
|
1489
|
-
import
|
|
1490
|
-
import Go from "tree-sitter-go";
|
|
1491
|
-
import { existsSync as existsSync4, readFileSync as readFileSync2, readdirSync as readdirSync2 } from "fs";
|
|
1521
|
+
import { existsSync as existsSync5, readFileSync as readFileSync2, readdirSync as readdirSync2 } from "fs";
|
|
1492
1522
|
import { join as join5, dirname as dirname4 } from "path";
|
|
1493
|
-
var parser = new Parser4();
|
|
1494
|
-
parser.setLanguage(Go);
|
|
1495
1523
|
function parseGoFile(filePath, sourceCode, projectRoot) {
|
|
1524
|
+
const parser = getParser("go");
|
|
1496
1525
|
const tree = parser.parse(sourceCode, null, { bufferSize: 1024 * 1024 });
|
|
1497
1526
|
const moduleName = readGoModuleName(projectRoot);
|
|
1498
1527
|
const context = {
|
|
@@ -1773,7 +1802,7 @@ function readGoModuleName(projectRoot) {
|
|
|
1773
1802
|
let currentDir = projectRoot;
|
|
1774
1803
|
for (let i = 0; i < 5; i++) {
|
|
1775
1804
|
const goModPath = join5(currentDir, "go.mod");
|
|
1776
|
-
if (
|
|
1805
|
+
if (existsSync5(goModPath)) {
|
|
1777
1806
|
try {
|
|
1778
1807
|
const content = readFileSync2(goModPath, "utf-8");
|
|
1779
1808
|
const lines = content.split("\n");
|
|
@@ -1804,13 +1833,13 @@ function resolveGoImport(importPath, projectRoot, moduleName) {
|
|
|
1804
1833
|
}
|
|
1805
1834
|
const segments = importPath.split("/");
|
|
1806
1835
|
const packageDir = join5(projectRoot, ...segments);
|
|
1807
|
-
if (
|
|
1836
|
+
if (existsSync5(packageDir)) {
|
|
1808
1837
|
return findGoFilesInDir(packageDir, projectRoot);
|
|
1809
1838
|
}
|
|
1810
1839
|
return [];
|
|
1811
1840
|
}
|
|
1812
1841
|
function findGoFilesInDir(dir, projectRoot) {
|
|
1813
|
-
if (!
|
|
1842
|
+
if (!existsSync5(dir)) return [];
|
|
1814
1843
|
try {
|
|
1815
1844
|
const files = readdirSync2(dir);
|
|
1816
1845
|
const goFiles = files.filter((f) => f.endsWith(".go") && !f.endsWith("_test.go"));
|
|
@@ -1938,7 +1967,8 @@ function shouldParseFile(fullPath) {
|
|
|
1938
1967
|
return false;
|
|
1939
1968
|
}
|
|
1940
1969
|
}
|
|
1941
|
-
function parseProject(projectRoot, options) {
|
|
1970
|
+
async function parseProject(projectRoot, options) {
|
|
1971
|
+
await initParser();
|
|
1942
1972
|
const files = scanDirectory(projectRoot);
|
|
1943
1973
|
const parsedFiles = [];
|
|
1944
1974
|
let skippedFiles = 0;
|
|
@@ -1965,14 +1995,14 @@ function parseProject(projectRoot, options) {
|
|
|
1965
1995
|
if (options?.verbose) {
|
|
1966
1996
|
console.error(`[Parser] Parsing: ${file}`);
|
|
1967
1997
|
}
|
|
1968
|
-
const
|
|
1969
|
-
if (!
|
|
1998
|
+
const parser = getParserForFile(file);
|
|
1999
|
+
if (!parser) {
|
|
1970
2000
|
console.error(`No parser found for file: ${file}`);
|
|
1971
2001
|
skippedFiles++;
|
|
1972
2002
|
continue;
|
|
1973
2003
|
}
|
|
1974
2004
|
const sourceCode = readFileSync3(fullPath, "utf-8");
|
|
1975
|
-
const parsed =
|
|
2005
|
+
const parsed = parser.parseFile(file, sourceCode, projectRoot);
|
|
1976
2006
|
parsedFiles.push(parsed);
|
|
1977
2007
|
} catch (err) {
|
|
1978
2008
|
errorFiles++;
|
|
@@ -2397,10 +2427,10 @@ function watchProject(projectRoot, callbacks) {
|
|
|
2397
2427
|
// src/viz/server.ts
|
|
2398
2428
|
import express from "express";
|
|
2399
2429
|
import open from "open";
|
|
2400
|
-
import { fileURLToPath } from "url";
|
|
2430
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2401
2431
|
import { dirname as dirname5, join as join7 } from "path";
|
|
2402
2432
|
import { WebSocketServer } from "ws";
|
|
2403
|
-
var __filename =
|
|
2433
|
+
var __filename = fileURLToPath2(import.meta.url);
|
|
2404
2434
|
var __dirname2 = dirname5(__filename);
|
|
2405
2435
|
var activeServer = null;
|
|
2406
2436
|
async function findAvailablePort(startPort, maxAttempts = 10) {
|
|
@@ -2473,7 +2503,7 @@ Depwire visualization running at ${url2}`);
|
|
|
2473
2503
|
onFileChanged: async (filePath) => {
|
|
2474
2504
|
console.error(`File changed: ${filePath} \u2014 re-parsing project...`);
|
|
2475
2505
|
try {
|
|
2476
|
-
const parsedFiles = parseProject(projectRoot, options);
|
|
2506
|
+
const parsedFiles = await parseProject(projectRoot, options);
|
|
2477
2507
|
const newGraph = buildGraph(parsedFiles);
|
|
2478
2508
|
graph.clear();
|
|
2479
2509
|
newGraph.forEachNode((node, attrs) => {
|
|
@@ -2492,7 +2522,7 @@ Depwire visualization running at ${url2}`);
|
|
|
2492
2522
|
onFileAdded: async (filePath) => {
|
|
2493
2523
|
console.error(`File added: ${filePath} \u2014 re-parsing project...`);
|
|
2494
2524
|
try {
|
|
2495
|
-
const parsedFiles = parseProject(projectRoot, options);
|
|
2525
|
+
const parsedFiles = await parseProject(projectRoot, options);
|
|
2496
2526
|
const newGraph = buildGraph(parsedFiles);
|
|
2497
2527
|
graph.clear();
|
|
2498
2528
|
newGraph.forEachNode((node, attrs) => {
|
|
@@ -2508,10 +2538,10 @@ Depwire visualization running at ${url2}`);
|
|
|
2508
2538
|
console.error(`Failed to update graph for ${filePath}:`, error);
|
|
2509
2539
|
}
|
|
2510
2540
|
},
|
|
2511
|
-
onFileDeleted: (filePath) => {
|
|
2541
|
+
onFileDeleted: async (filePath) => {
|
|
2512
2542
|
console.error(`File deleted: ${filePath} \u2014 re-parsing project...`);
|
|
2513
2543
|
try {
|
|
2514
|
-
const parsedFiles = parseProject(projectRoot, options);
|
|
2544
|
+
const parsedFiles = await parseProject(projectRoot, options);
|
|
2515
2545
|
const newGraph = buildGraph(parsedFiles);
|
|
2516
2546
|
graph.clear();
|
|
2517
2547
|
newGraph.forEachNode((node, attrs) => {
|
|
@@ -2609,7 +2639,7 @@ async function updateFileInGraph(graph, projectRoot, relativeFilePath) {
|
|
|
2609
2639
|
}
|
|
2610
2640
|
|
|
2611
2641
|
// src/docs/generator.ts
|
|
2612
|
-
import { writeFileSync as writeFileSync2, mkdirSync, existsSync as
|
|
2642
|
+
import { writeFileSync as writeFileSync2, mkdirSync, existsSync as existsSync7 } from "fs";
|
|
2613
2643
|
import { join as join10 } from "path";
|
|
2614
2644
|
|
|
2615
2645
|
// src/docs/architecture.ts
|
|
@@ -2725,7 +2755,7 @@ function generateProjectSummary(graph, parseTime) {
|
|
|
2725
2755
|
const fileCount = getFileCount(graph);
|
|
2726
2756
|
const symbolCount = graph.order;
|
|
2727
2757
|
const edgeCount = graph.size;
|
|
2728
|
-
const
|
|
2758
|
+
const languages2 = getLanguageStats(graph);
|
|
2729
2759
|
let output = "";
|
|
2730
2760
|
output += `- **Total Files:** ${formatNumber(fileCount)}
|
|
2731
2761
|
`;
|
|
@@ -2735,10 +2765,10 @@ function generateProjectSummary(graph, parseTime) {
|
|
|
2735
2765
|
`;
|
|
2736
2766
|
output += `- **Parse Time:** ${parseTime.toFixed(1)}s
|
|
2737
2767
|
`;
|
|
2738
|
-
if (Object.keys(
|
|
2768
|
+
if (Object.keys(languages2).length > 1) {
|
|
2739
2769
|
output += "\n**Languages:**\n\n";
|
|
2740
2770
|
const totalFiles = fileCount;
|
|
2741
|
-
for (const [lang, count] of Object.entries(
|
|
2771
|
+
for (const [lang, count] of Object.entries(languages2).sort((a, b) => b[1] - a[1])) {
|
|
2742
2772
|
output += `- ${lang}: ${count} files (${formatPercent(count, totalFiles)})
|
|
2743
2773
|
`;
|
|
2744
2774
|
}
|
|
@@ -3657,20 +3687,20 @@ function findLongestPaths(graph, limit) {
|
|
|
3657
3687
|
}
|
|
3658
3688
|
const allPaths = [];
|
|
3659
3689
|
const visited = /* @__PURE__ */ new Set();
|
|
3660
|
-
function dfs(file,
|
|
3690
|
+
function dfs(file, path2) {
|
|
3661
3691
|
visited.add(file);
|
|
3662
|
-
|
|
3692
|
+
path2.push(file);
|
|
3663
3693
|
const neighbors = fileGraph.get(file);
|
|
3664
3694
|
if (!neighbors || neighbors.size === 0) {
|
|
3665
|
-
allPaths.push([...
|
|
3695
|
+
allPaths.push([...path2]);
|
|
3666
3696
|
} else {
|
|
3667
3697
|
for (const neighbor of neighbors) {
|
|
3668
3698
|
if (!visited.has(neighbor)) {
|
|
3669
|
-
dfs(neighbor,
|
|
3699
|
+
dfs(neighbor, path2);
|
|
3670
3700
|
}
|
|
3671
3701
|
}
|
|
3672
3702
|
}
|
|
3673
|
-
|
|
3703
|
+
path2.pop();
|
|
3674
3704
|
visited.delete(file);
|
|
3675
3705
|
}
|
|
3676
3706
|
for (const root of roots.slice(0, 10)) {
|
|
@@ -3841,8 +3871,8 @@ function getLanguageStats2(graph) {
|
|
|
3841
3871
|
}
|
|
3842
3872
|
function generateQuickOrientation(graph) {
|
|
3843
3873
|
const fileCount = getFileCount4(graph);
|
|
3844
|
-
const
|
|
3845
|
-
const primaryLang = Object.entries(
|
|
3874
|
+
const languages2 = getLanguageStats2(graph);
|
|
3875
|
+
const primaryLang = Object.entries(languages2).sort((a, b) => b[1] - a[1])[0];
|
|
3846
3876
|
const dirs = /* @__PURE__ */ new Set();
|
|
3847
3877
|
graph.forEachNode((node, attrs) => {
|
|
3848
3878
|
const dir = dirname7(attrs.filePath);
|
|
@@ -4174,11 +4204,11 @@ function generateDepwireUsage(projectRoot) {
|
|
|
4174
4204
|
}
|
|
4175
4205
|
|
|
4176
4206
|
// src/docs/metadata.ts
|
|
4177
|
-
import { existsSync as
|
|
4207
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync } from "fs";
|
|
4178
4208
|
import { join as join9 } from "path";
|
|
4179
4209
|
function loadMetadata(outputDir) {
|
|
4180
4210
|
const metadataPath = join9(outputDir, "metadata.json");
|
|
4181
|
-
if (!
|
|
4211
|
+
if (!existsSync6(metadataPath)) {
|
|
4182
4212
|
return null;
|
|
4183
4213
|
}
|
|
4184
4214
|
try {
|
|
@@ -4233,7 +4263,7 @@ async function generateDocs(graph, projectRoot, version, parseTime, options) {
|
|
|
4233
4263
|
const generated = [];
|
|
4234
4264
|
const errors = [];
|
|
4235
4265
|
try {
|
|
4236
|
-
if (!
|
|
4266
|
+
if (!existsSync7(options.outputDir)) {
|
|
4237
4267
|
mkdirSync(options.outputDir, { recursive: true });
|
|
4238
4268
|
if (options.verbose) {
|
|
4239
4269
|
console.log(`Created output directory: ${options.outputDir}`);
|
|
@@ -4340,11 +4370,11 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4340
4370
|
|
|
4341
4371
|
// src/mcp/tools.ts
|
|
4342
4372
|
import { dirname as dirname8, join as join12 } from "path";
|
|
4343
|
-
import { existsSync as
|
|
4373
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "fs";
|
|
4344
4374
|
|
|
4345
4375
|
// src/mcp/connect.ts
|
|
4346
4376
|
import simpleGit from "simple-git";
|
|
4347
|
-
import { existsSync as
|
|
4377
|
+
import { existsSync as existsSync8 } from "fs";
|
|
4348
4378
|
import { join as join11, basename as basename3, resolve as resolve2 } from "path";
|
|
4349
4379
|
import { tmpdir, homedir } from "os";
|
|
4350
4380
|
function validateProjectPath(source) {
|
|
@@ -4389,7 +4419,7 @@ async function connectToRepo(source, subdirectory, state) {
|
|
|
4389
4419
|
const cloneDir = join11(reposDir, projectName);
|
|
4390
4420
|
console.error(`Connecting to GitHub repo: ${source}`);
|
|
4391
4421
|
const git = simpleGit();
|
|
4392
|
-
if (
|
|
4422
|
+
if (existsSync8(cloneDir)) {
|
|
4393
4423
|
console.error(`Repo already cloned at ${cloneDir}, pulling latest changes...`);
|
|
4394
4424
|
try {
|
|
4395
4425
|
await git.cwd(cloneDir).pull();
|
|
@@ -4416,7 +4446,7 @@ async function connectToRepo(source, subdirectory, state) {
|
|
|
4416
4446
|
message: validation2.error
|
|
4417
4447
|
};
|
|
4418
4448
|
}
|
|
4419
|
-
if (!
|
|
4449
|
+
if (!existsSync8(source)) {
|
|
4420
4450
|
return {
|
|
4421
4451
|
error: "Directory not found",
|
|
4422
4452
|
message: `Directory does not exist: ${source}`
|
|
@@ -4432,7 +4462,7 @@ async function connectToRepo(source, subdirectory, state) {
|
|
|
4432
4462
|
message: validation.error
|
|
4433
4463
|
};
|
|
4434
4464
|
}
|
|
4435
|
-
if (!
|
|
4465
|
+
if (!existsSync8(projectRoot)) {
|
|
4436
4466
|
return {
|
|
4437
4467
|
error: "Project root not found",
|
|
4438
4468
|
message: `Directory does not exist: ${projectRoot}`
|
|
@@ -5175,7 +5205,7 @@ The server will keep running until you end the MCP session or press Ctrl+C.`;
|
|
|
5175
5205
|
}
|
|
5176
5206
|
async function handleGetProjectDocs(docType, state) {
|
|
5177
5207
|
const docsDir = join12(state.projectRoot, ".depwire");
|
|
5178
|
-
if (!
|
|
5208
|
+
if (!existsSync9(docsDir)) {
|
|
5179
5209
|
const errorMessage = `Project documentation has not been generated yet.
|
|
5180
5210
|
|
|
5181
5211
|
Run \`depwire docs ${state.projectRoot}\` to generate codebase documentation.
|
|
@@ -5206,7 +5236,7 @@ Available document types:
|
|
|
5206
5236
|
continue;
|
|
5207
5237
|
}
|
|
5208
5238
|
const filePath = join12(docsDir, metadata.documents[doc].file);
|
|
5209
|
-
if (!
|
|
5239
|
+
if (!existsSync9(filePath)) {
|
|
5210
5240
|
missing.push(doc);
|
|
5211
5241
|
continue;
|
|
5212
5242
|
}
|
|
@@ -5237,14 +5267,14 @@ async function handleUpdateProjectDocs(docType, state) {
|
|
|
5237
5267
|
const startTime = Date.now();
|
|
5238
5268
|
const docsDir = join12(state.projectRoot, ".depwire");
|
|
5239
5269
|
console.error("Regenerating project documentation...");
|
|
5240
|
-
const parsedFiles = parseProject(state.projectRoot);
|
|
5270
|
+
const parsedFiles = await parseProject(state.projectRoot);
|
|
5241
5271
|
const graph = buildGraph(parsedFiles);
|
|
5242
5272
|
const parseTime = (Date.now() - startTime) / 1e3;
|
|
5243
5273
|
state.graph = graph;
|
|
5244
5274
|
const packageJsonPath = join12(__dirname, "../../package.json");
|
|
5245
5275
|
const packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf-8"));
|
|
5246
5276
|
const docsToGenerate = docType === "all" ? ["architecture", "conventions", "dependencies", "onboarding"] : [docType];
|
|
5247
|
-
const docsExist =
|
|
5277
|
+
const docsExist = existsSync9(docsDir);
|
|
5248
5278
|
const result = await generateDocs(graph, state.projectRoot, packageJson.version, parseTime, {
|
|
5249
5279
|
outputDir: docsDir,
|
|
5250
5280
|
format: "markdown",
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
startVizServer,
|
|
13
13
|
updateFileInGraph,
|
|
14
14
|
watchProject
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-X2DOGIIG.js";
|
|
16
16
|
|
|
17
17
|
// src/index.ts
|
|
18
18
|
import { Command } from "commander";
|
|
@@ -100,7 +100,7 @@ program.command("parse").description("Parse a TypeScript project and build depen
|
|
|
100
100
|
try {
|
|
101
101
|
const projectRoot = resolve(directory);
|
|
102
102
|
console.log(`Parsing project: ${projectRoot}`);
|
|
103
|
-
const parsedFiles = parseProject(projectRoot, {
|
|
103
|
+
const parsedFiles = await parseProject(projectRoot, {
|
|
104
104
|
exclude: options.exclude,
|
|
105
105
|
verbose: options.verbose
|
|
106
106
|
});
|
|
@@ -145,7 +145,7 @@ program.command("query").description("Query impact analysis for a symbol").argum
|
|
|
145
145
|
graph = importFromJSON(json);
|
|
146
146
|
} else {
|
|
147
147
|
console.log("Parsing project...");
|
|
148
|
-
const parsedFiles = parseProject(projectRoot);
|
|
148
|
+
const parsedFiles = await parseProject(projectRoot);
|
|
149
149
|
graph = buildGraph(parsedFiles);
|
|
150
150
|
}
|
|
151
151
|
const matches = searchSymbols(graph, symbolName);
|
|
@@ -186,7 +186,7 @@ program.command("viz").description("Launch interactive arc diagram visualization
|
|
|
186
186
|
try {
|
|
187
187
|
const projectRoot = resolve(directory);
|
|
188
188
|
console.log(`Parsing project: ${projectRoot}`);
|
|
189
|
-
const parsedFiles = parseProject(projectRoot, {
|
|
189
|
+
const parsedFiles = await parseProject(projectRoot, {
|
|
190
190
|
exclude: options.exclude,
|
|
191
191
|
verbose: options.verbose
|
|
192
192
|
});
|
|
@@ -210,7 +210,7 @@ program.command("mcp").description("Start MCP server for AI coding tools").argum
|
|
|
210
210
|
if (directory) {
|
|
211
211
|
const projectRoot = resolve(directory);
|
|
212
212
|
console.error(`Parsing project: ${projectRoot}`);
|
|
213
|
-
const parsedFiles = parseProject(projectRoot);
|
|
213
|
+
const parsedFiles = await parseProject(projectRoot);
|
|
214
214
|
console.error(`Parsed ${parsedFiles.length} files`);
|
|
215
215
|
const graph = buildGraph(parsedFiles);
|
|
216
216
|
console.error(`Built graph: ${graph.order} symbols, ${graph.size} edges`);
|
|
@@ -273,7 +273,7 @@ program.command("docs").description("Generate comprehensive codebase documentati
|
|
|
273
273
|
addToGitignore(projectRoot, ".depwire/");
|
|
274
274
|
}
|
|
275
275
|
console.log(`Parsing project: ${projectRoot}`);
|
|
276
|
-
const parsedFiles = parseProject(projectRoot, {
|
|
276
|
+
const parsedFiles = await parseProject(projectRoot, {
|
|
277
277
|
exclude: options.exclude,
|
|
278
278
|
verbose: options.verbose
|
|
279
279
|
});
|
package/dist/mcpb-entry.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
startMcpServer,
|
|
7
7
|
updateFileInGraph,
|
|
8
8
|
watchProject
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-X2DOGIIG.js";
|
|
10
10
|
|
|
11
11
|
// src/mcpb-entry.ts
|
|
12
12
|
import { resolve } from "path";
|
|
@@ -17,7 +17,7 @@ async function main() {
|
|
|
17
17
|
try {
|
|
18
18
|
const projectRoot = resolve(projectPath);
|
|
19
19
|
console.error(`[MCPB] Parsing project: ${projectRoot}`);
|
|
20
|
-
const parsedFiles = parseProject(projectRoot);
|
|
20
|
+
const parsedFiles = await parseProject(projectRoot);
|
|
21
21
|
console.error(`[MCPB] Parsed ${parsedFiles.length} files`);
|
|
22
22
|
const graph = buildGraph(parsedFiles);
|
|
23
23
|
console.error(`[MCPB] Built graph: ${graph.order} symbols, ${graph.size} edges`);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "depwire-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Code cross-reference visualization and AI context engine for TypeScript
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Code cross-reference visualization and AI context engine for TypeScript, JavaScript, Python, and Go. Zero native dependencies — works on Windows, macOS, and Linux.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"depwire": "dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsup src/index.ts src/mcpb-entry.ts --format esm --dts --clean && npm run copy-static",
|
|
11
|
-
"copy-static": "mkdir -p dist/viz/public && cp -r src/viz/public/* dist/viz/public/",
|
|
11
|
+
"copy-static": "mkdir -p dist/viz/public dist/parser/grammars && cp -r src/viz/public/* dist/viz/public/ && cp src/parser/grammars/*.wasm dist/parser/grammars/",
|
|
12
12
|
"dev": "tsup src/index.ts --format esm --watch",
|
|
13
13
|
"start": "node dist/index.js",
|
|
14
14
|
"build:mcpb": "npm run build && ./scripts/build-mcpb.sh"
|
|
@@ -59,11 +59,7 @@
|
|
|
59
59
|
"minimatch": "^10.2.4",
|
|
60
60
|
"open": "11.0.0",
|
|
61
61
|
"simple-git": "3.31.1",
|
|
62
|
-
"tree-sitter": "0.
|
|
63
|
-
"tree-sitter-go": "0.21.2",
|
|
64
|
-
"tree-sitter-javascript": "0.21.4",
|
|
65
|
-
"tree-sitter-python": "0.21.0",
|
|
66
|
-
"tree-sitter-typescript": "0.23.2",
|
|
62
|
+
"web-tree-sitter": "^0.26.6",
|
|
67
63
|
"ws": "8.19.0",
|
|
68
64
|
"zod": "4.3.6"
|
|
69
65
|
},
|