depwire-cli 0.3.0 → 0.3.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/dist/{chunk-C3LAKUAJ.js → chunk-LOX5NEND.js} +100 -22
- package/dist/index.js +1 -1
- package/dist/mcpb-entry.js +1 -1
- package/package.json +1 -1
|
@@ -2044,6 +2044,43 @@ function buildGraph(parsedFiles) {
|
|
|
2044
2044
|
}
|
|
2045
2045
|
|
|
2046
2046
|
// src/graph/queries.ts
|
|
2047
|
+
function findSymbols(graph, query) {
|
|
2048
|
+
if (query.includes("::")) {
|
|
2049
|
+
if (graph.hasNode(query)) {
|
|
2050
|
+
const attrs = graph.getNodeAttributes(query);
|
|
2051
|
+
return [{
|
|
2052
|
+
id: query,
|
|
2053
|
+
name: attrs.name,
|
|
2054
|
+
kind: attrs.kind,
|
|
2055
|
+
filePath: attrs.filePath,
|
|
2056
|
+
startLine: attrs.startLine,
|
|
2057
|
+
endLine: attrs.endLine,
|
|
2058
|
+
exported: attrs.exported,
|
|
2059
|
+
scope: attrs.scope,
|
|
2060
|
+
dependentCount: graph.inDegree(query)
|
|
2061
|
+
}];
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
const queryLower = query.toLowerCase();
|
|
2065
|
+
const results = [];
|
|
2066
|
+
graph.forEachNode((nodeId, attrs) => {
|
|
2067
|
+
if (attrs.name.toLowerCase() === queryLower) {
|
|
2068
|
+
results.push({
|
|
2069
|
+
id: nodeId,
|
|
2070
|
+
name: attrs.name,
|
|
2071
|
+
kind: attrs.kind,
|
|
2072
|
+
filePath: attrs.filePath,
|
|
2073
|
+
startLine: attrs.startLine,
|
|
2074
|
+
endLine: attrs.endLine,
|
|
2075
|
+
exported: attrs.exported,
|
|
2076
|
+
scope: attrs.scope,
|
|
2077
|
+
dependentCount: graph.inDegree(nodeId)
|
|
2078
|
+
});
|
|
2079
|
+
}
|
|
2080
|
+
});
|
|
2081
|
+
results.sort((a, b) => b.dependentCount - a.dependentCount);
|
|
2082
|
+
return results;
|
|
2083
|
+
}
|
|
2047
2084
|
function getDependencies(graph, symbolId) {
|
|
2048
2085
|
if (!graph.hasNode(symbolId)) return [];
|
|
2049
2086
|
const dependencies = [];
|
|
@@ -4520,13 +4557,13 @@ function getToolsList() {
|
|
|
4520
4557
|
},
|
|
4521
4558
|
{
|
|
4522
4559
|
name: "get_symbol_info",
|
|
4523
|
-
description: "Look up detailed information about a symbol (function, class, variable, type, etc.) by name.
|
|
4560
|
+
description: "Look up detailed information about a symbol (function, class, variable, type, etc.) by name. Pass a symbol name (e.g., 'Router') or a fully qualified ID (e.g., 'src/router.ts::Router') for exact matching. If multiple symbols share the same name, returns all matches for disambiguation.",
|
|
4524
4561
|
inputSchema: {
|
|
4525
4562
|
type: "object",
|
|
4526
4563
|
properties: {
|
|
4527
4564
|
name: {
|
|
4528
4565
|
type: "string",
|
|
4529
|
-
description: "The symbol name to look up (e.g., 'UserService'
|
|
4566
|
+
description: "The symbol name to look up (e.g., 'UserService') or full ID (e.g., 'src/services/UserService.ts::UserService')"
|
|
4530
4567
|
}
|
|
4531
4568
|
},
|
|
4532
4569
|
required: ["name"]
|
|
@@ -4534,13 +4571,13 @@ function getToolsList() {
|
|
|
4534
4571
|
},
|
|
4535
4572
|
{
|
|
4536
4573
|
name: "get_dependencies",
|
|
4537
|
-
description: "Get all symbols that a given symbol depends on (what does this symbol use/import/call?).",
|
|
4574
|
+
description: "Get all symbols that a given symbol depends on (what does this symbol use/import/call?). Pass a symbol name (e.g., 'Router') or a fully qualified ID (e.g., 'src/router.ts::Router') for exact matching. If multiple symbols share the same name, returns all matches for disambiguation.",
|
|
4538
4575
|
inputSchema: {
|
|
4539
4576
|
type: "object",
|
|
4540
4577
|
properties: {
|
|
4541
4578
|
symbol: {
|
|
4542
4579
|
type: "string",
|
|
4543
|
-
description: "Symbol name or ID
|
|
4580
|
+
description: "Symbol name (e.g., 'Router') or full ID (e.g., 'src/router.ts::Router')"
|
|
4544
4581
|
}
|
|
4545
4582
|
},
|
|
4546
4583
|
required: ["symbol"]
|
|
@@ -4548,13 +4585,13 @@ function getToolsList() {
|
|
|
4548
4585
|
},
|
|
4549
4586
|
{
|
|
4550
4587
|
name: "get_dependents",
|
|
4551
|
-
description: "Get all symbols that depend on a given symbol (what uses this symbol?).",
|
|
4588
|
+
description: "Get all symbols that depend on a given symbol (what uses this symbol?). Pass a symbol name (e.g., 'Router') or a fully qualified ID (e.g., 'src/router.ts::Router') for exact matching. If multiple symbols share the same name, returns all matches for disambiguation.",
|
|
4552
4589
|
inputSchema: {
|
|
4553
4590
|
type: "object",
|
|
4554
4591
|
properties: {
|
|
4555
4592
|
symbol: {
|
|
4556
4593
|
type: "string",
|
|
4557
|
-
description: "Symbol name or ID
|
|
4594
|
+
description: "Symbol name (e.g., 'Router') or full ID (e.g., 'src/router.ts::Router')"
|
|
4558
4595
|
}
|
|
4559
4596
|
},
|
|
4560
4597
|
required: ["symbol"]
|
|
@@ -4562,13 +4599,13 @@ function getToolsList() {
|
|
|
4562
4599
|
},
|
|
4563
4600
|
{
|
|
4564
4601
|
name: "impact_analysis",
|
|
4565
|
-
description: "Analyze what would break if a symbol is changed, renamed, or removed. Shows direct dependents, transitive dependents (chain reaction), and all affected files. Use this before making changes to understand the blast radius.",
|
|
4602
|
+
description: "Analyze what would break if a symbol is changed, renamed, or removed. Shows direct dependents, transitive dependents (chain reaction), and all affected files. Pass a symbol name (e.g., 'Router') or a fully qualified ID (e.g., 'src/router.ts::Router') for exact matching. If multiple symbols share the same name, returns all matches for disambiguation. Use this before making changes to understand the blast radius.",
|
|
4566
4603
|
inputSchema: {
|
|
4567
4604
|
type: "object",
|
|
4568
4605
|
properties: {
|
|
4569
4606
|
symbol: {
|
|
4570
4607
|
type: "string",
|
|
4571
|
-
description: "
|
|
4608
|
+
description: "Symbol name (e.g., 'Router') or full ID (e.g., 'src/router.ts::Router')"
|
|
4572
4609
|
}
|
|
4573
4610
|
},
|
|
4574
4611
|
required: ["symbol"]
|
|
@@ -4790,12 +4827,39 @@ async function handleToolCall(name, args, state) {
|
|
|
4790
4827
|
};
|
|
4791
4828
|
}
|
|
4792
4829
|
}
|
|
4830
|
+
function createDisambiguationResponse(matches, queryName) {
|
|
4831
|
+
const suggestion = matches.length > 0 ? matches[0].id : "";
|
|
4832
|
+
return {
|
|
4833
|
+
ambiguous: true,
|
|
4834
|
+
message: `Found ${matches.length} symbols named '${queryName}'. Please specify which one by using the full ID (e.g., '${suggestion}').`,
|
|
4835
|
+
matches: matches.map((m, index) => ({
|
|
4836
|
+
id: m.id,
|
|
4837
|
+
kind: m.kind,
|
|
4838
|
+
filePath: m.filePath,
|
|
4839
|
+
line: m.startLine,
|
|
4840
|
+
dependents: m.dependentCount,
|
|
4841
|
+
hint: index === 0 && m.dependentCount > 0 ? "Most dependents \u2014 likely the one you want" : ""
|
|
4842
|
+
})),
|
|
4843
|
+
suggestion
|
|
4844
|
+
};
|
|
4845
|
+
}
|
|
4793
4846
|
function handleGetSymbolInfo(name, graph) {
|
|
4794
|
-
const matches =
|
|
4795
|
-
|
|
4796
|
-
|
|
4847
|
+
const matches = findSymbols(graph, name);
|
|
4848
|
+
if (matches.length === 0) {
|
|
4849
|
+
const fuzzyMatches = searchSymbols(graph, name).slice(0, 10);
|
|
4850
|
+
return {
|
|
4851
|
+
error: `Symbol '${name}' not found`,
|
|
4852
|
+
suggestion: fuzzyMatches.length > 0 ? `Did you mean: ${fuzzyMatches.map((m) => m.name).join(", ")}?` : "Try using search_symbols to find available symbols",
|
|
4853
|
+
fuzzyMatches: fuzzyMatches.map((m) => ({
|
|
4854
|
+
id: m.id,
|
|
4855
|
+
name: m.name,
|
|
4856
|
+
kind: m.kind,
|
|
4857
|
+
filePath: m.filePath
|
|
4858
|
+
}))
|
|
4859
|
+
};
|
|
4860
|
+
}
|
|
4797
4861
|
return {
|
|
4798
|
-
matches:
|
|
4862
|
+
matches: matches.map((m) => ({
|
|
4799
4863
|
id: m.id,
|
|
4800
4864
|
name: m.name,
|
|
4801
4865
|
kind: m.kind,
|
|
@@ -4803,19 +4867,24 @@ function handleGetSymbolInfo(name, graph) {
|
|
|
4803
4867
|
startLine: m.startLine,
|
|
4804
4868
|
endLine: m.endLine,
|
|
4805
4869
|
exported: m.exported,
|
|
4806
|
-
scope: m.scope
|
|
4870
|
+
scope: m.scope,
|
|
4871
|
+
dependents: m.dependentCount
|
|
4807
4872
|
})),
|
|
4808
|
-
count:
|
|
4873
|
+
count: matches.length
|
|
4809
4874
|
};
|
|
4810
4875
|
}
|
|
4811
4876
|
function handleGetDependencies(symbol, graph) {
|
|
4812
|
-
const matches =
|
|
4877
|
+
const matches = findSymbols(graph, symbol);
|
|
4813
4878
|
if (matches.length === 0) {
|
|
4879
|
+
const fuzzyMatches = searchSymbols(graph, symbol).slice(0, 10);
|
|
4814
4880
|
return {
|
|
4815
4881
|
error: `Symbol '${symbol}' not found`,
|
|
4816
|
-
suggestion: "Try using search_symbols to find available symbols"
|
|
4882
|
+
suggestion: fuzzyMatches.length > 0 ? `Did you mean: ${fuzzyMatches.map((m) => m.name).join(", ")}?` : "Try using search_symbols to find available symbols"
|
|
4817
4883
|
};
|
|
4818
4884
|
}
|
|
4885
|
+
if (matches.length > 1) {
|
|
4886
|
+
return createDisambiguationResponse(matches, symbol);
|
|
4887
|
+
}
|
|
4819
4888
|
const target = matches[0];
|
|
4820
4889
|
const deps = getDependencies(graph, target.id);
|
|
4821
4890
|
const grouped = {};
|
|
@@ -4833,19 +4902,23 @@ function handleGetDependencies(symbol, graph) {
|
|
|
4833
4902
|
});
|
|
4834
4903
|
const totalCount = Object.values(grouped).reduce((sum, arr) => sum + arr.length, 0);
|
|
4835
4904
|
return {
|
|
4836
|
-
symbol:
|
|
4905
|
+
symbol: target.id,
|
|
4837
4906
|
dependencies: grouped,
|
|
4838
4907
|
totalCount
|
|
4839
4908
|
};
|
|
4840
4909
|
}
|
|
4841
4910
|
function handleGetDependents(symbol, graph) {
|
|
4842
|
-
const matches =
|
|
4911
|
+
const matches = findSymbols(graph, symbol);
|
|
4843
4912
|
if (matches.length === 0) {
|
|
4913
|
+
const fuzzyMatches = searchSymbols(graph, symbol).slice(0, 10);
|
|
4844
4914
|
return {
|
|
4845
4915
|
error: `Symbol '${symbol}' not found`,
|
|
4846
|
-
suggestion: "Try using search_symbols to find available symbols"
|
|
4916
|
+
suggestion: fuzzyMatches.length > 0 ? `Did you mean: ${fuzzyMatches.map((m) => m.name).join(", ")}?` : "Try using search_symbols to find available symbols"
|
|
4847
4917
|
};
|
|
4848
4918
|
}
|
|
4919
|
+
if (matches.length > 1) {
|
|
4920
|
+
return createDisambiguationResponse(matches, symbol);
|
|
4921
|
+
}
|
|
4849
4922
|
const target = matches[0];
|
|
4850
4923
|
const deps = getDependents(graph, target.id);
|
|
4851
4924
|
const grouped = {};
|
|
@@ -4863,19 +4936,23 @@ function handleGetDependents(symbol, graph) {
|
|
|
4863
4936
|
});
|
|
4864
4937
|
const totalCount = Object.values(grouped).reduce((sum, arr) => sum + arr.length, 0);
|
|
4865
4938
|
return {
|
|
4866
|
-
symbol:
|
|
4939
|
+
symbol: target.id,
|
|
4867
4940
|
dependents: grouped,
|
|
4868
4941
|
totalCount
|
|
4869
4942
|
};
|
|
4870
4943
|
}
|
|
4871
4944
|
function handleImpactAnalysis(symbol, graph) {
|
|
4872
|
-
const matches =
|
|
4945
|
+
const matches = findSymbols(graph, symbol);
|
|
4873
4946
|
if (matches.length === 0) {
|
|
4947
|
+
const fuzzyMatches = searchSymbols(graph, symbol).slice(0, 10);
|
|
4874
4948
|
return {
|
|
4875
4949
|
error: `Symbol '${symbol}' not found`,
|
|
4876
|
-
suggestion: "Try using search_symbols to find available symbols"
|
|
4950
|
+
suggestion: fuzzyMatches.length > 0 ? `Did you mean: ${fuzzyMatches.map((m) => m.name).join(", ")}?` : "Try using search_symbols to find available symbols"
|
|
4877
4951
|
};
|
|
4878
4952
|
}
|
|
4953
|
+
if (matches.length > 1) {
|
|
4954
|
+
return createDisambiguationResponse(matches, symbol);
|
|
4955
|
+
}
|
|
4879
4956
|
const target = matches[0];
|
|
4880
4957
|
const impact = getImpact(graph, target.id);
|
|
4881
4958
|
const directWithKinds = impact.directDependents.map((dep) => {
|
|
@@ -4898,6 +4975,7 @@ function handleImpactAnalysis(symbol, graph) {
|
|
|
4898
4975
|
const summary = `Changing ${target.name} would directly affect ${impact.directDependents.length} symbol(s) and transitively affect ${transitiveFormatted.length} more, across ${impact.affectedFiles.length} file(s).`;
|
|
4899
4976
|
return {
|
|
4900
4977
|
symbol: {
|
|
4978
|
+
id: target.id,
|
|
4901
4979
|
name: target.name,
|
|
4902
4980
|
filePath: target.filePath,
|
|
4903
4981
|
kind: target.kind
|
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.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Code cross-reference visualization and AI context engine for TypeScript. Analyzes codebases to show dependencies, enables AI tools with MCP, and renders beautiful arc diagrams.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|