@kaddo/mcp 3.66.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.
Files changed (2) hide show
  1. package/dist/index.js +102 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3963,6 +3963,8 @@ function workItemsSignal(dir) {
3963
3963
  if (wis.length === 0) return "none";
3964
3964
  if (wis.some((w3) => w3.lifecycle === "in-progress")) return "in-progress";
3965
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";
3966
3968
  return "none-ready";
3967
3969
  }
3968
3970
  function installedAdapters(dir) {
@@ -4391,6 +4393,8 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
4391
4393
  else if (understand === "missing") overall = "scanned";
4392
4394
  else if (firstWeak) overall = "knowledge-incomplete";
4393
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);
4394
4398
  else if (roadmap !== "has-candidates") overall = "ready-for-roadmap";
4395
4399
  else if (work_items === "none" || work_items === "none-ready") overall = "ready-for-work-item";
4396
4400
  else overall = "ready-for-implementation";
@@ -4403,6 +4407,16 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
4403
4407
  nextStepRecommendation: rec
4404
4408
  };
4405
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
+ }
4406
4420
 
4407
4421
  // ../cli/src/core/assets.ts
4408
4422
  import matter6 from "gray-matter";
@@ -7627,7 +7641,7 @@ var refineWorkItem = {
7627
7641
  id: "refine-work-item",
7628
7642
  label: "Refine Work Item",
7629
7643
  evaluate: (ctx) => {
7630
- 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" };
7631
7645
  if (ctx.draftWorkItems > 0) {
7632
7646
  return {
7633
7647
  status: "current",
@@ -7878,7 +7892,9 @@ function buildRouteContext(dir) {
7878
7892
  draftWorkItems: byState("draft"),
7879
7893
  readyWorkItems: byState("ready"),
7880
7894
  inProgressWorkItems: byState("in-progress"),
7895
+ blockedWorkItems: byState("blocked"),
7881
7896
  completedWorkItems: byState("completed"),
7897
+ archivedWorkItems: byState("archived"),
7882
7898
  ownershipCoverage: `${withOwnership}/${total}`,
7883
7899
  ownershipComplete: total > 0 && withOwnership >= total,
7884
7900
  decisionCandidates: td.candidates,
@@ -8368,6 +8384,20 @@ function buildProjectExplanation(dir) {
8368
8384
  scanSignals: loadScanSignals(dir),
8369
8385
  metadataHealth: analyzeMetadataHealth(dir),
8370
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
+ })(),
8371
8401
  implementationEvidence: workItemArtifacts.filter((a2) => a2.affectedModules.length > 0).map((a2) => {
8372
8402
  const fm = a2.rawFrontmatter;
8373
8403
  const evidence = fm.implementation_evidence;
@@ -8379,11 +8409,13 @@ function buildProjectExplanation(dir) {
8379
8409
  status: String(data.status ?? "unknown")
8380
8410
  };
8381
8411
  }
8412
+ const lc = lifecycleStateOf({ status: a2.status, filePath: a2.filePath });
8413
+ const historicalDefault = lc === "completed" || lc === "archived" ? "not-assessed" : "not-started";
8382
8414
  return {
8383
8415
  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",
8416
+ lifecycle: lc,
8417
+ implementationStatus: a2.implementationStatus || historicalDefault,
8418
+ validationStatus: a2.validationStatus || historicalDefault,
8387
8419
  releaseStatus: a2.releaseStatus || "not-assessed",
8388
8420
  affectedModules: a2.affectedModules,
8389
8421
  releaseGates: Array.isArray(fm.release_gates) ? fm.release_gates : [],
@@ -8628,6 +8660,17 @@ function renderExplanationHuman(exp) {
8628
8660
  }
8629
8661
  lines.push(`- Next step: ${exp.readiness.recommended_next_step.label}`);
8630
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
+ }
8631
8674
  const rec = exp.nextStepRecommendation;
8632
8675
  const secondary = rec.secondary ?? [];
8633
8676
  const steps = secondary.length > 0 || /Delivery|Active|Maintenance/.test(rec.phase) ? [rec.label, ...secondary.map((s2) => s2.label)] : exp.suggestedNextSteps;
@@ -8662,6 +8705,10 @@ function renderExplanationHuman(exp) {
8662
8705
  if (!exp.isModuleRepo) {
8663
8706
  lines.push(`- roadmap: ${s.roadmap}`);
8664
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
+ }
8665
8712
  lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
8666
8713
  } else {
8667
8714
  lines.push("- roadmap: managed-by-core");
@@ -10173,6 +10220,13 @@ function projectStatus(root) {
10173
10220
  agents: "managed-by-core",
10174
10221
  skills: "managed-by-core"
10175
10222
  };
10223
+ } else {
10224
+ result.readiness = {
10225
+ overall: explain.readiness?.overall ?? "unknown"
10226
+ };
10227
+ }
10228
+ if (explain.deliverySummary) {
10229
+ result.deliverySummary = explain.deliverySummary;
10176
10230
  }
10177
10231
  return ok(result);
10178
10232
  }
@@ -10876,19 +10930,21 @@ var OPERATING_RULES = [
10876
10930
  "Kaddo itself never calls an LLM and never runs git \u2014 every git action is the human\u2019s."
10877
10931
  ];
10878
10932
  function toContextWorkItem(a2) {
10933
+ const lifecycle = lifecycleStateOf({ status: a2.status, filePath: a2.filePath });
10934
+ const isHistorical = lifecycle === "completed" || lifecycle === "archived";
10879
10935
  const wi = {
10880
10936
  id: a2.id,
10881
10937
  type: a2.type,
10882
10938
  title: a2.title,
10883
10939
  status: a2.status,
10884
- lifecycle: lifecycleStateOf({ status: a2.status, filePath: a2.filePath }),
10940
+ lifecycle,
10885
10941
  knowledgeLevel: a2.knowledgeLevel,
10886
10942
  domains: a2.domains,
10887
10943
  source: parseWorkItemSource(a2.rawFrontmatter)
10888
10944
  };
10889
- if (a2.implementationStatus) wi.implementationStatus = a2.implementationStatus;
10890
- if (a2.validationStatus) wi.validationStatus = a2.validationStatus;
10891
- if (a2.releaseStatus) wi.releaseStatus = a2.releaseStatus;
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);
10892
10948
  if (a2.affectedModules.length > 0) wi.affectedModules = a2.affectedModules;
10893
10949
  return wi;
10894
10950
  }
@@ -10919,10 +10975,17 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
10919
10975
  missing.push("No roadmap baseline found.");
10920
10976
  }
10921
10977
  const allArtifacts = discoverKnowledge(dir);
10922
- const workItems = allArtifacts.filter(
10923
- (a2) => isDeliveryWorkItem(a2) && isActiveState(lifecycleStateOf({ status: a2.status, filePath: a2.filePath }))
10978
+ const allWorkItemArtifacts = allArtifacts.filter((a2) => isDeliveryWorkItem(a2));
10979
+ const workItems = allWorkItemArtifacts.filter(
10980
+ (a2) => isActiveState(lifecycleStateOf({ status: a2.status, filePath: a2.filePath }))
10924
10981
  );
10925
- if (workItems.length === 0 && !moduleRepo) {
10982
+ const completedWorkItems = allWorkItemArtifacts.filter(
10983
+ (a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "completed"
10984
+ );
10985
+ const archivedWorkItems = allWorkItemArtifacts.filter(
10986
+ (a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "archived"
10987
+ );
10988
+ if (allWorkItemArtifacts.length === 0 && !moduleRepo) {
10926
10989
  missing.push("No work items found.");
10927
10990
  }
10928
10991
  const state = config.project.state;
@@ -11037,6 +11100,10 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
11037
11100
  roadmapSummary,
11038
11101
  inventoryAvailable,
11039
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),
11040
11107
  artifacts: allArtifacts.filter((a2) => a2.codeGlobs.length > 0).map(toContextArtifact)
11041
11108
  },
11042
11109
  layers,
@@ -11053,6 +11120,30 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
11053
11120
  const compact = (a2) => ({ total: a2.total, installed: a2.total - a2.missing, outdated: a2.outdated, unknown_version: a2.unknown_version, modified: a2.modified });
11054
11121
  return { version: s.version, agents: compact(s.agents), skills: compact(s.skills) };
11055
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
+ })(),
11056
11147
  deliveryMix,
11057
11148
  external: loadExternalCapsules(dir),
11058
11149
  graph: loadGraphSummary(dir),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/mcp",
3
- "version": "3.66.0",
3
+ "version": "3.67.0",
4
4
  "description": "MCP server for Kaddo project knowledge: read-only resources/tools/prompts plus safe derived generation under .kaddo/.",
5
5
  "license": "MIT",
6
6
  "repository": {