@kaddo/mcp 3.37.0 → 3.37.1

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 +123 -75
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2218,14 +2218,7 @@ function buildAdapterStatuses(dir) {
2218
2218
  });
2219
2219
  }
2220
2220
 
2221
- // ../cli/src/core/readiness.ts
2222
- var KNOWLEDGE_FILES = [
2223
- { key: "current_state", path: "knowledge/tech/current-state.md", label: "knowledge/tech/current-state.md", agent: "architecture-agent" },
2224
- { key: "codebase", path: "knowledge/tech/codebase.md", label: "knowledge/tech/codebase.md", agent: "codebase-agent" },
2225
- { key: "capabilities", path: "knowledge/product/capabilities.md", label: "knowledge/product/capabilities.md", agent: "capability-agent" },
2226
- { key: "product", path: "knowledge/product/product.md", label: "knowledge/product/product.md", agent: "product-agent" },
2227
- { key: "business", path: "knowledge/business/business.md", label: "knowledge/business/business.md", agent: "business-agent" }
2228
- ];
2221
+ // ../cli/src/core/next-step.ts
2229
2222
  function roadmapSignal(dir) {
2230
2223
  const p = join(dir, "knowledge/delivery/roadmap.md");
2231
2224
  if (!exists(p)) return "missing";
@@ -2256,8 +2249,91 @@ function installedAdapters(dir) {
2256
2249
  (s) => s.state === "injected" || s.state === "legacy-injected" || s.state === "full-generated" && (s.originAdapter === s.id || s.originAdapter === null)
2257
2250
  ).map((s) => s.id);
2258
2251
  }
