@kaddo/mcp 3.39.0 → 3.40.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 +91 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1505,6 +1505,9 @@ function isPlaceholderLine(line) {
|
|
|
1505
1505
|
if (/<[^>]+>/.test(t)) return true;
|
|
1506
1506
|
if (/^[-*]\s+[^:]+:\s*$/.test(t)) return true;
|
|
1507
1507
|
if (/^[-*]\s+[^:]+:\s*\S.*\s\|\s/.test(t)) return true;
|
|
1508
|
+
if (/^\*\*[^*]+:\*\*\s*$/.test(t)) return true;
|
|
1509
|
+
if (/^\*\*[^*]+:\*\*\s*_.*_$/.test(t)) return true;
|
|
1510
|
+
if (/^\*\*[^*]+:\*\*\s*\S.*\s\|\s/.test(t)) return true;
|
|
1508
1511
|
return false;
|
|
1509
1512
|
}
|
|
1510
1513
|
function isStructuralLine(line, inFrontMatter) {
|
|
@@ -2310,7 +2313,7 @@ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
2310
2313
|
if (qBusiness !== "useful") return refine("refine-business", "business-agent", B, qBusiness);
|
|
2311
2314
|
if (qProduct !== "useful" || qCap !== "useful") {
|
|
2312
2315
|
if (qCap !== "useful") {
|
|
2313
|
-
return refine("refine-product", "capability-agent", CAP, qCap, discovery ? "discover and document existing system capabilities in" : "complete");
|
|
2316
|
+
return refine("refine-product", "capability-agent", CAP, qCap, discovery ? "discover and document existing system capabilities grouped by functional domains in" : "complete");
|
|
2314
2317
|
}
|
|
2315
2318
|
return refine("refine-product", "capability-agent", P, qProduct);
|
|
2316
2319
|
}
|
|
@@ -2430,6 +2433,76 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
2430
2433
|
};
|
|
2431
2434
|
}
|
|
2432
2435
|
|
|
2436
|
+
// ../cli/src/core/decisions.ts
|
|
2437
|
+
var CANDIDATES_PATH = "knowledge/tech/decision-candidates.md";
|
|
2438
|
+
var DECISIONS_DIR = "knowledge/tech/decisions";
|
|
2439
|
+
function slugify(s) {
|
|
2440
|
+
return s.toLowerCase().normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
|
|
2441
|
+
}
|
|
2442
|
+
function parseDecisionCandidates(md) {
|
|
2443
|
+
const out = [];
|
|
2444
|
+
for (const line of md.split(/\r?\n/)) {
|
|
2445
|
+
const m = line.match(/^##\s+(.+?)\s*$/);
|
|
2446
|
+
if (m) {
|
|
2447
|
+
const t = m[1].trim();
|
|
2448
|
+
if (t && !/^_.*_$/.test(t)) out.push(t);
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
return out;
|
|
2452
|
+
}
|
|
2453
|
+
function countAdrs(dir) {
|
|
2454
|
+
const base = join(dir, DECISIONS_DIR);
|
|
2455
|
+
if (!exists(base)) return { total: 0, draft: 0, accepted: 0 };
|
|
2456
|
+
let total = 0;
|
|
2457
|
+
let draft = 0;
|
|
2458
|
+
let accepted = 0;
|
|
2459
|
+
for (const entry of readDir(base)) {
|
|
2460
|
+
if (!entry.endsWith(".md") || entry === ".gitkeep") continue;
|
|
2461
|
+
const full = join(base, entry);
|
|
2462
|
+
if (!isFile(full)) continue;
|
|
2463
|
+
total += 1;
|
|
2464
|
+
let content = "";
|
|
2465
|
+
try {
|
|
2466
|
+
content = readFile(full);
|
|
2467
|
+
} catch {
|
|
2468
|
+
continue;
|
|
2469
|
+
}
|
|
2470
|
+
const status = content.match(/^\s*status:\s*([a-z-]+)/im)?.[1]?.toLowerCase();
|
|
2471
|
+
if (status === "accepted") accepted += 1;
|
|
2472
|
+
else draft += 1;
|
|
2473
|
+
}
|
|
2474
|
+
return { total, draft, accepted };
|
|
2475
|
+
}
|
|
2476
|
+
function buildTechDecisions(dir) {
|
|
2477
|
+
const candFile = join(dir, CANDIDATES_PATH);
|
|
2478
|
+
let titles = [];
|
|
2479
|
+
if (exists(candFile)) {
|
|
2480
|
+
try {
|
|
2481
|
+
titles = parseDecisionCandidates(readFile(candFile));
|
|
2482
|
+
} catch {
|
|
2483
|
+
titles = [];
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
const { total, draft, accepted } = countAdrs(dir);
|
|
2487
|
+
const candidate_list = titles.map((title, i) => {
|
|
2488
|
+
const n = String(total + i + 1).padStart(3, "0");
|
|
2489
|
+
return { title, source: CANDIDATES_PATH, suggestedAdrFile: `${DECISIONS_DIR}/ADR-${n}-${slugify(title)}.md` };
|
|
2490
|
+
});
|
|
2491
|
+
let status;
|
|
2492
|
+
if (accepted > 0) status = "accepted-adrs";
|
|
2493
|
+
else if (total > 0) status = "draft-adrs";
|
|
2494
|
+
else if (titles.length > 0) status = "candidates";
|
|
2495
|
+
else status = "none";
|
|
2496
|
+
return {
|
|
2497
|
+
status,
|
|
2498
|
+
candidates: titles.length,
|
|
2499
|
+
adrs: total,
|
|
2500
|
+
draft_adrs: draft,
|
|
2501
|
+
accepted_adrs: accepted,
|
|
2502
|
+
candidate_list
|
|
2503
|
+
};
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2433
2506
|
// ../cli/src/core/project-explain.ts
|
|
2434
2507
|
var ARCH_DIR2 = "knowledge";
|
|
2435
2508
|
function normalizeTitle(t) {
|
|
@@ -2641,7 +2714,8 @@ function buildProjectExplanation(dir) {
|
|
|
2641
2714
|
missingKnowledge,
|
|
2642
2715
|
suggestedNextSteps,
|
|
2643
2716
|
readiness,
|
|
2644
|
-
nextStepRecommendation: readiness.nextStepRecommendation
|
|
2717
|
+
nextStepRecommendation: readiness.nextStepRecommendation,
|
|
2718
|
+
techDecisions: buildTechDecisions(dir)
|
|
2645
2719
|
};
|
|
2646
2720
|
}
|
|
2647
2721
|
function stateLabel(state) {
|
|
@@ -2855,6 +2929,16 @@ function renderExplanationHuman(exp) {
|
|
|
2855
2929
|
lines.push("### Recommended next step");
|
|
2856
2930
|
lines.push(r.recommended_next_step.label);
|
|
2857
2931
|
lines.push("");
|
|
2932
|
+
const td = exp.techDecisions;
|
|
2933
|
+
lines.push("## Tech Decisions");
|
|
2934
|
+
lines.push(`- Decision candidates: ${td.candidates}`);
|
|
2935
|
+
lines.push(`- ADRs: ${td.adrs} (draft: ${td.draft_adrs}, accepted: ${td.accepted_adrs})`);
|
|
2936
|
+
lines.push(`- Status: ${td.status}`);
|
|
2937
|
+
if (td.candidates > 0 && td.adrs === 0) {
|
|
2938
|
+
lines.push("");
|
|
2939
|
+
lines.push("Use the adr-writing skill to materialize decision candidates into ADRs (`kaddo adr`) before implementing related technical Work Items.");
|
|
2940
|
+
}
|
|
2941
|
+
lines.push("");
|
|
2858
2942
|
return lines.join("\n").trimEnd() + "\n";
|
|
2859
2943
|
}
|
|
2860
2944
|
function renderExplanationAgent(exp) {
|
|
@@ -4310,6 +4394,10 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
4310
4394
|
}
|
|
4311
4395
|
});
|
|
4312
4396
|
const nextStepRecommendation = resolveNextStep(dir, now);
|
|
4397
|
+
const techDecisions = buildTechDecisions(dir);
|
|
4398
|
+
if (techDecisions.candidates > 0 && techDecisions.adrs === 0) {
|
|
4399
|
+
missing.push(`${techDecisions.candidates} technical decision candidate(s) not yet materialized as ADRs (run \`kaddo adr\`).`);
|
|
4400
|
+
}
|
|
4313
4401
|
const unifiedPhase = {
|
|
4314
4402
|
...phase,
|
|
4315
4403
|
nextStep: nextStepRecommendation.label,
|
|
@@ -4347,6 +4435,7 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
4347
4435
|
roadmap,
|
|
4348
4436
|
phase: unifiedPhase,
|
|
4349
4437
|
nextStepRecommendation,
|
|
4438
|
+
techDecisions,
|
|
4350
4439
|
deliveryMix,
|
|
4351
4440
|
external: loadExternalCapsules(dir),
|
|
4352
4441
|
graph: loadGraphSummary(dir),
|
package/package.json
CHANGED