@kaddo/mcp 3.21.0 → 3.22.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/index.js +65 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -504,8 +504,12 @@ function projectStatus(root) {
|
|
|
504
504
|
withOwnership: explain.ownership?.workItemsWithOwnership ?? 0,
|
|
505
505
|
total: explain.ownership?.workItemsTotal ?? 0
|
|
506
506
|
},
|
|
507
|
-
|
|
508
|
-
|
|
507
|
+
graph: {
|
|
508
|
+
scope: hints?.scope ?? "unknown (run `kaddo graph export`)",
|
|
509
|
+
scope_reason: hints?.scope_reason ?? "",
|
|
510
|
+
quality: hints?.quality ?? "unknown (run `kaddo graph export`)",
|
|
511
|
+
hints: hints?.summary?.hints ?? 0
|
|
512
|
+
},
|
|
509
513
|
capsules: capsules.length
|
|
510
514
|
});
|
|
511
515
|
}
|
|
@@ -553,7 +557,13 @@ function listGraphHints(root, filter = {}) {
|
|
|
553
557
|
if (filter.artifact_type) hints = hints.filter((h) => h.artifact_type === filter.artifact_type);
|
|
554
558
|
if (filter.severity) hints = hints.filter((h) => h.severity === filter.severity);
|
|
555
559
|
if (filter.active_only) hints = hints.filter((h) => h.artifact_type === "work-item");
|
|
556
|
-
return ok({
|
|
560
|
+
return ok({
|
|
561
|
+
scope: report.scope ?? "active",
|
|
562
|
+
scope_reason: report.scope_reason ?? "",
|
|
563
|
+
quality: report.quality ?? "unknown",
|
|
564
|
+
count: hints.length,
|
|
565
|
+
hints
|
|
566
|
+
});
|
|
557
567
|
}
|
|
558
568
|
|
|
559
569
|
// ../cli/src/core/config.ts
|
|
@@ -1521,6 +1531,11 @@ function loadExternalCapsules(dir) {
|
|
|
1521
1531
|
|
|
1522
1532
|
// ../cli/src/core/graph.ts
|
|
1523
1533
|
var KNOWLEDGE3 = "knowledge";
|
|
1534
|
+
var ACTIVE_STATUSES = ["draft", "ready", "in-progress", "blocked"];
|
|
1535
|
+
var ALL_STATUSES = ["draft", "ready", "in-progress", "blocked", "completed"];
|
|
1536
|
+
function scopeStatuses(scope) {
|
|
1537
|
+
return scope === "all" ? { included: ALL_STATUSES, excluded: ["archived"] } : { included: ACTIVE_STATUSES, excluded: ["completed", "archived"] };
|
|
1538
|
+
}
|
|
1524
1539
|
function toPosix3(p) {
|
|
1525
1540
|
return p.replace(/\\/g, "/");
|
|
1526
1541
|
}
|
|
@@ -1563,7 +1578,10 @@ function buildGraph(dir, config, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
1563
1578
|
}
|
|
1564
1579
|
const all = discoverKnowledge(dir);
|
|
1565
1580
|
const workItems = all.filter((a) => a.isWorkItem);
|
|
1566
|
-
const
|
|
1581
|
+
const { included, excluded } = scopeStatuses(scope);
|
|
1582
|
+
const includedSet = new Set(included);
|
|
1583
|
+
const activeWICount = workItems.filter((a) => a.lifecycle && isActiveState(a.lifecycle)).length;
|
|
1584
|
+
const selectedWIs = workItems.filter((a) => a.lifecycle && includedSet.has(a.lifecycle));
|
|
1567
1585
|
for (const wi of selectedWIs) {
|
|
1568
1586
|
const id = wi.id || wi.title;
|
|
1569
1587
|
const wiNodeId = `wi:${id}`;
|
|
@@ -1633,6 +1651,7 @@ function buildGraph(dir, config, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
1633
1651
|
}
|
|
1634
1652
|
}
|
|
1635
1653
|
}
|
|
1654
|
+
const scopeReason = scope === "all" ? "All supported Work Item statuses are included." : activeWICount === 0 ? "No active Work Items found. Completed Work Items are excluded from active scope." : "Active Work Items only; completed and archived are excluded.";
|
|
1636
1655
|
return {
|
|
1637
1656
|
generated_at: now.toISOString(),
|
|
1638
1657
|
project: {
|
|
@@ -1640,6 +1659,10 @@ function buildGraph(dir, config, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
1640
1659
|
state: config.project.state,
|
|
1641
1660
|
structure: config.project.structure
|
|
1642
1661
|
},
|
|
1662
|
+
scope,
|
|
1663
|
+
scope_reason: scopeReason,
|
|
1664
|
+
included_statuses: included,
|
|
1665
|
+
excluded_statuses: excluded,
|
|
1643
1666
|
nodes: [...nodes.values()],
|
|
1644
1667
|
edges
|
|
1645
1668
|
};
|
|
@@ -1687,8 +1710,13 @@ function loadGraphSummary(dir) {
|
|
|
1687
1710
|
const connected = new Set(
|
|
1688
1711
|
edges.filter((e) => e.type === "owns" && activeWiIds.has(e.from)).map((e) => e.from)
|
|
1689
1712
|
);
|
|
1713
|
+
const scope = graph.scope === "all" ? "all" : "active";
|
|
1690
1714
|
return {
|
|
1691
1715
|
generatedAt: String(graph.generated_at ?? ""),
|
|
1716
|
+
scope,
|
|
1717
|
+
scopeReason: String(graph.scope_reason ?? ""),
|
|
1718
|
+
includedStatuses: Array.isArray(graph.included_statuses) ? graph.included_statuses : [],
|
|
1719
|
+
excludedStatuses: Array.isArray(graph.excluded_statuses) ? graph.excluded_statuses : [],
|
|
1692
1720
|
nodes: nodes.length,
|
|
1693
1721
|
edges: edges.length,
|
|
1694
1722
|
activeWorkItemsConnectedToCode: connected.size
|
|
@@ -1840,6 +1868,8 @@ function buildGraphHints(dir, graph, now = /* @__PURE__ */ new Date()) {
|
|
|
1840
1868
|
const quality = assessQuality(nodes, relationshipEdges, hints.length);
|
|
1841
1869
|
return {
|
|
1842
1870
|
generated_at: now.toISOString(),
|
|
1871
|
+
scope: graph.scope,
|
|
1872
|
+
scope_reason: graph.scope_reason,
|
|
1843
1873
|
quality,
|
|
1844
1874
|
summary: { nodes, edges: graph.edges.length, hints: hints.length },
|
|
1845
1875
|
metrics,
|
|
@@ -1875,13 +1905,23 @@ function renderGraphHintsMarkdown(report) {
|
|
|
1875
1905
|
lines.push("");
|
|
1876
1906
|
lines.push("## Summary");
|
|
1877
1907
|
lines.push("");
|
|
1908
|
+
lines.push(`- Scope: ${report.scope} \u2014 ${report.scope_reason}`);
|
|
1878
1909
|
lines.push(`- Relationship quality: ${report.quality} \u2014 ${QUALITY_NOTE[report.quality]}`);
|
|
1879
1910
|
lines.push(`- Nodes: ${report.summary.nodes}`);
|
|
1880
1911
|
lines.push(`- Edges: ${report.summary.edges}`);
|
|
1881
1912
|
lines.push(`- Hints: ${report.summary.hints}`);
|
|
1882
1913
|
lines.push("");
|
|
1883
1914
|
if (report.hints.length === 0) {
|
|
1884
|
-
|
|
1915
|
+
if (report.quality === "empty") {
|
|
1916
|
+
lines.push("No active relationship hints were generated.");
|
|
1917
|
+
lines.push("");
|
|
1918
|
+
lines.push(`The graph is ${report.quality} for the **${report.scope}** scope \u2014 ${report.scope_reason}`);
|
|
1919
|
+
if (report.scope !== "all") {
|
|
1920
|
+
lines.push("Run `kaddo graph export --scope all` to inspect completed Work Items and historical relationships.");
|
|
1921
|
+
}
|
|
1922
|
+
} else {
|
|
1923
|
+
lines.push("No hints \u2014 the declared relationships look healthy. \u{1F389}");
|
|
1924
|
+
}
|
|
1885
1925
|
lines.push("");
|
|
1886
1926
|
return lines.join("\n");
|
|
1887
1927
|
}
|
|
@@ -1917,6 +1957,8 @@ function loadGraphHints(dir) {
|
|
|
1917
1957
|
const report = JSON.parse(readFile(p));
|
|
1918
1958
|
const hints = Array.isArray(report.hints) ? report.hints : [];
|
|
1919
1959
|
return {
|
|
1960
|
+
scope: String(report.scope ?? "active"),
|
|
1961
|
+
scopeReason: String(report.scope_reason ?? ""),
|
|
1920
1962
|
quality: report.quality ?? "empty",
|
|
1921
1963
|
totalHints: hints.length,
|
|
1922
1964
|
activeWorkItemHints: hints.filter((h) => h.artifact_type === "work-item").length,
|
|
@@ -2316,9 +2358,12 @@ function renderContextPack(pack) {
|
|
|
2316
2358
|
parts.push(
|
|
2317
2359
|
[
|
|
2318
2360
|
"- Available: yes",
|
|
2361
|
+
`- Scope: ${pack.graph.scope}`,
|
|
2319
2362
|
`- Nodes: ${pack.graph.nodes}`,
|
|
2320
2363
|
`- Edges: ${pack.graph.edges}`,
|
|
2321
|
-
|
|
2364
|
+
...pack.graphHints ? [`- Quality: ${pack.graphHints.quality}`] : [],
|
|
2365
|
+
`- Active Work Items connected to code: ${pack.graph.activeWorkItemsConnectedToCode}`,
|
|
2366
|
+
...pack.graph.scopeReason ? [`- Reason: ${pack.graph.scopeReason}`] : []
|
|
2322
2367
|
].join("\n") + "\n"
|
|
2323
2368
|
);
|
|
2324
2369
|
parts.push("Full graph: `.kaddo/graph.json` / `.kaddo/graph.mmd` (run `kaddo graph export` to refresh).\n");
|
|
@@ -2709,13 +2754,18 @@ function renderExplanationHuman(exp) {
|
|
|
2709
2754
|
}
|
|
2710
2755
|
if (exp.graph) {
|
|
2711
2756
|
lines.push("## Knowledge Graph");
|
|
2757
|
+
lines.push(`- Scope: ${exp.graph.scope}`);
|
|
2712
2758
|
lines.push(`- Nodes: ${exp.graph.nodes}`);
|
|
2713
2759
|
lines.push(`- Edges: ${exp.graph.edges}`);
|
|
2714
2760
|
if (exp.graphHints) {
|
|
2715
2761
|
lines.push(`- Quality: ${exp.graphHints.quality}`);
|
|
2716
2762
|
lines.push(`- Hints: ${exp.graphHints.totalHints}`);
|
|
2717
2763
|
}
|
|
2764
|
+
if (exp.graph.scopeReason) lines.push(`- Reason: ${exp.graph.scopeReason}`);
|
|
2718
2765
|
if (exp.graph.generatedAt) lines.push(`- Last exported: ${exp.graph.generatedAt}`);
|
|
2766
|
+
if (exp.graph.scope === "active" && exp.graphHints?.quality === "empty") {
|
|
2767
|
+
lines.push("- Tip: Run `kaddo graph export --scope all` to include completed Work Items");
|
|
2768
|
+
}
|
|
2719
2769
|
lines.push("");
|
|
2720
2770
|
}
|
|
2721
2771
|
if (exp.skills.total > 0) {
|
|
@@ -2973,10 +3023,10 @@ function generateUnderstand(root) {
|
|
|
2973
3023
|
next_suggested_resources: ["kaddo://understand"]
|
|
2974
3024
|
};
|
|
2975
3025
|
}
|
|
2976
|
-
function generateGraph(root) {
|
|
3026
|
+
function generateGraph(root, scope = "active") {
|
|
2977
3027
|
const config = requireConfig(root);
|
|
2978
3028
|
requireKnowledge(root);
|
|
2979
|
-
const graph = buildGraph(root, config, { scope
|
|
3029
|
+
const graph = buildGraph(root, config, { scope });
|
|
2980
3030
|
const hints = buildGraphHints(root, graph);
|
|
2981
3031
|
writeDerived(root, ".kaddo/graph.json", serializeGraphJson(graph));
|
|
2982
3032
|
writeDerived(root, ".kaddo/graph.mmd", renderGraphMermaid(graph));
|
|
@@ -2991,7 +3041,7 @@ function generateGraph(root) {
|
|
|
2991
3041
|
".kaddo/graph-hints.md",
|
|
2992
3042
|
".kaddo/graph-hints.json"
|
|
2993
3043
|
],
|
|
2994
|
-
summary:
|
|
3044
|
+
summary: `Knowledge graph and hints generated successfully (${scope} scope).`,
|
|
2995
3045
|
warnings,
|
|
2996
3046
|
next_suggested_resources: ["kaddo://graph", "kaddo://graph-hints"]
|
|
2997
3047
|
};
|
|
@@ -3172,8 +3222,12 @@ function createServer(root) {
|
|
|
3172
3222
|
);
|
|
3173
3223
|
server.registerTool(
|
|
3174
3224
|
"kaddo_generate_graph",
|
|
3175
|
-
{
|
|
3176
|
-
|
|
3225
|
+
{
|
|
3226
|
+
title: "Generate knowledge graph",
|
|
3227
|
+
description: `Regenerate .kaddo/graph.json/.mmd + graph-hints.md/.json. scope: active (default) or all. ${DERIVED_NOTE}`,
|
|
3228
|
+
inputSchema: { scope: z2.enum(["active", "all"]).optional() }
|
|
3229
|
+
},
|
|
3230
|
+
async (args) => generated(root, "generate knowledge graph", () => generateGraph(root, args.scope ?? "active"))
|
|
3177
3231
|
);
|
|
3178
3232
|
server.registerTool(
|
|
3179
3233
|
"kaddo_generate_capsule_draft",
|
package/package.json
CHANGED