@kaddo/cli 3.23.1 → 3.23.2
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 +1 -0
- package/dist/index.js +23 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -512,6 +512,7 @@ create --from roadmap → owners → guard → explain`.
|
|
|
512
512
|
| v3.22.1 | Guard project-root path normalization: matches `code:` globs when the project is a subfolder of the Git root |
|
|
513
513
|
| v3.23 | Knowledge Impact Report: `kaddo report impact` (Markdown/JSON, `--output`); evidence-first health/coverage/traceability/readiness/signals; MCP resource + tool |
|
|
514
514
|
| v3.23.1 | Impact report Actionable Gaps: per-Work-Item missing source/initiative/ownership/level/acceptance/DoD/validation, broad globs, overlaps; Work-Item-specific Suggested Actions + Score Breakdown |
|
|
515
|
+
| v3.23.2 | Impact report defaults to `all` scope (accumulated impact), graph built in memory; `--scope active`; `scope_source`/`default_scope` in JSON |
|
|
515
516
|
|
|
516
517
|
**Optional modules (installed with `kaddo add`):**
|
|
517
518
|
|
package/dist/index.js
CHANGED
|
@@ -10933,6 +10933,8 @@ function hasSection(body, re) {
|
|
|
10933
10933
|
return body.split(/\r?\n/).some((l) => /^#{1,6}\s+/.test(l) && re.test(l));
|
|
10934
10934
|
}
|
|
10935
10935
|
function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
10936
|
+
const resolvedScope = opts.scope ?? "all";
|
|
10937
|
+
const scopeSource = opts.scopeSource ?? (opts.scope ? "explicit" : "default");
|
|
10936
10938
|
const exp = buildProjectExplanation(dir);
|
|
10937
10939
|
const wis = discoverWorkItems(dir);
|
|
10938
10940
|
const total = wis.length;
|
|
@@ -11003,19 +11005,13 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
11003
11005
|
}
|
|
11004
11006
|
const ownershipOverlaps = gaps.ownership_overlaps.length;
|
|
11005
11007
|
let g;
|
|
11006
|
-
|
|
11007
|
-
|
|
11008
|
-
|
|
11009
|
-
|
|
11010
|
-
|
|
11011
|
-
g = { available: true, scope: graph.scope, scopeReason: graph.scope_reason, nodes: graph.nodes.length, edges: graph.edges.length, quality: hints.quality, hints: hints.summary.hints, generatedAt: graph.generated_at };
|
|
11012
|
-
} else {
|
|
11013
|
-
g = { available: false, scope: opts.scope, scopeReason: "", nodes: 0, edges: 0, quality: "unknown", hints: 0, generatedAt: "" };
|
|
11014
|
-
}
|
|
11015
|
-
} else if (exp.graph) {
|
|
11016
|
-
g = { available: true, scope: exp.graph.scope, scopeReason: exp.graph.scopeReason, nodes: exp.graph.nodes, edges: exp.graph.edges, quality: exp.graphHints?.quality ?? "unknown", hints: exp.graphHints?.totalHints ?? 0, generatedAt: exp.graph.generatedAt };
|
|
11008
|
+
const config = loadConfig(dir);
|
|
11009
|
+
if (config) {
|
|
11010
|
+
const graph = buildGraph(dir, config, { scope: resolvedScope }, now);
|
|
11011
|
+
const hints = buildGraphHints(dir, graph, now);
|
|
11012
|
+
g = { available: true, scope: graph.scope, scopeReason: graph.scope_reason, nodes: graph.nodes.length, edges: graph.edges.length, quality: hints.quality, hints: hints.summary.hints, generatedAt: graph.generated_at };
|
|
11017
11013
|
} else {
|
|
11018
|
-
g = { available: false, scope:
|
|
11014
|
+
g = { available: false, scope: resolvedScope, scopeReason: "", nodes: 0, edges: 0, quality: "unknown", hints: 0, generatedAt: "" };
|
|
11019
11015
|
}
|
|
11020
11016
|
const layerStatus = (name) => exp.layers.find((l) => l.layer === name)?.status ?? "Missing";
|
|
11021
11017
|
const byState = exp.workItems.byState;
|
|
@@ -11113,7 +11109,7 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
11113
11109
|
};
|
|
11114
11110
|
const actions = [];
|
|
11115
11111
|
if (!g.available) actions.push("Run `kaddo graph export --scope all` to inspect full traceability.");
|
|
11116
|
-
else if (g.scope === "active" && g.quality === "empty") actions.push("Run `kaddo
|
|
11112
|
+
else if (g.scope === "active" && g.quality === "empty") actions.push("Run `kaddo impact --scope all` to measure accumulated knowledge impact.");
|
|
11117
11113
|
if (exp.roadmap.remaining > 0) actions.push(`Materialize the ${exp.roadmap.remaining} remaining roadmap candidate(s) with \`kaddo create --from roadmap\`.`);
|
|
11118
11114
|
for (const a of [
|
|
11119
11115
|
groupedAction(gaps.missing_code_ownership, "Add `code:` ownership to"),
|
|
@@ -11138,6 +11134,8 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
11138
11134
|
generated_at: now.toISOString(),
|
|
11139
11135
|
project: exp.project.name,
|
|
11140
11136
|
scope: g.scope,
|
|
11137
|
+
default_scope: "all",
|
|
11138
|
+
scope_source: scopeSource,
|
|
11141
11139
|
executive_summary: summary,
|
|
11142
11140
|
knowledge_health,
|
|
11143
11141
|
knowledge_coverage,
|
|
@@ -11192,6 +11190,11 @@ function renderImpactMarkdown(r) {
|
|
|
11192
11190
|
L.push(`Scope: ${r.scope}`);
|
|
11193
11191
|
if (r.score !== null) L.push(`Knowledge Impact Score: ${r.score}/100`);
|
|
11194
11192
|
else L.push("Knowledge Impact Score: not available");
|
|
11193
|
+
if (r.scope_source === "default") {
|
|
11194
|
+
L.push("Scope note: Impact reports use `all` by default to measure accumulated knowledge impact.");
|
|
11195
|
+
} else if (r.scope === "active" && r.graph_quality.available === false) {
|
|
11196
|
+
L.push("Tip: Run `kaddo impact --scope all` to inspect accumulated knowledge impact.");
|
|
11197
|
+
}
|
|
11195
11198
|
L.push("");
|
|
11196
11199
|
L.push("## Executive Summary", "");
|
|
11197
11200
|
for (const s2 of r.executive_summary) L.push(`- ${s2}`);
|
|
@@ -11248,6 +11251,9 @@ function renderImpactMarkdown(r) {
|
|
|
11248
11251
|
L.push(`- Hints: ${gq.hints}`);
|
|
11249
11252
|
if (gq.reason) L.push(`- Reason: ${gq.reason}`);
|
|
11250
11253
|
if (gq.last_exported) L.push(`- Last exported: ${gq.last_exported}`);
|
|
11254
|
+
if (gq.scope === "active" && gq.quality === "empty") {
|
|
11255
|
+
L.push("- Tip: Run `kaddo impact --scope all` to inspect accumulated knowledge impact.");
|
|
11256
|
+
}
|
|
11251
11257
|
} else {
|
|
11252
11258
|
L.push("- Graph data not available.");
|
|
11253
11259
|
L.push(`- Tip: ${r.graph_quality.suggestion}`);
|
|
@@ -11331,7 +11337,8 @@ function serializeImpactJson(r) {
|
|
|
11331
11337
|
function runReportImpact(opts = {}) {
|
|
11332
11338
|
const dir = cwd();
|
|
11333
11339
|
requireConfig(dir);
|
|
11334
|
-
const
|
|
11340
|
+
const scope = opts.scope === "active" ? "active" : opts.scope === "all" ? "all" : void 0;
|
|
11341
|
+
const report = buildImpactReport(dir, { scope });
|
|
11335
11342
|
const content = opts.json ? serializeImpactJson(report) : renderImpactMarkdown(report);
|
|
11336
11343
|
if (opts.output) {
|
|
11337
11344
|
intro2("kaddo report impact");
|
|
@@ -11374,10 +11381,10 @@ graphCmd.command("export").description("Write the knowledge graph to .kaddo/grap
|
|
|
11374
11381
|
runGraphExport(opts);
|
|
11375
11382
|
});
|
|
11376
11383
|
var reportCmd = program.command("report").description("Generate Kaddo reports");
|
|
11377
|
-
reportCmd.command("impact").description("Knowledge Impact Report: knowledge health, coverage, traceability, readiness (deterministic, no LLM)").option("--json", "Output JSON instead of Markdown").option("--output <path>", "Write the report to a file (e.g. .kaddo/reports/impact-report.md)").action((opts) => {
|
|
11384
|
+
reportCmd.command("impact").description("Knowledge Impact Report: knowledge health, coverage, traceability, readiness (deterministic, no LLM)").option("--json", "Output JSON instead of Markdown").option("--scope <scope>", "Scope: all (default \u2014 accumulated impact) or active").option("--output <path>", "Write the report to a file (e.g. .kaddo/reports/impact-report.md)").action((opts) => {
|
|
11378
11385
|
runReportImpact(opts);
|
|
11379
11386
|
});
|
|
11380
|
-
program.command("impact").description("Alias for `kaddo report impact`").option("--json", "Output JSON instead of Markdown").option("--output <path>", "Write the report to a file").action((opts) => {
|
|
11387
|
+
program.command("impact").description("Alias for `kaddo report impact`").option("--json", "Output JSON instead of Markdown").option("--scope <scope>", "Scope: all (default \u2014 accumulated impact) or active").option("--output <path>", "Write the report to a file").action((opts) => {
|
|
11381
11388
|
runReportImpact(opts);
|
|
11382
11389
|
});
|
|
11383
11390
|
program.command("guard").description("Check if modified code has related artifacts that were not updated").option("--staged", "Check only staged files").option("--no-interactive", "Disable interactive ignore prompts").option("--ci", "CI mode: output JSON, no prompts, non-blocking").option("--json", "Output JSON (alias for --ci)").option("--workspace", "Also check local mapped module repos from .kaddo/modules.yml (opt-in)").option("--include-archived", "Include archived Work Items in ownership matching (excluded by default)").action(async (opts) => {
|