2252
+ var B = "knowledge/business/business.md";
2253
+ var P = "knowledge/product/product.md";
2254
+ var CAP = "knowledge/product/capabilities.md";
2255
+ var CS = "knowledge/tech/current-state.md";
2256
+ var CB = "knowledge/tech/codebase.md";
2257
+ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
2258
+ const config = loadConfig(dir);
2259
+ if (!config) {
2260
+ return { id: "init", phase: "Setup", label: "Run `kaddo init` to initialize Kaddo.", command: "kaddo init", reason: "Kaddo is not initialized in this project." };
2261
+ }
2262
+ const state = config.project.state;
2263
+ const q = (rel) => analyzeKnowledgeArtifact(dir, rel);
2264
+ const qBusiness = q(B), qProduct = q(P), qCap = q(CAP), qCurrentState = q(CS), qCodebase = q(CB);
2265
+ if (qBusiness === "missing" || qProduct === "missing") {
2266
+ return { id: "bootstrap", phase: "Setup", label: "Run `kaddo bootstrap` to create the project knowledge baseline.", command: "kaddo bootstrap", reason: "The knowledge baseline is incomplete." };
2267
+ }
2268
+ const ctx = buildCodexAdapterContext(dir);
2269
+ if (!ctx.hasAgents) {
2270
+ return { id: "add-agents", phase: "Setup", label: "Run `kaddo add agents` to install the Kaddo agent prompt packs.", command: "kaddo add agents", reason: "No Kaddo agents are installed yet." };
2271
+ }
2272
+ if (!ctx.hasSkills) {
2273
+ return { id: "add-skills", phase: "Setup", label: "Run `kaddo add skills` to install reusable Kaddo skills.", command: "kaddo add skills", reason: "No Kaddo skills are installed yet." };
2274
+ }
2275
+ if ((state === "pre-ai" || state === "legacy") && !exists(join(dir, ".kaddo", "scan.json"))) {
2276
+ return { id: "scan", phase: "Discovery", label: "Run `kaddo scan` to capture deterministic signals from the existing code.", command: "kaddo scan", reason: "No scan baseline exists for this existing project yet." };
2277
+ }
2278
+ if (!exists(join(dir, ".kaddo", "context-pack.md"))) {
2279
+ return { id: "context", phase: "Discovery", label: "Run `kaddo context` to prepare the LLM context pack.", command: "kaddo context", reason: "No context pack has been generated yet." };
2280
+ }
2281
+ if (!exists(join(dir, ".kaddo", "understand.md"))) {
2282
+ return { id: "understand", phase: "Discovery", label: "Run `kaddo understand` to summarize the project context.", command: "kaddo understand", reason: "No understand handoff has been generated yet." };
2283
+ }
2284
+ const refine = (id, agent, target, quality) => ({
2285
+ id,
2286
+ phase: "Knowledge Refinement",
2287
+ label: `Use ${agent} to complete \`${target}\`.`,
2288
+ agent,
2289
+ target,
2290
+ reason: `${target} is ${quality === "missing" ? "missing" : "still a bootstrap placeholder or too thin"}.`,
2291
+ instructions: [
2292
+ "The baseline file exists but does not yet hold real, project-specific knowledge.",
2293
+ `Use the ${agent} to replace the placeholders with real knowledge.`,
2294
+ "Do not write code."
2295
+ ]
2296
+ });
2297
+ if (qBusiness !== "useful") return refine("refine-business", "business-agent", B, qBusiness);
2298
+ if (qProduct !== "useful" || qCap !== "useful") {
2299
+ const target = qCap !== "useful" ? CAP : P;
2300
+ return refine("refine-product", "capability-agent", target, qCap !== "useful" ? qCap : qProduct);
2301
+ }
2302
+ if (qCurrentState !== "useful") return refine("refine-current-state", "architecture-agent", CS, qCurrentState);
2303
+ if (qCodebase !== "useful") {
2304
+ const agent = ctx.agents.includes("codebase-agent") ? "codebase-agent" : "architecture-agent";
2305
+ return refine("refine-codebase", agent, CB, qCodebase);
2306
+ }
2307
+ const oq = buildOpenQuestionsReport(dir, now);
2308
+ if (oq.summary.blocking_open > 0) {
2309
+ return { id: "questions", phase: "Knowledge Refinement", label: "Resolve, assume or defer the blocking open questions (`kaddo questions`).", command: "kaddo questions", reason: `${oq.summary.blocking_open} blocking open question(s) remain.` };
2310
+ }
2311
+ const roadmap = roadmapSignal(dir);
2312
+ if (roadmap !== "has-candidates") {
2313
+ return { id: "roadmap", phase: "Planning", label: "Use roadmap-agent to define roadmap candidates (`kaddo roadmap`).", command: "kaddo roadmap", agent: "roadmap-agent", target: "knowledge/delivery/roadmap.md", reason: "The roadmap has no candidates yet." };
2314
+ }
2315
+ const wi = workItemsSignal(dir);
2316
+ if (wi === "none" || wi === "none-ready") {
2317
+ return { id: "create-work-item", phase: "Delivery Preparation", label: "Run `kaddo create --from roadmap` to materialize the first Work Item.", command: "kaddo create --from roadmap", reason: "The roadmap has candidates but no Work Item is ready." };
2318
+ }
2319
+ const adapters = installedAdapters(dir);
2320
+ if (adapters.length === 0) {
2321
+ return { id: "install-adapter", phase: "Active Delivery", label: "Run `kaddo adapters list` and install the adapter for your preferred agent.", command: "kaddo adapters list", reason: "A Work Item is ready but no adapter is installed." };
2322
+ }
2323
+ return { id: "implement", phase: "Active Delivery", label: "Implement the ready Work Item and run `kaddo guard`.", reason: "A Work Item is ready and an adapter is installed." };
2324
+ }
2325
+
2326
+ // ../cli/src/core/readiness.ts
2327
+ var KNOWLEDGE_FILES = [
2328
+ { key: "current_state", path: "knowledge/tech/current-state.md", label: "knowledge/tech/current-state.md", agent: "architecture-agent" },
2329
+ { key: "codebase", path: "knowledge/tech/codebase.md", label: "knowledge/tech/codebase.md", agent: "codebase-agent" },
2330
+ { key: "capabilities", path: "knowledge/product/capabilities.md", label: "knowledge/product/capabilities.md", agent: "capability-agent" },
2331
+ { key: "product", path: "knowledge/product/product.md", label: "knowledge/product/product.md", agent: "product-agent" },
2332
+ { key: "business", path: "knowledge/business/business.md", label: "knowledge/business/business.md", agent: "business-agent" }
2333
+ ];
2259
2334
  function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
2260
2335
  const config = loadConfig(dir);
2336
+ const rec = resolveNextStep(dir, now);
2261
2337
  const stub = (overall2, label, command) => ({
2262
2338
  project_name: config?.project.name ?? "unknown",
2263
2339
  project_type: config?.project.state ?? "unknown",
@@ -2281,9 +2357,10 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
2281
2357
  resolved_questions: 0,
2282
2358
  deferred_questions: 0
2283
2359
  },
2284
- recommended_next_step: { label, ...command ? { command } : {} }
2360
+ recommended_next_step: { label, ...command ? { command } : {} },
2361
+ nextStepRecommendation: rec
2285
2362
  });
2286
- if (!config) return stub("not-initialized", "Run `kaddo init` to initialize Kaddo.", "kaddo init");
2363
+ if (!config) return stub("not-initialized", rec.label, rec.command);
2287
2364
  if (config.project.state === "new") return stub("not-applicable", "This project uses the standard new-project Kaddo flow.");
2288
2365
  if (config.project.state === "legacy") return stub("legacy-project", "Use the legacy project flow.");
2289
2366
  const scan = exists(join(dir, ".kaddo", "scan.json")) ? "available" : "missing";
@@ -2316,41 +2393,26 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
2316
2393
  resolved_questions: oq.summary.resolution.resolved,
