kirograph 0.27.1 → 0.28.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/README.md +35 -2
- package/dist/bin/commands/annotations.js +56 -0
- package/dist/bin/commands/annotations.js.map +7 -0
- package/dist/bin/commands/ast-rewrite.js +55 -0
- package/dist/bin/commands/ast-rewrite.js.map +7 -0
- package/dist/bin/commands/bench.js +103 -0
- package/dist/bin/commands/bench.js.map +7 -0
- package/dist/bin/commands/branch.js +133 -0
- package/dist/bin/commands/branch.js.map +7 -0
- package/dist/bin/commands/callees.js +76 -0
- package/dist/bin/commands/callees.js.map +7 -0
- package/dist/bin/commands/callers.js +76 -0
- package/dist/bin/commands/callers.js.map +7 -0
- package/dist/bin/commands/changelog.js +55 -0
- package/dist/bin/commands/changelog.js.map +7 -0
- package/dist/bin/commands/circular-deps.js +68 -0
- package/dist/bin/commands/circular-deps.js.map +7 -0
- package/dist/bin/commands/commit-context.js +55 -0
- package/dist/bin/commands/commit-context.js.map +7 -0
- package/dist/bin/commands/complexity.js +60 -0
- package/dist/bin/commands/complexity.js.map +7 -0
- package/dist/bin/commands/cost.js +146 -0
- package/dist/bin/commands/cost.js.map +7 -0
- package/dist/bin/commands/dependency-depth.js +55 -0
- package/dist/bin/commands/dependency-depth.js.map +7 -0
- package/dist/bin/commands/diff-context.js +55 -0
- package/dist/bin/commands/diff-context.js.map +7 -0
- package/dist/bin/commands/distribution.js +56 -0
- package/dist/bin/commands/distribution.js.map +7 -0
- package/dist/bin/commands/doc-coverage.js +56 -0
- package/dist/bin/commands/doc-coverage.js.map +7 -0
- package/dist/bin/commands/doctor.js +202 -0
- package/dist/bin/commands/doctor.js.map +7 -0
- package/dist/bin/commands/dsm.js +56 -0
- package/dist/bin/commands/dsm.js.map +7 -0
- package/dist/bin/commands/gini.js +55 -0
- package/dist/bin/commands/gini.js.map +7 -0
- package/dist/bin/commands/god-class.js +56 -0
- package/dist/bin/commands/god-class.js.map +7 -0
- package/dist/bin/commands/health.js +55 -0
- package/dist/bin/commands/health.js.map +7 -0
- package/dist/bin/commands/help.js +224 -45
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/impact.js +76 -0
- package/dist/bin/commands/impact.js.map +7 -0
- package/dist/bin/commands/inheritance-depth.js +56 -0
- package/dist/bin/commands/inheritance-depth.js.map +7 -0
- package/dist/bin/commands/insert-at.js +55 -0
- package/dist/bin/commands/insert-at.js.map +7 -0
- package/dist/bin/commands/largest.js +56 -0
- package/dist/bin/commands/largest.js.map +7 -0
- package/dist/bin/commands/manifest.js +158 -0
- package/dist/bin/commands/manifest.js.map +7 -0
- package/dist/bin/commands/module-api.js +57 -0
- package/dist/bin/commands/module-api.js.map +7 -0
- package/dist/bin/commands/monitor.js +91 -0
- package/dist/bin/commands/monitor.js.map +7 -0
- package/dist/bin/commands/multi-replace.js +66 -0
- package/dist/bin/commands/multi-replace.js.map +7 -0
- package/dist/bin/commands/pr-context.js +55 -0
- package/dist/bin/commands/pr-context.js.map +7 -0
- package/dist/bin/commands/query.js +19 -1
- package/dist/bin/commands/query.js.map +3 -3
- package/dist/bin/commands/rank.js +56 -0
- package/dist/bin/commands/rank.js.map +7 -0
- package/dist/bin/commands/read.js +1 -1
- package/dist/bin/commands/read.js.map +2 -2
- package/dist/bin/commands/recursion.js +56 -0
- package/dist/bin/commands/recursion.js.map +7 -0
- package/dist/bin/commands/rename-preview.js +56 -0
- package/dist/bin/commands/rename-preview.js.map +7 -0
- package/dist/bin/commands/session.js +60 -0
- package/dist/bin/commands/session.js.map +7 -0
- package/dist/bin/commands/simplify-scan.js +56 -0
- package/dist/bin/commands/simplify-scan.js.map +7 -0
- package/dist/bin/commands/str-replace.js +55 -0
- package/dist/bin/commands/str-replace.js.map +7 -0
- package/dist/bin/commands/test-coverage.js +59 -0
- package/dist/bin/commands/test-coverage.js.map +7 -0
- package/dist/bin/commands/test-map.js +56 -0
- package/dist/bin/commands/test-map.js.map +7 -0
- package/dist/bin/commands/test-risk.js +59 -0
- package/dist/bin/commands/test-risk.js.map +7 -0
- package/dist/bin/commands/type-hierarchy.js +76 -0
- package/dist/bin/commands/type-hierarchy.js.map +7 -0
- package/dist/bin/commands/unused-imports.js +55 -0
- package/dist/bin/commands/unused-imports.js.map +7 -0
- package/dist/bin/commands/upgrade.js +78 -0
- package/dist/bin/commands/upgrade.js.map +7 -0
- package/dist/bin/installer/common.js +19 -9
- package/dist/bin/installer/common.js.map +2 -2
- package/dist/bin/installer/config-prompt.js +147 -12
- package/dist/bin/installer/config-prompt.js.map +3 -3
- package/dist/bin/installer/index.js +62 -6
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/instructions.js +14 -25
- package/dist/bin/installer/instructions.js.map +2 -2
- package/dist/bin/installer/mcp.js.map +2 -2
- package/dist/bin/installer/steering.js +569 -100
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/aider.js +3 -3
- package/dist/bin/installer/targets/aider.js.map +2 -2
- package/dist/bin/installer/targets/amp.js +3 -3
- package/dist/bin/installer/targets/amp.js.map +2 -2
- package/dist/bin/installer/targets/antigravity.js +4 -4
- package/dist/bin/installer/targets/antigravity.js.map +2 -2
- package/dist/bin/installer/targets/augment.js +3 -3
- package/dist/bin/installer/targets/augment.js.map +2 -2
- package/dist/bin/installer/targets/claude.js +3 -3
- package/dist/bin/installer/targets/claude.js.map +2 -2
- package/dist/bin/installer/targets/cline.js +4 -4
- package/dist/bin/installer/targets/cline.js.map +2 -2
- package/dist/bin/installer/targets/codex.js +4 -4
- package/dist/bin/installer/targets/codex.js.map +2 -2
- package/dist/bin/installer/targets/continue.js +4 -4
- package/dist/bin/installer/targets/continue.js.map +2 -2
- package/dist/bin/installer/targets/copilot-cli.js +4 -4
- package/dist/bin/installer/targets/copilot-cli.js.map +2 -2
- package/dist/bin/installer/targets/copilot.js +4 -4
- package/dist/bin/installer/targets/copilot.js.map +2 -2
- package/dist/bin/installer/targets/cursor.js +5 -5
- package/dist/bin/installer/targets/cursor.js.map +2 -2
- package/dist/bin/installer/targets/devin.js +4 -4
- package/dist/bin/installer/targets/devin.js.map +2 -2
- package/dist/bin/installer/targets/gemini-cli.js +4 -4
- package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
- package/dist/bin/installer/targets/generic.js +2 -2
- package/dist/bin/installer/targets/generic.js.map +2 -2
- package/dist/bin/installer/targets/goose.js +3 -4
- package/dist/bin/installer/targets/goose.js.map +3 -3
- package/dist/bin/installer/targets/index.js.map +1 -1
- package/dist/bin/installer/targets/junie.js +4 -4
- package/dist/bin/installer/targets/junie.js.map +2 -2
- package/dist/bin/installer/targets/kilo.js +4 -4
- package/dist/bin/installer/targets/kilo.js.map +2 -2
- package/dist/bin/installer/targets/kiro.js +27 -3
- package/dist/bin/installer/targets/kiro.js.map +2 -2
- package/dist/bin/installer/targets/opencode.js +3 -3
- package/dist/bin/installer/targets/opencode.js.map +2 -2
- package/dist/bin/installer/targets/openhands.js +3 -3
- package/dist/bin/installer/targets/openhands.js.map +2 -2
- package/dist/bin/installer/targets/qoder.js +2 -2
- package/dist/bin/installer/targets/qoder.js.map +2 -2
- package/dist/bin/installer/targets/qwen.js +2 -2
- package/dist/bin/installer/targets/qwen.js.map +2 -2
- package/dist/bin/installer/targets/replit.js +3 -3
- package/dist/bin/installer/targets/replit.js.map +2 -2
- package/dist/bin/installer/targets/roo.js +4 -4
- package/dist/bin/installer/targets/roo.js.map +2 -2
- package/dist/bin/installer/targets/tabnine.js +3 -3
- package/dist/bin/installer/targets/tabnine.js.map +2 -2
- package/dist/bin/installer/targets/trae.js +3 -3
- package/dist/bin/installer/targets/trae.js.map +2 -2
- package/dist/bin/installer/targets/warp.js +4 -4
- package/dist/bin/installer/targets/warp.js.map +2 -2
- package/dist/bin/installer/targets/windsurf.js +4 -4
- package/dist/bin/installer/targets/windsurf.js.map +2 -2
- package/dist/bin/kirograph.js +83 -1
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/config.js +30 -8
- package/dist/config.js.map +2 -2
- package/dist/core/branch-manager.js +111 -0
- package/dist/core/branch-manager.js.map +7 -0
- package/dist/core/pipeline.js +3 -3
- package/dist/core/pipeline.js.map +2 -2
- package/dist/data/pixelrag-bridge.js +93 -0
- package/dist/data/pixelrag-bridge.js.map +7 -0
- package/dist/data/pixelrag-manager.js +416 -0
- package/dist/data/pixelrag-manager.js.map +7 -0
- package/dist/db/database.js +34 -7
- package/dist/db/database.js.map +2 -2
- package/dist/db/schema.sql +7 -1
- package/dist/extraction/complexity.js +116 -0
- package/dist/extraction/complexity.js.map +7 -0
- package/dist/extraction/extractor.js +52 -1
- package/dist/extraction/extractor.js.map +2 -2
- package/dist/graph/git-context.js +229 -0
- package/dist/graph/git-context.js.map +7 -0
- package/dist/index.js +4 -2
- package/dist/index.js.map +2 -2
- package/dist/mcp/cache.js +1 -1
- package/dist/mcp/cache.js.map +2 -2
- package/dist/mcp/handler.js +446 -0
- package/dist/mcp/handler.js.map +7 -0
- package/dist/mcp/handlers/architecture.js +297 -0
- package/dist/mcp/handlers/architecture.js.map +7 -0
- package/dist/mcp/handlers/branch.js +175 -0
- package/dist/mcp/handlers/branch.js.map +7 -0
- package/dist/mcp/handlers/code-health.js +563 -0
- package/dist/mcp/handlers/code-health.js.map +7 -0
- package/dist/mcp/handlers/complexity.js +267 -0
- package/dist/mcp/handlers/complexity.js.map +7 -0
- package/dist/mcp/handlers/core.js +611 -0
- package/dist/mcp/handlers/core.js.map +7 -0
- package/dist/mcp/handlers/data.js +337 -0
- package/dist/mcp/handlers/data.js.map +7 -0
- package/dist/mcp/handlers/docs.js +159 -0
- package/dist/mcp/handlers/docs.js.map +7 -0
- package/dist/mcp/handlers/edit-primitives.js +200 -0
- package/dist/mcp/handlers/edit-primitives.js.map +7 -0
- package/dist/mcp/handlers/git-context.js +286 -0
- package/dist/mcp/handlers/git-context.js.map +7 -0
- package/dist/mcp/handlers/memory.js +363 -0
- package/dist/mcp/handlers/memory.js.map +7 -0
- package/dist/mcp/handlers/patterns.js +310 -0
- package/dist/mcp/handlers/patterns.js.map +7 -0
- package/dist/mcp/handlers/security.js +699 -0
- package/dist/mcp/handlers/security.js.map +7 -0
- package/dist/mcp/handlers/utils.js +97 -0
- package/dist/mcp/handlers/utils.js.map +7 -0
- package/dist/mcp/handlers/watchmen.js +104 -0
- package/dist/mcp/handlers/watchmen.js.map +7 -0
- package/dist/mcp/handlers/wiki.js +242 -0
- package/dist/mcp/handlers/wiki.js.map +7 -0
- package/dist/mcp/server.js +72 -3
- package/dist/mcp/server.js.map +2 -2
- package/dist/mcp/tool-names.js +136 -10
- package/dist/mcp/tool-names.js.map +2 -2
- package/dist/mcp/tools.js +846 -3019
- package/dist/mcp/tools.js.map +3 -3
- package/dist/types.js.map +2 -2
- package/package.json +36 -10
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var complexity_exports = {};
|
|
20
|
+
__export(complexity_exports, {
|
|
21
|
+
handleComplexity: () => handleComplexity
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(complexity_exports);
|
|
24
|
+
var import_utils = require("./utils");
|
|
25
|
+
async function handleComplexity(toolName, args, cg) {
|
|
26
|
+
const rawDb = cg.getDatabase().getRawDb();
|
|
27
|
+
switch (toolName) {
|
|
28
|
+
case "kirograph_complexity": {
|
|
29
|
+
const limitN = (0, import_utils.clampLimit)(args.limit, 30);
|
|
30
|
+
const metric = args.metric ?? "cyclomatic";
|
|
31
|
+
const col = metric === "cognitive" ? "complexity_cognitive" : metric === "maintainability" ? "maintainability_index" : "complexity_cyclomatic";
|
|
32
|
+
const order = metric === "maintainability" ? "ASC" : "DESC";
|
|
33
|
+
const threshold = args.threshold ?? (metric === "maintainability" ? 50 : 10);
|
|
34
|
+
const rows = rawDb.all(
|
|
35
|
+
`SELECT name, kind, file_path, start_line, complexity_cyclomatic, complexity_cognitive,
|
|
36
|
+
maintainability_index, nesting_depth, (end_line - start_line + 1) as loc
|
|
37
|
+
FROM nodes WHERE ${col} IS NOT NULL AND kind IN ('function','method')
|
|
38
|
+
ORDER BY ${col} ${order} LIMIT ?`,
|
|
39
|
+
[limitN]
|
|
40
|
+
);
|
|
41
|
+
if (rows.length === 0) {
|
|
42
|
+
return "No complexity data found. Re-index with enableComplexity: true in .kirograph/config.json, then run `kirograph index`.";
|
|
43
|
+
}
|
|
44
|
+
const flagged = rows.filter(
|
|
45
|
+
(r) => metric === "maintainability" ? (r.maintainability_index ?? 100) <= threshold : (r[col] ?? 0) >= threshold
|
|
46
|
+
);
|
|
47
|
+
const lines = [
|
|
48
|
+
`Symbols ranked by ${metric} complexity (${rows.length} shown${flagged.length > 0 ? `, ${flagged.length} exceeding threshold ${threshold}` : ""}):
|
|
49
|
+
`
|
|
50
|
+
];
|
|
51
|
+
for (const r of rows) {
|
|
52
|
+
const cc = r.complexity_cyclomatic ?? "\u2014";
|
|
53
|
+
const mi = r.maintainability_index !== null ? r.maintainability_index.toFixed(1) : "\u2014";
|
|
54
|
+
const depth = r.nesting_depth ?? "\u2014";
|
|
55
|
+
const warn = flagged.includes(r) ? "\u26A0 " : " ";
|
|
56
|
+
lines.push(`${warn}CC=${cc} MI=${mi} depth=${depth} ${r.loc}LOC ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`);
|
|
57
|
+
}
|
|
58
|
+
return lines.join("\n");
|
|
59
|
+
}
|
|
60
|
+
case "kirograph_simplify_scan": {
|
|
61
|
+
const limitN = (0, import_utils.clampLimit)(args.limit, 30);
|
|
62
|
+
const thresholdCC = args.thresholdCC ?? 10;
|
|
63
|
+
const thresholdMI = args.thresholdMI ?? 50;
|
|
64
|
+
const thresholdLOC = args.thresholdLOC ?? 50;
|
|
65
|
+
const rows = rawDb.all(
|
|
66
|
+
`SELECT name, kind, file_path, start_line,
|
|
67
|
+
complexity_cyclomatic, maintainability_index,
|
|
68
|
+
nesting_depth, (end_line - start_line + 1) as loc
|
|
69
|
+
FROM nodes WHERE kind IN ('function','method')
|
|
70
|
+
AND (
|
|
71
|
+
(complexity_cyclomatic IS NOT NULL AND complexity_cyclomatic >= ?)
|
|
72
|
+
OR (maintainability_index IS NOT NULL AND maintainability_index <= ?)
|
|
73
|
+
OR ((end_line - start_line + 1) >= ?)
|
|
74
|
+
)
|
|
75
|
+
ORDER BY complexity_cyclomatic DESC NULLS LAST LIMIT ?`,
|
|
76
|
+
[thresholdCC, thresholdMI, thresholdLOC, limitN]
|
|
77
|
+
);
|
|
78
|
+
if (rows.length === 0) return "No simplification candidates found \u2014 complexity is within thresholds.";
|
|
79
|
+
const lines = [`Simplification candidates (${rows.length}):
|
|
80
|
+
`];
|
|
81
|
+
for (const r of rows) {
|
|
82
|
+
const issues = [];
|
|
83
|
+
if (r.complexity_cyclomatic !== null && r.complexity_cyclomatic >= thresholdCC) issues.push(`CC=${r.complexity_cyclomatic}`);
|
|
84
|
+
if (r.maintainability_index !== null && r.maintainability_index <= thresholdMI) issues.push(`MI=${r.maintainability_index.toFixed(1)}`);
|
|
85
|
+
if (r.loc >= thresholdLOC) issues.push(`${r.loc}LOC`);
|
|
86
|
+
lines.push(` [${issues.join(", ")}] ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`);
|
|
87
|
+
}
|
|
88
|
+
return lines.join("\n");
|
|
89
|
+
}
|
|
90
|
+
case "kirograph_health": {
|
|
91
|
+
const ccRows = rawDb.all(
|
|
92
|
+
`SELECT COUNT(*) as total,
|
|
93
|
+
SUM(CASE WHEN complexity_cyclomatic <= 10 THEN 1 ELSE 0 END) as good
|
|
94
|
+
FROM nodes WHERE kind IN ('function','method') AND complexity_cyclomatic IS NOT NULL`,
|
|
95
|
+
[]
|
|
96
|
+
);
|
|
97
|
+
let complexity_score;
|
|
98
|
+
let complexityNote = "";
|
|
99
|
+
if (!ccRows[0] || ccRows[0].total === 0) {
|
|
100
|
+
complexity_score = 2500;
|
|
101
|
+
complexityNote = " (no CC data \u2014 set enableComplexity: true in config)";
|
|
102
|
+
} else {
|
|
103
|
+
const total = ccRows[0].total;
|
|
104
|
+
const good = ccRows[0].good;
|
|
105
|
+
complexity_score = Math.round(good / total * 2500);
|
|
106
|
+
}
|
|
107
|
+
const nodeCountRow = rawDb.all(
|
|
108
|
+
`SELECT COUNT(*) as cnt FROM nodes WHERE kind NOT IN ('file','module')`,
|
|
109
|
+
[]
|
|
110
|
+
);
|
|
111
|
+
const totalNonFile = nodeCountRow[0]?.cnt ?? 0;
|
|
112
|
+
let dead_code_score = 2500;
|
|
113
|
+
if (totalNonFile > 0) {
|
|
114
|
+
const deadRows = rawDb.all(
|
|
115
|
+
`SELECT COUNT(*) as cnt FROM nodes n
|
|
116
|
+
WHERE n.kind NOT IN ('file','module')
|
|
117
|
+
AND NOT EXISTS (SELECT 1 FROM edges e WHERE e.target = n.id)
|
|
118
|
+
AND NOT EXISTS (SELECT 1 FROM edges e WHERE e.source = n.id)`,
|
|
119
|
+
[]
|
|
120
|
+
);
|
|
121
|
+
const deadCount = deadRows[0]?.cnt ?? 0;
|
|
122
|
+
const dead_code_ratio = deadCount / totalNonFile;
|
|
123
|
+
dead_code_score = Math.round((1 - dead_code_ratio) * 2500);
|
|
124
|
+
}
|
|
125
|
+
const fanInRows = rawDb.all(
|
|
126
|
+
`SELECT AVG(cnt) as avg_fan_in FROM (SELECT target, COUNT(*) as cnt FROM edges WHERE kind='calls' GROUP BY target)`,
|
|
127
|
+
[]
|
|
128
|
+
);
|
|
129
|
+
const avg_fan_in = fanInRows[0]?.avg_fan_in ?? 0;
|
|
130
|
+
let coupling_score;
|
|
131
|
+
if (avg_fan_in < 3) coupling_score = 2500;
|
|
132
|
+
else if (avg_fan_in < 6) coupling_score = 2e3;
|
|
133
|
+
else if (avg_fan_in < 10) coupling_score = 1500;
|
|
134
|
+
else coupling_score = 1e3;
|
|
135
|
+
const circRows = rawDb.all(
|
|
136
|
+
`SELECT COUNT(DISTINCT source) as cnt FROM edges WHERE kind='circular_dep'`,
|
|
137
|
+
[]
|
|
138
|
+
);
|
|
139
|
+
const circCount = circRows[0]?.cnt ?? 0;
|
|
140
|
+
let circular_score;
|
|
141
|
+
if (circCount === 0) circular_score = 2500;
|
|
142
|
+
else if (circCount <= 5) circular_score = 2e3;
|
|
143
|
+
else if (circCount <= 15) circular_score = 1500;
|
|
144
|
+
else if (circCount <= 30) circular_score = 1e3;
|
|
145
|
+
else circular_score = 500;
|
|
146
|
+
const total_score = complexity_score + dead_code_score + coupling_score + circular_score;
|
|
147
|
+
const gradeLabel = total_score >= 9e3 ? "Excellent" : total_score >= 7e3 ? "Good" : total_score >= 5e3 ? "Fair" : total_score >= 3e3 ? "Poor" : "Critical";
|
|
148
|
+
const lines = [
|
|
149
|
+
`## Graph Health Score: ${total_score} / 10000 (${gradeLabel})
|
|
150
|
+
`,
|
|
151
|
+
`Breakdown:`,
|
|
152
|
+
` Complexity ${complexity_score.toString().padStart(5)} / 2500${complexityNote}`,
|
|
153
|
+
` Dead Code ${dead_code_score.toString().padStart(5)} / 2500 (avg dead ratio)`,
|
|
154
|
+
` Coupling ${coupling_score.toString().padStart(5)} / 2500 (avg fan-in: ${avg_fan_in.toFixed(2)})`,
|
|
155
|
+
` Circular Deps ${circular_score.toString().padStart(5)} / 2500 (${circCount} circular dep sources)`,
|
|
156
|
+
"",
|
|
157
|
+
`Interpretation:`,
|
|
158
|
+
` Complexity: ${complexity_score >= 2e3 ? "Most functions have acceptable complexity." : complexity_score >= 1500 ? "Some high-complexity functions detected." : "Many high-complexity functions \u2014 refactor recommended."}`,
|
|
159
|
+
` Dead Code: ${dead_code_score >= 2e3 ? "Very little unreachable code." : dead_code_score >= 1500 ? "Some potentially dead code nodes." : "Significant dead code detected \u2014 consider cleanup."}`,
|
|
160
|
+
` Coupling: ${coupling_score >= 2e3 ? "Low coupling \u2014 healthy fan-in." : coupling_score >= 1500 ? "Moderate coupling." : "High coupling \u2014 consider reducing dependencies."}`,
|
|
161
|
+
` Circular Deps: ${circular_score >= 2e3 ? "Few or no circular dependencies." : circular_score >= 1500 ? "Moderate circular dependencies." : "Many circular dependencies \u2014 architectural refactor recommended."}`
|
|
162
|
+
];
|
|
163
|
+
if (complexityNote) lines.push("\nNote: enableComplexity: false in config \u2014 set to true and re-index for accurate complexity scoring.");
|
|
164
|
+
return lines.join("\n");
|
|
165
|
+
}
|
|
166
|
+
case "kirograph_dsm": {
|
|
167
|
+
const limitN = (0, import_utils.clampLimit)(args.limit, 15);
|
|
168
|
+
const nodes = rawDb.all(
|
|
169
|
+
`SELECT id, file_path FROM nodes WHERE file_path IS NOT NULL AND file_path != ''`,
|
|
170
|
+
[]
|
|
171
|
+
);
|
|
172
|
+
const nodeGroup = /* @__PURE__ */ new Map();
|
|
173
|
+
const groupSet = /* @__PURE__ */ new Set();
|
|
174
|
+
for (const n of nodes) {
|
|
175
|
+
const parts = n.file_path.replace(/\\/g, "/").split("/");
|
|
176
|
+
const group = parts.length > 1 ? parts[0] : "<root>";
|
|
177
|
+
nodeGroup.set(n.id, group);
|
|
178
|
+
groupSet.add(group);
|
|
179
|
+
}
|
|
180
|
+
let groups = Array.from(groupSet).sort();
|
|
181
|
+
if (groups.length > limitN) groups = groups.slice(0, limitN);
|
|
182
|
+
if (groups.length === 0) return "No nodes with file paths found in the index.";
|
|
183
|
+
const matrix = groups.map(() => groups.map(() => 0));
|
|
184
|
+
const edges = rawDb.all(
|
|
185
|
+
`SELECT source, target FROM edges`,
|
|
186
|
+
[]
|
|
187
|
+
);
|
|
188
|
+
for (const e of edges) {
|
|
189
|
+
const srcGroup = nodeGroup.get(e.source);
|
|
190
|
+
const tgtGroup = nodeGroup.get(e.target);
|
|
191
|
+
if (!srcGroup || !tgtGroup) continue;
|
|
192
|
+
const ri = groups.indexOf(srcGroup);
|
|
193
|
+
const ci = groups.indexOf(tgtGroup);
|
|
194
|
+
if (ri >= 0 && ci >= 0) matrix[ri][ci]++;
|
|
195
|
+
}
|
|
196
|
+
const colWidth = Math.max(...groups.map((g) => g.length), 6);
|
|
197
|
+
const pad = (s, w) => s.slice(0, w).padEnd(w);
|
|
198
|
+
const lines = [`## Design Structure Matrix (${groups.length} groups)
|
|
199
|
+
`];
|
|
200
|
+
const header = "".padEnd(colWidth + 2) + groups.map((g) => pad(g, colWidth)).join(" ");
|
|
201
|
+
lines.push(header);
|
|
202
|
+
lines.push("-".repeat(header.length));
|
|
203
|
+
for (let r = 0; r < groups.length; r++) {
|
|
204
|
+
const row = pad(groups[r], colWidth) + " " + matrix[r].map((v) => v.toString().padEnd(colWidth)).join(" ");
|
|
205
|
+
lines.push(row);
|
|
206
|
+
}
|
|
207
|
+
const couplings = [];
|
|
208
|
+
for (let r = 0; r < groups.length; r++) {
|
|
209
|
+
for (let c = 0; c < groups.length; c++) {
|
|
210
|
+
if (r !== c && matrix[r][c] > 0) couplings.push({ a: groups[r], b: groups[c], count: matrix[r][c] });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
couplings.sort((x, y) => y.count - x.count);
|
|
214
|
+
lines.push("\n## Top 5 Heaviest Couplings:");
|
|
215
|
+
if (couplings.length === 0) {
|
|
216
|
+
lines.push(" No cross-group dependencies found.");
|
|
217
|
+
} else {
|
|
218
|
+
for (const cp of couplings.slice(0, 5)) {
|
|
219
|
+
lines.push(` ${cp.a} \u2192 ${cp.b} (${cp.count} edges)`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return lines.join("\n");
|
|
223
|
+
}
|
|
224
|
+
case "kirograph_test_risk": {
|
|
225
|
+
const limitN = (0, import_utils.clampLimit)(args.limit, 20);
|
|
226
|
+
const threshold = args.threshold ?? 0;
|
|
227
|
+
const rows = rawDb.all(
|
|
228
|
+
`SELECT n.name, n.kind, n.file_path, n.start_line,
|
|
229
|
+
n.complexity_cyclomatic as cc,
|
|
230
|
+
COUNT(e.source) as fan_in
|
|
231
|
+
FROM nodes n
|
|
232
|
+
LEFT JOIN edges e ON e.target = n.id AND e.kind = 'calls'
|
|
233
|
+
WHERE n.kind IN ('function','method')
|
|
234
|
+
AND n.complexity_cyclomatic IS NOT NULL
|
|
235
|
+
GROUP BY n.id
|
|
236
|
+
HAVING (n.complexity_cyclomatic * COUNT(e.source)) > ?
|
|
237
|
+
ORDER BY (n.complexity_cyclomatic * COUNT(e.source)) DESC
|
|
238
|
+
LIMIT ?`,
|
|
239
|
+
[threshold, limitN]
|
|
240
|
+
);
|
|
241
|
+
if (rows.length === 0) {
|
|
242
|
+
return "No test risk data found. Ensure complexity is enabled (enableComplexity: true) and re-index.";
|
|
243
|
+
}
|
|
244
|
+
const lines = [
|
|
245
|
+
`## Test Risk Scores (top ${rows.length}, threshold=${threshold})
|
|
246
|
+
`,
|
|
247
|
+
`${"risk".padEnd(8)} ${"cc".padEnd(6)} ${"fan_in".padEnd(8)} kind name \u2014 location`,
|
|
248
|
+
"-".repeat(80)
|
|
249
|
+
];
|
|
250
|
+
for (const r of rows) {
|
|
251
|
+
const risk = r.cc * r.fan_in;
|
|
252
|
+
lines.push(
|
|
253
|
+
`${risk.toString().padEnd(8)} ${(r.cc ?? 0).toString().padEnd(6)} ${r.fan_in.toString().padEnd(8)} ${(0, import_utils.mapKind)(r.kind).padEnd(10)} \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
lines.push("\nNote: Coverage and churn factors not yet available \u2014 scores reflect complexity \xD7 fan-in only.");
|
|
257
|
+
return lines.join("\n");
|
|
258
|
+
}
|
|
259
|
+
default:
|
|
260
|
+
return `Unknown tool: ${toolName}`;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
264
|
+
0 && (module.exports = {
|
|
265
|
+
handleComplexity
|
|
266
|
+
});
|
|
267
|
+
//# sourceMappingURL=complexity.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/handlers/complexity.ts"],
|
|
4
|
+
"sourcesContent": ["import KiroGraph from '../../index';\nimport { clampLimit, mapKind } from './utils';\n\nexport async function handleComplexity(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n const rawDb = cg.getDatabase().getRawDb();\n\n switch (toolName) {\n case 'kirograph_complexity': {\n const limitN = clampLimit(args.limit as number | undefined, 30);\n const metric = (args.metric as string) ?? 'cyclomatic';\n const col = metric === 'cognitive' ? 'complexity_cognitive'\n : metric === 'maintainability' ? 'maintainability_index'\n : 'complexity_cyclomatic';\n const order = metric === 'maintainability' ? 'ASC' : 'DESC';\n const threshold = (args.threshold as number) ?? (metric === 'maintainability' ? 50 : 10);\n\n const rows = rawDb.all(\n `SELECT name, kind, file_path, start_line, complexity_cyclomatic, complexity_cognitive,\n maintainability_index, nesting_depth, (end_line - start_line + 1) as loc\n FROM nodes WHERE ${col} IS NOT NULL AND kind IN ('function','method')\n ORDER BY ${col} ${order} LIMIT ?`,\n [limitN]\n );\n if (rows.length === 0) {\n return 'No complexity data found. Re-index with enableComplexity: true in .kirograph/config.json, then run `kirograph index`.';\n }\n const flagged = rows.filter((r: any) =>\n metric === 'maintainability' ? (r.maintainability_index ?? 100) <= threshold : (r[col] ?? 0) >= threshold\n );\n const lines = [\n `Symbols ranked by ${metric} complexity (${rows.length} shown${flagged.length > 0 ? `, ${flagged.length} exceeding threshold ${threshold}` : ''}):\\n`,\n ];\n for (const r of rows) {\n const cc = r.complexity_cyclomatic ?? '\u2014';\n const mi = r.maintainability_index !== null ? (r.maintainability_index as number).toFixed(1) : '\u2014';\n const depth = r.nesting_depth ?? '\u2014';\n const warn = flagged.includes(r) ? '\u26A0 ' : ' ';\n lines.push(`${warn}CC=${cc} MI=${mi} depth=${depth} ${r.loc}LOC ${mapKind(r.kind)} \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_simplify_scan': {\n // Quality analysis of changed files \u2014 complexity + size on recently modified symbols\n const limitN = clampLimit(args.limit as number | undefined, 30);\n const thresholdCC = (args.thresholdCC as number) ?? 10;\n const thresholdMI = (args.thresholdMI as number) ?? 50;\n const thresholdLOC = (args.thresholdLOC as number) ?? 50;\n\n const rows = rawDb.all(\n `SELECT name, kind, file_path, start_line,\n complexity_cyclomatic, maintainability_index,\n nesting_depth, (end_line - start_line + 1) as loc\n FROM nodes WHERE kind IN ('function','method')\n AND (\n (complexity_cyclomatic IS NOT NULL AND complexity_cyclomatic >= ?)\n OR (maintainability_index IS NOT NULL AND maintainability_index <= ?)\n OR ((end_line - start_line + 1) >= ?)\n )\n ORDER BY complexity_cyclomatic DESC NULLS LAST LIMIT ?`,\n [thresholdCC, thresholdMI, thresholdLOC, limitN]\n );\n if (rows.length === 0) return 'No simplification candidates found \u2014 complexity is within thresholds.';\n const lines = [`Simplification candidates (${rows.length}):\\n`];\n for (const r of rows) {\n const issues = [];\n if (r.complexity_cyclomatic !== null && r.complexity_cyclomatic >= thresholdCC) issues.push(`CC=${r.complexity_cyclomatic}`);\n if (r.maintainability_index !== null && r.maintainability_index <= thresholdMI) issues.push(`MI=${(r.maintainability_index as number).toFixed(1)}`);\n if (r.loc >= thresholdLOC) issues.push(`${r.loc}LOC`);\n lines.push(` [${issues.join(', ')}] ${mapKind(r.kind)} \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_health': {\n // complexity_score (0\u20132500): % of function/method nodes with CC <= 10\n const ccRows = rawDb.all(\n `SELECT COUNT(*) as total,\n SUM(CASE WHEN complexity_cyclomatic <= 10 THEN 1 ELSE 0 END) as good\n FROM nodes WHERE kind IN ('function','method') AND complexity_cyclomatic IS NOT NULL`,\n []\n );\n let complexity_score: number;\n let complexityNote = '';\n if (!ccRows[0] || (ccRows[0] as any).total === 0) {\n complexity_score = 2500;\n complexityNote = ' (no CC data \u2014 set enableComplexity: true in config)';\n } else {\n const total = (ccRows[0] as any).total as number;\n const good = (ccRows[0] as any).good as number;\n complexity_score = Math.round((good / total) * 2500);\n }\n\n // dead_code_score (0\u20132500)\n const nodeCountRow = rawDb.all(\n `SELECT COUNT(*) as cnt FROM nodes WHERE kind NOT IN ('file','module')`,\n []\n );\n const totalNonFile = (nodeCountRow[0] as any)?.cnt as number ?? 0;\n let dead_code_score = 2500;\n if (totalNonFile > 0) {\n const deadRows = rawDb.all(\n `SELECT COUNT(*) as cnt FROM nodes n\n WHERE n.kind NOT IN ('file','module')\n AND NOT EXISTS (SELECT 1 FROM edges e WHERE e.target = n.id)\n AND NOT EXISTS (SELECT 1 FROM edges e WHERE e.source = n.id)`,\n []\n );\n const deadCount = (deadRows[0] as any)?.cnt as number ?? 0;\n const dead_code_ratio = deadCount / totalNonFile;\n dead_code_score = Math.round((1 - dead_code_ratio) * 2500);\n }\n\n // coupling_score (0\u20132500)\n const fanInRows = rawDb.all(\n `SELECT AVG(cnt) as avg_fan_in FROM (SELECT target, COUNT(*) as cnt FROM edges WHERE kind='calls' GROUP BY target)`,\n []\n );\n const avg_fan_in = (fanInRows[0] as any)?.avg_fan_in as number ?? 0;\n let coupling_score: number;\n if (avg_fan_in < 3) coupling_score = 2500;\n else if (avg_fan_in < 6) coupling_score = 2000;\n else if (avg_fan_in < 10) coupling_score = 1500;\n else coupling_score = 1000;\n\n // circular_score (0\u20132500)\n const circRows = rawDb.all(\n `SELECT COUNT(DISTINCT source) as cnt FROM edges WHERE kind='circular_dep'`,\n []\n );\n const circCount = (circRows[0] as any)?.cnt as number ?? 0;\n let circular_score: number;\n if (circCount === 0) circular_score = 2500;\n else if (circCount <= 5) circular_score = 2000;\n else if (circCount <= 15) circular_score = 1500;\n else if (circCount <= 30) circular_score = 1000;\n else circular_score = 500;\n\n const total_score = complexity_score + dead_code_score + coupling_score + circular_score;\n\n const gradeLabel = total_score >= 9000 ? 'Excellent'\n : total_score >= 7000 ? 'Good'\n : total_score >= 5000 ? 'Fair'\n : total_score >= 3000 ? 'Poor'\n : 'Critical';\n\n const lines = [\n `## Graph Health Score: ${total_score} / 10000 (${gradeLabel})\\n`,\n `Breakdown:`,\n ` Complexity ${complexity_score.toString().padStart(5)} / 2500${complexityNote}`,\n ` Dead Code ${dead_code_score.toString().padStart(5)} / 2500 (avg dead ratio)`,\n ` Coupling ${coupling_score.toString().padStart(5)} / 2500 (avg fan-in: ${avg_fan_in.toFixed(2)})`,\n ` Circular Deps ${circular_score.toString().padStart(5)} / 2500 (${circCount} circular dep sources)`,\n '',\n `Interpretation:`,\n ` Complexity: ${complexity_score >= 2000 ? 'Most functions have acceptable complexity.' : complexity_score >= 1500 ? 'Some high-complexity functions detected.' : 'Many high-complexity functions \u2014 refactor recommended.'}`,\n ` Dead Code: ${dead_code_score >= 2000 ? 'Very little unreachable code.' : dead_code_score >= 1500 ? 'Some potentially dead code nodes.' : 'Significant dead code detected \u2014 consider cleanup.'}`,\n ` Coupling: ${coupling_score >= 2000 ? 'Low coupling \u2014 healthy fan-in.' : coupling_score >= 1500 ? 'Moderate coupling.' : 'High coupling \u2014 consider reducing dependencies.'}`,\n ` Circular Deps: ${circular_score >= 2000 ? 'Few or no circular dependencies.' : circular_score >= 1500 ? 'Moderate circular dependencies.' : 'Many circular dependencies \u2014 architectural refactor recommended.'}`,\n ];\n if (complexityNote) lines.push('\\nNote: enableComplexity: false in config \u2014 set to true and re-index for accurate complexity scoring.');\n return lines.join('\\n');\n }\n\n case 'kirograph_dsm': {\n const limitN = clampLimit(args.limit as number | undefined, 15);\n\n // Get all nodes with file_path\n const nodes = rawDb.all(\n `SELECT id, file_path FROM nodes WHERE file_path IS NOT NULL AND file_path != ''`,\n []\n ) as Array<{ id: string; file_path: string }>;\n\n // Extract top-level dir\n const nodeGroup = new Map<string, string>();\n const groupSet = new Set<string>();\n for (const n of nodes) {\n const parts = n.file_path.replace(/\\\\/g, '/').split('/');\n const group = parts.length > 1 ? parts[0] : '<root>';\n nodeGroup.set(n.id, group);\n groupSet.add(group);\n }\n\n let groups = Array.from(groupSet).sort();\n if (groups.length > limitN) groups = groups.slice(0, limitN);\n\n if (groups.length === 0) return 'No nodes with file paths found in the index.';\n\n // Build matrix: for each pair (A, B), count edges from nodes in A to nodes in B\n const matrix: number[][] = groups.map(() => groups.map(() => 0));\n const edges = rawDb.all(\n `SELECT source, target FROM edges`,\n []\n ) as Array<{ source: string; target: string }>;\n\n for (const e of edges) {\n const srcGroup = nodeGroup.get(e.source);\n const tgtGroup = nodeGroup.get(e.target);\n if (!srcGroup || !tgtGroup) continue;\n const ri = groups.indexOf(srcGroup);\n const ci = groups.indexOf(tgtGroup);\n if (ri >= 0 && ci >= 0) matrix[ri][ci]++;\n }\n\n // Build text table\n const colWidth = Math.max(...groups.map(g => g.length), 6);\n const pad = (s: string, w: number) => s.slice(0, w).padEnd(w);\n const lines = [`## Design Structure Matrix (${groups.length} groups)\\n`];\n const header = ''.padEnd(colWidth + 2) + groups.map(g => pad(g, colWidth)).join(' ');\n lines.push(header);\n lines.push('-'.repeat(header.length));\n for (let r = 0; r < groups.length; r++) {\n const row = pad(groups[r], colWidth) + ' ' + matrix[r].map(v => v.toString().padEnd(colWidth)).join(' ');\n lines.push(row);\n }\n\n // Top 5 heaviest couplings\n const couplings: Array<{ a: string; b: string; count: number }> = [];\n for (let r = 0; r < groups.length; r++) {\n for (let c = 0; c < groups.length; c++) {\n if (r !== c && matrix[r][c] > 0) couplings.push({ a: groups[r], b: groups[c], count: matrix[r][c] });\n }\n }\n couplings.sort((x, y) => y.count - x.count);\n lines.push('\\n## Top 5 Heaviest Couplings:');\n if (couplings.length === 0) {\n lines.push(' No cross-group dependencies found.');\n } else {\n for (const cp of couplings.slice(0, 5)) {\n lines.push(` ${cp.a} \u2192 ${cp.b} (${cp.count} edges)`);\n }\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_test_risk': {\n const limitN = clampLimit(args.limit as number | undefined, 20);\n const threshold = (args.threshold as number) ?? 0;\n\n // Risk = CC * fan_in (coverage and churn not yet available)\n const rows = rawDb.all(\n `SELECT n.name, n.kind, n.file_path, n.start_line,\n n.complexity_cyclomatic as cc,\n COUNT(e.source) as fan_in\n FROM nodes n\n LEFT JOIN edges e ON e.target = n.id AND e.kind = 'calls'\n WHERE n.kind IN ('function','method')\n AND n.complexity_cyclomatic IS NOT NULL\n GROUP BY n.id\n HAVING (n.complexity_cyclomatic * COUNT(e.source)) > ?\n ORDER BY (n.complexity_cyclomatic * COUNT(e.source)) DESC\n LIMIT ?`,\n [threshold, limitN]\n ) as Array<{ name: string; kind: string; file_path: string; start_line: number; cc: number; fan_in: number }>;\n\n if (rows.length === 0) {\n return 'No test risk data found. Ensure complexity is enabled (enableComplexity: true) and re-index.';\n }\n\n const lines = [\n `## Test Risk Scores (top ${rows.length}, threshold=${threshold})\\n`,\n `${'risk'.padEnd(8)} ${'cc'.padEnd(6)} ${'fan_in'.padEnd(8)} kind name \u2014 location`,\n '-'.repeat(80),\n ];\n for (const r of rows) {\n const risk = r.cc * r.fan_in;\n lines.push(\n `${risk.toString().padEnd(8)} ${(r.cc ?? 0).toString().padEnd(6)} ${r.fan_in.toString().padEnd(8)} ${mapKind(r.kind).padEnd(10)} \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`\n );\n }\n lines.push('\\nNote: Coverage and churn factors not yet available \u2014 scores reflect complexity \u00D7 fan-in only.');\n return lines.join('\\n');\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|