@kaddo/mcp 3.64.0 → 3.66.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 +279 -65
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -521,7 +521,14 @@ function parseArtifact(filePath, raw) {
|
|
|
521
521
|
sourceId: String(data.source_id ?? ""),
|
|
522
522
|
rawFrontmatter: data,
|
|
523
523
|
decisions: Array.isArray(data.decisions) ? data.decisions.map(String).filter(Boolean) : [],
|
|
524
|
-
capsules: Array.isArray(data.capsules) ? data.capsules.map(String).filter(Boolean) : []
|
|
524
|
+
capsules: Array.isArray(data.capsules) ? data.capsules.map(String).filter(Boolean) : [],
|
|
525
|
+
implementationStatus: String(data.implementation_status ?? ""),
|
|
526
|
+
validationStatus: String(data.validation_status ?? ""),
|
|
527
|
+
releaseStatus: String(data.release_status ?? ""),
|
|
528
|
+
affectedModules: Array.isArray(data.affected_modules) ? data.affected_modules.map(String).filter(Boolean) : [],
|
|
529
|
+
refinedBy: String(data.refined_by ?? ""),
|
|
530
|
+
implementedBy: String(data.implemented_by ?? ""),
|
|
531
|
+
closedBy: String(data.closed_by ?? "")
|
|
525
532
|
};
|
|
526
533
|
} catch {
|
|
527
534
|
return null;
|
|
@@ -698,7 +705,7 @@ function assessPhase(input) {
|
|
|
698
705
|
const techReady = !NOT_READY_LAYER.includes(techStatus);
|
|
699
706
|
if (techReady) {
|
|
700
707
|
return {
|
|
701
|
-
phase: "
|
|
708
|
+
phase: "Ready for Core Orchestration",
|
|
702
709
|
reasons: ["Module repo \u2014 Tech layer ready", "Business/Product managed by core"],
|
|
703
710
|
recommendedAgents: [],
|
|
704
711
|
nextStep: "Module knowledge is ready for core orchestration.",
|
|
@@ -2413,6 +2420,7 @@ function buildGraph(dir, config, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
2413
2420
|
const selectedWIs = workItems.filter((a2) => a2.lifecycle && includedSet.has(a2.lifecycle));
|
|
2414
2421
|
for (const wi of selectedWIs) {
|
|
2415
2422
|
const id = wi.id || wi.title;
|
|
2423
|
+
if (!id || !id.trim()) continue;
|
|
2416
2424
|
const wiNodeId = `wi:${id}`;
|
|
2417
2425
|
addNode({
|
|
2418
2426
|
id: wiNodeId,
|
|
@@ -2423,16 +2431,19 @@ function buildGraph(dir, config, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
2423
2431
|
knowledge_level: wi.knowledgeLevel || void 0
|
|
2424
2432
|
});
|
|
2425
2433
|
for (const glob of wi.codeGlobs) {
|
|
2434
|
+
if (!glob || !glob.trim()) continue;
|
|
2426
2435
|
const codeId = `code:${glob}`;
|
|
2427
2436
|
addNode({ id: codeId, type: "code-glob", label: glob });
|
|
2428
2437
|
addEdge(wiNodeId, codeId, "owns");
|
|
2429
2438
|
}
|
|
2430
2439
|
for (const cap of wi.capabilities) {
|
|
2440
|
+
if (!cap || !cap.trim()) continue;
|
|
2431
2441
|
const capId = `capability:${slug(cap) || cap}`;
|
|
2432
2442
|
addNode({ id: capId, type: "capability", label: cap });
|
|
2433
2443
|
addEdge(wiNodeId, capId, "implements");
|
|
2434
2444
|
}
|
|
2435
2445
|
for (const dec of wi.decisions) {
|
|
2446
|
+
if (!dec || !dec.trim()) continue;
|
|
2436
2447
|
const adrId = `adr:${dec}`;
|
|
2437
2448
|
addNode({ id: adrId, type: "decision", label: dec });
|
|
2438
2449
|
addEdge(wiNodeId, adrId, "depends_on");
|
|
@@ -2449,16 +2460,19 @@ function buildGraph(dir, config, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
2449
2460
|
}
|
|
2450
2461
|
}
|
|
2451
2462
|
for (const adr of all.filter(isAdr)) {
|
|
2452
|
-
const
|
|
2463
|
+
const adrLabel = adr.id || adr.title;
|
|
2464
|
+
if (!adrLabel || !adrLabel.trim()) continue;
|
|
2465
|
+
const adrId = `adr:${adrLabel}`;
|
|
2453
2466
|
const referenced = nodes.has(adrId);
|
|
2454
2467
|
if (scope === "all" || referenced) {
|
|
2455
2468
|
nodes.set(adrId, {
|
|
2456
2469
|
id: adrId,
|
|
2457
2470
|
type: "decision",
|
|
2458
|
-
label: `${adr.id} ${adr.title}`.trim() ||
|
|
2471
|
+
label: `${adr.id} ${adr.title}`.trim() || adrLabel,
|
|
2459
2472
|
path: adr.relPath
|
|
2460
2473
|
});
|
|
2461
2474
|
for (const glob of adr.codeGlobs) {
|
|
2475
|
+
if (!glob || !glob.trim()) continue;
|
|
2462
2476
|
const codeId = `code:${glob}`;
|
|
2463
2477
|
addNode({ id: codeId, type: "code-glob", label: glob });
|
|
2464
2478
|
addEdge(adrId, codeId, "governs");
|
|
@@ -2514,13 +2528,20 @@ function renderGraphMermaid(graph) {
|
|
|
2514
2528
|
safeIds.set(id, candidate);
|
|
2515
2529
|
return candidate;
|
|
2516
2530
|
};
|
|
2517
|
-
const escapeLabel = (s) => s.replace(/"/g, "'");
|
|
2531
|
+
const escapeLabel = (s) => s.replace(/"/g, "'").replace(/\[/g, "(").replace(/\]/g, ")").replace(/\n/g, " ");
|
|
2532
|
+
const validNodes = graph.nodes.filter(
|
|
2533
|
+
(n) => n.id && n.id.trim() !== "" && n.label && n.label.trim() !== ""
|
|
2534
|
+
);
|
|
2535
|
+
const validNodeIds = new Set(validNodes.map((n) => n.id));
|
|
2518
2536
|
const lines = ["flowchart LR"];
|
|
2519
|
-
for (const node of
|
|
2537
|
+
for (const node of validNodes) {
|
|
2520
2538
|
lines.push(` ${safe(node.id)}["${escapeLabel(node.label)}"]`);
|
|
2521
2539
|
}
|
|
2522
|
-
|
|
2523
|
-
|
|
2540
|
+
const validEdges = graph.edges.filter(
|
|
2541
|
+
(e) => validNodeIds.has(e.from) && validNodeIds.has(e.to)
|
|
2542
|
+
);
|
|
2543
|
+
if (validEdges.length > 0) lines.push("");
|
|
2544
|
+
for (const edge of validEdges) {
|
|
2524
2545
|
lines.push(` ${safe(edge.from)} -->|${edge.type}| ${safe(edge.to)}`);
|
|
2525
2546
|
}
|
|
2526
2547
|
return lines.join("\n") + "\n";
|
|
@@ -4290,6 +4311,47 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
4290
4311
|
if (!config) return stub("not-initialized", rec.label, rec.command);
|
|
4291
4312
|
if (config.project.state === "new") return stub("not-applicable", "This project uses the standard new-project Kaddo flow.");
|
|
4292
4313
|
if (config.project.state === "legacy") return stub("legacy-project", "Use the legacy project flow.");
|
|
4314
|
+
if (isModule(config)) {
|
|
4315
|
+
const scan2 = exists(join(dir, ".kaddo", "scan.json")) ? "available" : "missing";
|
|
4316
|
+
const understand2 = exists(join(dir, ".kaddo", "understand.md")) ? "available" : "missing";
|
|
4317
|
+
const mcNew = "knowledge/tech/module/module-context.md";
|
|
4318
|
+
const mcLegacy = "knowledge/module/module-context.md";
|
|
4319
|
+
const mcPath = exists(join(dir, mcNew)) ? mcNew : mcLegacy;
|
|
4320
|
+
const qMC = analyzeKnowledgeArtifact(dir, mcPath);
|
|
4321
|
+
const qCS = analyzeKnowledgeArtifact(dir, "knowledge/tech/current-state.md");
|
|
4322
|
+
const qCB = analyzeKnowledgeArtifact(dir, "knowledge/tech/codebase.md");
|
|
4323
|
+
const moduleBaseline = qMC !== "missing" && qCS !== "missing" && qCB !== "missing" ? "complete" : "incomplete";
|
|
4324
|
+
const moduleReady = qMC === "useful" && qCS === "useful" && qCB === "useful";
|
|
4325
|
+
const overall2 = moduleReady ? "ready-for-core-orchestration" : moduleBaseline === "incomplete" ? "bootstrap-incomplete" : "knowledge-incomplete";
|
|
4326
|
+
return {
|
|
4327
|
+
project_name: config.project.name,
|
|
4328
|
+
project_type: config.project.state,
|
|
4329
|
+
project_role: "module",
|
|
4330
|
+
overall: overall2,
|
|
4331
|
+
signals: {
|
|
4332
|
+
scan: scan2,
|
|
4333
|
+
understand: understand2,
|
|
4334
|
+
bootstrap_baseline: moduleBaseline,
|
|
4335
|
+
agents: "managed-by-core",
|
|
4336
|
+
skills: "managed-by-core",
|
|
4337
|
+
current_state: qCS,
|
|
4338
|
+
codebase: qCB,
|
|
4339
|
+
module_context: qMC,
|
|
4340
|
+
capabilities: "managed-by-core",
|
|
4341
|
+
product: "not-applicable",
|
|
4342
|
+
business: "not-applicable",
|
|
4343
|
+
roadmap: "managed-by-core",
|
|
4344
|
+
work_items: "managed-by-core",
|
|
4345
|
+
adapters: [],
|
|
4346
|
+
blocking_open_questions: 0,
|
|
4347
|
+
assumed_questions: 0,
|
|
4348
|
+
resolved_questions: 0,
|
|
4349
|
+
deferred_questions: 0
|
|
4350
|
+
},
|
|
4351
|
+
recommended_next_step: { label: rec.label, ...rec.command ? { command: rec.command } : {} },
|
|
4352
|
+
nextStepRecommendation: rec
|
|
4353
|
+
};
|
|
4354
|
+
}
|
|
4293
4355
|
const scan = exists(join(dir, ".kaddo", "scan.json")) ? "available" : "missing";
|
|
4294
4356
|
const understand = exists(join(dir, ".kaddo", "understand.md")) ? "available" : "missing";
|
|
4295
4357
|
const presence = Object.fromEntries(KNOWLEDGE_FILES.map((f3) => [f3.key, analyzeKnowledgeArtifact(dir, f3.path)]));
|
|
@@ -7989,6 +8051,33 @@ function analyzeMetadataHealth(dir) {
|
|
|
7989
8051
|
if (fileDrifted) drifted++;
|
|
7990
8052
|
else healthy++;
|
|
7991
8053
|
}
|
|
8054
|
+
const wiDir = join(dir, "knowledge/delivery/work-items");
|
|
8055
|
+
if (exists(wiDir)) {
|
|
8056
|
+
const walkWIs = (d3) => {
|
|
8057
|
+
for (const entry of readDir(d3)) {
|
|
8058
|
+
const p = join(d3, entry);
|
|
8059
|
+
if (isFile(p) && entry.endsWith(".md")) {
|
|
8060
|
+
try {
|
|
8061
|
+
const raw = readFile(p);
|
|
8062
|
+
const fm = matter7(raw).data;
|
|
8063
|
+
if (fm.status === "done") {
|
|
8064
|
+
const rel = p.replace(dir + "/", "").replace(dir + "\\", "").replace(/\\/g, "/");
|
|
8065
|
+
findings.push({
|
|
8066
|
+
file: rel,
|
|
8067
|
+
field: "status",
|
|
8068
|
+
issue: "inconsistent",
|
|
8069
|
+
detail: "Legacy status `done` detected. Canonical status is `completed`."
|
|
8070
|
+
});
|
|
8071
|
+
}
|
|
8072
|
+
} catch {
|
|
8073
|
+
}
|
|
8074
|
+
} else if (!isFile(p) && !entry.startsWith(".")) {
|
|
8075
|
+
walkWIs(p);
|
|
8076
|
+
}
|
|
8077
|
+
}
|
|
8078
|
+
};
|
|
8079
|
+
walkWIs(wiDir);
|
|
8080
|
+
}
|
|
7992
8081
|
return { findings, healthy, drifted };
|
|
7993
8082
|
}
|
|
7994
8083
|
|
|
@@ -8169,51 +8258,73 @@ function buildProjectExplanation(dir) {
|
|
|
8169
8258
|
const roadmapMd = exists(roadmapPath) ? readFile(roadmapPath) : null;
|
|
8170
8259
|
const roadmap = roadmapStats(roadmapMd, items.length);
|
|
8171
8260
|
const mappedModules = loadMappedModules(dir);
|
|
8261
|
+
const moduleRepo = config != null && isModule(config);
|
|
8172
8262
|
const missingKnowledge = [];
|
|
8173
|
-
if (
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
|
|
8178
|
-
if (!knowledge.hasRoadmap) missingKnowledge.push("Roadmap (knowledge/delivery/roadmap.md)");
|
|
8179
|
-
if (!knowledge.hasAgents) missingKnowledge.push("Agents (knowledge/agents/)");
|
|
8180
|
-
if (items.length === 0) missingKnowledge.push("Work items (knowledge/delivery/work-items/)");
|
|
8181
|
-
const suggestedNextSteps = [];
|
|
8182
|
-
const baselineIncomplete = !knowledge.hasBusiness || !knowledge.hasProduct;
|
|
8183
|
-
if (baselineIncomplete) {
|
|
8184
|
-
suggestedNextSteps.push("Run `kaddo bootstrap` to create the project knowledge baseline.");
|
|
8185
|
-
if (!knowledge.hasAgents) suggestedNextSteps.push("Then run `kaddo add agents`.");
|
|
8186
|
-
if (!knowledge.hasSkills) suggestedNextSteps.push("Then run `kaddo add skills`.");
|
|
8187
|
-
suggestedNextSteps.push("Then run `kaddo context`.");
|
|
8188
|
-
suggestedNextSteps.push("Then run `kaddo understand`.");
|
|
8263
|
+
if (moduleRepo) {
|
|
8264
|
+
if (!knowledge.hasScan) missingKnowledge.push("Scan baseline (.kaddo/scan.json)");
|
|
8265
|
+
if (!knowledge.hasContextPack) missingKnowledge.push("Context pack (.kaddo/context-pack.md)");
|
|
8266
|
+
if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
|
|
8189
8267
|
} else {
|
|
8268
|
+
if (!knowledge.hasScan) missingKnowledge.push("Scan baseline (.kaddo/scan.json)");
|
|
8269
|
+
if (!knowledge.hasContextPack) missingKnowledge.push("Context pack (.kaddo/context-pack.md)");
|
|
8270
|
+
if (!knowledge.hasInventory) missingKnowledge.push("Inventory (knowledge/inventory.md)");
|
|
8271
|
+
if (!knowledge.hasCapabilities) missingKnowledge.push("Product knowledge (knowledge/product/)");
|
|
8272
|
+
if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
|
|
8273
|
+
if (!knowledge.hasRoadmap) missingKnowledge.push("Roadmap (knowledge/delivery/roadmap.md)");
|
|
8274
|
+
if (!knowledge.hasAgents) missingKnowledge.push("Agents (knowledge/agents/)");
|
|
8275
|
+
if (items.length === 0) missingKnowledge.push("Work items (knowledge/delivery/work-items/)");
|
|
8276
|
+
}
|
|
8277
|
+
const suggestedNextSteps = [];
|
|
8278
|
+
if (moduleRepo) {
|
|
8190
8279
|
if (!knowledge.hasScan) {
|
|
8191
8280
|
suggestedNextSteps.push("Run `kaddo scan` to detect the technical stack.");
|
|
8192
8281
|
} else if (!knowledge.hasContextPack) {
|
|
8193
8282
|
suggestedNextSteps.push("Run `kaddo context` to prepare an LLM context pack.");
|
|
8283
|
+
} else if (!knowledge.hasArchitecture) {
|
|
8284
|
+
suggestedNextSteps.push("Use module-context-agent to refine knowledge/tech/module/module-context.md.");
|
|
8285
|
+
} else {
|
|
8286
|
+
suggestedNextSteps.push("Return to the core repository.");
|
|
8287
|
+
suggestedNextSteps.push("Create or continue the Work Item from the core.");
|
|
8288
|
+
suggestedNextSteps.push("Add this module to `affected_modules` when the change touches it.");
|
|
8289
|
+
suggestedNextSteps.push("Re-run `kaddo context` and `kaddo understand` from the core.");
|
|
8194
8290
|
}
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
suggestedNextSteps.push("
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
suggestedNextSteps.push("
|
|
8203
|
-
}
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
)
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
8291
|
+
} else {
|
|
8292
|
+
const baselineIncomplete = !knowledge.hasBusiness || !knowledge.hasProduct;
|
|
8293
|
+
if (baselineIncomplete) {
|
|
8294
|
+
suggestedNextSteps.push("Run `kaddo bootstrap` to create the project knowledge baseline.");
|
|
8295
|
+
if (!knowledge.hasAgents) suggestedNextSteps.push("Then run `kaddo add agents`.");
|
|
8296
|
+
if (!knowledge.hasSkills) suggestedNextSteps.push("Then run `kaddo add skills`.");
|
|
8297
|
+
suggestedNextSteps.push("Then run `kaddo context`.");
|
|
8298
|
+
suggestedNextSteps.push("Then run `kaddo understand`.");
|
|
8299
|
+
} else {
|
|
8300
|
+
if (!knowledge.hasScan) {
|
|
8301
|
+
suggestedNextSteps.push("Run `kaddo scan` to detect the technical stack.");
|
|
8302
|
+
} else if (!knowledge.hasContextPack) {
|
|
8303
|
+
suggestedNextSteps.push("Run `kaddo context` to prepare an LLM context pack.");
|
|
8304
|
+
}
|
|
8305
|
+
if (!knowledge.hasAgents) {
|
|
8306
|
+
suggestedNextSteps.push("Run `kaddo add agents` to install knowledge agents.");
|
|
8307
|
+
}
|
|
8308
|
+
if (!knowledge.hasCapabilities) {
|
|
8309
|
+
suggestedNextSteps.push("Use capability-agent to generate knowledge/product/capabilities.md.");
|
|
8310
|
+
}
|
|
8311
|
+
if (!knowledge.hasArchitecture) {
|
|
8312
|
+
suggestedNextSteps.push("Use architecture-agent to generate knowledge/tech/current-state.md.");
|
|
8313
|
+
}
|
|
8314
|
+
if (!knowledge.hasRoadmap) {
|
|
8315
|
+
suggestedNextSteps.push("Use roadmap-agent to generate knowledge/delivery/roadmap.md.");
|
|
8316
|
+
} else if (roadmap.remaining > 0) {
|
|
8317
|
+
suggestedNextSteps.push(
|
|
8318
|
+
`Materialize ${roadmap.remaining} roadmap candidate(s) with \`kaddo create --from roadmap\`.`
|
|
8319
|
+
);
|
|
8320
|
+
}
|
|
8321
|
+
if (items.length === 0 && !roadmap.present) {
|
|
8322
|
+
suggestedNextSteps.push("Create your first Work Item with `kaddo create`.");
|
|
8323
|
+
} else if (ownership.workItemsMissingOwnership > 0) {
|
|
8324
|
+
suggestedNextSteps.push(
|
|
8325
|
+
"Run `kaddo owners suggest` for Work Items without code ownership."
|
|
8326
|
+
);
|
|
8327
|
+
}
|
|
8217
8328
|
}
|
|
8218
8329
|
}
|
|
8219
8330
|
const readiness = buildReadinessReport(dir);
|
|
@@ -8256,7 +8367,30 @@ function buildProjectExplanation(dir) {
|
|
|
8256
8367
|
projectRoute: buildProjectRoute(dir),
|
|
8257
8368
|
scanSignals: loadScanSignals(dir),
|
|
8258
8369
|
metadataHealth: analyzeMetadataHealth(dir),
|
|
8259
|
-
isModuleRepo: config != null && isModule(config)
|
|
8370
|
+
isModuleRepo: config != null && isModule(config),
|
|
8371
|
+
implementationEvidence: workItemArtifacts.filter((a2) => a2.affectedModules.length > 0).map((a2) => {
|
|
8372
|
+
const fm = a2.rawFrontmatter;
|
|
8373
|
+
const evidence = fm.implementation_evidence;
|
|
8374
|
+
const repos = evidence?.repositories ?? {};
|
|
8375
|
+
const repoEvidence = {};
|
|
8376
|
+
for (const [repoId, data] of Object.entries(repos)) {
|
|
8377
|
+
repoEvidence[repoId] = {
|
|
8378
|
+
role: String(data.role ?? (repoId === "core" ? "core" : "module")),
|
|
8379
|
+
status: String(data.status ?? "unknown")
|
|
8380
|
+
};
|
|
8381
|
+
}
|
|
8382
|
+
return {
|
|
8383
|
+
id: a2.id || a2.title,
|
|
8384
|
+
lifecycle: lifecycleStateOf({ status: a2.status, filePath: a2.filePath }),
|
|
8385
|
+
implementationStatus: a2.implementationStatus || "not-started",
|
|
8386
|
+
validationStatus: a2.validationStatus || "not-started",
|
|
8387
|
+
releaseStatus: a2.releaseStatus || "not-assessed",
|
|
8388
|
+
affectedModules: a2.affectedModules,
|
|
8389
|
+
releaseGates: Array.isArray(fm.release_gates) ? fm.release_gates : [],
|
|
8390
|
+
completionExceptions: Array.isArray(fm.completion_exceptions) ? fm.completion_exceptions : [],
|
|
8391
|
+
repoEvidence
|
|
8392
|
+
};
|
|
8393
|
+
})
|
|
8260
8394
|
};
|
|
8261
8395
|
}
|
|
8262
8396
|
function stateLabel(state) {
|
|
@@ -8309,11 +8443,19 @@ function renderExplanationHuman(exp) {
|
|
|
8309
8443
|
lines.push("## Knowledge Status");
|
|
8310
8444
|
lines.push(`- Inventory: ${exp.knowledge.hasInventory ? "available" : "missing"}`);
|
|
8311
8445
|
lines.push(`- Context pack: ${exp.knowledge.hasContextPack ? "available" : "missing"}`);
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
|
|
8315
|
-
|
|
8316
|
-
|
|
8446
|
+
if (exp.isModuleRepo) {
|
|
8447
|
+
lines.push("- Business: Not applicable");
|
|
8448
|
+
lines.push("- Product: Not applicable");
|
|
8449
|
+
lines.push(`- Tech: ${ls("Tech")}`);
|
|
8450
|
+
lines.push("- Delivery: Managed by core");
|
|
8451
|
+
lines.push("- Agents: Managed by core");
|
|
8452
|
+
} else {
|
|
8453
|
+
lines.push(`- Business: ${ls("Business")}`);
|
|
8454
|
+
lines.push(`- Product: ${ls("Product")}`);
|
|
8455
|
+
lines.push(`- Tech: ${ls("Tech")}`);
|
|
8456
|
+
lines.push(`- Delivery: ${ls("Delivery")}`);
|
|
8457
|
+
lines.push(`- Agents: ${exp.knowledge.hasAgents ? "available" : "missing"}`);
|
|
8458
|
+
}
|
|
8317
8459
|
if (exp.roadmap.present) {
|
|
8318
8460
|
lines.push(`- Roadmap initiatives: ${exp.roadmap.initiatives}`);
|
|
8319
8461
|
lines.push(`- Work Item candidates: ${exp.roadmap.work_item_candidates}`);
|
|
@@ -8374,6 +8516,36 @@ function renderExplanationHuman(exp) {
|
|
|
8374
8516
|
}
|
|
8375
8517
|
lines.push("");
|
|
8376
8518
|
}
|
|
8519
|
+
if (exp.implementationEvidence.length > 0) {
|
|
8520
|
+
lines.push("## Implementation Evidence");
|
|
8521
|
+
for (const ev of exp.implementationEvidence) {
|
|
8522
|
+
lines.push("");
|
|
8523
|
+
lines.push(`### ${ev.id}`);
|
|
8524
|
+
lines.push(`- Lifecycle: ${ev.lifecycle.charAt(0).toUpperCase() + ev.lifecycle.slice(1)}`);
|
|
8525
|
+
lines.push(`- Implementation: ${ev.implementationStatus}`);
|
|
8526
|
+
lines.push(`- Validation: ${ev.validationStatus}`);
|
|
8527
|
+
lines.push(`- Release: ${ev.releaseStatus}`);
|
|
8528
|
+
if (Object.keys(ev.repoEvidence).length > 0) {
|
|
8529
|
+
lines.push("Repositories:");
|
|
8530
|
+
for (const [repoId, info] of Object.entries(ev.repoEvidence)) {
|
|
8531
|
+
lines.push(`- ${repoId} \u2014 ${info.status}`);
|
|
8532
|
+
}
|
|
8533
|
+
} else if (ev.affectedModules.length > 0) {
|
|
8534
|
+
lines.push(`Affected modules: ${ev.affectedModules.join(", ")}`);
|
|
8535
|
+
}
|
|
8536
|
+
const pendingGates = ev.releaseGates.filter((g) => g.status === "blocked" || g.status === "pending");
|
|
8537
|
+
if (pendingGates.length > 0) {
|
|
8538
|
+
lines.push("Pending release gates:");
|
|
8539
|
+
for (const g of pendingGates) lines.push(`- ${g.id}${g.reason ? ` \u2014 ${g.reason}` : ""}`);
|
|
8540
|
+
}
|
|
8541
|
+
const acceptedExceptions = ev.completionExceptions.filter((e) => e.status === "accepted" || e.status === "deferred");
|
|
8542
|
+
if (acceptedExceptions.length > 0) {
|
|
8543
|
+
lines.push("Completion exceptions:");
|
|
8544
|
+
for (const e of acceptedExceptions) lines.push(`- ${e.id}: ${e.status}${e.reason ? ` \u2014 ${e.reason}` : ""}`);
|
|
8545
|
+
}
|
|
8546
|
+
}
|
|
8547
|
+
lines.push("");
|
|
8548
|
+
}
|
|
8377
8549
|
if (exp.domains.length > 0) {
|
|
8378
8550
|
lines.push("## Domains");
|
|
8379
8551
|
lines.push(`- ${exp.domains.join(", ")}`);
|
|
@@ -8474,14 +8646,27 @@ function renderExplanationHuman(exp) {
|
|
|
8474
8646
|
lines.push(`- understand: ${s.understand}`);
|
|
8475
8647
|
lines.push(`- agents: ${s.agents}`);
|
|
8476
8648
|
lines.push(`- skills: ${s.skills}`);
|
|
8477
|
-
|
|
8478
|
-
|
|
8649
|
+
if (exp.isModuleRepo) {
|
|
8650
|
+
lines.push("- business: not-applicable");
|
|
8651
|
+
lines.push("- product: not-applicable");
|
|
8652
|
+
} else {
|
|
8653
|
+
lines.push(`- business: ${s.business}`);
|
|
8654
|
+
lines.push(`- product: ${s.product}`);
|
|
8655
|
+
}
|
|
8479
8656
|
lines.push(`- capabilities: ${s.capabilities}`);
|
|
8480
8657
|
lines.push(`- current-state: ${s.current_state}`);
|
|
8481
8658
|
lines.push(`- codebase: ${s.codebase}`);
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8659
|
+
if (s.module_context != null) {
|
|
8660
|
+
lines.push(`- module-context: ${s.module_context}`);
|
|
8661
|
+
}
|
|
8662
|
+
if (!exp.isModuleRepo) {
|
|
8663
|
+
lines.push(`- roadmap: ${s.roadmap}`);
|
|
8664
|
+
lines.push(`- work-items: ${s.work_items}`);
|
|
8665
|
+
lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
|
|
8666
|
+
} else {
|
|
8667
|
+
lines.push("- roadmap: managed-by-core");
|
|
8668
|
+
lines.push("- work-items: managed-by-core");
|
|
8669
|
+
}
|
|
8485
8670
|
lines.push(`- blocking open questions: ${s.blocking_open_questions}`);
|
|
8486
8671
|
lines.push(`- assumptions: ${s.assumed_questions}`);
|
|
8487
8672
|
lines.push(`- deferred: ${s.deferred_questions}`);
|
|
@@ -9557,7 +9742,16 @@ function listWorkItems(root) {
|
|
|
9557
9742
|
capsules: strArray(data.capsules),
|
|
9558
9743
|
source,
|
|
9559
9744
|
domains,
|
|
9560
|
-
readiness
|
|
9745
|
+
readiness,
|
|
9746
|
+
...data.implementation_status ? { implementation_status: String(data.implementation_status) } : {},
|
|
9747
|
+
...data.validation_status ? { validation_status: String(data.validation_status) } : {},
|
|
9748
|
+
...data.release_status ? { release_status: String(data.release_status) } : {},
|
|
9749
|
+
...Array.isArray(data.affected_modules) && data.affected_modules.length > 0 ? { affected_modules: data.affected_modules.map(String) } : {},
|
|
9750
|
+
...data.refined_by ? { refined_by: String(data.refined_by) } : {},
|
|
9751
|
+
...data.implemented_by ? { implemented_by: String(data.implemented_by) } : {},
|
|
9752
|
+
...data.closed_by ? { closed_by: String(data.closed_by) } : {},
|
|
9753
|
+
...Array.isArray(data.release_gates) && data.release_gates.length > 0 ? { release_gates: data.release_gates } : {},
|
|
9754
|
+
...Array.isArray(data.completion_exceptions) && data.completion_exceptions.length > 0 ? { completion_exceptions: data.completion_exceptions } : {}
|
|
9561
9755
|
});
|
|
9562
9756
|
}
|
|
9563
9757
|
return items.sort((a2, b2) => a2.id.localeCompare(b2.id));
|
|
@@ -9950,7 +10144,7 @@ function projectStatus(root) {
|
|
|
9950
10144
|
return fail("Project status needs `.kaddo/explain.json`. Run `kaddo explain` first.");
|
|
9951
10145
|
}
|
|
9952
10146
|
const maturity = (explain.layers ?? []).map((l2) => `${l2.layer}: ${l2.status}`);
|
|
9953
|
-
|
|
10147
|
+
const result = {
|
|
9954
10148
|
project: explain.project?.name ?? "unknown",
|
|
9955
10149
|
state: explain.project?.state ?? "unknown",
|
|
9956
10150
|
knowledgeMaturity: maturity,
|
|
@@ -9970,7 +10164,17 @@ function projectStatus(root) {
|
|
|
9970
10164
|
hints: hints?.summary?.hints ?? 0
|
|
9971
10165
|
},
|
|
9972
10166
|
capsules: capsules.length
|
|
9973
|
-
}
|
|
10167
|
+
};
|
|
10168
|
+
if (explain.isModuleRepo) {
|
|
10169
|
+
result.isModuleRepo = true;
|
|
10170
|
+
result.readiness = {
|
|
10171
|
+
overall: explain.readiness?.overall ?? "unknown",
|
|
10172
|
+
project_role: explain.readiness?.project_role ?? "module",
|
|
10173
|
+
agents: "managed-by-core",
|
|
10174
|
+
skills: "managed-by-core"
|
|
10175
|
+
};
|
|
10176
|
+
}
|
|
10177
|
+
return ok(result);
|
|
9974
10178
|
}
|
|
9975
10179
|
function listWorkItemsTool(root, filter = {}) {
|
|
9976
10180
|
let items = listWorkItems(root);
|
|
@@ -10672,7 +10876,7 @@ var OPERATING_RULES = [
|
|
|
10672
10876
|
"Kaddo itself never calls an LLM and never runs git \u2014 every git action is the human\u2019s."
|
|
10673
10877
|
];
|
|
10674
10878
|
function toContextWorkItem(a2) {
|
|
10675
|
-
|
|
10879
|
+
const wi = {
|
|
10676
10880
|
id: a2.id,
|
|
10677
10881
|
type: a2.type,
|
|
10678
10882
|
title: a2.title,
|
|
@@ -10682,6 +10886,11 @@ function toContextWorkItem(a2) {
|
|
|
10682
10886
|
domains: a2.domains,
|
|
10683
10887
|
source: parseWorkItemSource(a2.rawFrontmatter)
|
|
10684
10888
|
};
|
|
10889
|
+
if (a2.implementationStatus) wi.implementationStatus = a2.implementationStatus;
|
|
10890
|
+
if (a2.validationStatus) wi.validationStatus = a2.validationStatus;
|
|
10891
|
+
if (a2.releaseStatus) wi.releaseStatus = a2.releaseStatus;
|
|
10892
|
+
if (a2.affectedModules.length > 0) wi.affectedModules = a2.affectedModules;
|
|
10893
|
+
return wi;
|
|
10685
10894
|
}
|
|
10686
10895
|
function toContextArtifact(a2) {
|
|
10687
10896
|
return { id: a2.id, type: a2.type, title: a2.title, summary: a2.summary, codeGlobs: a2.codeGlobs };
|
|
@@ -10700,11 +10909,11 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
10700
10909
|
if (!inventoryAvailable) {
|
|
10701
10910
|
missing.push("No technical inventory found. Run `kaddo scan` to generate it.");
|
|
10702
10911
|
}
|
|
10912
|
+
const moduleRepo = config != null && isModule(config);
|
|
10703
10913
|
const knowledgeSummary = readMarkdownSummary(dir, "knowledge.md") ?? "";
|
|
10704
|
-
if (!knowledgeSummary) {
|
|
10914
|
+
if (!knowledgeSummary && !moduleRepo) {
|
|
10705
10915
|
missing.push("No project knowledge summary found yet.");
|
|
10706
10916
|
}
|
|
10707
|
-
const moduleRepo = config != null && isModule(config);
|
|
10708
10917
|
const roadmapSummary = readMarkdownSummary(dir, "delivery/roadmap.md") ?? "";
|
|
10709
10918
|
if (!roadmapSummary && !moduleRepo) {
|
|
10710
10919
|
missing.push("No roadmap baseline found.");
|
|
@@ -10878,11 +11087,12 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
10878
11087
|
}
|
|
10879
11088
|
return contexts;
|
|
10880
11089
|
})(),
|
|
11090
|
+
isModuleRepo: moduleRepo,
|
|
10881
11091
|
missing,
|
|
10882
11092
|
// VS-052/VS-073.2: the handoff is driven by the unified next step, so the pack never contradicts
|
|
10883
11093
|
// the Current Phase block above it.
|
|
10884
11094
|
handoff: {
|
|
10885
|
-
recommendedAgents: isBootstrap ? [] : unifiedPhase.recommendedAgents.length > 0 ? unifiedPhase.recommendedAgents : recommendedAgentsForState(state),
|
|
11095
|
+
recommendedAgents: isBootstrap ? [] : unifiedPhase.recommendedAgents.length > 0 ? unifiedPhase.recommendedAgents : moduleRepo ? [] : recommendedAgentsForState(state),
|
|
10886
11096
|
nextSteps: [nextStepRecommendation.label],
|
|
10887
11097
|
instructions: isBootstrap ? ["No agent handoff yet.", "Run `kaddo bootstrap` first to create the baseline files."] : unifiedPhase.llmInstructions.length > 0 ? unifiedPhase.llmInstructions : LLM_INSTRUCTIONS,
|
|
10888
11098
|
operatingRules: OPERATING_RULES
|
|
@@ -11193,7 +11403,11 @@ function renderContextPack(pack) {
|
|
|
11193
11403
|
}
|
|
11194
11404
|
}
|
|
11195
11405
|
parts.push("## Recommended Agent Handoff\n");
|
|
11196
|
-
if (
|
|
11406
|
+
if (pack.isModuleRepo && handoff.recommendedAgents.length === 0) {
|
|
11407
|
+
parts.push("No local agent action is required.\n");
|
|
11408
|
+
parts.push("This module is ready for core orchestration.\n");
|
|
11409
|
+
parts.push("Business, Product, Delivery, Agents and Skills are managed by the core repository.\n");
|
|
11410
|
+
} else if (isBootstrapIncomplete) {
|
|
11197
11411
|
parts.push("No agent handoff yet.\n");
|
|
11198
11412
|
parts.push("Run `kaddo bootstrap` first to create the baseline files.\n");
|
|
11199
11413
|
} else if (rec.agent && rec.agentInstalled === false) {
|
package/package.json
CHANGED