2317
2394
  deferred_questions: oq.summary.resolution.deferred
2318
2395
  };
2319
- let overall;
2320
- let next;
2321
2396
  const firstWeak = KNOWLEDGE_FILES.find((f) => presence[f.key] !== "useful");
2322
- if (scan === "missing") {
2323
- overall = "initialized";
2324
- next = { label: "Run `kaddo scan` to capture deterministic signals from the existing code.", command: "kaddo scan" };
2325
- } else if (bootstrapBaseline === "incomplete") {
2326
- overall = "bootstrap-incomplete";
2327
- next = { label: "Run `kaddo bootstrap` to create the project knowledge baseline.", command: "kaddo bootstrap" };
2328
- } else if (agents === "missing") {
2329
- overall = "agents-missing";
2330
- next = { label: "Run `kaddo add agents` to install the Kaddo agent prompt packs.", command: "kaddo add agents" };
2331
- } else if (skills === "missing") {
2332
- overall = "skills-missing";
2333
- next = { label: "Run `kaddo add skills` to install reusable Kaddo skills.", command: "kaddo add skills" };
2334
- } else if (understand === "missing") {
2335
- overall = "scanned";
2336
- next = { label: "Run `kaddo understand` to summarize the project context.", command: "kaddo understand" };
2337
- } else if (firstWeak) {
2338
- overall = "knowledge-incomplete";
2339
- next = { label: `Use ${firstWeak.agent} to complete \`${firstWeak.label}\` (it is ${presence[firstWeak.key]}).` };
2340
- } else if (oq.summary.blocking_open > 0) {
2341
- overall = "needs-decisions";
2342
- next = { label: "Resolve, assume or defer the blocking open questions (`kaddo questions`).", command: "kaddo questions" };
2343
- } else if (roadmap !== "has-candidates") {
2344
- overall = "ready-for-roadmap";
2345
- next = { label: "Run `kaddo roadmap` to draft the roadmap from the current knowledge.", command: "kaddo roadmap" };
2346
- } else if (work_items === "none" || work_items === "none-ready") {
2347
- overall = "ready-for-work-item";
2348
- next = { label: "Run `kaddo create --from roadmap` to materialize the first Work Item.", command: "kaddo create --from roadmap" };
2349
- } else {
2350
- overall = "ready-for-implementation";
2351
- next = adapters.length > 0 ? { label: "Implement the ready Work Item and run `kaddo guard`." } : { label: "Run `kaddo adapters list` and install the adapter for your preferred agent.", command: "kaddo adapters list" };
2352
- }
2353
- return { project_name: config.project.name, project_type: config.project.state, overall, signals, recommended_next_step: next };
2397
+ let overall;
2398
+ if (scan === "missing") overall = "initialized";
2399
+ else if (bootstrapBaseline === "incomplete") overall = "bootstrap-incomplete";
2400
+ else if (agents === "missing") overall = "agents-missing";
2401
+ else if (skills === "missing") overall = "skills-missing";
2402
+ else if (understand === "missing") overall = "scanned";
2403
+ else if (firstWeak) overall = "knowledge-incomplete";
2404
+ else if (oq.summary.blocking_open > 0) overall = "needs-decisions";
2405
+ else if (roadmap !== "has-candidates") overall = "ready-for-roadmap";
2406
+ else if (work_items === "none" || work_items === "none-ready") overall = "ready-for-work-item";
2407
+ else overall = "ready-for-implementation";
2408
+ return {
2409
+ project_name: config.project.name,
2410
+ project_type: config.project.state,
2411
+ overall,
2412
+ signals,
2413
+ recommended_next_step: { label: rec.label, ...rec.command ? { command: rec.command } : {} },
2414
+ nextStepRecommendation: rec
2415
+ };
2354
2416
  }
2355
2417
 
2356
2418
  // ../cli/src/core/project-explain.ts
@@ -2542,6 +2604,7 @@ function buildProjectExplanation(dir) {
2542
2604
  "Run `kaddo owners suggest` for Work Items without code ownership."
2543
2605
  );
2544
2606
  }
2607
+ const readiness = buildReadinessReport(dir);
2545
2608
  return {
2546
2609
  project,
2547
2610
  stack,
@@ -2562,7 +2625,8 @@ function buildProjectExplanation(dir) {
2562
2625
  mappedModules,
2563
2626
  missingKnowledge,
2564
2627
  suggestedNextSteps,
2565
- readiness: buildReadinessReport(dir)
2628
+ readiness,
2629
+ nextStepRecommendation: readiness.nextStepRecommendation
2566
2630
  };
2567
2631
  }
