@kaddo/mcp 3.65.0 → 3.67.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 +221 -15
- 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;
|
|
@@ -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";
|
|
@@ -3942,6 +3963,8 @@ function workItemsSignal(dir) {
|
|
|
3942
3963
|
if (wis.length === 0) return "none";
|
|
3943
3964
|
if (wis.some((w3) => w3.lifecycle === "in-progress")) return "in-progress";
|
|
3944
3965
|
if (wis.some((w3) => w3.lifecycle === "ready")) return "ready";
|
|
3966
|
+
const hasActive = wis.some((w3) => w3.lifecycle === "draft" || w3.lifecycle === "blocked");
|
|
3967
|
+
if (!hasActive && wis.some((w3) => w3.lifecycle === "completed" || w3.lifecycle === "archived")) return "completed-only";
|
|
3945
3968
|
return "none-ready";
|
|
3946
3969
|
}
|
|
3947
3970
|
function installedAdapters(dir) {
|
|
@@ -4370,6 +4393,8 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
4370
4393
|
else if (understand === "missing") overall = "scanned";
|
|
4371
4394
|
else if (firstWeak) overall = "knowledge-incomplete";
|
|
4372
4395
|
else if (oq.summary.blocking_open > 0) overall = "needs-decisions";
|
|
4396
|
+
else if (work_items === "in-progress") overall = "active-implementation";
|
|
4397
|
+
else if (work_items === "completed-only") overall = deriveDeliveryCompletedStatus(dir);
|
|
4373
4398
|
else if (roadmap !== "has-candidates") overall = "ready-for-roadmap";
|
|
4374
4399
|
else if (work_items === "none" || work_items === "none-ready") overall = "ready-for-work-item";
|
|
4375
4400
|
else overall = "ready-for-implementation";
|
|
@@ -4382,6 +4407,16 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
4382
4407
|
nextStepRecommendation: rec
|
|
4383
4408
|
};
|
|
4384
4409
|
}
|
|
4410
|
+
function deriveDeliveryCompletedStatus(dir) {
|
|
4411
|
+
const wis = discoverWorkItems(dir);
|
|
4412
|
+
const completed = wis.filter((w3) => lifecycleStateOf({ status: w3.status, filePath: w3.filePath }) === "completed");
|
|
4413
|
+
if (completed.length === 0) return "delivery-completed";
|
|
4414
|
+
const hasReleaseBlocked = completed.some((w3) => w3.releaseStatus === "blocked");
|
|
4415
|
+
const hasReleaseReady = completed.some((w3) => w3.releaseStatus === "ready" || w3.releaseStatus === "released");
|
|
4416
|
+
if (hasReleaseBlocked) return "delivery-completed-release-blocked";
|
|
4417
|
+
if (hasReleaseReady) return "delivery-completed-release-ready";
|
|
4418
|
+
return "delivery-completed";
|
|
4419
|
+
}
|
|
4385
4420
|
|
|
4386
4421
|
// ../cli/src/core/assets.ts
|
|
4387
4422
|
import matter6 from "gray-matter";
|
|
@@ -7606,7 +7641,7 @@ var refineWorkItem = {
|
|
|
7606
7641
|
id: "refine-work-item",
|
|
7607
7642
|
label: "Refine Work Item",
|
|
7608
7643
|
evaluate: (ctx) => {
|
|
7609
|
-
if (ctx.readyWorkItems > 0 || ctx.inProgressWorkItems > 0) return { status: "done" };
|
|
7644
|
+
if (ctx.readyWorkItems > 0 || ctx.inProgressWorkItems > 0 || ctx.blockedWorkItems > 0 || ctx.completedWorkItems > 0 || ctx.archivedWorkItems > 0) return { status: "done" };
|
|
7610
7645
|
if (ctx.draftWorkItems > 0) {
|
|
7611
7646
|
return {
|
|
7612
7647
|
status: "current",
|
|
@@ -7857,7 +7892,9 @@ function buildRouteContext(dir) {
|
|
|
7857
7892
|
draftWorkItems: byState("draft"),
|
|
7858
7893
|
readyWorkItems: byState("ready"),
|
|
7859
7894
|
inProgressWorkItems: byState("in-progress"),
|
|
7895
|
+
blockedWorkItems: byState("blocked"),
|
|
7860
7896
|
completedWorkItems: byState("completed"),
|
|
7897
|
+
archivedWorkItems: byState("archived"),
|
|
7861
7898
|
ownershipCoverage: `${withOwnership}/${total}`,
|
|
7862
7899
|
ownershipComplete: total > 0 && withOwnership >= total,
|
|
7863
7900
|
decisionCandidates: td.candidates,
|
|
@@ -8030,6 +8067,33 @@ function analyzeMetadataHealth(dir) {
|
|
|
8030
8067
|
if (fileDrifted) drifted++;
|
|
8031
8068
|
else healthy++;
|
|
8032
8069
|
}
|
|
8070
|
+
const wiDir = join(dir, "knowledge/delivery/work-items");
|
|
8071
|
+
if (exists(wiDir)) {
|
|
8072
|
+
const walkWIs = (d3) => {
|
|
8073
|
+
for (const entry of readDir(d3)) {
|
|
8074
|
+
const p = join(d3, entry);
|
|
8075
|
+
if (isFile(p) && entry.endsWith(".md")) {
|
|
8076
|
+
try {
|
|
8077
|
+
const raw = readFile(p);
|
|
8078
|
+
const fm = matter7(raw).data;
|
|
8079
|
+
if (fm.status === "done") {
|
|
8080
|
+
const rel = p.replace(dir + "/", "").replace(dir + "\\", "").replace(/\\/g, "/");
|
|
8081
|
+
findings.push({
|
|
8082
|
+
file: rel,
|
|
8083
|
+
field: "status",
|
|
8084
|
+
issue: "inconsistent",
|
|
8085
|
+
detail: "Legacy status `done` detected. Canonical status is `completed`."
|
|
8086
|
+
});
|
|
8087
|
+
}
|
|
8088
|
+
} catch {
|
|
8089
|
+
}
|
|
8090
|
+
} else if (!isFile(p) && !entry.startsWith(".")) {
|
|
8091
|
+
walkWIs(p);
|
|
8092
|
+
}
|
|
8093
|
+
}
|
|
8094
|
+
};
|
|
8095
|
+
walkWIs(wiDir);
|
|
8096
|
+
}
|
|
8033
8097
|
return { findings, healthy, drifted };
|
|
8034
8098
|
}
|
|
8035
8099
|
|
|
@@ -8319,7 +8383,46 @@ function buildProjectExplanation(dir) {
|
|
|
8319
8383
|
projectRoute: buildProjectRoute(dir),
|
|
8320
8384
|
scanSignals: loadScanSignals(dir),
|
|
8321
8385
|
metadataHealth: analyzeMetadataHealth(dir),
|
|
8322
|
-
isModuleRepo: config != null && isModule(config)
|
|
8386
|
+
isModuleRepo: config != null && isModule(config),
|
|
8387
|
+
deliverySummary: (() => {
|
|
8388
|
+
const completed = workItemArtifacts.filter((a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "completed");
|
|
8389
|
+
const archived = workItemArtifacts.filter((a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "archived");
|
|
8390
|
+
const active = workItemArtifacts.filter((a2) => isActiveState(lifecycleStateOf({ status: a2.status, filePath: a2.filePath })));
|
|
8391
|
+
if (completed.length === 0 && archived.length === 0) return null;
|
|
8392
|
+
return {
|
|
8393
|
+
completedWorkItems: completed.length,
|
|
8394
|
+
archivedWorkItems: archived.length,
|
|
8395
|
+
activeWorkItems: active.length,
|
|
8396
|
+
implementationCompleted: completed.filter((a2) => a2.implementationStatus === "completed").length,
|
|
8397
|
+
releaseBlocked: completed.filter((a2) => a2.releaseStatus === "blocked").length,
|
|
8398
|
+
releaseReady: completed.filter((a2) => a2.releaseStatus === "ready" || a2.releaseStatus === "released").length
|
|
8399
|
+
};
|
|
8400
|
+
})(),
|
|
8401
|
+
implementationEvidence: workItemArtifacts.filter((a2) => a2.affectedModules.length > 0).map((a2) => {
|
|
8402
|
+
const fm = a2.rawFrontmatter;
|
|
8403
|
+
const evidence = fm.implementation_evidence;
|
|
8404
|
+
const repos = evidence?.repositories ?? {};
|
|
8405
|
+
const repoEvidence = {};
|
|
8406
|
+
for (const [repoId, data] of Object.entries(repos)) {
|
|
8407
|
+
repoEvidence[repoId] = {
|
|
8408
|
+
role: String(data.role ?? (repoId === "core" ? "core" : "module")),
|
|
8409
|
+
status: String(data.status ?? "unknown")
|
|
8410
|
+
};
|
|
8411
|
+
}
|
|
8412
|
+
const lc = lifecycleStateOf({ status: a2.status, filePath: a2.filePath });
|
|
8413
|
+
const historicalDefault = lc === "completed" || lc === "archived" ? "not-assessed" : "not-started";
|
|
8414
|
+
return {
|
|
8415
|
+
id: a2.id || a2.title,
|
|
8416
|
+
lifecycle: lc,
|
|
8417
|
+
implementationStatus: a2.implementationStatus || historicalDefault,
|
|
8418
|
+
validationStatus: a2.validationStatus || historicalDefault,
|
|
8419
|
+
releaseStatus: a2.releaseStatus || "not-assessed",
|
|
8420
|
+
affectedModules: a2.affectedModules,
|
|
8421
|
+
releaseGates: Array.isArray(fm.release_gates) ? fm.release_gates : [],
|
|
8422
|
+
completionExceptions: Array.isArray(fm.completion_exceptions) ? fm.completion_exceptions : [],
|
|
8423
|
+
repoEvidence
|
|
8424
|
+
};
|
|
8425
|
+
})
|
|
8323
8426
|
};
|
|
8324
8427
|
}
|
|
8325
8428
|
function stateLabel(state) {
|
|
@@ -8445,6 +8548,36 @@ function renderExplanationHuman(exp) {
|
|
|
8445
8548
|
}
|
|
8446
8549
|
lines.push("");
|
|
8447
8550
|
}
|
|
8551
|
+
if (exp.implementationEvidence.length > 0) {
|
|
8552
|
+
lines.push("## Implementation Evidence");
|
|
8553
|
+
for (const ev of exp.implementationEvidence) {
|
|
8554
|
+
lines.push("");
|
|
8555
|
+
lines.push(`### ${ev.id}`);
|
|
8556
|
+
lines.push(`- Lifecycle: ${ev.lifecycle.charAt(0).toUpperCase() + ev.lifecycle.slice(1)}`);
|
|
8557
|
+
lines.push(`- Implementation: ${ev.implementationStatus}`);
|
|
8558
|
+
lines.push(`- Validation: ${ev.validationStatus}`);
|
|
8559
|
+
lines.push(`- Release: ${ev.releaseStatus}`);
|
|
8560
|
+
if (Object.keys(ev.repoEvidence).length > 0) {
|
|
8561
|
+
lines.push("Repositories:");
|
|
8562
|
+
for (const [repoId, info] of Object.entries(ev.repoEvidence)) {
|
|
8563
|
+
lines.push(`- ${repoId} \u2014 ${info.status}`);
|
|
8564
|
+
}
|
|
8565
|
+
} else if (ev.affectedModules.length > 0) {
|
|
8566
|
+
lines.push(`Affected modules: ${ev.affectedModules.join(", ")}`);
|
|
8567
|
+
}
|
|
8568
|
+
const pendingGates = ev.releaseGates.filter((g) => g.status === "blocked" || g.status === "pending");
|
|
8569
|
+
if (pendingGates.length > 0) {
|
|
8570
|
+
lines.push("Pending release gates:");
|
|
8571
|
+
for (const g of pendingGates) lines.push(`- ${g.id}${g.reason ? ` \u2014 ${g.reason}` : ""}`);
|
|
8572
|
+
}
|
|
8573
|
+
const acceptedExceptions = ev.completionExceptions.filter((e) => e.status === "accepted" || e.status === "deferred");
|
|
8574
|
+
if (acceptedExceptions.length > 0) {
|
|
8575
|
+
lines.push("Completion exceptions:");
|
|
8576
|
+
for (const e of acceptedExceptions) lines.push(`- ${e.id}: ${e.status}${e.reason ? ` \u2014 ${e.reason}` : ""}`);
|
|
8577
|
+
}
|
|
8578
|
+
}
|
|
8579
|
+
lines.push("");
|
|
8580
|
+
}
|
|
8448
8581
|
if (exp.domains.length > 0) {
|
|
8449
8582
|
lines.push("## Domains");
|
|
8450
8583
|
lines.push(`- ${exp.domains.join(", ")}`);
|
|
@@ -8527,6 +8660,17 @@ function renderExplanationHuman(exp) {
|
|
|
8527
8660
|
}
|
|
8528
8661
|
lines.push(`- Next step: ${exp.readiness.recommended_next_step.label}`);
|
|
8529
8662
|
lines.push("");
|
|
8663
|
+
if (exp.deliverySummary) {
|
|
8664
|
+
const ds = exp.deliverySummary;
|
|
8665
|
+
lines.push("## Delivery Summary");
|
|
8666
|
+
lines.push(`- Completed Work Items: ${ds.completedWorkItems}`);
|
|
8667
|
+
if (ds.archivedWorkItems > 0) lines.push(`- Archived Work Items: ${ds.archivedWorkItems}`);
|
|
8668
|
+
lines.push(`- Active Work Items: ${ds.activeWorkItems}`);
|
|
8669
|
+
if (ds.implementationCompleted > 0) lines.push(`- Implementation completed: ${ds.implementationCompleted}`);
|
|
8670
|
+
if (ds.releaseBlocked > 0) lines.push(`- Release blocked: ${ds.releaseBlocked}`);
|
|
8671
|
+
if (ds.releaseReady > 0) lines.push(`- Release ready: ${ds.releaseReady}`);
|
|
8672
|
+
lines.push("");
|
|
8673
|
+
}
|
|
8530
8674
|
const rec = exp.nextStepRecommendation;
|
|
8531
8675
|
const secondary = rec.secondary ?? [];
|
|
8532
8676
|
const steps = secondary.length > 0 || /Delivery|Active|Maintenance/.test(rec.phase) ? [rec.label, ...secondary.map((s2) => s2.label)] : exp.suggestedNextSteps;
|
|
@@ -8561,6 +8705,10 @@ function renderExplanationHuman(exp) {
|
|
|
8561
8705
|
if (!exp.isModuleRepo) {
|
|
8562
8706
|
lines.push(`- roadmap: ${s.roadmap}`);
|
|
8563
8707
|
lines.push(`- work-items: ${s.work_items}`);
|
|
8708
|
+
if (exp.deliverySummary) {
|
|
8709
|
+
lines.push(`- work-items completed: ${exp.deliverySummary.completedWorkItems}`);
|
|
8710
|
+
lines.push(`- work-items active: ${exp.deliverySummary.activeWorkItems}`);
|
|
8711
|
+
}
|
|
8564
8712
|
lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
|
|
8565
8713
|
} else {
|
|
8566
8714
|
lines.push("- roadmap: managed-by-core");
|
|
@@ -9641,7 +9789,16 @@ function listWorkItems(root) {
|
|
|
9641
9789
|
capsules: strArray(data.capsules),
|
|
9642
9790
|
source,
|
|
9643
9791
|
domains,
|
|
9644
|
-
readiness
|
|
9792
|
+
readiness,
|
|
9793
|
+
...data.implementation_status ? { implementation_status: String(data.implementation_status) } : {},
|
|
9794
|
+
...data.validation_status ? { validation_status: String(data.validation_status) } : {},
|
|
9795
|
+
...data.release_status ? { release_status: String(data.release_status) } : {},
|
|
9796
|
+
...Array.isArray(data.affected_modules) && data.affected_modules.length > 0 ? { affected_modules: data.affected_modules.map(String) } : {},
|
|
9797
|
+
...data.refined_by ? { refined_by: String(data.refined_by) } : {},
|
|
9798
|
+
...data.implemented_by ? { implemented_by: String(data.implemented_by) } : {},
|
|
9799
|
+
...data.closed_by ? { closed_by: String(data.closed_by) } : {},
|
|
9800
|
+
...Array.isArray(data.release_gates) && data.release_gates.length > 0 ? { release_gates: data.release_gates } : {},
|
|
9801
|
+
...Array.isArray(data.completion_exceptions) && data.completion_exceptions.length > 0 ? { completion_exceptions: data.completion_exceptions } : {}
|
|
9645
9802
|
});
|
|
9646
9803
|
}
|
|
9647
9804
|
return items.sort((a2, b2) => a2.id.localeCompare(b2.id));
|
|
@@ -10063,6 +10220,13 @@ function projectStatus(root) {
|
|
|
10063
10220
|
agents: "managed-by-core",
|
|
10064
10221
|
skills: "managed-by-core"
|
|
10065
10222
|
};
|
|
10223
|
+
} else {
|
|
10224
|
+
result.readiness = {
|
|
10225
|
+
overall: explain.readiness?.overall ?? "unknown"
|
|
10226
|
+
};
|
|
10227
|
+
}
|
|
10228
|
+
if (explain.deliverySummary) {
|
|
10229
|
+
result.deliverySummary = explain.deliverySummary;
|
|
10066
10230
|
}
|
|
10067
10231
|
return ok(result);
|
|
10068
10232
|
}
|
|
@@ -10766,16 +10930,23 @@ var OPERATING_RULES = [
|
|
|
10766
10930
|
"Kaddo itself never calls an LLM and never runs git \u2014 every git action is the human\u2019s."
|
|
10767
10931
|
];
|
|
10768
10932
|
function toContextWorkItem(a2) {
|
|
10769
|
-
|
|
10933
|
+
const lifecycle = lifecycleStateOf({ status: a2.status, filePath: a2.filePath });
|
|
10934
|
+
const isHistorical = lifecycle === "completed" || lifecycle === "archived";
|
|
10935
|
+
const wi = {
|
|
10770
10936
|
id: a2.id,
|
|
10771
10937
|
type: a2.type,
|
|
10772
10938
|
title: a2.title,
|
|
10773
10939
|
status: a2.status,
|
|
10774
|
-
lifecycle
|
|
10940
|
+
lifecycle,
|
|
10775
10941
|
knowledgeLevel: a2.knowledgeLevel,
|
|
10776
10942
|
domains: a2.domains,
|
|
10777
10943
|
source: parseWorkItemSource(a2.rawFrontmatter)
|
|
10778
10944
|
};
|
|
10945
|
+
wi.implementationStatus = a2.implementationStatus || (isHistorical ? "not-assessed" : void 0);
|
|
10946
|
+
wi.validationStatus = a2.validationStatus || (isHistorical ? "not-assessed" : void 0);
|
|
10947
|
+
wi.releaseStatus = a2.releaseStatus || (isHistorical ? "not-assessed" : void 0);
|
|
10948
|
+
if (a2.affectedModules.length > 0) wi.affectedModules = a2.affectedModules;
|
|
10949
|
+
return wi;
|
|
10779
10950
|
}
|
|
10780
10951
|
function toContextArtifact(a2) {
|
|
10781
10952
|
return { id: a2.id, type: a2.type, title: a2.title, summary: a2.summary, codeGlobs: a2.codeGlobs };
|
|
@@ -10804,10 +10975,17 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
10804
10975
|
missing.push("No roadmap baseline found.");
|
|
10805
10976
|
}
|
|
10806
10977
|
const allArtifacts = discoverKnowledge(dir);
|
|
10807
|
-
const
|
|
10808
|
-
|
|
10978
|
+
const allWorkItemArtifacts = allArtifacts.filter((a2) => isDeliveryWorkItem(a2));
|
|
10979
|
+
const workItems = allWorkItemArtifacts.filter(
|
|
10980
|
+
(a2) => isActiveState(lifecycleStateOf({ status: a2.status, filePath: a2.filePath }))
|
|
10981
|
+
);
|
|
10982
|
+
const completedWorkItems = allWorkItemArtifacts.filter(
|
|
10983
|
+
(a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "completed"
|
|
10809
10984
|
);
|
|
10810
|
-
|
|
10985
|
+
const archivedWorkItems = allWorkItemArtifacts.filter(
|
|
10986
|
+
(a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "archived"
|
|
10987
|
+
);
|
|
10988
|
+
if (allWorkItemArtifacts.length === 0 && !moduleRepo) {
|
|
10811
10989
|
missing.push("No work items found.");
|
|
10812
10990
|
}
|
|
10813
10991
|
const state = config.project.state;
|
|
@@ -10922,6 +11100,10 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
10922
11100
|
roadmapSummary,
|
|
10923
11101
|
inventoryAvailable,
|
|
10924
11102
|
workItems: workItems.map(toContextWorkItem),
|
|
11103
|
+
activeWorkItems: workItems.map(toContextWorkItem),
|
|
11104
|
+
completedWorkItems: completedWorkItems.map(toContextWorkItem),
|
|
11105
|
+
archivedWorkItems: archivedWorkItems.map(toContextWorkItem),
|
|
11106
|
+
allWorkItems: allWorkItemArtifacts.map(toContextWorkItem),
|
|
10925
11107
|
artifacts: allArtifacts.filter((a2) => a2.codeGlobs.length > 0).map(toContextArtifact)
|
|
10926
11108
|
},
|
|
10927
11109
|
layers,
|
|
@@ -10938,6 +11120,30 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
10938
11120
|
const compact = (a2) => ({ total: a2.total, installed: a2.total - a2.missing, outdated: a2.outdated, unknown_version: a2.unknown_version, modified: a2.modified });
|
|
10939
11121
|
return { version: s.version, agents: compact(s.agents), skills: compact(s.skills) };
|
|
10940
11122
|
})(),
|
|
11123
|
+
workItemSummary: (() => {
|
|
11124
|
+
const lc = (s) => allWorkItemArtifacts.filter(
|
|
11125
|
+
(a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === s
|
|
11126
|
+
).length;
|
|
11127
|
+
const draft = lc("draft");
|
|
11128
|
+
const ready = lc("ready");
|
|
11129
|
+
const inProgress = lc("in-progress");
|
|
11130
|
+
const blocked = lc("blocked");
|
|
11131
|
+
const completed = lc("completed");
|
|
11132
|
+
const archived = lc("archived");
|
|
11133
|
+
const active = draft + ready + inProgress + blocked;
|
|
11134
|
+
const total = allWorkItemArtifacts.length;
|
|
11135
|
+
let summary = "none";
|
|
11136
|
+
if (total === 0) summary = "none";
|
|
11137
|
+
else if (active === 0 && completed > 0 && archived === 0) summary = "completed-only";
|
|
11138
|
+
else if (active === 0 && archived > 0 && completed === 0) summary = "archived-only";
|
|
11139
|
+
else if (active === 0 && completed + archived > 0) summary = "historical-only";
|
|
11140
|
+
else if (inProgress > 0) summary = "active";
|
|
11141
|
+
else if (blocked > 0 && ready === 0 && inProgress === 0) summary = "blocked";
|
|
11142
|
+
else if (ready > 0) summary = "ready";
|
|
11143
|
+
else if (draft > 0 && ready === 0) summary = "draft-only";
|
|
11144
|
+
else summary = "mixed-active";
|
|
11145
|
+
return { total, active, draft, ready, in_progress: inProgress, blocked, completed, archived, summary };
|
|
11146
|
+
})(),
|
|
10941
11147
|
deliveryMix,
|
|
10942
11148
|
external: loadExternalCapsules(dir),
|
|
10943
11149
|
graph: loadGraphSummary(dir),
|
package/package.json
CHANGED