depwire-cli 0.9.1 → 0.9.3
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 -6
- package/dist/{chunk-UPAZDLUB.js → chunk-JICAYZUJ.js} +211 -53
- package/dist/index.js +4 -3
- package/dist/mcpb-entry.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
# Depwire
|
|
2
2
|
|
|
3
|
-
<p align="center">
|
|
4
|
-
<a href="https://glama.ai/mcp/servers/depwire/depwire">
|
|
5
|
-
<img width="380" height="200" src="https://glama.ai/mcp/servers/depwire/depwire/badge" alt="Depwire MCP server" />
|
|
6
|
-
</a>
|
|
7
|
-
</p>
|
|
8
|
-
|
|
9
3
|
<p align="center">
|
|
10
4
|
<a href="https://www.npmjs.com/package/depwire-cli">
|
|
11
5
|
<img src="https://img.shields.io/npm/v/depwire-cli.svg?style=flat-square" alt="npm version" />
|
|
@@ -13,6 +7,9 @@
|
|
|
13
7
|
<a href="https://www.npmjs.com/package/depwire-cli">
|
|
14
8
|
<img src="https://img.shields.io/npm/dm/depwire-cli.svg?style=flat-square" alt="npm downloads" />
|
|
15
9
|
</a>
|
|
10
|
+
<a href="https://glama.ai/mcp/servers/depwire/depwire">
|
|
11
|
+
<img src="https://glama.ai/mcp/servers/depwire/depwire/badges/score.svg" alt="depwire/depwire MCP server" />
|
|
12
|
+
</a>
|
|
16
13
|
<a href="LICENSE">
|
|
17
14
|
<img src="https://img.shields.io/badge/license-BUSL--1.1-blue.svg?style=flat-square" alt="License" />
|
|
18
15
|
</a>
|
|
@@ -3987,21 +3987,89 @@ function loadHealthHistory(projectRoot) {
|
|
|
3987
3987
|
|
|
3988
3988
|
// src/dead-code/detector.ts
|
|
3989
3989
|
import path2 from "path";
|
|
3990
|
-
|
|
3990
|
+
import { readFileSync as readFileSync7, existsSync as existsSync9 } from "fs";
|
|
3991
|
+
function findDeadSymbols(graph, projectRoot, includeTests = false, debug = false) {
|
|
3991
3992
|
const deadSymbols = [];
|
|
3992
3993
|
const context = { graph, projectRoot };
|
|
3994
|
+
const stats = {
|
|
3995
|
+
total: 0,
|
|
3996
|
+
excludedByTestFile: 0,
|
|
3997
|
+
excludedByEntryPoint: 0,
|
|
3998
|
+
excludedByConfigFile: 0,
|
|
3999
|
+
excludedByTypeDeclaration: 0,
|
|
4000
|
+
excludedByDefaultExport: 0,
|
|
4001
|
+
excludedByFrameworkDir: 0
|
|
4002
|
+
};
|
|
4003
|
+
const packageEntryPoints = getPackageEntryPoints(projectRoot);
|
|
4004
|
+
if (debug) {
|
|
4005
|
+
console.log("\n\u{1F50D} Debug: Graph Structure");
|
|
4006
|
+
console.log(`Total nodes in graph: ${graph.order}`);
|
|
4007
|
+
console.log(`Total edges in graph: ${graph.size}`);
|
|
4008
|
+
let nodesWithZeroInDegree = 0;
|
|
4009
|
+
let nodesWithZeroOutDegree = 0;
|
|
4010
|
+
graph.forEachNode((node) => {
|
|
4011
|
+
if (graph.inDegree(node) === 0) nodesWithZeroInDegree++;
|
|
4012
|
+
if (graph.outDegree(node) === 0) nodesWithZeroOutDegree++;
|
|
4013
|
+
});
|
|
4014
|
+
console.log(`Nodes with inDegree=0: ${nodesWithZeroInDegree}`);
|
|
4015
|
+
console.log(`Nodes with outDegree=0: ${nodesWithZeroOutDegree}`);
|
|
4016
|
+
if (nodesWithZeroInDegree <= 10) {
|
|
4017
|
+
console.log("\nSample nodes with inDegree=0:");
|
|
4018
|
+
let count = 0;
|
|
4019
|
+
graph.forEachNode((node) => {
|
|
4020
|
+
if (graph.inDegree(node) === 0 && count < 10) {
|
|
4021
|
+
const attrs = graph.getNodeAttributes(node);
|
|
4022
|
+
const filePath = attrs.file || attrs.filePath || "unknown";
|
|
4023
|
+
console.log(` - ${attrs.name} (${attrs.kind}) in ${path2.relative(projectRoot, filePath)}`);
|
|
4024
|
+
count++;
|
|
4025
|
+
}
|
|
4026
|
+
});
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
3993
4029
|
for (const node of graph.nodes()) {
|
|
3994
4030
|
const attrs = graph.getNodeAttributes(node);
|
|
3995
|
-
if (!attrs.
|
|
4031
|
+
if (!attrs.name) continue;
|
|
4032
|
+
if (!attrs.file && !attrs.filePath) {
|
|
4033
|
+
if (debug) {
|
|
4034
|
+
console.log(`Skipping node ${attrs.name} - no file attribute`);
|
|
4035
|
+
}
|
|
4036
|
+
continue;
|
|
4037
|
+
}
|
|
4038
|
+
const filePath = attrs.file || attrs.filePath;
|
|
4039
|
+
if (!isRelevantForDeadCodeDetection(attrs)) {
|
|
4040
|
+
continue;
|
|
4041
|
+
}
|
|
3996
4042
|
const inDegree = graph.inDegree(node);
|
|
3997
4043
|
if (inDegree === 0) {
|
|
3998
|
-
|
|
4044
|
+
stats.total++;
|
|
4045
|
+
const exclusionReason = shouldExclude(attrs, context, includeTests, packageEntryPoints);
|
|
4046
|
+
if (exclusionReason) {
|
|
4047
|
+
switch (exclusionReason) {
|
|
4048
|
+
case "test":
|
|
4049
|
+
stats.excludedByTestFile++;
|
|
4050
|
+
break;
|
|
4051
|
+
case "entry":
|
|
4052
|
+
stats.excludedByEntryPoint++;
|
|
4053
|
+
break;
|
|
4054
|
+
case "config":
|
|
4055
|
+
stats.excludedByConfigFile++;
|
|
4056
|
+
break;
|
|
4057
|
+
case "types":
|
|
4058
|
+
stats.excludedByTypeDeclaration++;
|
|
4059
|
+
break;
|
|
4060
|
+
case "default":
|
|
4061
|
+
stats.excludedByDefaultExport++;
|
|
4062
|
+
break;
|
|
4063
|
+
case "framework":
|
|
4064
|
+
stats.excludedByFrameworkDir++;
|
|
4065
|
+
break;
|
|
4066
|
+
}
|
|
3999
4067
|
continue;
|
|
4000
4068
|
}
|
|
4001
4069
|
deadSymbols.push({
|
|
4002
4070
|
name: attrs.name,
|
|
4003
4071
|
kind: attrs.kind || "unknown",
|
|
4004
|
-
file:
|
|
4072
|
+
file: filePath,
|
|
4005
4073
|
line: attrs.startLine || 0,
|
|
4006
4074
|
exported: attrs.exported || false,
|
|
4007
4075
|
dependents: 0,
|
|
@@ -4010,38 +4078,115 @@ function findDeadSymbols(graph, projectRoot, includeTests = false) {
|
|
|
4010
4078
|
});
|
|
4011
4079
|
}
|
|
4012
4080
|
}
|
|
4013
|
-
|
|
4081
|
+
if (debug) {
|
|
4082
|
+
console.log("\n\u{1F50D} Debug: Exclusion Statistics");
|
|
4083
|
+
console.log(`Total symbols with 0 incoming edges: ${stats.total}`);
|
|
4084
|
+
console.log(`Excluded by test file: ${stats.excludedByTestFile}`);
|
|
4085
|
+
console.log(`Excluded by entry point: ${stats.excludedByEntryPoint}`);
|
|
4086
|
+
console.log(`Excluded by config file: ${stats.excludedByConfigFile}`);
|
|
4087
|
+
console.log(`Excluded by type declaration: ${stats.excludedByTypeDeclaration}`);
|
|
4088
|
+
console.log(`Excluded by default export: ${stats.excludedByDefaultExport}`);
|
|
4089
|
+
console.log(`Excluded by framework dir: ${stats.excludedByFrameworkDir}`);
|
|
4090
|
+
console.log(`Remaining dead symbols: ${deadSymbols.length}
|
|
4091
|
+
`);
|
|
4092
|
+
}
|
|
4093
|
+
return { symbols: deadSymbols, stats };
|
|
4094
|
+
}
|
|
4095
|
+
function isRelevantForDeadCodeDetection(attrs) {
|
|
4096
|
+
const kind = attrs.kind;
|
|
4097
|
+
const relevantKinds = [
|
|
4098
|
+
"function",
|
|
4099
|
+
"class",
|
|
4100
|
+
"interface",
|
|
4101
|
+
"type",
|
|
4102
|
+
"enum",
|
|
4103
|
+
"const",
|
|
4104
|
+
"let",
|
|
4105
|
+
"var",
|
|
4106
|
+
"method",
|
|
4107
|
+
"property"
|
|
4108
|
+
];
|
|
4109
|
+
if (!relevantKinds.includes(kind)) {
|
|
4110
|
+
return false;
|
|
4111
|
+
}
|
|
4112
|
+
if (kind === "const" || kind === "let" || kind === "var" || kind === "variable") {
|
|
4113
|
+
return attrs.exported === true;
|
|
4114
|
+
}
|
|
4115
|
+
return true;
|
|
4116
|
+
}
|
|
4117
|
+
function getPackageEntryPoints(projectRoot) {
|
|
4118
|
+
const entryPoints = /* @__PURE__ */ new Set();
|
|
4119
|
+
const packageJsonPath = path2.join(projectRoot, "package.json");
|
|
4120
|
+
if (!existsSync9(packageJsonPath)) {
|
|
4121
|
+
return entryPoints;
|
|
4122
|
+
}
|
|
4123
|
+
try {
|
|
4124
|
+
const packageJson = JSON.parse(readFileSync7(packageJsonPath, "utf-8"));
|
|
4125
|
+
if (packageJson.main) {
|
|
4126
|
+
entryPoints.add(path2.resolve(projectRoot, packageJson.main));
|
|
4127
|
+
}
|
|
4128
|
+
if (packageJson.module) {
|
|
4129
|
+
entryPoints.add(path2.resolve(projectRoot, packageJson.module));
|
|
4130
|
+
}
|
|
4131
|
+
if (packageJson.exports) {
|
|
4132
|
+
const addExports = (exp) => {
|
|
4133
|
+
if (typeof exp === "string") {
|
|
4134
|
+
entryPoints.add(path2.resolve(projectRoot, exp));
|
|
4135
|
+
} else if (typeof exp === "object") {
|
|
4136
|
+
for (const key in exp) {
|
|
4137
|
+
if (typeof exp[key] === "string") {
|
|
4138
|
+
entryPoints.add(path2.resolve(projectRoot, exp[key]));
|
|
4139
|
+
} else if (typeof exp[key] === "object") {
|
|
4140
|
+
addExports(exp[key]);
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4144
|
+
};
|
|
4145
|
+
addExports(packageJson.exports);
|
|
4146
|
+
}
|
|
4147
|
+
} catch (e) {
|
|
4148
|
+
}
|
|
4149
|
+
return entryPoints;
|
|
4014
4150
|
}
|
|
4015
|
-
function shouldExclude(attrs, context, includeTests) {
|
|
4016
|
-
const filePath = attrs.file;
|
|
4151
|
+
function shouldExclude(attrs, context, includeTests, packageEntryPoints) {
|
|
4152
|
+
const filePath = attrs.file || attrs.filePath;
|
|
4153
|
+
if (!filePath) {
|
|
4154
|
+
return null;
|
|
4155
|
+
}
|
|
4017
4156
|
const relativePath = path2.relative(context.projectRoot, filePath);
|
|
4018
4157
|
if (!includeTests && isTestFile(relativePath)) {
|
|
4019
|
-
return
|
|
4158
|
+
return "test";
|
|
4020
4159
|
}
|
|
4021
|
-
if (
|
|
4022
|
-
return
|
|
4160
|
+
if (isRealPackageEntryPoint(filePath, packageEntryPoints)) {
|
|
4161
|
+
return "entry";
|
|
4023
4162
|
}
|
|
4024
4163
|
if (isConfigFile(relativePath)) {
|
|
4025
|
-
return
|
|
4164
|
+
return "config";
|
|
4026
4165
|
}
|
|
4027
4166
|
if (isTypeDeclarationFile(relativePath)) {
|
|
4028
|
-
return
|
|
4167
|
+
return "types";
|
|
4029
4168
|
}
|
|
4030
4169
|
if (attrs.kind === "default") {
|
|
4031
|
-
return
|
|
4170
|
+
return "default";
|
|
4032
4171
|
}
|
|
4033
4172
|
if (isFrameworkAutoLoadedFile(relativePath)) {
|
|
4034
|
-
return
|
|
4173
|
+
return "framework";
|
|
4174
|
+
}
|
|
4175
|
+
return null;
|
|
4176
|
+
}
|
|
4177
|
+
function isRealPackageEntryPoint(filePath, packageEntryPoints) {
|
|
4178
|
+
const normalizedPath = path2.normalize(filePath);
|
|
4179
|
+
for (const entryPoint of packageEntryPoints) {
|
|
4180
|
+
const normalizedEntry = path2.normalize(entryPoint);
|
|
4181
|
+
if (normalizedPath === normalizedEntry || normalizedPath === normalizedEntry.replace(/\.(js|ts)$/, ".ts") || normalizedPath === normalizedEntry.replace(/\.(js|ts)$/, ".js")) {
|
|
4182
|
+
return true;
|
|
4183
|
+
}
|
|
4035
4184
|
}
|
|
4036
4185
|
return false;
|
|
4037
4186
|
}
|
|
4038
4187
|
function isTestFile(filePath) {
|
|
4039
4188
|
return filePath.includes("__tests__/") || filePath.includes(".test.") || filePath.includes(".spec.") || filePath.includes("/test/") || filePath.includes("/tests/");
|
|
4040
4189
|
}
|
|
4041
|
-
function isEntryPoint(filePath) {
|
|
4042
|
-
const basename6 = path2.basename(filePath);
|
|
4043
|
-
return basename6 === "index.ts" || basename6 === "index.js" || basename6 === "main.ts" || basename6 === "main.js" || basename6 === "app.ts" || basename6 === "app.js" || basename6 === "server.ts" || basename6 === "server.js";
|
|
4044
|
-
}
|
|
4045
4190
|
function isConfigFile(filePath) {
|
|
4046
4191
|
return filePath.includes(".config.") || filePath.includes("config/") || filePath.includes("vite.config") || filePath.includes("rollup.config") || filePath.includes("webpack.config");
|
|
4047
4192
|
}
|
|
@@ -4192,17 +4337,24 @@ function displayConfidenceGroup(level, symbols, verbose, projectRoot) {
|
|
|
4192
4337
|
color.bold(`
|
|
4193
4338
|
${emoji} ${level} CONFIDENCE `) + chalk.gray(`(${level === "HIGH" ? "definitely" : level === "MEDIUM" ? "probably" : "might be"} dead)`)
|
|
4194
4339
|
);
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
const
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4340
|
+
if (verbose) {
|
|
4341
|
+
const headers = ["Symbol", "Kind", "File", "Reason"];
|
|
4342
|
+
const rows = symbols.map((symbol) => {
|
|
4343
|
+
const relativePath = path4.relative(projectRoot, symbol.file);
|
|
4344
|
+
return [
|
|
4345
|
+
chalk.bold(symbol.name),
|
|
4346
|
+
symbol.kind,
|
|
4347
|
+
`${relativePath}:${symbol.line}`,
|
|
4348
|
+
symbol.reason
|
|
4349
|
+
];
|
|
4350
|
+
});
|
|
4351
|
+
displayTable(headers, rows);
|
|
4352
|
+
} else {
|
|
4353
|
+
symbols.forEach((symbol) => {
|
|
4354
|
+
const relativePath = path4.relative(projectRoot, symbol.file);
|
|
4355
|
+
console.log(` ${relativePath} :: ${symbol.name}`);
|
|
4356
|
+
});
|
|
4357
|
+
}
|
|
4206
4358
|
}
|
|
4207
4359
|
function displayTable(headers, rows) {
|
|
4208
4360
|
if (rows.length === 0) return;
|
|
@@ -4252,9 +4404,15 @@ function analyzeDeadCode(graph, projectRoot, options = {}) {
|
|
|
4252
4404
|
includeTests: options.includeTests || false,
|
|
4253
4405
|
verbose: options.verbose || false,
|
|
4254
4406
|
stats: options.stats || false,
|
|
4255
|
-
json: options.json || false
|
|
4407
|
+
json: options.json || false,
|
|
4408
|
+
debug: options.debug || false
|
|
4256
4409
|
};
|
|
4257
|
-
const rawDeadSymbols = findDeadSymbols(
|
|
4410
|
+
const { symbols: rawDeadSymbols } = findDeadSymbols(
|
|
4411
|
+
graph,
|
|
4412
|
+
projectRoot,
|
|
4413
|
+
opts.includeTests,
|
|
4414
|
+
opts.debug
|
|
4415
|
+
);
|
|
4258
4416
|
const classifiedSymbols = classifyDeadSymbols(rawDeadSymbols, graph);
|
|
4259
4417
|
const filteredSymbols = filterByConfidence(classifiedSymbols, opts.confidence);
|
|
4260
4418
|
const totalSymbols = graph.order;
|
|
@@ -4284,7 +4442,7 @@ function filterByConfidence(symbols, minConfidence) {
|
|
|
4284
4442
|
}
|
|
4285
4443
|
|
|
4286
4444
|
// src/docs/generator.ts
|
|
4287
|
-
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, existsSync as
|
|
4445
|
+
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, existsSync as existsSync12 } from "fs";
|
|
4288
4446
|
import { join as join14 } from "path";
|
|
4289
4447
|
|
|
4290
4448
|
// src/docs/architecture.ts
|
|
@@ -7621,7 +7779,7 @@ function getTopLevelDir2(filePath) {
|
|
|
7621
7779
|
}
|
|
7622
7780
|
|
|
7623
7781
|
// src/docs/status.ts
|
|
7624
|
-
import { readFileSync as
|
|
7782
|
+
import { readFileSync as readFileSync8, existsSync as existsSync10 } from "fs";
|
|
7625
7783
|
import { join as join12 } from "path";
|
|
7626
7784
|
function generateStatus(graph, projectRoot, version) {
|
|
7627
7785
|
let output = "";
|
|
@@ -7656,11 +7814,11 @@ function getFileCount11(graph) {
|
|
|
7656
7814
|
function extractComments(projectRoot, filePath) {
|
|
7657
7815
|
const comments = [];
|
|
7658
7816
|
const fullPath = join12(projectRoot, filePath);
|
|
7659
|
-
if (!
|
|
7817
|
+
if (!existsSync10(fullPath)) {
|
|
7660
7818
|
return comments;
|
|
7661
7819
|
}
|
|
7662
7820
|
try {
|
|
7663
|
-
const content =
|
|
7821
|
+
const content = readFileSync8(fullPath, "utf-8");
|
|
7664
7822
|
const lines = content.split("\n");
|
|
7665
7823
|
const patterns = [
|
|
7666
7824
|
{ type: "TODO", regex: /(?:\/\/|#|\/\*)\s*TODO:?\s*(.+)/i },
|
|
@@ -8222,15 +8380,15 @@ function generateConfidenceSection(title, description, symbols, projectRoot) {
|
|
|
8222
8380
|
}
|
|
8223
8381
|
|
|
8224
8382
|
// src/docs/metadata.ts
|
|
8225
|
-
import { existsSync as
|
|
8383
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync2 } from "fs";
|
|
8226
8384
|
import { join as join13 } from "path";
|
|
8227
8385
|
function loadMetadata(outputDir) {
|
|
8228
8386
|
const metadataPath = join13(outputDir, "metadata.json");
|
|
8229
|
-
if (!
|
|
8387
|
+
if (!existsSync11(metadataPath)) {
|
|
8230
8388
|
return null;
|
|
8231
8389
|
}
|
|
8232
8390
|
try {
|
|
8233
|
-
const content =
|
|
8391
|
+
const content = readFileSync9(metadataPath, "utf-8");
|
|
8234
8392
|
return JSON.parse(content);
|
|
8235
8393
|
} catch (err) {
|
|
8236
8394
|
console.error("Failed to load metadata:", err);
|
|
@@ -8281,7 +8439,7 @@ async function generateDocs(graph, projectRoot, version, parseTime, options) {
|
|
|
8281
8439
|
const generated = [];
|
|
8282
8440
|
const errors = [];
|
|
8283
8441
|
try {
|
|
8284
|
-
if (!
|
|
8442
|
+
if (!existsSync12(options.outputDir)) {
|
|
8285
8443
|
mkdirSync2(options.outputDir, { recursive: true });
|
|
8286
8444
|
if (options.verbose) {
|
|
8287
8445
|
console.log(`Created output directory: ${options.outputDir}`);
|
|
@@ -8501,11 +8659,11 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
8501
8659
|
|
|
8502
8660
|
// src/mcp/tools.ts
|
|
8503
8661
|
import { dirname as dirname16, join as join17 } from "path";
|
|
8504
|
-
import { existsSync as
|
|
8662
|
+
import { existsSync as existsSync15, readFileSync as readFileSync11 } from "fs";
|
|
8505
8663
|
|
|
8506
8664
|
// src/mcp/connect.ts
|
|
8507
8665
|
import simpleGit from "simple-git";
|
|
8508
|
-
import { existsSync as
|
|
8666
|
+
import { existsSync as existsSync13 } from "fs";
|
|
8509
8667
|
import { join as join15, basename as basename5, resolve as resolve2 } from "path";
|
|
8510
8668
|
import { tmpdir, homedir } from "os";
|
|
8511
8669
|
function validateProjectPath(source) {
|
|
@@ -8550,7 +8708,7 @@ async function connectToRepo(source, subdirectory, state) {
|
|
|
8550
8708
|
const cloneDir = join15(reposDir, projectName);
|
|
8551
8709
|
console.error(`Connecting to GitHub repo: ${source}`);
|
|
8552
8710
|
const git = simpleGit();
|
|
8553
|
-
if (
|
|
8711
|
+
if (existsSync13(cloneDir)) {
|
|
8554
8712
|
console.error(`Repo already cloned at ${cloneDir}, pulling latest changes...`);
|
|
8555
8713
|
try {
|
|
8556
8714
|
await git.cwd(cloneDir).pull();
|
|
@@ -8577,7 +8735,7 @@ async function connectToRepo(source, subdirectory, state) {
|
|
|
8577
8735
|
message: validation2.error
|
|
8578
8736
|
};
|
|
8579
8737
|
}
|
|
8580
|
-
if (!
|
|
8738
|
+
if (!existsSync13(source)) {
|
|
8581
8739
|
return {
|
|
8582
8740
|
error: "Directory not found",
|
|
8583
8741
|
message: `Directory does not exist: ${source}`
|
|
@@ -8593,7 +8751,7 @@ async function connectToRepo(source, subdirectory, state) {
|
|
|
8593
8751
|
message: validation.error
|
|
8594
8752
|
};
|
|
8595
8753
|
}
|
|
8596
|
-
if (!
|
|
8754
|
+
if (!existsSync13(projectRoot)) {
|
|
8597
8755
|
return {
|
|
8598
8756
|
error: "Project root not found",
|
|
8599
8757
|
message: `Directory does not exist: ${projectRoot}`
|
|
@@ -8874,10 +9032,10 @@ function getWeekNumber(date) {
|
|
|
8874
9032
|
}
|
|
8875
9033
|
|
|
8876
9034
|
// src/temporal/snapshots.ts
|
|
8877
|
-
import { writeFileSync as writeFileSync4, readFileSync as
|
|
9035
|
+
import { writeFileSync as writeFileSync4, readFileSync as readFileSync10, mkdirSync as mkdirSync3, existsSync as existsSync14, readdirSync as readdirSync5 } from "fs";
|
|
8878
9036
|
import { join as join16 } from "path";
|
|
8879
9037
|
function saveSnapshot(snapshot, outputDir) {
|
|
8880
|
-
if (!
|
|
9038
|
+
if (!existsSync14(outputDir)) {
|
|
8881
9039
|
mkdirSync3(outputDir, { recursive: true });
|
|
8882
9040
|
}
|
|
8883
9041
|
const filename = `${snapshot.commitHash.substring(0, 8)}.json`;
|
|
@@ -8887,11 +9045,11 @@ function saveSnapshot(snapshot, outputDir) {
|
|
|
8887
9045
|
function loadSnapshot(commitHash, outputDir) {
|
|
8888
9046
|
const shortHash = commitHash.substring(0, 8);
|
|
8889
9047
|
const filepath = join16(outputDir, `${shortHash}.json`);
|
|
8890
|
-
if (!
|
|
9048
|
+
if (!existsSync14(filepath)) {
|
|
8891
9049
|
return null;
|
|
8892
9050
|
}
|
|
8893
9051
|
try {
|
|
8894
|
-
const content =
|
|
9052
|
+
const content = readFileSync10(filepath, "utf-8");
|
|
8895
9053
|
return JSON.parse(content);
|
|
8896
9054
|
} catch {
|
|
8897
9055
|
return null;
|
|
@@ -9666,7 +9824,7 @@ The server will keep running until you end the MCP session or press Ctrl+C.`;
|
|
|
9666
9824
|
}
|
|
9667
9825
|
async function handleGetProjectDocs(docType, state) {
|
|
9668
9826
|
const docsDir = join17(state.projectRoot, ".depwire");
|
|
9669
|
-
if (!
|
|
9827
|
+
if (!existsSync15(docsDir)) {
|
|
9670
9828
|
const errorMessage = `Project documentation has not been generated yet.
|
|
9671
9829
|
|
|
9672
9830
|
Run \`depwire docs ${state.projectRoot}\` to generate codebase documentation.
|
|
@@ -9697,11 +9855,11 @@ Available document types:
|
|
|
9697
9855
|
continue;
|
|
9698
9856
|
}
|
|
9699
9857
|
const filePath = join17(docsDir, metadata.documents[doc].file);
|
|
9700
|
-
if (!
|
|
9858
|
+
if (!existsSync15(filePath)) {
|
|
9701
9859
|
missing.push(doc);
|
|
9702
9860
|
continue;
|
|
9703
9861
|
}
|
|
9704
|
-
const content =
|
|
9862
|
+
const content = readFileSync11(filePath, "utf-8");
|
|
9705
9863
|
if (docsToReturn.length > 1) {
|
|
9706
9864
|
output += `
|
|
9707
9865
|
|
|
@@ -9733,9 +9891,9 @@ async function handleUpdateProjectDocs(docType, state) {
|
|
|
9733
9891
|
const parseTime = (Date.now() - startTime) / 1e3;
|
|
9734
9892
|
state.graph = graph;
|
|
9735
9893
|
const packageJsonPath = join17(__dirname, "../../package.json");
|
|
9736
|
-
const packageJson = JSON.parse(
|
|
9894
|
+
const packageJson = JSON.parse(readFileSync11(packageJsonPath, "utf-8"));
|
|
9737
9895
|
const docsToGenerate = docType === "all" ? ["architecture", "conventions", "dependencies", "onboarding"] : [docType];
|
|
9738
|
-
const docsExist =
|
|
9896
|
+
const docsExist = existsSync15(docsDir);
|
|
9739
9897
|
const result = await generateDocs(graph, state.projectRoot, packageJson.version, parseTime, {
|
|
9740
9898
|
outputDir: docsDir,
|
|
9741
9899
|
format: "markdown",
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
stashChanges,
|
|
28
28
|
updateFileInGraph,
|
|
29
29
|
watchProject
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-JICAYZUJ.js";
|
|
31
31
|
|
|
32
32
|
// src/index.ts
|
|
33
33
|
import { Command } from "commander";
|
|
@@ -788,7 +788,7 @@ program.command("health").description("Analyze dependency architecture health (0
|
|
|
788
788
|
process.exit(1);
|
|
789
789
|
}
|
|
790
790
|
});
|
|
791
|
-
program.command("dead-code").description("Identify dead code - symbols defined but never referenced").argument("[directory]", "Project directory to analyze (defaults to current directory or auto-detected project root)").option("--confidence <level>", "Minimum confidence level to show: high, medium, low (default: medium)", "medium").option("--json", "Output as JSON (for CI/automation)").option("--verbose", "Show detailed info for each dead symbol").option("--stats", "Show summary statistics").option("--include-tests", "Include test files in analysis").option("--include-low", "Shortcut for --confidence low").action(async (directory, options) => {
|
|
791
|
+
program.command("dead-code").description("Identify dead code - symbols defined but never referenced").argument("[directory]", "Project directory to analyze (defaults to current directory or auto-detected project root)").option("--confidence <level>", "Minimum confidence level to show: high, medium, low (default: medium)", "medium").option("--json", "Output as JSON (for CI/automation)").option("--verbose", "Show detailed info for each dead symbol").option("--stats", "Show summary statistics").option("--include-tests", "Include test files in analysis").option("--include-low", "Shortcut for --confidence low").option("--debug", "Show debug information (exclusion stats)").action(async (directory, options) => {
|
|
792
792
|
try {
|
|
793
793
|
const projectRoot = directory ? resolve(directory) : findProjectRoot();
|
|
794
794
|
const startTime = Date.now();
|
|
@@ -800,7 +800,8 @@ program.command("dead-code").description("Identify dead code - symbols defined b
|
|
|
800
800
|
includeTests: options.includeTests || false,
|
|
801
801
|
verbose: options.verbose || false,
|
|
802
802
|
stats: options.stats || false,
|
|
803
|
-
json: options.json || false
|
|
803
|
+
json: options.json || false,
|
|
804
|
+
debug: options.debug || false
|
|
804
805
|
});
|
|
805
806
|
if (options.json) {
|
|
806
807
|
console.log(JSON.stringify(report, null, 2));
|
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.3",
|
|
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": {
|