@kaddo/cli 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 +297 -73
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5067,7 +5067,8 @@ var RECOMMENDED_BY_STATE = {
5067
5067
  "backlog-agent.md",
5068
5068
  "work-item-agent.md",
5069
5069
  "implementation-agent.md",
5070
- "adr-agent.md"
5070
+ "adr-agent.md",
5071
+ "module-context-agent.md"
5071
5072
  ],
5072
5073
  "pre-ai": [
5073
5074
  "business-agent.md",
@@ -5077,7 +5078,8 @@ var RECOMMENDED_BY_STATE = {
5077
5078
  "backlog-agent.md",
5078
5079
  "work-item-agent.md",
5079
5080
  "implementation-agent.md",
5080
- "ownership-agent.md"
5081
+ "ownership-agent.md",
5082
+ "module-context-agent.md"
5081
5083
  ],
5082
5084
  legacy: [
5083
5085
  "legacy-agent.md",
@@ -7587,6 +7589,34 @@ function firstUnrefinedLayerAgent(layers) {
7587
7589
  return { agent: "architecture-agent", step: "Use architecture-agent to complete knowledge/tech/current-state.md" };
7588
7590
  }
7589
7591
  function assessPhase(input) {
7592
+ if (input.isModuleRepo) {
7593
+ const techStatus = layer(input.layers, "Tech");
7594
+ const techReady = !NOT_READY_LAYER.includes(techStatus);
7595
+ if (techReady) {
7596
+ return {
7597
+ phase: "Ready for Core Orchestration",
7598
+ reasons: ["Module repo \u2014 Tech layer ready", "Business/Product managed by core"],
7599
+ recommendedAgents: [],
7600
+ nextStep: "Module knowledge is ready for core orchestration.",
7601
+ llmInstructions: [
7602
+ "This is a module repo. Business, Product, and Delivery are managed by the core repo.",
7603
+ "Do not create business, product, roadmap or Work Items here."
7604
+ ]
7605
+ };
7606
+ }
7607
+ return {
7608
+ phase: "Knowledge Refinement",
7609
+ reasons: ["Module repo \u2014 Tech layer incomplete", "Business/Product managed by core"],
7610
+ recommendedAgents: ["module-context-agent"],
7611
+ nextStep: "Use module-context-agent to refine knowledge/tech/module/module-context.md",
7612
+ llmInstructions: [
7613
+ "Use the module-context-agent to refine the module context.",
7614
+ "Do not create business, product, roadmap or Work Items in this module.",
7615
+ "Do not install agents or skills.",
7616
+ "Do not write application code."
7617
+ ]
7618
+ };
7619
+ }
7590
7620
  const phase = determinePhase(input);
7591
7621
  const reasons = buildReasons(input);
7592
7622
  const bs = input.workItems.byState;
@@ -10687,6 +10717,21 @@ function layerQuality(dir, layer2) {
10687
10717
  return worst;
10688
10718
  }
10689
10719
  function knowledgeLayers(dir) {
10720
+ const config = loadConfig(dir);
10721
+ if (config && isModule(config)) {
10722
+ return [
10723
+ { layer: "Business", status: "Not applicable", detected: [] },
10724
+ { layer: "Product", status: "Not applicable", detected: [] },
10725
+ ...discoverLayers(dir).filter((l) => l.layer === "Tech").map((l) => {
10726
+ if (l.status !== "Consolidated" && l.status !== "Structured") return l;
10727
+ const q = layerQuality(dir, l.layer);
10728
+ if (q === "placeholder") return { ...l, status: "Placeholder" };
10729
+ if (q === "weak") return { ...l, status: "Weak" };
10730
+ return l;
10731
+ }),
10732
+ { layer: "Delivery", status: "Managed by core", detected: [] }
10733
+ ];
10734
+ }
10690
10735
  return discoverLayers(dir).map((l) => {
10691
10736
  if (l.status !== "Consolidated" && l.status !== "Structured") return l;
10692
10737
  const q = layerQuality(dir, l.layer);
@@ -11547,6 +11592,13 @@ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
11547
11592
  }
11548
11593
  const state = config.project.state;
11549
11594
  const q = (rel) => analyzeKnowledgeArtifact(dir, rel);
11595
+ const resolveAgent = (agent) => {
11596
+ const file = agent.endsWith(".md") ? agent : `${agent}.md`;
11597
+ const path8 = agentInstallPath(file);
11598
+ const installed = isFile(join(dir, path8));
11599
+ const group = agentGroupOf(file);
11600
+ return { agentPath: path8, agentInstalled: installed, installCommand: installed ? void 0 : `kaddo add agents --group ${group}` };
11601
+ };
11550
11602
  const moduleRepo = isModule(config);
11551
11603
  const coreRepo = isCore(config);
11552
11604
  const MC = exists(join(dir, "knowledge/tech/module/module-context.md")) ? "knowledge/tech/module/module-context.md" : "knowledge/module/module-context.md";
@@ -11562,15 +11614,26 @@ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
11562
11614
  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." };
11563
11615
  }
11564
11616
  if (qMC !== "useful") {
11617
+ const ar = resolveAgent("module-context-agent");
11565
11618
  return {
11566
11619
  id: "refine-module-context",
11567
11620
  phase: "Knowledge Refinement",
11568
- label: "Use module-context-agent to refine `knowledge/module/module-context.md`.",
11621
+ label: "Use module-context-agent to refine `knowledge/tech/module/module-context.md`.",
11569
11622
  agent: "module-context-agent",
11570
11623
  skill: "module-context-refinement",
11571
11624
  target: MC,
11625
+ agentPath: ar.agentPath,
11626
+ agentInstalled: ar.agentInstalled,
11627
+ installCommand: ar.installCommand,
11572
11628
  reason: "Module context is still a placeholder.",
11573
- instructions: ["Refine the module context with real knowledge about this module.", "Do not create business.md or product.md.", "Do not write code."]
11629
+ instructions: [
11630
+ "Refine the module context using evidence from this repository.",
11631
+ "Use the parent system context when available.",
11632
+ "Do not create business, product, roadmap or Work Items in this module.",
11633
+ "Do not install agents or skills in this module.",
11634
+ "Do not write application code.",
11635
+ "Preserve frontmatter and record unknowns as open questions."
11636
+ ]
11574
11637
  };
11575
11638
  }
11576
11639
  const qCurrentState2 = q(CS), qCodebase2 = q(CB);
@@ -11599,7 +11662,7 @@ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
11599
11662
  if (!exists(join(dir, ".kaddo", "understand.md"))) {
11600
11663
  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." };
11601
11664
  }
11602
- 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." };
11665
+ 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." };
11603
11666
  }
11604
11667
  const qBusiness = q(B), qProduct = q(P), qCap = q(CAP), qCurrentState = q(CS), qCodebase = q(CB);
11605
11668
  if (!coreRepo && (qBusiness === "missing" || qProduct === "missing")) {
@@ -11625,13 +11688,6 @@ function resolveNextStep(dir, now = /* @__PURE__ */ new Date()) {
11625
11688
  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." };
11626
11689
  }
11627
11690
  const discovery = state === "pre-ai" || state === "legacy";
11628
- const resolveAgent = (agent) => {
11629
- const file = agent.endsWith(".md") ? agent : `${agent}.md`;
11630
- const path8 = agentInstallPath(file);
11631
- const installed = isFile(join(dir, path8));
11632
- const group = agentGroupOf(file);
11633
- return { agentPath: path8, agentInstalled: installed, installCommand: installed ? void 0 : `kaddo add agents --group ${group}` };
11634
- };
11635
11691
  const refine = (id, agent, target, quality, verb = "complete") => {
11636
11692
  const ar = resolveAgent(agent);
11637
11693
  return {
@@ -11865,6 +11921,47 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
11865
11921
  if (!config) return stub("not-initialized", rec.label, rec.command);
11866
11922
  if (config.project.state === "new") return stub("not-applicable", "This project uses the standard new-project Kaddo flow.");
11867
11923
  if (config.project.state === "legacy") return stub("legacy-project", "Use the legacy project flow.");
11924
+ if (isModule(config)) {
11925
+ const scan3 = exists(join(dir, ".kaddo", "scan.json")) ? "available" : "missing";
11926
+ const understand2 = exists(join(dir, ".kaddo", "understand.md")) ? "available" : "missing";
11927
+ const mcNew = "knowledge/tech/module/module-context.md";
11928
+ const mcLegacy = "knowledge/module/module-context.md";
11929
+ const mcPath = exists(join(dir, mcNew)) ? mcNew : mcLegacy;
11930
+ const qMC = analyzeKnowledgeArtifact(dir, mcPath);
11931
+ const qCS = analyzeKnowledgeArtifact(dir, "knowledge/tech/current-state.md");
11932
+ const qCB = analyzeKnowledgeArtifact(dir, "knowledge/tech/codebase.md");
11933
+ const moduleBaseline = qMC !== "missing" && qCS !== "missing" && qCB !== "missing" ? "complete" : "incomplete";
11934
+ const moduleReady = qMC === "useful" && qCS === "useful" && qCB === "useful";
11935
+ const overall2 = moduleReady ? "ready-for-core-orchestration" : moduleBaseline === "incomplete" ? "bootstrap-incomplete" : "knowledge-incomplete";
11936
+ return {
11937
+ project_name: config.project.name,
11938
+ project_type: config.project.state,
11939
+ project_role: "module",
11940
+ overall: overall2,
11941
+ signals: {
11942
+ scan: scan3,
11943
+ understand: understand2,
11944
+ bootstrap_baseline: moduleBaseline,
11945
+ agents: "managed-by-core",
11946
+ skills: "managed-by-core",
11947
+ current_state: qCS,
11948
+ codebase: qCB,
11949
+ module_context: qMC,
11950
+ capabilities: "managed-by-core",
11951
+ product: "not-applicable",
11952
+ business: "not-applicable",
11953
+ roadmap: "managed-by-core",
11954
+ work_items: "managed-by-core",
11955
+ adapters: [],
11956
+ blocking_open_questions: 0,
11957
+ assumed_questions: 0,
11958
+ resolved_questions: 0,
11959
+ deferred_questions: 0
11960
+ },
11961
+ recommended_next_step: { label: rec.label, ...rec.command ? { command: rec.command } : {} },
11962
+ nextStepRecommendation: rec
11963
+ };
11964
+ }
11868
11965
  const scan2 = exists(join(dir, ".kaddo", "scan.json")) ? "available" : "missing";
11869
11966
  const understand = exists(join(dir, ".kaddo", "understand.md")) ? "available" : "missing";
11870
11967
  const presence = Object.fromEntries(KNOWLEDGE_FILES2.map((f) => [f.key, analyzeKnowledgeArtifact(dir, f.path)]));
@@ -12370,6 +12467,67 @@ var identifyRisks = {
12370
12467
  return { status: hasLegacy ? "done" : "pending", agent: hasLegacy ? void 0 : "legacy-agent" };
12371
12468
  }
12372
12469
  };
12470
+ var refineModuleContext = {
12471
+ id: "refine-module-context",
12472
+ label: "Refine module context",
12473
+ evaluate: (ctx) => {
12474
+ const newPath = join(ctx.dir, "knowledge/tech/module/module-context.md");
12475
+ const legacyPath = join(ctx.dir, "knowledge/module/module-context.md");
12476
+ const mcPath = exists(newPath) ? "knowledge/tech/module/module-context.md" : exists(legacyPath) ? "knowledge/module/module-context.md" : null;
12477
+ if (!mcPath) return { status: "pending", agent: "module-context-agent", skill: "module-context-refinement" };
12478
+ const q = analyzeKnowledgeArtifact(ctx.dir, mcPath);
12479
+ if (q === "useful") return { status: "done", evidence: [mcPath] };
12480
+ return { status: "current", agent: "module-context-agent", skill: "module-context-refinement", evidence: [mcPath], reason: "Module context is still a placeholder." };
12481
+ }
12482
+ };
12483
+ var describeModuleCurrentState = {
12484
+ id: "describe-current-state",
12485
+ label: "Describe current state",
12486
+ evaluate: (ctx) => ({
12487
+ status: isUseful(ctx.qCurrentState) ? "done" : "pending",
12488
+ evidence: isUseful(ctx.qCurrentState) ? ["knowledge/tech/current-state.md"] : void 0,
12489
+ agent: isUseful(ctx.qCurrentState) ? void 0 : "architecture-agent"
12490
+ })
12491
+ };
12492
+ var mapModuleCodebase = {
12493
+ id: "map-codebase",
12494
+ label: "Map codebase",
12495
+ evaluate: (ctx) => ({
12496
+ status: isUseful(ctx.qCodebase) ? "done" : "pending",
12497
+ evidence: isUseful(ctx.qCodebase) ? ["knowledge/tech/codebase.md"] : void 0,
12498
+ agent: isUseful(ctx.qCodebase) ? void 0 : "architecture-agent"
12499
+ })
12500
+ };
12501
+ var validateModuleKnowledge = {
12502
+ id: "validate-module-knowledge",
12503
+ label: "Validate module knowledge",
12504
+ evaluate: (ctx) => {
12505
+ const hasUnderstand = exists(join(ctx.dir, ".kaddo/understand.md"));
12506
+ if (hasUnderstand) return { status: "done", evidence: [".kaddo/understand.md"] };
12507
+ return { status: "pending", command: "kaddo understand" };
12508
+ }
12509
+ };
12510
+ var readyForCoreOrchestration = {
12511
+ id: "ready-for-core-orchestration",
12512
+ label: "Ready for core orchestration",
12513
+ evaluate: (ctx) => {
12514
+ const newPath = join(ctx.dir, "knowledge/tech/module/module-context.md");
12515
+ const legacyPath = join(ctx.dir, "knowledge/module/module-context.md");
12516
+ const mcPath = exists(newPath) ? "knowledge/tech/module/module-context.md" : exists(legacyPath) ? "knowledge/module/module-context.md" : null;
12517
+ const mcUseful = mcPath ? analyzeKnowledgeArtifact(ctx.dir, mcPath) === "useful" : false;
12518
+ const allDone = mcUseful && isUseful(ctx.qCurrentState) && isUseful(ctx.qCodebase);
12519
+ return { status: allDone ? "done" : "pending", reason: allDone ? void 0 : "Module knowledge is not yet complete." };
12520
+ }
12521
+ };
12522
+ var MODULE_STEPS = [
12523
+ enableKaddo,
12524
+ scanRepository,
12525
+ refineModuleContext,
12526
+ describeModuleCurrentState,
12527
+ mapModuleCodebase,
12528
+ validateModuleKnowledge,
12529
+ readyForCoreOrchestration
12530
+ ];
12373
12531
  var NEW_STEPS = [
12374
12532
  enableKaddo,
12375
12533
  defineBusiness,
@@ -12510,10 +12668,10 @@ function mapNextStepId(id) {
12510
12668
  "review-work-item": "refine-work-item",
12511
12669
  "prepare-implementation": "prepare-implementation",
12512
12670
  "implement-work-item": "prepare-implementation",
12513
- "refine-module-context": "refine-work-item",
12671
+ "refine-module-context": "refine-module-context",
12514
12672
  "init-module-context": "enable-kaddo",
12515
- "module-ready": "prepare-implementation",
12516
- "validate-work-item-modules": "prepare-implementation",
12673
+ "module-ready": "ready-for-core-orchestration",
12674
+ "validate-work-item-modules": "validate-module-knowledge",
12517
12675
  "modules-discover": "enable-kaddo"
12518
12676
  };
12519
12677
  return MAP[id] ?? id;
@@ -12521,7 +12679,7 @@ function mapNextStepId(id) {
12521
12679
  function buildProjectRoute(dir) {
12522
12680
  const config = loadConfig(dir);
12523
12681
  const state = config?.project.state ?? "pre-ai";
12524
- const defs = stepsForState(state);
12682
+ const defs = config && isModule(config) ? MODULE_STEPS : stepsForState(state);
12525
12683
  const ctx = buildRouteContext(dir);
12526
12684
  const steps = defs.map((d) => {
12527
12685
  const result = d.evaluate(ctx);
@@ -12774,51 +12932,73 @@ function buildProjectExplanation(dir) {
12774
12932
  const roadmapMd = exists(roadmapPath) ? readFile(roadmapPath) : null;
12775
12933
  const roadmap = roadmapStats(roadmapMd, items.length);
12776
12934
  const mappedModules = loadMappedModules(dir);
12935
+ const moduleRepo = config != null && isModule(config);
12777
12936
  const missingKnowledge = [];
12778
- if (!knowledge.hasScan) missingKnowledge.push("Scan baseline (.kaddo/scan.json)");
12779
- if (!knowledge.hasContextPack) missingKnowledge.push("Context pack (.kaddo/context-pack.md)");
12780
- if (!knowledge.hasInventory) missingKnowledge.push("Inventory (knowledge/inventory.md)");
12781
- if (!knowledge.hasCapabilities) missingKnowledge.push("Product knowledge (knowledge/product/)");
12782
- if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
12783
- if (!knowledge.hasRoadmap) missingKnowledge.push("Roadmap (knowledge/delivery/roadmap.md)");
12784
- if (!knowledge.hasAgents) missingKnowledge.push("Agents (knowledge/agents/)");
12785
- if (items.length === 0) missingKnowledge.push("Work items (knowledge/delivery/work-items/)");
12786
- const suggestedNextSteps = [];
12787
- const baselineIncomplete = !knowledge.hasBusiness || !knowledge.hasProduct;
12788
- if (baselineIncomplete) {
12789
- suggestedNextSteps.push("Run `kaddo bootstrap` to create the project knowledge baseline.");
12790
- if (!knowledge.hasAgents) suggestedNextSteps.push("Then run `kaddo add agents`.");
12791
- if (!knowledge.hasSkills) suggestedNextSteps.push("Then run `kaddo add skills`.");
12792
- suggestedNextSteps.push("Then run `kaddo context`.");
12793
- suggestedNextSteps.push("Then run `kaddo understand`.");
12937
+ if (moduleRepo) {
12938
+ if (!knowledge.hasScan) missingKnowledge.push("Scan baseline (.kaddo/scan.json)");
12939
+ if (!knowledge.hasContextPack) missingKnowledge.push("Context pack (.kaddo/context-pack.md)");
12940
+ if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
12794
12941
  } else {
12942
+ if (!knowledge.hasScan) missingKnowledge.push("Scan baseline (.kaddo/scan.json)");
12943
+ if (!knowledge.hasContextPack) missingKnowledge.push("Context pack (.kaddo/context-pack.md)");
12944
+ if (!knowledge.hasInventory) missingKnowledge.push("Inventory (knowledge/inventory.md)");
12945
+ if (!knowledge.hasCapabilities) missingKnowledge.push("Product knowledge (knowledge/product/)");
12946
+ if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
12947
+ if (!knowledge.hasRoadmap) missingKnowledge.push("Roadmap (knowledge/delivery/roadmap.md)");
12948
+ if (!knowledge.hasAgents) missingKnowledge.push("Agents (knowledge/agents/)");
12949
+ if (items.length === 0) missingKnowledge.push("Work items (knowledge/delivery/work-items/)");
12950
+ }
12951
+ const suggestedNextSteps = [];
12952
+ if (moduleRepo) {
12795
12953
  if (!knowledge.hasScan) {
12796
12954
  suggestedNextSteps.push("Run `kaddo scan` to detect the technical stack.");
12797
12955
  } else if (!knowledge.hasContextPack) {
12798
12956
  suggestedNextSteps.push("Run `kaddo context` to prepare an LLM context pack.");
12957
+ } else if (!knowledge.hasArchitecture) {
12958
+ suggestedNextSteps.push("Use module-context-agent to refine knowledge/tech/module/module-context.md.");
12959
+ } else {
12960
+ suggestedNextSteps.push("Return to the core repository.");
12961
+ suggestedNextSteps.push("Create or continue the Work Item from the core.");
12962
+ suggestedNextSteps.push("Add this module to `affected_modules` when the change touches it.");
12963
+ suggestedNextSteps.push("Re-run `kaddo context` and `kaddo understand` from the core.");
12799
12964
  }
12800
- if (!knowledge.hasAgents) {
12801
- suggestedNextSteps.push("Run `kaddo add agents` to install knowledge agents.");
12802
- }
12803
- if (!knowledge.hasCapabilities) {
12804
- suggestedNextSteps.push("Use capability-agent to generate knowledge/product/capabilities.md.");
12805
- }
12806
- if (!knowledge.hasArchitecture) {
12807
- suggestedNextSteps.push("Use architecture-agent to generate knowledge/tech/current-state.md.");
12808
- }
12809
- if (!knowledge.hasRoadmap) {
12810
- suggestedNextSteps.push("Use roadmap-agent to generate knowledge/delivery/roadmap.md.");
12811
- } else if (roadmap.remaining > 0) {
12812
- suggestedNextSteps.push(
12813
- `Materialize ${roadmap.remaining} roadmap candidate(s) with \`kaddo create --from roadmap\`.`
12814
- );
12815
- }
12816
- if (items.length === 0 && !roadmap.present) {
12817
- suggestedNextSteps.push("Create your first Work Item with `kaddo create`.");
12818
- } else if (ownership.workItemsMissingOwnership > 0) {
12819
- suggestedNextSteps.push(
12820
- "Run `kaddo owners suggest` for Work Items without code ownership."
12821
- );
12965
+ } else {
12966
+ const baselineIncomplete = !knowledge.hasBusiness || !knowledge.hasProduct;
12967
+ if (baselineIncomplete) {
12968
+ suggestedNextSteps.push("Run `kaddo bootstrap` to create the project knowledge baseline.");
12969
+ if (!knowledge.hasAgents) suggestedNextSteps.push("Then run `kaddo add agents`.");
12970
+ if (!knowledge.hasSkills) suggestedNextSteps.push("Then run `kaddo add skills`.");
12971
+ suggestedNextSteps.push("Then run `kaddo context`.");
12972
+ suggestedNextSteps.push("Then run `kaddo understand`.");
12973
+ } else {
12974
+ if (!knowledge.hasScan) {
12975
+ suggestedNextSteps.push("Run `kaddo scan` to detect the technical stack.");
12976
+ } else if (!knowledge.hasContextPack) {
12977
+ suggestedNextSteps.push("Run `kaddo context` to prepare an LLM context pack.");
12978
+ }
12979
+ if (!knowledge.hasAgents) {
12980
+ suggestedNextSteps.push("Run `kaddo add agents` to install knowledge agents.");
12981
+ }
12982
+ if (!knowledge.hasCapabilities) {
12983
+ suggestedNextSteps.push("Use capability-agent to generate knowledge/product/capabilities.md.");
12984
+ }
12985
+ if (!knowledge.hasArchitecture) {
12986
+ suggestedNextSteps.push("Use architecture-agent to generate knowledge/tech/current-state.md.");
12987
+ }
12988
+ if (!knowledge.hasRoadmap) {
12989
+ suggestedNextSteps.push("Use roadmap-agent to generate knowledge/delivery/roadmap.md.");
12990
+ } else if (roadmap.remaining > 0) {
12991
+ suggestedNextSteps.push(
12992
+ `Materialize ${roadmap.remaining} roadmap candidate(s) with \`kaddo create --from roadmap\`.`
12993
+ );
12994
+ }
12995
+ if (items.length === 0 && !roadmap.present) {
12996
+ suggestedNextSteps.push("Create your first Work Item with `kaddo create`.");
12997
+ } else if (ownership.workItemsMissingOwnership > 0) {
12998
+ suggestedNextSteps.push(
12999
+ "Run `kaddo owners suggest` for Work Items without code ownership."
13000
+ );
13001
+ }
12822
13002
  }
12823
13003
  }
12824
13004
  const readiness = buildReadinessReport(dir);
@@ -12860,7 +13040,8 @@ function buildProjectExplanation(dir) {
12860
13040
  roadmapQuality: buildRoadmapQuality(dir),
12861
13041
  projectRoute: buildProjectRoute(dir),
12862
13042
  scanSignals: loadScanSignals(dir),
12863
- metadataHealth: analyzeMetadataHealth(dir)
13043
+ metadataHealth: analyzeMetadataHealth(dir),
13044
+ isModuleRepo: config != null && isModule(config)
12864
13045
  };
12865
13046
  }
12866
13047
  function stateLabel(state) {
@@ -12913,11 +13094,19 @@ function renderExplanationHuman(exp) {
12913
13094
  lines.push("## Knowledge Status");
12914
13095
  lines.push(`- Inventory: ${exp.knowledge.hasInventory ? "available" : "missing"}`);
12915
13096
  lines.push(`- Context pack: ${exp.knowledge.hasContextPack ? "available" : "missing"}`);
12916
- lines.push(`- Business: ${ls("Business")}`);
12917
- lines.push(`- Product: ${ls("Product")}`);
12918
- lines.push(`- Tech: ${ls("Tech")}`);
12919
- lines.push(`- Delivery: ${ls("Delivery")}`);
12920
- lines.push(`- Agents: ${exp.knowledge.hasAgents ? "available" : "missing"}`);
13097
+ if (exp.isModuleRepo) {
13098
+ lines.push("- Business: Not applicable");
13099
+ lines.push("- Product: Not applicable");
13100
+ lines.push(`- Tech: ${ls("Tech")}`);
13101
+ lines.push("- Delivery: Managed by core");
13102
+ lines.push("- Agents: Managed by core");
13103
+ } else {
13104
+ lines.push(`- Business: ${ls("Business")}`);
13105
+ lines.push(`- Product: ${ls("Product")}`);
13106
+ lines.push(`- Tech: ${ls("Tech")}`);
13107
+ lines.push(`- Delivery: ${ls("Delivery")}`);
13108
+ lines.push(`- Agents: ${exp.knowledge.hasAgents ? "available" : "missing"}`);
13109
+ }
12921
13110
  if (exp.roadmap.present) {
12922
13111
  lines.push(`- Roadmap initiatives: ${exp.roadmap.initiatives}`);
12923
13112
  lines.push(`- Work Item candidates: ${exp.roadmap.work_item_candidates}`);
@@ -13078,14 +13267,27 @@ function renderExplanationHuman(exp) {
13078
13267
  lines.push(`- understand: ${s.understand}`);
13079
13268
  lines.push(`- agents: ${s.agents}`);
13080
13269
  lines.push(`- skills: ${s.skills}`);
13081
- lines.push(`- business: ${s.business}`);
13082
- lines.push(`- product: ${s.product}`);
13270
+ if (exp.isModuleRepo) {
13271
+ lines.push("- business: not-applicable");
13272
+ lines.push("- product: not-applicable");
13273
+ } else {
13274
+ lines.push(`- business: ${s.business}`);
13275
+ lines.push(`- product: ${s.product}`);
13276
+ }
13083
13277
  lines.push(`- capabilities: ${s.capabilities}`);
13084
13278
  lines.push(`- current-state: ${s.current_state}`);
13085
13279
  lines.push(`- codebase: ${s.codebase}`);
13086
- lines.push(`- roadmap: ${s.roadmap}`);
13087
- lines.push(`- work-items: ${s.work_items}`);
13088
- lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
13280
+ if (s.module_context != null) {
13281
+ lines.push(`- module-context: ${s.module_context}`);
13282
+ }
13283
+ if (!exp.isModuleRepo) {
13284
+ lines.push(`- roadmap: ${s.roadmap}`);
13285
+ lines.push(`- work-items: ${s.work_items}`);
13286
+ lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
13287
+ } else {
13288
+ lines.push("- roadmap: managed-by-core");
13289
+ lines.push("- work-items: managed-by-core");
13290
+ }
13089
13291
  lines.push(`- blocking open questions: ${s.blocking_open_questions}`);
13090
13292
  lines.push(`- assumptions: ${s.assumed_questions}`);
13091
13293
  lines.push(`- deferred: ${s.deferred_questions}`);
@@ -13450,19 +13652,20 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
13450
13652
  if (!inventoryAvailable) {
13451
13653
  missing.push("No technical inventory found. Run `kaddo scan` to generate it.");
13452
13654
  }
13655
+ const moduleRepo = config != null && isModule(config);
13453
13656
  const knowledgeSummary = readMarkdownSummary(dir, "knowledge.md") ?? "";
13454
- if (!knowledgeSummary) {
13657
+ if (!knowledgeSummary && !moduleRepo) {
13455
13658
  missing.push("No project knowledge summary found yet.");
13456
13659
  }
13457
13660
  const roadmapSummary = readMarkdownSummary(dir, "delivery/roadmap.md") ?? "";
13458
- if (!roadmapSummary) {
13661
+ if (!roadmapSummary && !moduleRepo) {
13459
13662
  missing.push("No roadmap baseline found.");
13460
13663
  }
13461
13664
  const allArtifacts = discoverKnowledge(dir);
13462
13665
  const workItems = allArtifacts.filter(
13463
13666
  (a) => isDeliveryWorkItem(a) && isActiveState(lifecycleStateOf({ status: a.status, filePath: a.filePath }))
13464
13667
  );
13465
- if (workItems.length === 0) {
13668
+ if (workItems.length === 0 && !moduleRepo) {
13466
13669
  missing.push("No work items found.");
13467
13670
  }
13468
13671
  const state = config.project.state;
@@ -13494,8 +13697,8 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
13494
13697
  tech: { status: layerStatusOf("Tech"), artifacts: { "knowledge/tech/codebase.md": qCodebase, "knowledge/tech/current-state.md": qCurrentState } },
13495
13698
  delivery: { status: layerStatusOf("Delivery"), artifacts: { "knowledge/delivery/roadmap.md": qRoadmap } }
13496
13699
  };
13497
- if (qBusiness === "placeholder") missing.push("Business context exists but still looks like a bootstrap placeholder.");
13498
- if (qProduct === "placeholder" || qCapabilities === "placeholder") missing.push("Product capabilities exist but still look like a bootstrap placeholder.");
13700
+ if (qBusiness === "placeholder" && !moduleRepo) missing.push("Business context exists but still looks like a bootstrap placeholder.");
13701
+ if ((qProduct === "placeholder" || qCapabilities === "placeholder") && !moduleRepo) missing.push("Product capabilities exist but still look like a bootstrap placeholder.");
13499
13702
  if (qCurrentState === "placeholder") missing.push("Current state exists but still looks like a bootstrap placeholder.");
13500
13703
  if (qCodebase === "placeholder") missing.push("Codebase map exists but still looks like a bootstrap placeholder.");
13501
13704
  const allWorkItems = allArtifacts.filter((a) => a.isWorkItem);
@@ -13518,7 +13721,8 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
13518
13721
  workItemsTotal: allWorkItems.length,
13519
13722
  workItemsWithOwnership: wiWithOwnership,
13520
13723
  workItemsMissingOwnership: allWorkItems.length - wiWithOwnership
13521
- }
13724
+ },
13725
+ isModuleRepo: config != null && isModule(config)
13522
13726
  });
13523
13727
  const nextStepRecommendation = resolveNextStep(dir, now);
13524
13728
  const techDecisions = buildTechDecisions(dir);
@@ -13626,11 +13830,12 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
13626
13830
  }
13627
13831
  return contexts;
13628
13832
  })(),
13833
+ isModuleRepo: moduleRepo,
13629
13834
  missing,
13630
13835
  // VS-052/VS-073.2: the handoff is driven by the unified next step, so the pack never contradicts
13631
13836
  // the Current Phase block above it.
13632
13837
  handoff: {
13633
- recommendedAgents: isBootstrap ? [] : unifiedPhase.recommendedAgents.length > 0 ? unifiedPhase.recommendedAgents : recommendedAgentsForState(state),
13838
+ recommendedAgents: isBootstrap ? [] : unifiedPhase.recommendedAgents.length > 0 ? unifiedPhase.recommendedAgents : moduleRepo ? [] : recommendedAgentsForState(state),
13634
13839
  nextSteps: [nextStepRecommendation.label],
13635
13840
  instructions: isBootstrap ? ["No agent handoff yet.", "Run `kaddo bootstrap` first to create the baseline files."] : unifiedPhase.llmInstructions.length > 0 ? unifiedPhase.llmInstructions : LLM_INSTRUCTIONS,
13636
13841
  operatingRules: OPERATING_RULES
@@ -13941,7 +14146,11 @@ function renderContextPack(pack) {
13941
14146
  }
13942
14147
  }
13943
14148
  parts.push("## Recommended Agent Handoff\n");
13944
- if (isBootstrapIncomplete) {
14149
+ if (pack.isModuleRepo && handoff.recommendedAgents.length === 0) {
14150
+ parts.push("No local agent action is required.\n");
14151
+ parts.push("This module is ready for core orchestration.\n");
14152
+ parts.push("Business, Product, Delivery, Agents and Skills are managed by the core repository.\n");
14153
+ } else if (isBootstrapIncomplete) {
13945
14154
  parts.push("No agent handoff yet.\n");
13946
14155
  parts.push("Run `kaddo bootstrap` first to create the baseline files.\n");
13947
14156
  } else if (rec.agent && rec.agentInstalled === false) {
@@ -14039,6 +14248,16 @@ function flowForState(state) {
14039
14248
  }
14040
14249
  function buildUnderstandPlan(dir, config) {
14041
14250
  const state = config.project.state;
14251
+ if (isModule(config)) {
14252
+ return {
14253
+ project: { name: config.project.name, state, teamSize: config.team.size, structure: config.project.structure, language: "English" },
14254
+ steps: [],
14255
+ missingAgents: [],
14256
+ agentsInstalled: true,
14257
+ scanAvailable: exists(join(dir, ".kaddo", "scan.json")),
14258
+ contextPackPath: ".kaddo/context-pack.md"
14259
+ };
14260
+ }
14042
14261
  const flow = flowForState(state).filter((s) => !exists(join(dir, s.output)));
14043
14262
  const steps = flow.map((s) => {
14044
14263
  const installed = agentIsInstalled(dir, s.agent);
@@ -15127,6 +15346,11 @@ function runAdd(moduleName, opts = {}, dir = cwd()) {
15127
15346
  console.error("Run `kaddo init` first.");
15128
15347
  process.exit(1);
15129
15348
  }
15349
+ const addConfig = loadConfig(dir);
15350
+ if ((mod.name === "agents" || mod.name === "skills") && addConfig && isModule(addConfig)) {
15351
+ console.error(`Module repos do not use ${mod.name}. ${mod.name === "agents" ? "Agents" : "Skills"} are managed by the core repo.`);
15352
+ process.exit(1);
15353
+ }
15130
15354
  const alreadyInstalled = isModuleInstalled(dir, mod.configKey);
15131
15355
  for (const d of mod.dirs) {
15132
15356
  ensureDir(join(dir, d));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/cli",
3
- "version": "3.63.0",
3
+ "version": "3.65.0",
4
4
  "description": "Knowledge Driven Development toolkit",
5
5
  "license": "MIT",
6
6
  "repository": {