depwire-cli 0.9.9 → 0.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/{chunk-VVYRHPAE.js → chunk-S3NZMIIU.js} +40 -7
- package/dist/index.js +1 -1
- package/dist/mcpb-entry.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -401,7 +401,7 @@ depwire docs --output ./docs
|
|
|
401
401
|
depwire docs --update --only conventions
|
|
402
402
|
```
|
|
403
403
|
|
|
404
|
-
**Generated Documents (
|
|
404
|
+
**Generated Documents (13 total):**
|
|
405
405
|
|
|
406
406
|
| Document | What It Contains |
|
|
407
407
|
|----------|------------------|
|
|
@@ -417,7 +417,7 @@ depwire docs --update --only conventions
|
|
|
417
417
|
| `CURRENT.md` | Complete codebase snapshot (every file, symbol, connection) |
|
|
418
418
|
| `STATUS.md` | TODO/FIXME/HACK inventory with priority matrix |
|
|
419
419
|
| `HEALTH.md` | Dependency health score (0-100) across 6 dimensions with recommendations |
|
|
420
|
-
| `DEAD_CODE.md` |
|
|
420
|
+
| `DEAD_CODE.md` | Unused symbols by confidence level (high/medium/low) with smart exclusions |
|
|
421
421
|
|
|
422
422
|
Documents are stored in `.depwire/` with `metadata.json` tracking generation timestamps for staleness detection.
|
|
423
423
|
|
|
@@ -625,7 +625,7 @@ See [SECURITY.md](SECURITY.md) for full details.
|
|
|
625
625
|
- [x] WASM migration (Windows support)
|
|
626
626
|
|
|
627
627
|
### 🔜 Coming Next
|
|
628
|
-
- [ ] New language support (C — community requested)
|
|
628
|
+
- [ ] New language support (Java, C++, Ruby — community requested)
|
|
629
629
|
- [ ] "What If" simulation — simulate refactors before touching code
|
|
630
630
|
- [ ] Cross-language edge detection (API routes ↔ frontend calls)
|
|
631
631
|
- [ ] Cloud dashboard (first paid feature)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/utils/files.ts
|
|
2
2
|
import { readdirSync, statSync, existsSync, lstatSync } from "fs";
|
|
3
3
|
import { join, relative } from "path";
|
|
4
|
+
import os from "os";
|
|
4
5
|
function scanDirectory(rootDir, baseDir = rootDir) {
|
|
5
6
|
const files = [];
|
|
6
7
|
try {
|
|
@@ -71,9 +72,21 @@ function findProjectRoot(startDir = process.cwd()) {
|
|
|
71
72
|
".git"
|
|
72
73
|
// Any git repo
|
|
73
74
|
];
|
|
75
|
+
const blocklist = ["Library", "System", "Applications", "usr", "bin", "etc", "var", "private"];
|
|
74
76
|
let currentDir = startDir;
|
|
75
77
|
const rootDir = "/";
|
|
76
|
-
|
|
78
|
+
const maxDepth = 10;
|
|
79
|
+
let depth = 0;
|
|
80
|
+
const home = os.homedir();
|
|
81
|
+
while (currentDir !== rootDir && depth < maxDepth) {
|
|
82
|
+
if (currentDir === home || !currentDir.startsWith(home)) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
const dirName = currentDir.split("/").pop();
|
|
86
|
+
if (dirName && blocklist.includes(dirName)) {
|
|
87
|
+
console.warn(`\u26A0\uFE0F Skipping blocked directory: ${dirName}`);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
77
90
|
for (const marker of projectMarkers) {
|
|
78
91
|
const markerPath = join(currentDir, marker);
|
|
79
92
|
if (existsSync(markerPath)) {
|
|
@@ -85,7 +98,9 @@ function findProjectRoot(startDir = process.cwd()) {
|
|
|
85
98
|
break;
|
|
86
99
|
}
|
|
87
100
|
currentDir = parentDir;
|
|
101
|
+
depth++;
|
|
88
102
|
}
|
|
103
|
+
console.warn(`\u26A0\uFE0F No project root found within ${maxDepth} levels. Using current directory: ${startDir}`);
|
|
89
104
|
return startDir;
|
|
90
105
|
}
|
|
91
106
|
|
|
@@ -9211,6 +9226,10 @@ function getToolsList() {
|
|
|
9211
9226
|
symbol: {
|
|
9212
9227
|
type: "string",
|
|
9213
9228
|
description: "Symbol name (e.g., 'Router') or full ID (e.g., 'src/router.ts::Router')"
|
|
9229
|
+
},
|
|
9230
|
+
file: {
|
|
9231
|
+
type: "string",
|
|
9232
|
+
description: "Optional: File path to disambiguate when multiple symbols have the same name (e.g., 'src/router.ts')"
|
|
9214
9233
|
}
|
|
9215
9234
|
},
|
|
9216
9235
|
required: ["symbol"]
|
|
@@ -9442,7 +9461,7 @@ async function handleToolCall(name, args, state) {
|
|
|
9442
9461
|
result = handleGetDependents(args.symbol, graph);
|
|
9443
9462
|
break;
|
|
9444
9463
|
case "impact_analysis":
|
|
9445
|
-
result = handleImpactAnalysis(args.symbol, graph);
|
|
9464
|
+
result = handleImpactAnalysis(args.symbol, graph, args.file);
|
|
9446
9465
|
break;
|
|
9447
9466
|
case "get_file_context":
|
|
9448
9467
|
result = handleGetFileContext(args.filePath, graph);
|
|
@@ -9502,9 +9521,12 @@ async function handleToolCall(name, args, state) {
|
|
|
9502
9521
|
}
|
|
9503
9522
|
function createDisambiguationResponse(matches, queryName) {
|
|
9504
9523
|
const suggestion = matches.length > 0 ? matches[0].id : "";
|
|
9524
|
+
const exampleFile = matches.length > 0 ? matches[0].filePath : "";
|
|
9505
9525
|
return {
|
|
9506
9526
|
ambiguous: true,
|
|
9507
|
-
message: `Found ${matches.length} symbols named '${queryName}'.
|
|
9527
|
+
message: `Found ${matches.length} symbols named '${queryName}'. Disambiguate by:
|
|
9528
|
+
1. Using full ID: '${suggestion}'
|
|
9529
|
+
2. Or adding file parameter: { symbol: '${queryName}', file: '${exampleFile}' }`,
|
|
9508
9530
|
matches: matches.map((m, index) => ({
|
|
9509
9531
|
id: m.id,
|
|
9510
9532
|
kind: m.kind,
|
|
@@ -9614,7 +9636,7 @@ function handleGetDependents(symbol, graph) {
|
|
|
9614
9636
|
totalCount
|
|
9615
9637
|
};
|
|
9616
9638
|
}
|
|
9617
|
-
function handleImpactAnalysis(symbol, graph) {
|
|
9639
|
+
function handleImpactAnalysis(symbol, graph, file) {
|
|
9618
9640
|
const matches = findSymbols(graph, symbol);
|
|
9619
9641
|
if (matches.length === 0) {
|
|
9620
9642
|
const fuzzyMatches = searchSymbols(graph, symbol).slice(0, 10);
|
|
@@ -9623,10 +9645,21 @@ function handleImpactAnalysis(symbol, graph) {
|
|
|
9623
9645
|
suggestion: fuzzyMatches.length > 0 ? `Did you mean: ${fuzzyMatches.map((m) => m.name).join(", ")}?` : "Try using search_symbols to find available symbols"
|
|
9624
9646
|
};
|
|
9625
9647
|
}
|
|
9626
|
-
|
|
9627
|
-
|
|
9648
|
+
let filteredMatches = matches;
|
|
9649
|
+
if (file) {
|
|
9650
|
+
filteredMatches = matches.filter((m) => m.filePath === file || m.filePath.endsWith(file));
|
|
9651
|
+
if (filteredMatches.length === 0) {
|
|
9652
|
+
return {
|
|
9653
|
+
error: `Symbol '${symbol}' not found in file '${file}'`,
|
|
9654
|
+
availableFiles: matches.map((m) => m.filePath),
|
|
9655
|
+
suggestion: `The symbol exists in: ${matches.map((m) => m.filePath).join(", ")}`
|
|
9656
|
+
};
|
|
9657
|
+
}
|
|
9628
9658
|
}
|
|
9629
|
-
|
|
9659
|
+
if (filteredMatches.length > 1) {
|
|
9660
|
+
return createDisambiguationResponse(filteredMatches, symbol);
|
|
9661
|
+
}
|
|
9662
|
+
const target = filteredMatches[0];
|
|
9630
9663
|
const impact = getImpact(graph, target.id);
|
|
9631
9664
|
const directWithKinds = impact.directDependents.map((dep) => {
|
|
9632
9665
|
let relationship = "unknown";
|
package/dist/index.js
CHANGED
package/dist/mcpb-entry.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "depwire-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.10",
|
|
4
4
|
"description": "Code cross-reference visualization and AI context engine for TypeScript, JavaScript, Python, Go, Rust, and C. Zero native dependencies — works on Windows, macOS, and Linux.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|