2568
2632
  function stateLabel(state) {
@@ -2743,7 +2807,7 @@ function renderExplanationHuman(exp) {
2743
2807
  lines.push("- Reason:");
2744
2808
  for (const r2 of assessment.reasons) lines.push(` - ${r2}`);
2745
2809
  }
2746
- if (assessment.nextStep) lines.push(`- Next step: ${assessment.nextStep}`);
2810
+ lines.push(`- Next step: ${exp.readiness.recommended_next_step.label}`);
2747
2811
  lines.push("");
2748
2812
  if (exp.suggestedNextSteps.length > 0) {
2749
2813
  lines.push("## Suggested Next Steps");
@@ -2765,7 +2829,6 @@ function renderExplanationHuman(exp) {
2765
2829
  lines.push(`- capabilities: ${s.capabilities}`);
2766
2830
  lines.push(`- current-state: ${s.current_state}`);
2767
2831
  lines.push(`- codebase: ${s.codebase}`);
2768
- lines.push(`- capabilities: ${s.capabilities}`);
2769
2832
  lines.push(`- roadmap: ${s.roadmap}`);
2770
2833
  lines.push(`- work-items: ${s.work_items}`);
2771
2834
  lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
@@ -4120,28 +4183,6 @@ function recommendedAgentsForState(state) {
4120
4183
  return ["capability-agent", "architecture-agent", "roadmap-agent"];
4121
4184
  }
4122
4185
  }
4123
- function nextStepsForState(state) {
4124
- switch (state) {
4125
- case "new":
4126
- return [
4127
- "Use roadmap-agent to shape an initial roadmap.",
4128
- "Use architecture-agent to outline the intended architecture."
4129
- ];
4130
- case "legacy":
4131
- return [
4132
- "Use legacy-agent to surface risks and unknowns before changing code.",
4133
- "Use architecture-agent to reconstruct the current architecture.",
4134
- "Use capability-agent to map existing capabilities."
4135
- ];
4136
- case "pre-ai":
4137
- default:
4138
- return [
4139
- "Use capability-agent to extract system capabilities.",
4140
- "Use architecture-agent to reconstruct the current architecture.",
4141
- "Use roadmap-agent to propose roadmap candidates."
4142
- ];
4143
- }
4144
- }
4145
4186
  var LLM_INSTRUCTIONS = [
4146
4187
  "Use this context pack as the project baseline.",
4147
4188
  "Do not write code yet.",
@@ -4253,6 +4294,12 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
4253
4294
  workItemsMissingOwnership: allWorkItems.length - wiWithOwnership
4254
4295
  }
4255
4296
  });
4297
+ const nextStepRecommendation = resolveNextStep(dir, now);
4298
+ const unifiedPhase = {
4299
+ ...phase,
4300
+ nextStep: nextStepRecommendation.label,
4301
+ recommendedAgents: nextStepRecommendation.agent ? [nextStepRecommendation.agent] : phase.recommendedAgents
4302
+ };
4256
4303
  return {
4257
4304
  version: CONTEXT_PACK_VERSION,
4258
4305
  generatedAt: now.toISOString(),
@@ -4283,7 +4330,8 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
4283
4330
  layers,
4284
4331
  knowledgeQuality,
4285
4332
  roadmap,
4286
- phase,
4333
+ phase: unifiedPhase,
4334
+ nextStepRecommendation,
4287
4335
  deliveryMix,
4288
4336
  external: loadExternalCapsules(dir),
4289
4337
  graph: loadGraphSummary(dir),
@@ -4291,12 +4339,12 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
4291
4339
  skills: discoverInstalledSkills(dir).map((s) => s.id),
4292
4340
  mappedModules,
4293
4341
  missing,
4294
- // VS-052: the handoff is driven by the REAL phase, not project.state, so the pack never
4295
- // contradicts the Current Phase block above it.
4342
+ // VS-052/VS-073.2: the handoff is driven by the unified next step, so the pack never contradicts
4343
+ // the Current Phase block above it.
4296
4344
  handoff: {
4297
- recommendedAgents: phase.recommendedAgents.length > 0 ? phase.recommendedAgents : recommendedAgentsForState(state),
4298
- nextSteps: phase.nextStep ? [phase.nextStep] : nextStepsForState(state),
4299
- instructions: phase.llmInstructions.length > 0 ? phase.llmInstructions : LLM_INSTRUCTIONS,
4345
+ recommendedAgents: unifiedPhase.recommendedAgents.length > 0 ? unifiedPhase.recommendedAgents : recommendedAgentsForState(state),
4346
+ nextSteps: [nextStepRecommendation.label],
4347
+ instructions: unifiedPhase.llmInstructions.length > 0 ? unifiedPhase.llmInstructions : LLM_INSTRUCTIONS,
4300
4348
  operatingRules: OPERATING_RULES
4301
4349
  }
4302
4350
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/mcp",
3
- "version": "3.37.0",
3
+ "version": "3.37.1",
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": {