@kaddo/mcp 3.42.0 → 3.43.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 +165 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3628,6 +3628,24 @@ Adapt priorities to the project state from the context pack:
|
|
|
3628
3628
|
- **legacy** \u2014 prioritize risk reduction, unknowns and safe modernization before feature
|
|
3629
3629
|
delivery.
|
|
3630
3630
|
|
|
3631
|
+
## Grounding rules (VS-077)
|
|
3632
|
+
|
|
3633
|
+
Every candidate initiative must be **grounded** in the knowledge base \u2014 never a loose idea. For each
|
|
3634
|
+
\`### RM-xxx\` you must provide:
|
|
3635
|
+
|
|
3636
|
+
- **Related domain** \u2014 a domain from \`## Capability Domains\` in \`capabilities.md\` (or, if genuinely
|
|
3637
|
+
new, prefix it \`[new candidate domain] <name>\` \u2014 do not invent domains silently).
|
|
3638
|
+
- **Related capabilities** \u2014 one or more existing/partial capabilities.
|
|
3639
|
+
- **Source signals** \u2014 at least one traceable reason: Capability Gap, Roadmap Candidate Signal, Risk,
|
|
3640
|
+
Open Question, Assumption, Deferred Decision, Tech Decision Candidate, ADR, Business Goal,
|
|
3641
|
+
Operational Need or Legacy Modernization Signal.
|
|
3642
|
+
- **Expected value**, **Risks**, **Dependencies**, and **Suggested Work Items** (candidates only).
|
|
3643
|
+
|
|
3644
|
+
Do **not** emit a candidate with no source signal. Keep initiatives at initiative granularity (small
|
|
3645
|
+
tasks go under **Suggested Work Items**, not as their own RM). Every roadmap ends with a global
|
|
3646
|
+
**## Not Now** section. For pre-ai/legacy, prioritize stabilization, security, data, operations,
|
|
3647
|
+
architectural decisions and business-blocking gaps before expansive features.
|
|
3648
|
+
|
|
3631
3649
|
## Constraints
|
|
3632
3650
|
|
|
3633
3651
|
- Do not invent business priorities or business facts \u2014 mark them as assumptions when inferred.
|
|
@@ -3636,6 +3654,8 @@ Adapt priorities to the project state from the context pack:
|
|
|
3636
3654
|
implementation-agent, and only after Work Items are materialized. Your handoff is
|
|
3637
3655
|
\`kaddo create --from roadmap\` \u2192 work-item-agent.
|
|
3638
3656
|
- Do not create the work items themselves; only propose candidates.
|
|
3657
|
+
- **Never create files under \`knowledge/delivery/work-items/\`** \u2014 materialization is
|
|
3658
|
+
\`kaddo create --from roadmap\`, not the roadmap-agent.
|
|
3639
3659
|
- Make clear that initiatives and work items are **candidates**, not final decisions.
|
|
3640
3660
|
- Mark any uncertain information as an assumption or open question.
|
|
3641
3661
|
- Keep sequencing justified by dependencies and risk.
|
|
@@ -3669,31 +3689,38 @@ human review \u2014 not final commitments.
|
|
|
3669
3689
|
|
|
3670
3690
|
### RM-001: <Initiative Name>
|
|
3671
3691
|
|
|
3672
|
-
**
|
|
3692
|
+
**Status:** candidate <!-- candidate | selected | deferred | rejected -->
|
|
3673
3693
|
|
|
3674
|
-
**
|
|
3694
|
+
**Priority:** high / medium / low
|
|
3675
3695
|
|
|
3676
|
-
**
|
|
3696
|
+
**Suggested Knowledge Level:** K1 / K2 / K3 / K4
|
|
3677
3697
|
|
|
3678
|
-
**
|
|
3698
|
+
**Related domain:** <one of the ## Capability Domains from capabilities.md>
|
|
3679
3699
|
|
|
3680
|
-
**
|
|
3700
|
+
**Related capabilities:**
|
|
3701
|
+
- <existing or partial capability>
|
|
3681
3702
|
|
|
3682
|
-
**
|
|
3703
|
+
**Source signals:** <!-- REQUIRED: why this candidate exists (at least one) -->
|
|
3704
|
+
- Capability Gap: <...>
|
|
3705
|
+
- Roadmap Candidate Signal: <...>
|
|
3706
|
+
- Risk / Open Question / Assumption / Deferred Decision / Tech Decision Candidate / ADR / Business Goal: <...>
|
|
3683
3707
|
|
|
3684
|
-
**
|
|
3708
|
+
**Problem / opportunity:**
|
|
3709
|
+
|
|
3710
|
+
**Expected value:**
|
|
3685
3711
|
|
|
3686
|
-
**
|
|
3712
|
+
**Risks:**
|
|
3687
3713
|
|
|
3688
|
-
**
|
|
3714
|
+
**Dependencies:**
|
|
3689
3715
|
|
|
3716
|
+
**Suggested Work Items:**
|
|
3690
3717
|
- WI-CANDIDATE-001: <candidate work item>
|
|
3691
3718
|
- type:
|
|
3692
3719
|
- suggested knowledge level:
|
|
3693
3720
|
- expected value:
|
|
3694
3721
|
- notes:
|
|
3695
3722
|
|
|
3696
|
-
**
|
|
3723
|
+
**Not now:**
|
|
3697
3724
|
|
|
3698
3725
|
---
|
|
3699
3726
|
|
|
@@ -3988,6 +4015,14 @@ that it should be materialized first (\`kaddo adr\` + the adr-writing skill) and
|
|
|
3988
4015
|
without surfacing it. -->
|
|
3989
4016
|
\`\`\`
|
|
3990
4017
|
|
|
4018
|
+
### Preserve roadmap metadata (VS-077)
|
|
4019
|
+
|
|
4020
|
+
When a Work Item comes from \`kaddo create --from roadmap\`, the front matter already carries
|
|
4021
|
+
\`source_roadmap_candidate\`, \`related_domain\`, \`related_capability\` (+ \`related_capabilities\`),
|
|
4022
|
+
\`knowledge_level\`, \`expected_value\`, \`risks\` and \`dependencies\`. **Keep and refine** this metadata \u2014
|
|
4023
|
+
do not drop the trace back to the capability domain and source signals. Add \`related_decisions\` /
|
|
4024
|
+
\`decision_candidates\` when the work depends on a technical decision.
|
|
4025
|
+
|
|
3991
4026
|
## Where to Save the Result
|
|
3992
4027
|
|
|
3993
4028
|
Save new output as a draft under \`knowledge/delivery/work-items/draft/\` unless a human
|
|
@@ -5208,6 +5243,79 @@ function installedAssetsSummary(dir) {
|
|
|
5208
5243
|
return { version: KADDO_VERSION, agents: assetStatus(dir, "agent"), skills: assetStatus(dir, "skill") };
|
|
5209
5244
|
}
|
|
5210
5245
|
|
|
5246
|
+
// ../cli/src/core/roadmap-quality.ts
|
|
5247
|
+
var ROADMAP_PATH = "knowledge/delivery/roadmap.md";
|
|
5248
|
+
var INITIATIVE_RE2 = /^#{2,4}\s+(RM-[\w.-]+)\s*[:\-–]?\s*(.*)$/;
|
|
5249
|
+
function fieldPresent(lines, label) {
|
|
5250
|
+
for (let i = 0; i < lines.length; i++) {
|
|
5251
|
+
const m = lines[i].match(new RegExp(`^\\s*[-*]?\\s*(?:\\*\\*)?\\s*(${label.source})\\s*(?:\\*\\*)?\\s*:\\s*(.*)$`, "i"));
|
|
5252
|
+
if (!m) continue;
|
|
5253
|
+
const inline = m[2].trim();
|
|
5254
|
+
if (inline) return true;
|
|
5255
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
5256
|
+
if (/^\s{2,}[-*]\s+\S/.test(lines[j])) return true;
|
|
5257
|
+
if (/^\S/.test(lines[j]) || /^#{2,4}\s/.test(lines[j])) break;
|
|
5258
|
+
if (/^\s*[-*]\s+\S/.test(lines[j]) && !/^\s{2,}/.test(lines[j])) break;
|
|
5259
|
+
}
|
|
5260
|
+
}
|
|
5261
|
+
return false;
|
|
5262
|
+
}
|
|
5263
|
+
function parseRoadmapCandidateQuality(md) {
|
|
5264
|
+
const lines = md.split(/\r?\n/);
|
|
5265
|
+
const items = [];
|
|
5266
|
+
let cur = null;
|
|
5267
|
+
const flush = () => {
|
|
5268
|
+
if (!cur) return;
|
|
5269
|
+
const hasRelatedDomain = fieldPresent(cur.lines, /related domain/);
|
|
5270
|
+
const hasRelatedCapability = fieldPresent(cur.lines, /related capabilit(?:y|ies)/);
|
|
5271
|
+
const hasSourceSignals = fieldPresent(cur.lines, /source signals?/);
|
|
5272
|
+
items.push({
|
|
5273
|
+
id: cur.id,
|
|
5274
|
+
title: cur.title,
|
|
5275
|
+
hasRelatedDomain,
|
|
5276
|
+
hasRelatedCapability,
|
|
5277
|
+
hasSourceSignals,
|
|
5278
|
+
grounded: hasRelatedDomain && hasRelatedCapability && hasSourceSignals
|
|
5279
|
+
});
|
|
5280
|
+
cur = null;
|
|
5281
|
+
};
|
|
5282
|
+
for (const line of lines) {
|
|
5283
|
+
const m = line.match(INITIATIVE_RE2);
|
|
5284
|
+
if (m) {
|
|
5285
|
+
flush();
|
|
5286
|
+
cur = { id: m[1], title: m[2].trim(), lines: [] };
|
|
5287
|
+
continue;
|
|
5288
|
+
}
|
|
5289
|
+
if (cur) cur.lines.push(line);
|
|
5290
|
+
}
|
|
5291
|
+
flush();
|
|
5292
|
+
return items;
|
|
5293
|
+
}
|
|
5294
|
+
function buildRoadmapQuality(dir) {
|
|
5295
|
+
let md = "";
|
|
5296
|
+
const p = join(dir, ROADMAP_PATH);
|
|
5297
|
+
if (exists(p)) {
|
|
5298
|
+
try {
|
|
5299
|
+
md = readFile(p);
|
|
5300
|
+
} catch {
|
|
5301
|
+
md = "";
|
|
5302
|
+
}
|
|
5303
|
+
}
|
|
5304
|
+
const items = parseRoadmapCandidateQuality(md);
|
|
5305
|
+
const count = (pred) => items.filter(pred).length;
|
|
5306
|
+
const grounded = count((i) => i.grounded);
|
|
5307
|
+
return {
|
|
5308
|
+
candidates: items.length,
|
|
5309
|
+
grounded,
|
|
5310
|
+
with_related_domain: count((i) => i.hasRelatedDomain),
|
|
5311
|
+
with_related_capability: count((i) => i.hasRelatedCapability),
|
|
5312
|
+
with_source_signals: count((i) => i.hasSourceSignals),
|
|
5313
|
+
// Only "needs refinement" when there are candidates and at least one isn't grounded.
|
|
5314
|
+
needs_refinement: items.length > 0 && grounded < items.length,
|
|
5315
|
+
items
|
|
5316
|
+
};
|
|
5317
|
+
}
|
|
5318
|
+
|
|
5211
5319
|
// ../cli/src/core/project-explain.ts
|
|
5212
5320
|
var ARCH_DIR2 = "knowledge";
|
|
5213
5321
|
function normalizeTitle(t) {
|
|
@@ -5432,7 +5540,8 @@ function buildProjectExplanation(dir) {
|
|
|
5432
5540
|
legacyLocation: exists(join(dir, "knowledge/tech/architecture-notes.md")) || exists(join(dir, "knowledge/tech/decision-candidates.md"))
|
|
5433
5541
|
}
|
|
5434
5542
|
},
|
|
5435
|
-
installedAssets: installedAssetsSummary(dir)
|
|
5543
|
+
installedAssets: installedAssetsSummary(dir),
|
|
5544
|
+
roadmapQuality: buildRoadmapQuality(dir)
|
|
5436
5545
|
};
|
|
5437
5546
|
}
|
|
5438
5547
|
function stateLabel(state) {
|
|
@@ -5667,6 +5776,20 @@ function renderExplanationHuman(exp) {
|
|
|
5667
5776
|
lines.push("Tech discovery files are in the legacy `knowledge/tech/` root. Suggested cleanup: run `kaddo tech organize`.");
|
|
5668
5777
|
lines.push("");
|
|
5669
5778
|
}
|
|
5779
|
+
const rq = exp.roadmapQuality;
|
|
5780
|
+
if (rq.candidates > 0) {
|
|
5781
|
+
lines.push("## Roadmap Quality");
|
|
5782
|
+
lines.push(`- Candidates: ${rq.candidates}`);
|
|
5783
|
+
lines.push(`- Grounded: ${rq.grounded}/${rq.candidates}`);
|
|
5784
|
+
lines.push(`- With related domain: ${rq.with_related_domain}/${rq.candidates}`);
|
|
5785
|
+
lines.push(`- With related capability: ${rq.with_related_capability}/${rq.candidates}`);
|
|
5786
|
+
lines.push(`- With source signals: ${rq.with_source_signals}/${rq.candidates}`);
|
|
5787
|
+
if (rq.needs_refinement) {
|
|
5788
|
+
lines.push("");
|
|
5789
|
+
lines.push("Roadmap quality: needs refinement. Suggested: use roadmap-agent to add domain / capability / source signals.");
|
|
5790
|
+
}
|
|
5791
|
+
lines.push("");
|
|
5792
|
+
}
|
|
5670
5793
|
const ia = exp.installedAssets;
|
|
5671
5794
|
const agentsInstalled = ia.agents.total - ia.agents.missing;
|
|
5672
5795
|
const skillsInstalled = ia.skills.total - ia.skills.missing;
|
|
@@ -6892,6 +7015,18 @@ var RESOURCES = [
|
|
|
6892
7015
|
}
|
|
6893
7016
|
return [{ uri: "kaddo://installed-assets", text: JSON.stringify(installedAssetsSummary(root), null, 2), mimeType: "application/json" }];
|
|
6894
7017
|
}
|
|
7018
|
+
},
|
|
7019
|
+
{
|
|
7020
|
+
uri: "kaddo://roadmap-quality",
|
|
7021
|
+
name: "Kaddo roadmap quality",
|
|
7022
|
+
description: "How well roadmap candidates are grounded in capability domains, related capabilities and source signals (VS-077). Read-only.",
|
|
7023
|
+
mimeType: "application/json",
|
|
7024
|
+
read: (root) => {
|
|
7025
|
+
if (!hasKnowledge(root)) {
|
|
7026
|
+
return text("kaddo://roadmap-quality", "Knowledge repository not found. Run `kaddo bootstrap` first.", "text/plain");
|
|
7027
|
+
}
|
|
7028
|
+
return [{ uri: "kaddo://roadmap-quality", text: JSON.stringify(buildRoadmapQuality(root), null, 2), mimeType: "application/json" }];
|
|
7029
|
+
}
|
|
6895
7030
|
}
|
|
6896
7031
|
];
|
|
6897
7032
|
|
|
@@ -7220,6 +7355,7 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
7220
7355
|
nextStepRecommendation,
|
|
7221
7356
|
techDecisions,
|
|
7222
7357
|
techKnowledge,
|
|
7358
|
+
roadmapQuality: buildRoadmapQuality(dir),
|
|
7223
7359
|
installedAssets: (() => {
|
|
7224
7360
|
const s = installedAssetsSummary(dir);
|
|
7225
7361
|
const compact = (a) => ({ total: a.total, installed: a.total - a.missing, outdated: a.outdated, unknown_version: a.unknown_version, modified: a.modified });
|
|
@@ -7334,6 +7470,24 @@ function renderContextPack(pack) {
|
|
|
7334
7470
|
}
|
|
7335
7471
|
}
|
|
7336
7472
|
parts.push((knowledge.roadmapSummary || "No roadmap baseline found.") + "\n");
|
|
7473
|
+
const rq = pack.roadmapQuality;
|
|
7474
|
+
if (rq.candidates > 0) {
|
|
7475
|
+
parts.push("## Roadmap Quality\n");
|
|
7476
|
+
parts.push(
|
|
7477
|
+
[
|
|
7478
|
+
`- Candidates: ${rq.candidates}`,
|
|
7479
|
+
`- Grounded: ${rq.grounded}/${rq.candidates}`,
|
|
7480
|
+
`- With related domain: ${rq.with_related_domain}/${rq.candidates}`,
|
|
7481
|
+
`- With related capability: ${rq.with_related_capability}/${rq.candidates}`,
|
|
7482
|
+
`- With source signals: ${rq.with_source_signals}/${rq.candidates}`
|
|
7483
|
+
].join("\n") + "\n"
|
|
7484
|
+
);
|
|
7485
|
+
if (rq.needs_refinement) {
|
|
7486
|
+
parts.push(
|
|
7487
|
+
"Roadmap quality: needs refinement. Use the roadmap-agent to add domain / capability / source signals.\n"
|
|
7488
|
+
);
|
|
7489
|
+
}
|
|
7490
|
+
}
|
|
7337
7491
|
parts.push("## Active Work Items\n");
|
|
7338
7492
|
if (knowledge.workItems.length > 0) {
|
|
7339
7493
|
const lines = knowledge.workItems.map((wi) => {
|
package/package.json
CHANGED