@kaddo/mcp 3.63.0 → 3.65.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 +300 -73
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -693,6 +693,34 @@ function firstUnrefinedLayerAgent(layers) {
693
693
  return { agent: "architecture-agent", step: "Use architecture-agent to complete knowledge/tech/current-state.md" };
694
694
  }
695
695
  function assessPhase(input) {
696
+ if (input.isModuleRepo) {
697
+ const techStatus = layer(input.layers, "Tech");
698
+ const techReady = !NOT_READY_LAYER.includes(techStatus);
699
+ if (techReady) {
700
+ return {
701
+ phase: "Ready for Core Orchestration",
702
+ reasons: ["Module repo \u2014 Tech layer ready", "Business/Product managed by core"],
703
+ recommendedAgents: [],
704
+ nextStep: "Module knowledge is ready for core orchestration.",
705
+ llmInstructions: [
706
+ "This is a module repo. Business, Product, and Delivery are managed by the core repo.",
707
+ "Do not create business, product, roadmap or Work Items here."
708
+ ]
709
+ };
710
+ }
711
+ return {
712
+ phase: "Knowledge Refinement",
713
+ reasons: ["Module repo \u2014 Tech layer incomplete", "Business/Product managed by core"],
714
+ recommendedAgents: ["module-context-agent"],
715
+ nextStep: "Use module-context-agent to refine knowledge/tech/module/module-context.md",
716
+ llmInstructions: [
717
+ "Use the module-context-agent to refine the module context.",
718
+ "Do not create business, product, roadmap or Work Items in this module.",
719
+ "Do not install agents or skills.",
720
+ "Do not write application code."
721
+ ]
722
+ };
723
+ }
696
724
  const phase = determinePhase(input);
697
725
  const reasons = buildReasons(input);
698
726
  const bs = input.workItems.byState;
@@ -3009,6 +3037,21 @@ function layerQuality(dir, layer2) {
3009
3037
  return worst;
3010
3038
  }
3011
3039
  function knowledgeLayers(dir) {
3040
+ const config = loadConfig(dir);
3041
+ if (config && isModule(config)) {
3042
+ return [
3043
+ { layer: "Business", status: "Not applicable", detected: [] },
3044
+ { layer: "Product", status: "Not applicable", detected: [] },
3045
+ ...discoverLayers(dir).filter((l2) => l2.layer === "Tech").map((l2) => {
3046
+ if (l2.status !== "Consolidated" && l2.status !== "Structured") return l2;
3047
+ const q3 = layerQuality(dir, l2.layer);
3048
+ if (q3 === "placeholder") return { ...l2, status: "Placeholder" };
3049
+ if (q3 === "weak") return { ...l2, status: "Weak" };
3050
+ return l2;
3051
+ }),
3052
+ { layer: "Delivery", status: "Managed by core", detected: [] }
3053
+ ];
3054
+ }
3012
3055
  return discoverLayers(dir).map((l2) => {
3013
3056
  if (l2.status !== "Consolidated" && l2.status !== "Structured") return l2;
3014
3057
  const q3 = layerQuality(dir, l2.layer);
@@ -3918,6 +3961,13 @@ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
3918
3961
  }
3919
3962
  const state = config.project.state;
3920
3963
  const q3 = (rel) => analyzeKnowledgeArtifact(dir, rel);
3964
+ const resolveAgent = (agent) => {
3965
+ const file = agent.endsWith(".md") ? agent : `${agent}.md`;
3966
+ const path4 = agentInstallPath(file);
3967
+ const installed = isFile(join(dir, path4));
3968
+ const group = agentGroupOf(file);
3969
+ return { agentPath: path4, agentInstalled: installed, installCommand: installed ? void 0 : `kaddo add agents --group ${group}` };
3970
+ };
3921
3971
  const moduleRepo = isModule(config);
3922
3972
  const coreRepo = isCore(config);
3923
3973
  const MC = exists(join(dir, "knowledge/tech/module/module-context.md")) ? "knowledge/tech/module/module-context.md" : "knowledge/module/module-context.md";
@@ -3933,15 +3983,26 @@ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
3933
3983
  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." };
3934
3984
  }
3935
3985
  if (qMC !== "useful") {
3986
+ const ar = resolveAgent("module-context-agent");
3936
3987
  return {
3937
3988
  id: "refine-module-context",
3938
3989
  phase: "Knowledge Refinement",
3939
- label: "Use module-context-agent to refine `knowledge/module/module-context.md`.",
3990
+ label: "Use module-context-agent to refine `knowledge/tech/module/module-context.md`.",
3940
3991
  agent: "module-context-agent",
3941
3992
  skill: "module-context-refinement",
3942
3993
  target: MC,
3994
+ agentPath: ar.agentPath,
3995
+ agentInstalled: ar.agentInstalled,
3996
+ installCommand: ar.installCommand,
3943
3997
  reason: "Module context is still a placeholder.",
3944
- instructions: ["Refine the module context with real knowledge about this module.", "Do not create business.md or product.md.", "Do not write code."]
3998
+ instructions: [
3999
+ "Refine the module context using evidence from this repository.",
4000
+ "Use the parent system context when available.",
4001
+ "Do not create business, product, roadmap or Work Items in this module.",
4002
+ "Do not install agents or skills in this module.",
4003
+ "Do not write application code.",
4004
+ "Preserve frontmatter and record unknowns as open questions."
4005
+ ]
3945
4006
  };
3946
4007
  }
3947
4008
  const qCurrentState2 = q3(CS), qCodebase2 = q3(CB);
@@ -3970,7 +4031,7 @@ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
3970
4031
  if (!exists(join(dir, ".kaddo", "understand.md"))) {
3971
4032
  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." };
3972
4033
  }
3973
- return { id: "module-ready", phase: "Active Delivery", label: "Module context is complete. Create and manage Work Items from the core repository.", reason: "This module's knowledge is ready. Work Items are created and tracked in the core." };
4034
+ return { id: "module-ready", phase: "Ready for Core Orchestration", label: "Module knowledge is complete. Create and manage Work Items from the core repository.", reason: "This module's knowledge is ready for core orchestration. Work Items are created and tracked in the core." };
3974
4035
  }
3975
4036
  const qBusiness = q3(B2), qProduct = q3(P2), qCap = q3(CAP), qCurrentState = q3(CS), qCodebase = q3(CB);
3976
4037
  if (!coreRepo && (qBusiness === "missing" || qProduct === "missing")) {
@@ -3996,13 +4057,6 @@ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
3996
4057
  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." };
3997
4058
  }
3998
4059
  const discovery = state === "pre-ai" || state === "legacy";
3999
- const resolveAgent = (agent) => {
4000
- const file = agent.endsWith(".md") ? agent : `${agent}.md`;
4001
- const path4 = agentInstallPath(file);
4002
- const installed = isFile(join(dir, path4));
4003
- const group = agentGroupOf(file);
4004
- return { agentPath: path4, agentInstalled: installed, installCommand: installed ? void 0 : `kaddo add agents --group ${group}` };
4005
- };
4006
4060
  const refine = (id, agent, target, quality, verb = "complete") => {
4007
4061
  const ar = resolveAgent(agent);
4008
4062
  return {
@@ -4236,6 +4290,47 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
4236
4290
  if (!config) return stub("not-initialized", rec.label, rec.command);
4237
4291
  if (config.project.state === "new") return stub("not-applicable", "This project uses the standard new-project Kaddo flow.");
4238
4292
  if (config.project.state === "legacy") return stub("legacy-project", "Use the legacy project flow.");
4293
+ if (isModule(config)) {
4294
+ const scan2 = exists(join(dir, ".kaddo", "scan.json")) ? "available" : "missing";
4295
+ const understand2 = exists(join(dir, ".kaddo", "understand.md")) ? "available" : "missing";
4296
+ const mcNew = "knowledge/tech/module/module-context.md";
4297
+ const mcLegacy = "knowledge/module/module-context.md";
4298
+ const mcPath = exists(join(dir, mcNew)) ? mcNew : mcLegacy;
4299
+ const qMC = analyzeKnowledgeArtifact(dir, mcPath);
4300
+ const qCS = analyzeKnowledgeArtifact(dir, "knowledge/tech/current-state.md");
4301
+ const qCB = analyzeKnowledgeArtifact(dir, "knowledge/tech/codebase.md");
4302
+ const moduleBaseline = qMC !== "missing" && qCS !== "missing" && qCB !== "missing" ? "complete" : "incomplete";
4303
+ const moduleReady = qMC === "useful" && qCS === "useful" && qCB === "useful";
4304
+ const overall2 = moduleReady ? "ready-for-core-orchestration" : moduleBaseline === "incomplete" ? "bootstrap-incomplete" : "knowledge-incomplete";
4305
+ return {
4306
+ project_name: config.project.name,
4307
+ project_type: config.project.state,
4308
+ project_role: "module",
4309
+ overall: overall2,
4310
+ signals: {
4311
+ scan: scan2,
4312
+ understand: understand2,
4313
+ bootstrap_baseline: moduleBaseline,
4314
+ agents: "managed-by-core",
4315
+ skills: "managed-by-core",
4316
+ current_state: qCS,
4317
+ codebase: qCB,
4318
+ module_context: qMC,
4319
+ capabilities: "managed-by-core",
4320
+ product: "not-applicable",
4321
+ business: "not-applicable",
4322
+ roadmap: "managed-by-core",
4323
+ work_items: "managed-by-core",
4324
+ adapters: [],
4325
+ blocking_open_questions: 0,
4326
+ assumed_questions: 0,
4327
+ resolved_questions: 0,
4328
+ deferred_questions: 0
4329
+ },
4330
+ recommended_next_step: { label: rec.label, ...rec.command ? { command: rec.command } : {} },
4331
+ nextStepRecommendation: rec
4332
+ };
4333
+ }
4239
4334
  const scan = exists(join(dir, ".kaddo", "scan.json")) ? "available" : "missing";
4240
4335
  const understand = exists(join(dir, ".kaddo", "understand.md")) ? "available" : "missing";
4241
4336
  const presence = Object.fromEntries(KNOWLEDGE_FILES.map((f3) => [f3.key, analyzeKnowledgeArtifact(dir, f3.path)]));
@@ -7602,6 +7697,67 @@ var identifyRisks = {
7602
7697
  return { status: hasLegacy ? "done" : "pending", agent: hasLegacy ? void 0 : "legacy-agent" };
7603
7698
  }
7604
7699
  };
7700
+ var refineModuleContext = {
7701
+ id: "refine-module-context",
7702
+ label: "Refine module context",
7703
+ evaluate: (ctx) => {
7704
+ const newPath = join(ctx.dir, "knowledge/tech/module/module-context.md");
7705
+ const legacyPath = join(ctx.dir, "knowledge/module/module-context.md");
7706
+ const mcPath = exists(newPath) ? "knowledge/tech/module/module-context.md" : exists(legacyPath) ? "knowledge/module/module-context.md" : null;
7707
+ if (!mcPath) return { status: "pending", agent: "module-context-agent", skill: "module-context-refinement" };
7708
+ const q3 = analyzeKnowledgeArtifact(ctx.dir, mcPath);
7709
+ if (q3 === "useful") return { status: "done", evidence: [mcPath] };
7710
+ return { status: "current", agent: "module-context-agent", skill: "module-context-refinement", evidence: [mcPath], reason: "Module context is still a placeholder." };
7711
+ }
7712
+ };
7713
+ var describeModuleCurrentState = {
7714
+ id: "describe-current-state",
7715
+ label: "Describe current state",
7716
+ evaluate: (ctx) => ({
7717
+ status: isUseful(ctx.qCurrentState) ? "done" : "pending",
7718
+ evidence: isUseful(ctx.qCurrentState) ? ["knowledge/tech/current-state.md"] : void 0,
7719
+ agent: isUseful(ctx.qCurrentState) ? void 0 : "architecture-agent"
7720
+ })
7721
+ };
7722
+ var mapModuleCodebase = {
7723
+ id: "map-codebase",
7724
+ label: "Map codebase",
7725
+ evaluate: (ctx) => ({
7726
+ status: isUseful(ctx.qCodebase) ? "done" : "pending",
7727
+ evidence: isUseful(ctx.qCodebase) ? ["knowledge/tech/codebase.md"] : void 0,
7728
+ agent: isUseful(ctx.qCodebase) ? void 0 : "architecture-agent"
7729
+ })
7730
+ };
7731
+ var validateModuleKnowledge = {
7732
+ id: "validate-module-knowledge",
7733
+ label: "Validate module knowledge",
7734
+ evaluate: (ctx) => {
7735
+ const hasUnderstand = exists(join(ctx.dir, ".kaddo/understand.md"));
7736
+ if (hasUnderstand) return { status: "done", evidence: [".kaddo/understand.md"] };
7737
+ return { status: "pending", command: "kaddo understand" };
7738
+ }
7739
+ };
7740
+ var readyForCoreOrchestration = {
7741
+ id: "ready-for-core-orchestration",
7742
+ label: "Ready for core orchestration",
7743
+ evaluate: (ctx) => {
7744
+ const newPath = join(ctx.dir, "knowledge/tech/module/module-context.md");
7745
+ const legacyPath = join(ctx.dir, "knowledge/module/module-context.md");
7746
+ const mcPath = exists(newPath) ? "knowledge/tech/module/module-context.md" : exists(legacyPath) ? "knowledge/module/module-context.md" : null;
7747
+ const mcUseful = mcPath ? analyzeKnowledgeArtifact(ctx.dir, mcPath) === "useful" : false;
7748
+ const allDone = mcUseful && isUseful(ctx.qCurrentState) && isUseful(ctx.qCodebase);
7749
+ return { status: allDone ? "done" : "pending", reason: allDone ? void 0 : "Module knowledge is not yet complete." };
7750
+ }
7751
+ };
7752
+ var MODULE_STEPS = [
7753
+ enableKaddo,
7754
+ scanRepository,
7755
+ refineModuleContext,
7756
+ describeModuleCurrentState,
7757
+ mapModuleCodebase,
7758
+ validateModuleKnowledge,
7759
+ readyForCoreOrchestration
7760
+ ];
7605
7761
  var NEW_STEPS = [
7606
7762
  enableKaddo,
7607
7763
  defineBusiness,
@@ -7742,10 +7898,10 @@ function mapNextStepId(id) {
7742
7898
  "review-work-item": "refine-work-item",
7743
7899
  "prepare-implementation": "prepare-implementation",
7744
7900
  "implement-work-item": "prepare-implementation",
7745
- "refine-module-context": "refine-work-item",
7901
+ "refine-module-context": "refine-module-context",
7746
7902
  "init-module-context": "enable-kaddo",
7747
- "module-ready": "prepare-implementation",
7748
- "validate-work-item-modules": "prepare-implementation",
7903
+ "module-ready": "ready-for-core-orchestration",
7904
+ "validate-work-item-modules": "validate-module-knowledge",
7749
7905
  "modules-discover": "enable-kaddo"
7750
7906
  };
7751
7907
  return MAP[id] ?? id;
@@ -7753,7 +7909,7 @@ function mapNextStepId(id) {
7753
7909
  function buildProjectRoute(dir) {
7754
7910
  const config = loadConfig(dir);
7755
7911
  const state = config?.project.state ?? "pre-ai";
7756
- const defs = stepsForState(state);
7912
+ const defs = config && isModule(config) ? MODULE_STEPS : stepsForState(state);
7757
7913
  const ctx = buildRouteContext(dir);
7758
7914
  const steps = defs.map((d3) => {
7759
7915
  const result = d3.evaluate(ctx);
@@ -8054,51 +8210,73 @@ function buildProjectExplanation(dir) {
8054
8210
  const roadmapMd = exists(roadmapPath) ? readFile(roadmapPath) : null;
8055
8211
  const roadmap = roadmapStats(roadmapMd, items.length);
8056
8212
  const mappedModules = loadMappedModules(dir);
8213
+ const moduleRepo = config != null && isModule(config);
8057
8214
  const missingKnowledge = [];
8058
- if (!knowledge.hasScan) missingKnowledge.push("Scan baseline (.kaddo/scan.json)");
8059
- if (!knowledge.hasContextPack) missingKnowledge.push("Context pack (.kaddo/context-pack.md)");
8060
- if (!knowledge.hasInventory) missingKnowledge.push("Inventory (knowledge/inventory.md)");
8061
- if (!knowledge.hasCapabilities) missingKnowledge.push("Product knowledge (knowledge/product/)");
8062
- if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
8063
- if (!knowledge.hasRoadmap) missingKnowledge.push("Roadmap (knowledge/delivery/roadmap.md)");
8064
- if (!knowledge.hasAgents) missingKnowledge.push("Agents (knowledge/agents/)");
8065
- if (items.length === 0) missingKnowledge.push("Work items (knowledge/delivery/work-items/)");
8066
- const suggestedNextSteps = [];
8067
- const baselineIncomplete = !knowledge.hasBusiness || !knowledge.hasProduct;
8068
- if (baselineIncomplete) {
8069
- suggestedNextSteps.push("Run `kaddo bootstrap` to create the project knowledge baseline.");
8070
- if (!knowledge.hasAgents) suggestedNextSteps.push("Then run `kaddo add agents`.");
8071
- if (!knowledge.hasSkills) suggestedNextSteps.push("Then run `kaddo add skills`.");
8072
- suggestedNextSteps.push("Then run `kaddo context`.");
8073
- suggestedNextSteps.push("Then run `kaddo understand`.");
8215
+ if (moduleRepo) {
8216
+ if (!knowledge.hasScan) missingKnowledge.push("Scan baseline (.kaddo/scan.json)");
8217
+ if (!knowledge.hasContextPack) missingKnowledge.push("Context pack (.kaddo/context-pack.md)");
8218
+ if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
8074
8219
  } else {
8220
+ if (!knowledge.hasScan) missingKnowledge.push("Scan baseline (.kaddo/scan.json)");
8221
+ if (!knowledge.hasContextPack) missingKnowledge.push("Context pack (.kaddo/context-pack.md)");
8222
+ if (!knowledge.hasInventory) missingKnowledge.push("Inventory (knowledge/inventory.md)");
8223
+ if (!knowledge.hasCapabilities) missingKnowledge.push("Product knowledge (knowledge/product/)");
8224
+ if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
8225
+ if (!knowledge.hasRoadmap) missingKnowledge.push("Roadmap (knowledge/delivery/roadmap.md)");
8226
+ if (!knowledge.hasAgents) missingKnowledge.push("Agents (knowledge/agents/)");
8227
+ if (items.length === 0) missingKnowledge.push("Work items (knowledge/delivery/work-items/)");
8228
+ }
8229
+ const suggestedNextSteps = [];
8230
+ if (moduleRepo) {
8075
8231
  if (!knowledge.hasScan) {
8076
8232
  suggestedNextSteps.push("Run `kaddo scan` to detect the technical stack.");
8077
8233
  } else if (!knowledge.hasContextPack) {
8078
8234
  suggestedNextSteps.push("Run `kaddo context` to prepare an LLM context pack.");
8235
+ } else if (!knowledge.hasArchitecture) {
8236
+ suggestedNextSteps.push("Use module-context-agent to refine knowledge/tech/module/module-context.md.");
8237
+ } else {
8238
+ suggestedNextSteps.push("Return to the core repository.");
8239
+ suggestedNextSteps.push("Create or continue the Work Item from the core.");
8240
+ suggestedNextSteps.push("Add this module to `affected_modules` when the change touches it.");
8241
+ suggestedNextSteps.push("Re-run `kaddo context` and `kaddo understand` from the core.");
8079
8242
  }
8080
- if (!knowledge.hasAgents) {
8081
- suggestedNextSteps.push("Run `kaddo add agents` to install knowledge agents.");
8082
- }
8083
- if (!knowledge.hasCapabilities) {
8084
- suggestedNextSteps.push("Use capability-agent to generate knowledge/product/capabilities.md.");
8085
- }
8086
- if (!knowledge.hasArchitecture) {
8087
- suggestedNextSteps.push("Use architecture-agent to generate knowledge/tech/current-state.md.");
8088
- }
8089
- if (!knowledge.hasRoadmap) {
8090
- suggestedNextSteps.push("Use roadmap-agent to generate knowledge/delivery/roadmap.md.");
8091
- } else if (roadmap.remaining > 0) {
8092
- suggestedNextSteps.push(
8093
- `Materialize ${roadmap.remaining} roadmap candidate(s) with \`kaddo create --from roadmap\`.`
8094
- );
8095
- }
8096
- if (items.length === 0 && !roadmap.present) {
8097
- suggestedNextSteps.push("Create your first Work Item with `kaddo create`.");
8098
- } else if (ownership.workItemsMissingOwnership > 0) {
8099
- suggestedNextSteps.push(
8100
- "Run `kaddo owners suggest` for Work Items without code ownership."
8101
- );
8243
+ } else {
8244
+ const baselineIncomplete = !knowledge.hasBusiness || !knowledge.hasProduct;
8245
+ if (baselineIncomplete) {
8246
+ suggestedNextSteps.push("Run `kaddo bootstrap` to create the project knowledge baseline.");
8247
+ if (!knowledge.hasAgents) suggestedNextSteps.push("Then run `kaddo add agents`.");
8248
+ if (!knowledge.hasSkills) suggestedNextSteps.push("Then run `kaddo add skills`.");
8249
+ suggestedNextSteps.push("Then run `kaddo context`.");
8250
+ suggestedNextSteps.push("Then run `kaddo understand`.");
8251
+ } else {
8252
+ if (!knowledge.hasScan) {
8253
+ suggestedNextSteps.push("Run `kaddo scan` to detect the technical stack.");
8254
+ } else if (!knowledge.hasContextPack) {
8255
+ suggestedNextSteps.push("Run `kaddo context` to prepare an LLM context pack.");
8256
+ }
8257
+ if (!knowledge.hasAgents) {
8258
+ suggestedNextSteps.push("Run `kaddo add agents` to install knowledge agents.");
8259
+ }
8260
+ if (!knowledge.hasCapabilities) {
8261
+ suggestedNextSteps.push("Use capability-agent to generate knowledge/product/capabilities.md.");
8262
+ }
8263
+ if (!knowledge.hasArchitecture) {
8264
+ suggestedNextSteps.push("Use architecture-agent to generate knowledge/tech/current-state.md.");
8265
+ }
8266
+ if (!knowledge.hasRoadmap) {
8267
+ suggestedNextSteps.push("Use roadmap-agent to generate knowledge/delivery/roadmap.md.");
8268
+ } else if (roadmap.remaining > 0) {
8269
+ suggestedNextSteps.push(
8270
+ `Materialize ${roadmap.remaining} roadmap candidate(s) with \`kaddo create --from roadmap\`.`
8271
+ );
8272
+ }
8273
+ if (items.length === 0 && !roadmap.present) {
8274
+ suggestedNextSteps.push("Create your first Work Item with `kaddo create`.");
8275
+ } else if (ownership.workItemsMissingOwnership > 0) {
8276
+ suggestedNextSteps.push(
8277
+ "Run `kaddo owners suggest` for Work Items without code ownership."
8278
+ );
8279
+ }
8102
8280
  }
8103
8281
  }
8104
8282
  const readiness = buildReadinessReport(dir);
@@ -8140,7 +8318,8 @@ function buildProjectExplanation(dir) {
8140
8318
  roadmapQuality: buildRoadmapQuality(dir),
8141
8319
  projectRoute: buildProjectRoute(dir),
8142
8320
  scanSignals: loadScanSignals(dir),
8143
- metadataHealth: analyzeMetadataHealth(dir)
8321
+ metadataHealth: analyzeMetadataHealth(dir),
8322
+ isModuleRepo: config != null && isModule(config)
8144
8323
  };
8145
8324
  }
8146
8325
  function stateLabel(state) {
@@ -8193,11 +8372,19 @@ function renderExplanationHuman(exp) {
8193
8372
  lines.push("## Knowledge Status");
8194
8373
  lines.push(`- Inventory: ${exp.knowledge.hasInventory ? "available" : "missing"}`);
8195
8374
  lines.push(`- Context pack: ${exp.knowledge.hasContextPack ? "available" : "missing"}`);
8196
- lines.push(`- Business: ${ls("Business")}`);
8197
- lines.push(`- Product: ${ls("Product")}`);
8198
- lines.push(`- Tech: ${ls("Tech")}`);
8199
- lines.push(`- Delivery: ${ls("Delivery")}`);
8200
- lines.push(`- Agents: ${exp.knowledge.hasAgents ? "available" : "missing"}`);
8375
+ if (exp.isModuleRepo) {
8376
+ lines.push("- Business: Not applicable");
8377
+ lines.push("- Product: Not applicable");
8378
+ lines.push(`- Tech: ${ls("Tech")}`);
8379
+ lines.push("- Delivery: Managed by core");
8380
+ lines.push("- Agents: Managed by core");
8381
+ } else {
8382
+ lines.push(`- Business: ${ls("Business")}`);
8383
+ lines.push(`- Product: ${ls("Product")}`);
8384
+ lines.push(`- Tech: ${ls("Tech")}`);
8385
+ lines.push(`- Delivery: ${ls("Delivery")}`);
8386
+ lines.push(`- Agents: ${exp.knowledge.hasAgents ? "available" : "missing"}`);
8387
+ }
8201
8388
  if (exp.roadmap.present) {
8202
8389
  lines.push(`- Roadmap initiatives: ${exp.roadmap.initiatives}`);
8203
8390
  lines.push(`- Work Item candidates: ${exp.roadmap.work_item_candidates}`);
@@ -8358,14 +8545,27 @@ function renderExplanationHuman(exp) {
8358
8545
  lines.push(`- understand: ${s.understand}`);
8359
8546
  lines.push(`- agents: ${s.agents}`);
8360
8547
  lines.push(`- skills: ${s.skills}`);
8361
- lines.push(`- business: ${s.business}`);
8362
- lines.push(`- product: ${s.product}`);
8548
+ if (exp.isModuleRepo) {
8549
+ lines.push("- business: not-applicable");
8550
+ lines.push("- product: not-applicable");
8551
+ } else {
8552
+ lines.push(`- business: ${s.business}`);
8553
+ lines.push(`- product: ${s.product}`);
8554
+ }
8363
8555
  lines.push(`- capabilities: ${s.capabilities}`);
8364
8556
  lines.push(`- current-state: ${s.current_state}`);
8365
8557
  lines.push(`- codebase: ${s.codebase}`);
8366
- lines.push(`- roadmap: ${s.roadmap}`);
8367
- lines.push(`- work-items: ${s.work_items}`);
8368
- lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
8558
+ if (s.module_context != null) {
8559
+ lines.push(`- module-context: ${s.module_context}`);
8560
+ }
8561
+ if (!exp.isModuleRepo) {
8562
+ lines.push(`- roadmap: ${s.roadmap}`);
8563
+ lines.push(`- work-items: ${s.work_items}`);
8564
+ lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
8565
+ } else {
8566
+ lines.push("- roadmap: managed-by-core");
8567
+ lines.push("- work-items: managed-by-core");
8568
+ }
8369
8569
  lines.push(`- blocking open questions: ${s.blocking_open_questions}`);
8370
8570
  lines.push(`- assumptions: ${s.assumed_questions}`);
8371
8571
  lines.push(`- deferred: ${s.deferred_questions}`);
@@ -9834,7 +10034,7 @@ function projectStatus(root) {
9834
10034
  return fail("Project status needs `.kaddo/explain.json`. Run `kaddo explain` first.");
9835
10035
  }
9836
10036
  const maturity = (explain.layers ?? []).map((l2) => `${l2.layer}: ${l2.status}`);
9837
- return ok({
10037
+ const result = {
9838
10038
  project: explain.project?.name ?? "unknown",
9839
10039
  state: explain.project?.state ?? "unknown",
9840
10040
  knowledgeMaturity: maturity,
@@ -9854,7 +10054,17 @@ function projectStatus(root) {
9854
10054
  hints: hints?.summary?.hints ?? 0
9855
10055
  },
9856
10056
  capsules: capsules.length
9857
- });
10057
+ };
10058
+ if (explain.isModuleRepo) {
10059
+ result.isModuleRepo = true;
10060
+ result.readiness = {
10061
+ overall: explain.readiness?.overall ?? "unknown",
10062
+ project_role: explain.readiness?.project_role ?? "module",
10063
+ agents: "managed-by-core",
10064
+ skills: "managed-by-core"
10065
+ };
10066
+ }
10067
+ return ok(result);
9858
10068
  }
9859
10069
  function listWorkItemsTool(root, filter = {}) {
9860
10070
  let items = listWorkItems(root);
@@ -10584,19 +10794,20 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
10584
10794
  if (!inventoryAvailable) {
10585
10795
  missing.push("No technical inventory found. Run `kaddo scan` to generate it.");
10586
10796
  }
10797
+ const moduleRepo = config != null && isModule(config);
10587
10798
  const knowledgeSummary = readMarkdownSummary(dir, "knowledge.md") ?? "";
10588
- if (!knowledgeSummary) {
10799
+ if (!knowledgeSummary && !moduleRepo) {
10589
10800
  missing.push("No project knowledge summary found yet.");
10590
10801
  }
10591
10802
  const roadmapSummary = readMarkdownSummary(dir, "delivery/roadmap.md") ?? "";
10592
- if (!roadmapSummary) {
10803
+ if (!roadmapSummary && !moduleRepo) {
10593
10804
  missing.push("No roadmap baseline found.");
10594
10805
  }
10595
10806
  const allArtifacts = discoverKnowledge(dir);
10596
10807
  const workItems = allArtifacts.filter(
10597
10808
  (a2) => isDeliveryWorkItem(a2) && isActiveState(lifecycleStateOf({ status: a2.status, filePath: a2.filePath }))
10598
10809
  );
10599
- if (workItems.length === 0) {
10810
+ if (workItems.length === 0 && !moduleRepo) {
10600
10811
  missing.push("No work items found.");
10601
10812
  }
10602
10813
  const state = config.project.state;
@@ -10628,8 +10839,8 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
10628
10839
  tech: { status: layerStatusOf("Tech"), artifacts: { "knowledge/tech/codebase.md": qCodebase, "knowledge/tech/current-state.md": qCurrentState } },
10629
10840
  delivery: { status: layerStatusOf("Delivery"), artifacts: { "knowledge/delivery/roadmap.md": qRoadmap } }
10630
10841
  };
10631
- if (qBusiness === "placeholder") missing.push("Business context exists but still looks like a bootstrap placeholder.");
10632
- if (qProduct === "placeholder" || qCapabilities === "placeholder") missing.push("Product capabilities exist but still look like a bootstrap placeholder.");
10842
+ if (qBusiness === "placeholder" && !moduleRepo) missing.push("Business context exists but still looks like a bootstrap placeholder.");
10843
+ if ((qProduct === "placeholder" || qCapabilities === "placeholder") && !moduleRepo) missing.push("Product capabilities exist but still look like a bootstrap placeholder.");
10633
10844
  if (qCurrentState === "placeholder") missing.push("Current state exists but still looks like a bootstrap placeholder.");
10634
10845
  if (qCodebase === "placeholder") missing.push("Codebase map exists but still looks like a bootstrap placeholder.");
10635
10846
  const allWorkItems = allArtifacts.filter((a2) => a2.isWorkItem);
@@ -10652,7 +10863,8 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
10652
10863
  workItemsTotal: allWorkItems.length,
10653
10864
  workItemsWithOwnership: wiWithOwnership,
10654
10865
  workItemsMissingOwnership: allWorkItems.length - wiWithOwnership
10655
- }
10866
+ },
10867
+ isModuleRepo: config != null && isModule(config)
10656
10868
  });
10657
10869
  const nextStepRecommendation = resolveNextStep(dir, now);
10658
10870
  const techDecisions = buildTechDecisions(dir);
@@ -10760,11 +10972,12 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
10760
10972
  }
10761
10973
  return contexts;
10762
10974
  })(),
10975
+ isModuleRepo: moduleRepo,
10763
10976
  missing,
10764
10977
  // VS-052/VS-073.2: the handoff is driven by the unified next step, so the pack never contradicts
10765
10978
  // the Current Phase block above it.
10766
10979
  handoff: {
10767
- recommendedAgents: isBootstrap ? [] : unifiedPhase.recommendedAgents.length > 0 ? unifiedPhase.recommendedAgents : recommendedAgentsForState(state),
10980
+ recommendedAgents: isBootstrap ? [] : unifiedPhase.recommendedAgents.length > 0 ? unifiedPhase.recommendedAgents : moduleRepo ? [] : recommendedAgentsForState(state),
10768
10981
  nextSteps: [nextStepRecommendation.label],
10769
10982
  instructions: isBootstrap ? ["No agent handoff yet.", "Run `kaddo bootstrap` first to create the baseline files."] : unifiedPhase.llmInstructions.length > 0 ? unifiedPhase.llmInstructions : LLM_INSTRUCTIONS,
10770
10983
  operatingRules: OPERATING_RULES
@@ -11075,7 +11288,11 @@ function renderContextPack(pack) {
11075
11288
  }
11076
11289
  }
11077
11290
  parts.push("## Recommended Agent Handoff\n");
11078
- if (isBootstrapIncomplete) {
11291
+ if (pack.isModuleRepo && handoff.recommendedAgents.length === 0) {
11292
+ parts.push("No local agent action is required.\n");
11293
+ parts.push("This module is ready for core orchestration.\n");
11294
+ parts.push("Business, Product, Delivery, Agents and Skills are managed by the core repository.\n");
11295
+ } else if (isBootstrapIncomplete) {
11079
11296
  parts.push("No agent handoff yet.\n");
11080
11297
  parts.push("Run `kaddo bootstrap` first to create the baseline files.\n");
11081
11298
  } else if (rec.agent && rec.agentInstalled === false) {
@@ -11134,6 +11351,16 @@ function flowForState(state) {
11134
11351
  }
11135
11352
  function buildUnderstandPlan(dir, config) {
11136
11353
  const state = config.project.state;
11354
+ if (isModule(config)) {
11355
+ return {
11356
+ project: { name: config.project.name, state, teamSize: config.team.size, structure: config.project.structure, language: "English" },
11357
+ steps: [],
11358
+ missingAgents: [],
11359
+ agentsInstalled: true,
11360
+ scanAvailable: exists(join(dir, ".kaddo", "scan.json")),
11361
+ contextPackPath: ".kaddo/context-pack.md"
11362
+ };
11363
+ }
11137
11364
  const flow = flowForState(state).filter((s) => !exists(join(dir, s.output)));
11138
11365
  const steps = flow.map((s) => {
11139
11366
  const installed = agentIsInstalled(dir, s.agent);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/mcp",
3
- "version": "3.63.0",
3
+ "version": "3.65.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": {