@kaddo/cli 3.49.0 → 3.51.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 +262 -174
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9052,7 +9052,7 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
9052
9052
  const ctx = buildCodexAdapterContext(dir);
9053
9053
  const agents = ctx.hasAgents ? "present" : "missing";
9054
9054
  const skills = ctx.hasSkills ? "present" : "missing";
9055
- const bootstrapBaseline = presence.business !== "missing" && presence.product !== "missing" ? "complete" : "incomplete";
9055
+ const bootstrapBaseline2 = presence.business !== "missing" && presence.product !== "missing" ? "complete" : "incomplete";
9056
9056
  const roadmap = roadmapSignal(dir);
9057
9057
  const work_items = workItemsSignal(dir);
9058
9058
  const adapters = installedAdapters(dir);
@@ -9060,7 +9060,7 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
9060
9060
  const signals = {
9061
9061
  scan: scan2,
9062
9062
  understand,
9063
- bootstrap_baseline: bootstrapBaseline,
9063
+ bootstrap_baseline: bootstrapBaseline2,
9064
9064
  agents,
9065
9065
  skills,
9066
9066
  current_state: presence.current_state,
@@ -9079,7 +9079,7 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
9079
9079
  const firstWeak = KNOWLEDGE_FILES.find((f) => presence[f.key] !== "useful");
9080
9080
  let overall;
9081
9081
  if (scan2 === "missing") overall = "initialized";
9082
- else if (bootstrapBaseline === "incomplete") overall = "bootstrap-incomplete";
9082
+ else if (bootstrapBaseline2 === "incomplete") overall = "bootstrap-incomplete";
9083
9083
  else if (agents === "missing") overall = "agents-missing";
9084
9084
  else if (skills === "missing") overall = "skills-missing";
9085
9085
  else if (understand === "missing") overall = "scanned";
@@ -9346,6 +9346,14 @@ var scanRepository = {
9346
9346
  return { status: "done", evidence: [".kaddo/scan.json"] };
9347
9347
  }
9348
9348
  };
9349
+ var bootstrapBaseline = {
9350
+ id: "bootstrap",
9351
+ label: "Bootstrap knowledge baseline",
9352
+ evaluate: (ctx) => {
9353
+ if (ctx.qBusiness !== "missing" && ctx.qProduct !== "missing") return { status: "done", evidence: ["knowledge/business/business.md", "knowledge/product/product.md"] };
9354
+ return { status: "pending", command: "kaddo bootstrap", reason: "The knowledge baseline is incomplete." };
9355
+ }
9356
+ };
9349
9357
  var defineBusiness = {
9350
9358
  id: "define-business",
9351
9359
  label: "Define business context",
@@ -9542,6 +9550,7 @@ var NEW_STEPS = [
9542
9550
  var PRE_AI_STEPS = [
9543
9551
  enableKaddo,
9544
9552
  scanRepository,
9553
+ bootstrapBaseline,
9545
9554
  defineBusiness,
9546
9555
  defineProduct,
9547
9556
  discoverCapabilities,
@@ -9559,6 +9568,7 @@ var PRE_AI_STEPS = [
9559
9568
  var LEGACY_STEPS = [
9560
9569
  enableKaddo,
9561
9570
  scanRepository,
9571
+ bootstrapBaseline,
9562
9572
  identifyLegacyModules,
9563
9573
  { ...discoverCapabilities, label: "Discover critical capabilities" },
9564
9574
  describeArchitecture,
@@ -9650,7 +9660,7 @@ function loadScanWarnings(dir) {
9650
9660
  function mapNextStepId(id) {
9651
9661
  const MAP = {
9652
9662
  init: "enable-kaddo",
9653
- bootstrap: "define-business",
9663
+ bootstrap: "bootstrap",
9654
9664
  "add-agents": "enable-kaddo",
9655
9665
  "add-skills": "enable-kaddo",
9656
9666
  scan: "scan-repository",
@@ -9819,6 +9829,15 @@ function hasAgents(dir) {
9819
9829
  }
9820
9830
  return hasAgentMd(agentsDir);
9821
9831
  }
9832
+ function hasSkills(dir) {
9833
+ const skillsDir = join(dir, ARCH_DIR4, "skills");
9834
+ if (!exists(skillsDir)) return false;
9835
+ try {
9836
+ return readDir(skillsDir).some((e) => e.endsWith(".md") && isFile(join(skillsDir, e)));
9837
+ } catch {
9838
+ return false;
9839
+ }
9840
+ }
9822
9841
  function buildProjectExplanation(dir) {
9823
9842
  const config = loadConfig(dir);
9824
9843
  const project = {
@@ -9845,10 +9864,13 @@ function buildProjectExplanation(dir) {
9845
9864
  hasInventory: exists(join(dir, ARCH_DIR4, "inventory.md")),
9846
9865
  hasContextPack: exists(join(dir, ".kaddo", "context-pack.md")),
9847
9866
  hasUnderstand: exists(join(dir, ".kaddo", "understand.md")),
9867
+ hasBusiness: exists(join(dir, "knowledge/business/business.md")),
9868
+ hasProduct: exists(join(dir, "knowledge/product/product.md")),
9848
9869
  hasCapabilities: layerStatus("Product") !== "Missing",
9849
9870
  hasArchitecture: layerStatus("Tech") !== "Missing",
9850
9871
  hasRoadmap: layerStatus("Delivery") !== "Missing",
9851
- hasAgents: hasAgents(dir)
9872
+ hasAgents: hasAgents(dir),
9873
+ hasSkills: hasSkills(dir)
9852
9874
  };
9853
9875
  const workItemArtifacts = discoverWorkItems(dir);
9854
9876
  const items = workItemArtifacts.map((a) => {
@@ -9913,33 +9935,42 @@ function buildProjectExplanation(dir) {
9913
9935
  if (!knowledge.hasAgents) missingKnowledge.push("Agents (knowledge/agents/)");
9914
9936
  if (items.length === 0) missingKnowledge.push("Work items (knowledge/delivery/work-items/)");
9915
9937
  const suggestedNextSteps = [];
9916
- if (!knowledge.hasScan) {
9917
- suggestedNextSteps.push("Run `kaddo scan` to detect the technical stack.");
9918
- } else if (!knowledge.hasContextPack) {
9919
- suggestedNextSteps.push("Run `kaddo context` to prepare an LLM context pack.");
9920
- }
9921
- if (!knowledge.hasAgents) {
9922
- suggestedNextSteps.push("Run `kaddo add agents` to install knowledge agents.");
9923
- }
9924
- if (!knowledge.hasCapabilities) {
9925
- suggestedNextSteps.push("Use capability-agent to generate knowledge/product/capabilities.md.");
9926
- }
9927
- if (!knowledge.hasArchitecture) {
9928
- suggestedNextSteps.push("Use architecture-agent to generate knowledge/tech/current-state.md.");
9929
- }
9930
- if (!knowledge.hasRoadmap) {
9931
- suggestedNextSteps.push("Use roadmap-agent to generate knowledge/delivery/roadmap.md.");
9932
- } else if (roadmap.remaining > 0) {
9933
- suggestedNextSteps.push(
9934
- `Materialize ${roadmap.remaining} roadmap candidate(s) with \`kaddo create --from roadmap\`.`
9935
- );
9936
- }
9937
- if (items.length === 0 && !roadmap.present) {
9938
- suggestedNextSteps.push("Create your first Work Item with `kaddo create`.");
9939
- } else if (ownership.workItemsMissingOwnership > 0) {
9940
- suggestedNextSteps.push(
9941
- "Run `kaddo owners suggest` for Work Items without code ownership."
9942
- );
9938
+ const baselineIncomplete = !knowledge.hasBusiness || !knowledge.hasProduct;
9939
+ if (baselineIncomplete) {
9940
+ suggestedNextSteps.push("Run `kaddo bootstrap` to create the project knowledge baseline.");
9941
+ if (!knowledge.hasAgents) suggestedNextSteps.push("Then run `kaddo add agents`.");
9942
+ if (!knowledge.hasSkills) suggestedNextSteps.push("Then run `kaddo add skills`.");
9943
+ suggestedNextSteps.push("Then run `kaddo context`.");
9944
+ suggestedNextSteps.push("Then run `kaddo understand`.");
9945
+ } else {
9946
+ if (!knowledge.hasScan) {
9947
+ suggestedNextSteps.push("Run `kaddo scan` to detect the technical stack.");
9948
+ } else if (!knowledge.hasContextPack) {
9949
+ suggestedNextSteps.push("Run `kaddo context` to prepare an LLM context pack.");
9950
+ }
9951
+ if (!knowledge.hasAgents) {
9952
+ suggestedNextSteps.push("Run `kaddo add agents` to install knowledge agents.");
9953
+ }
9954
+ if (!knowledge.hasCapabilities) {
9955
+ suggestedNextSteps.push("Use capability-agent to generate knowledge/product/capabilities.md.");
9956
+ }
9957
+ if (!knowledge.hasArchitecture) {
9958
+ suggestedNextSteps.push("Use architecture-agent to generate knowledge/tech/current-state.md.");
9959
+ }
9960
+ if (!knowledge.hasRoadmap) {
9961
+ suggestedNextSteps.push("Use roadmap-agent to generate knowledge/delivery/roadmap.md.");
9962
+ } else if (roadmap.remaining > 0) {
9963
+ suggestedNextSteps.push(
9964
+ `Materialize ${roadmap.remaining} roadmap candidate(s) with \`kaddo create --from roadmap\`.`
9965
+ );
9966
+ }
9967
+ if (items.length === 0 && !roadmap.present) {
9968
+ suggestedNextSteps.push("Create your first Work Item with `kaddo create`.");
9969
+ } else if (ownership.workItemsMissingOwnership > 0) {
9970
+ suggestedNextSteps.push(
9971
+ "Run `kaddo owners suggest` for Work Items without code ownership."
9972
+ );
9973
+ }
9943
9974
  }
9944
9975
  const readiness = buildReadinessReport(dir);
9945
9976
  return {
@@ -10653,10 +10684,14 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
10653
10684
  if (techKnowledge.discovery.legacyLocation) {
10654
10685
  missing.push("Tech discovery files are in the legacy `knowledge/tech/` root. Run `kaddo tech organize` to move them to `knowledge/tech/discovery/`.");
10655
10686
  }
10687
+ const isBootstrap = nextStepRecommendation.id === "bootstrap";
10656
10688
  const unifiedPhase = {
10657
10689
  ...phase,
10690
+ phase: isBootstrap ? "Setup" : phase.phase,
10691
+ reasons: isBootstrap ? ["The knowledge baseline is incomplete."] : phase.reasons,
10658
10692
  nextStep: nextStepRecommendation.label,
10659
- recommendedAgents: nextStepRecommendation.agent ? [nextStepRecommendation.agent] : phase.recommendedAgents
10693
+ recommendedAgents: isBootstrap ? [] : nextStepRecommendation.agent ? [nextStepRecommendation.agent] : phase.recommendedAgents,
10694
+ llmInstructions: isBootstrap ? ["Run `kaddo bootstrap` before using agent handoff.", "Do not ask an LLM to generate baseline knowledge until bootstrap files exist."] : phase.llmInstructions
10660
10695
  };
10661
10696
  const deliveryState = { ...buildDeliveryState(dir), phase: nextStepRecommendation.phase };
10662
10697
  return {
@@ -10712,9 +10747,9 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
10712
10747
  // VS-052/VS-073.2: the handoff is driven by the unified next step, so the pack never contradicts
10713
10748
  // the Current Phase block above it.
10714
10749
  handoff: {
10715
- recommendedAgents: unifiedPhase.recommendedAgents.length > 0 ? unifiedPhase.recommendedAgents : recommendedAgentsForState(state),
10750
+ recommendedAgents: isBootstrap ? [] : unifiedPhase.recommendedAgents.length > 0 ? unifiedPhase.recommendedAgents : recommendedAgentsForState(state),
10716
10751
  nextSteps: [nextStepRecommendation.label],
10717
- instructions: unifiedPhase.llmInstructions.length > 0 ? unifiedPhase.llmInstructions : LLM_INSTRUCTIONS,
10752
+ instructions: isBootstrap ? ["No agent handoff yet.", "Run `kaddo bootstrap` first to create the baseline files."] : unifiedPhase.llmInstructions.length > 0 ? unifiedPhase.llmInstructions : LLM_INSTRUCTIONS,
10718
10753
  operatingRules: OPERATING_RULES
10719
10754
  }
10720
10755
  };
@@ -10978,19 +11013,35 @@ function renderContextPack(pack) {
10978
11013
  parts.push(pack.skills.map((s) => `- ${s}`).join("\n") + "\n");
10979
11014
  parts.push("Read full skill definitions in `knowledge/skills/` or via the Kaddo MCP server (`kaddo://skills`).\n");
10980
11015
  }
11016
+ const isBootstrapIncomplete = rec.id === "bootstrap";
10981
11017
  parts.push("## Missing Context\n");
10982
- if (missing.length > 0) {
11018
+ if (isBootstrapIncomplete) {
11019
+ const baselineMissing = [
11020
+ "- Bootstrap baseline is incomplete.",
11021
+ ...!pack.knowledgeQuality.business || pack.knowledgeQuality.business.status === "Missing" ? ["- Missing business knowledge."] : [],
11022
+ ...!pack.knowledgeQuality.product || pack.knowledgeQuality.product.status === "Missing" ? ["- Missing product knowledge."] : []
11023
+ ];
11024
+ if (missing.length > 0) {
11025
+ baselineMissing.push(...missing.filter((m) => !baselineMissing.some((b) => b.includes(m))));
11026
+ }
11027
+ parts.push(baselineMissing.join("\n") + "\n");
11028
+ } else if (missing.length > 0) {
10983
11029
  parts.push(missing.map((m) => `- ${m}`).join("\n") + "\n");
10984
11030
  } else {
10985
11031
  parts.push("_None \u2014 all expected context is present._\n");
10986
11032
  }
10987
11033
  parts.push("## Recommended Agent Handoff\n");
10988
- parts.push(`Recommended next for the **${pack.phase.phase}** phase:
11034
+ if (isBootstrapIncomplete) {
11035
+ parts.push("No agent handoff yet.\n");
11036
+ parts.push("Run `kaddo bootstrap` first to create the baseline files.\n");
11037
+ } else {
11038
+ parts.push(`Recommended next for the **${pack.phase.phase}** phase:
10989
11039
  `);
10990
- parts.push(handoff.recommendedAgents.map((a, i) => `${i + 1}. ${a}`).join("\n") + "\n");
10991
- if (handoff.nextSteps.length > 0) {
10992
- parts.push("Next step:\n");
10993
- parts.push(handoff.nextSteps.map((s) => `- ${s}`).join("\n") + "\n");
11040
+ parts.push(handoff.recommendedAgents.map((a, i) => `${i + 1}. ${a}`).join("\n") + "\n");
11041
+ if (handoff.nextSteps.length > 0) {
11042
+ parts.push("Next step:\n");
11043
+ parts.push(handoff.nextSteps.map((s) => `- ${s}`).join("\n") + "\n");
11044
+ }
10994
11045
  }
10995
11046
  parts.push("## Instructions for the LLM\n");
10996
11047
  parts.push(handoff.instructions.map((i) => `- ${i}`).join("\n") + "\n");
@@ -11155,7 +11206,12 @@ function renderUnderstand(plan) {
11155
11206
  parts.push("## Project Route\n");
11156
11207
  parts.push(renderRouteCompact(plan.projectRoute));
11157
11208
  }
11158
- if (steps.length > 0) {
11209
+ const isBootstrap = rec && rec.id === "bootstrap";
11210
+ if (isBootstrap) {
11211
+ parts.push("## Agent Handoff\n");
11212
+ parts.push("Agent handoff is not ready yet.\n");
11213
+ parts.push("Run `kaddo bootstrap` first.\n");
11214
+ } else if (steps.length > 0) {
11159
11215
  parts.push("## Recommended Agent Flow\n");
11160
11216
  parts.push(`Recommended order for a ${stateLabel2(project.state)} project:
11161
11217
  `);
@@ -11207,75 +11263,87 @@ function renderUnderstand(plan) {
11207
11263
  const scanNote = plan.scanAvailable ? "" : " (incomplete \u2014 run `kaddo scan` first for a richer baseline)";
11208
11264
  parts.push(`Use \`${plan.contextPackPath}\` as the primary input${scanNote}.
11209
11265
  `);
11210
- const agentPaths = [];
11211
- if (plan.recommendedPaths && plan.recommendedPaths.length > 0) {
11212
- agentPaths.push(...plan.recommendedPaths);
11213
- } else if (steps.length > 0) {
11214
- agentPaths.push(...steps.map((s) => agentInstallPath(s.agent)));
11215
- }
11216
- if (plan.recommendedSkillPaths && plan.recommendedSkillPaths.length > 0) {
11217
- agentPaths.push(...plan.recommendedSkillPaths);
11218
- }
11219
- agentPaths.push(plan.contextPackPath);
11220
- parts.push("## Agent Prompts\n");
11221
- if (agentPaths.length > 1) {
11222
- parts.push("Use:\n");
11223
- parts.push(agentPaths.map((p2) => `- \`${p2}\``).join("\n") + "\n");
11224
- } else {
11225
- parts.push(`- \`${plan.contextPackPath}\`
11266
+ if (!isBootstrap) {
11267
+ const agentPaths = [];
11268
+ if (plan.recommendedPaths && plan.recommendedPaths.length > 0) {
11269
+ agentPaths.push(...plan.recommendedPaths);
11270
+ } else if (steps.length > 0) {
11271
+ agentPaths.push(...steps.map((s) => agentInstallPath(s.agent)));
11272
+ }
11273
+ if (plan.recommendedSkillPaths && plan.recommendedSkillPaths.length > 0) {
11274
+ agentPaths.push(...plan.recommendedSkillPaths);
11275
+ }
11276
+ agentPaths.push(plan.contextPackPath);
11277
+ parts.push("## Agent Prompts\n");
11278
+ if (agentPaths.length > 1) {
11279
+ parts.push("Use:\n");
11280
+ parts.push(agentPaths.map((p2) => `- \`${p2}\``).join("\n") + "\n");
11281
+ } else {
11282
+ parts.push(`- \`${plan.contextPackPath}\`
11226
11283
  `);
11227
- }
11228
- if (steps.length > 0) {
11229
- parts.push("## Expected Outputs\n");
11230
- parts.push(steps.map((s) => `- \`${s.output}\``).join("\n") + "\n");
11231
- } else if (rec) {
11232
- parts.push("## Expected Outputs\n");
11233
- const outputs = [];
11234
- if (rec.target) outputs.push(`- \`${rec.target}\``);
11235
- if (rec.id === "refine-work-item" || rec.id === "resolve-blocker")
11236
- outputs.push("- Refined Work Item content.");
11237
- if (rec.id === "create-work-item")
11238
- outputs.push("- A new Work Item under `knowledge/delivery/work-items/`.");
11239
- if (rec.id === "implement")
11240
- outputs.push("- Implementation plan or code changes guided by the Work Item.");
11241
- if (rec.id === "guard")
11242
- outputs.push("- Updated knowledge artifacts reflecting recent code changes.");
11243
- if (rec.id === "install-adapter")
11244
- outputs.push("- An adapter configured and injected (`kaddo adapters list`).");
11245
- if (outputs.length > 0) {
11246
- parts.push("The LLM should produce:\n");
11247
- parts.push(outputs.join("\n") + "\n");
11284
+ }
11285
+ if (steps.length > 0) {
11286
+ parts.push("## Expected Outputs\n");
11287
+ parts.push(steps.map((s) => `- \`${s.output}\``).join("\n") + "\n");
11288
+ } else if (rec) {
11289
+ parts.push("## Expected Outputs\n");
11290
+ const outputs = [];
11291
+ if (rec.target) outputs.push(`- \`${rec.target}\``);
11292
+ if (rec.id === "refine-work-item" || rec.id === "resolve-blocker")
11293
+ outputs.push("- Refined Work Item content.");
11294
+ if (rec.id === "create-work-item")
11295
+ outputs.push("- A new Work Item under `knowledge/delivery/work-items/`.");
11296
+ if (rec.id === "implement")
11297
+ outputs.push("- Implementation plan or code changes guided by the Work Item.");
11298
+ if (rec.id === "guard")
11299
+ outputs.push("- Updated knowledge artifacts reflecting recent code changes.");
11300
+ if (rec.id === "install-adapter")
11301
+ outputs.push("- An adapter configured and injected (`kaddo adapters list`).");
11302
+ if (outputs.length > 0) {
11303
+ parts.push("The LLM should produce:\n");
11304
+ parts.push(outputs.join("\n") + "\n");
11305
+ } else {
11306
+ parts.push("_See the primary recommendation above._\n");
11307
+ }
11308
+ }
11309
+ parts.push("## Copy/Paste Instructions\n");
11310
+ if (steps.length > 0) {
11311
+ const first2 = steps[0];
11312
+ parts.push(
11313
+ [
11314
+ `Start with **${agentName(first2.agent)}**:`,
11315
+ "",
11316
+ "1. Open your preferred LLM chat (Claude, ChatGPT, Cursor, Copilot, Windsurf\u2026).",
11317
+ `2. Paste the context pack: \`${plan.contextPackPath}\``,
11318
+ `3. Paste the agent prompt: \`${agentInstallPath(first2.agent)}\``,
11319
+ `4. Ask the LLM to produce: \`${first2.output}\``,
11320
+ `5. Save the result in: \`${first2.output}\``
11321
+ ].join("\n") + "\n"
11322
+ );
11323
+ } else if (agentPaths.length > 1) {
11324
+ parts.push("Paste the following into your LLM chat:\n");
11325
+ parts.push(agentPaths.map((p2, i) => `${i + 1}. \`${p2}\``).join("\n") + "\n");
11326
+ if (rec?.agent) {
11327
+ parts.push(`Ask the LLM to follow the ${agentName(rec.agent)} instructions.
11328
+ `);
11329
+ }
11248
11330
  } else {
11249
- parts.push("_See the primary recommendation above._\n");
11331
+ parts.push(`Paste \`${plan.contextPackPath}\` into your LLM chat.
11332
+ `);
11250
11333
  }
11251
11334
  }
11252
- parts.push("## Copy/Paste Instructions\n");
11253
- if (steps.length > 0) {
11254
- const first2 = steps[0];
11335
+ parts.push("## Next Steps\n");
11336
+ if (isBootstrap) {
11255
11337
  parts.push(
11256
11338
  [
11257
- `Start with **${agentName(first2.agent)}**:`,
11258
- "",
11259
- "1. Open your preferred LLM chat (Claude, ChatGPT, Cursor, Copilot, Windsurf\u2026).",
11260
- `2. Paste the context pack: \`${plan.contextPackPath}\``,
11261
- `3. Paste the agent prompt: \`${agentInstallPath(first2.agent)}\``,
11262
- `4. Ask the LLM to produce: \`${first2.output}\``,
11263
- `5. Save the result in: \`${first2.output}\``
11339
+ "1. Run `kaddo bootstrap`.",
11340
+ "2. Run `kaddo add agents`.",
11341
+ "3. Run `kaddo add skills`.",
11342
+ "4. Run `kaddo context`.",
11343
+ "5. Run `kaddo understand`."
11264
11344
  ].join("\n") + "\n"
11265
11345
  );
11266
- } else if (agentPaths.length > 1) {
11267
- parts.push("Paste the following into your LLM chat:\n");
11268
- parts.push(agentPaths.map((p2, i) => `${i + 1}. \`${p2}\``).join("\n") + "\n");
11269
- if (rec?.agent) {
11270
- parts.push(`Ask the LLM to follow the ${agentName(rec.agent)} instructions.
11271
- `);
11272
- }
11273
- } else {
11274
- parts.push(`Paste \`${plan.contextPackPath}\` into your LLM chat.
11275
- `);
11276
- }
11277
- parts.push("## Next Steps\n");
11278
- if (rec) {
11346
+ } else if (rec) {
11279
11347
  const nextLines = [];
11280
11348
  nextLines.push(`1. ${rec.label}`);
11281
11349
  let n = 2;
@@ -11308,25 +11376,41 @@ function renderUnderstandTerminal(plan) {
11308
11376
  lines.push(`Team: ${project.teamSize}`);
11309
11377
  lines.push(`Structure: ${project.structure}`);
11310
11378
  lines.push("");
11311
- const first2 = steps[0];
11312
- if (first2) {
11313
- lines.push("Foundational knowledge still needed:");
11314
- steps.forEach((s, i) => {
11315
- const flag = s.installed ? "" : " (not installed)";
11316
- lines.push(` ${i + 1}. ${agentName(s.agent)} \u2192 ${s.output}${flag}`);
11317
- });
11318
- lines.push("");
11319
- lines.push(`First step: use ${agentName(first2.agent)}.`);
11379
+ const rec = plan.nextStepRecommendation;
11380
+ const isBootstrapIncomplete = rec && rec.id === "bootstrap";
11381
+ if (isBootstrapIncomplete) {
11382
+ lines.push("Current phase: Setup");
11383
+ lines.push("Next step: Run `kaddo bootstrap` to create the project knowledge baseline.");
11384
+ lines.push("Reason: The knowledge baseline is incomplete.");
11320
11385
  lines.push("");
11321
- lines.push(` Context: ${plan.contextPackPath}`);
11322
- lines.push(` Agent prompt: ${agentInstallPath(first2.agent)}`);
11323
- lines.push(` Expected output: ${first2.output}`);
11386
+ lines.push("Agent handoff is not ready yet.");
11324
11387
  lines.push("");
11325
- lines.push("Instructions:");
11326
- lines.push(" Open your preferred LLM chat, paste the context pack, then paste the agent");
11327
- lines.push(" prompt. Ask the LLM to generate the expected output and save it in the target file.");
11388
+ lines.push("Run `kaddo bootstrap` first. Then run:");
11389
+ lines.push(" 1. kaddo add agents");
11390
+ lines.push(" 2. kaddo add skills");
11391
+ lines.push(" 3. kaddo context");
11392
+ lines.push(" 4. kaddo understand");
11328
11393
  } else {
11329
- lines.push("Foundational knowledge looks complete \u2014 see the phase recommendation below.");
11394
+ const first2 = steps[0];
11395
+ if (first2) {
11396
+ lines.push("Foundational knowledge still needed:");
11397
+ steps.forEach((s, i) => {
11398
+ const flag = s.installed ? "" : " (not installed)";
11399
+ lines.push(` ${i + 1}. ${agentName(s.agent)} \u2192 ${s.output}${flag}`);
11400
+ });
11401
+ lines.push("");
11402
+ lines.push(`First step: use ${agentName(first2.agent)}.`);
11403
+ lines.push("");
11404
+ lines.push(` Context: ${plan.contextPackPath}`);
11405
+ lines.push(` Agent prompt: ${agentInstallPath(first2.agent)}`);
11406
+ lines.push(` Expected output: ${first2.output}`);
11407
+ lines.push("");
11408
+ lines.push("Instructions:");
11409
+ lines.push(" Open your preferred LLM chat, paste the context pack, then paste the agent");
11410
+ lines.push(" prompt. Ask the LLM to generate the expected output and save it in the target file.");
11411
+ } else {
11412
+ lines.push("Foundational knowledge looks complete \u2014 see the phase recommendation below.");
11413
+ }
11330
11414
  }
11331
11415
  lines.push("");
11332
11416
  lines.push("Kaddo does not call an LLM. You stay in control of the interpretation.");
@@ -11420,73 +11504,77 @@ function runUnderstand() {
11420
11504
  writeFile(join(dir, ".kaddo", "context-pack.md"), renderContextPack(pack));
11421
11505
  log2.success("Refreshed .kaddo/context-pack.md");
11422
11506
  const plan = buildUnderstandPlan(dir, config);
11423
- if (plan.missingAgents.length > 0) {
11507
+ const earlyRec = resolveNextStep(dir);
11508
+ if (earlyRec.id !== "bootstrap" && plan.missingAgents.length > 0) {
11424
11509
  log2.warn(
11425
11510
  `Agents are not installed (${plan.missingAgents.map((a) => a.replace(/\.md$/, "")).join(", ")}). Run \`kaddo add agents\`.`
11426
11511
  );
11427
11512
  }
11513
+ plan.nextStepRecommendation = earlyRec;
11428
11514
  console.log(renderUnderstandTerminal(plan));
11429
11515
  console.log(`Project language: ${pack.project.language} (knowledge artifacts are written in this language)`);
11430
11516
  const exp = buildProjectExplanation(dir);
11431
11517
  const assessment = assessPhase(exp);
11432
11518
  const rec = exp.nextStepRecommendation;
11433
- console.log("");
11434
- console.log(`Current phase: ${assessment.phase}`);
11435
- if (assessment.reasons.length > 0) {
11436
- console.log("Reason:");
11437
- for (const r of assessment.reasons) console.log(` - ${r}`);
11438
- }
11439
- if (rec.agent) console.log(`Recommended: ${rec.agent}`);
11440
- if (rec.skill) console.log(`Recommended skill: ${rec.skill}`);
11441
- console.log(`Next step: ${rec.label}`);
11442
- if (rec.reason) console.log(`Why: ${rec.reason}`);
11443
- if (rec.secondary && rec.secondary.length > 0) {
11444
- console.log("Also:");
11445
- for (const s of rec.secondary) console.log(` - ${s.label}`);
11446
- }
11447
- const installedSkills = discoverInstalledSkills(dir);
11448
- if (installedSkills.length > 0 && assessment.recommendedAgents.length > 0) {
11449
- const recSkills = skillsForAgents(installedSkills, assessment.recommendedAgents);
11450
- if (recSkills.length > 0) {
11451
- console.log("Recommended skills:");
11452
- for (const s of recSkills) console.log(` - ${s}`);
11453
- }
11454
- }
11455
- const td = exp.techDecisions;
11456
- if (td.candidates > 0 && td.adrs === 0) {
11457
- console.log("");
11458
- console.log(`Tech decisions: ${td.candidates} decision candidate(s) not yet materialized as ADRs.`);
11459
- console.log(" \u2192 Use the adr-writing skill to create ADR drafts from `knowledge/tech/decision-candidates.md`");
11460
- console.log(" into `knowledge/tech/decisions/` before implementing affected technical Work Items (`kaddo adr`).");
11461
- }
11462
- const rqi = exp.roadmapQuality.initiatives;
11463
- if (rqi.needs_refinement) {
11464
- console.log("");
11465
- console.log(`Roadmap quality: ${rqi.grounded}/${rqi.total} initiatives grounded.`);
11466
- console.log(" \u2192 Use roadmap-agent to ground roadmap initiatives in capability domains, gaps and source signals");
11467
- console.log(" before `kaddo create --from roadmap`.");
11468
- } else if (rqi.total > 0 && rqi.grounded === rqi.total && exp.roadmap.materialized_work_items === 0) {
11519
+ if (earlyRec.id !== "bootstrap") {
11469
11520
  console.log("");
11470
- console.log("Roadmap initiatives are grounded. \u2192 Run `kaddo create --from roadmap` to materialize the first Work Item.");
11471
- }
11472
- const ia = exp.installedAssets;
11473
- const outdatedRecommended = ia.agents.items.filter(
11474
- (a) => (a.state === "outdated" || a.state === "unknown-version") && assessment.recommendedAgents.includes(a.name)
11475
- );
11476
- if (outdatedRecommended.length > 0) {
11477
- console.log("");
11478
- for (const a of outdatedRecommended) {
11479
- console.log(`Recommended agent ${a.name} is ${a.state} (installed ${a.installed ?? "unknown"}, available ${a.available}).`);
11521
+ console.log(`Current phase: ${assessment.phase}`);
11522
+ if (assessment.reasons.length > 0) {
11523
+ console.log("Reason:");
11524
+ for (const r of assessment.reasons) console.log(` - ${r}`);
11525
+ }
11526
+ if (rec.agent) console.log(`Recommended: ${rec.agent}`);
11527
+ if (rec.skill) console.log(`Recommended skill: ${rec.skill}`);
11528
+ console.log(`Next step: ${rec.label}`);
11529
+ if (rec.reason) console.log(`Why: ${rec.reason}`);
11530
+ if (rec.secondary && rec.secondary.length > 0) {
11531
+ console.log("Also:");
11532
+ for (const s of rec.secondary) console.log(` - ${s.label}`);
11533
+ }
11534
+ const installedSkills = discoverInstalledSkills(dir);
11535
+ if (installedSkills.length > 0 && assessment.recommendedAgents.length > 0) {
11536
+ const recSkills = skillsForAgents(installedSkills, assessment.recommendedAgents);
11537
+ if (recSkills.length > 0) {
11538
+ console.log("Recommended skills:");
11539
+ for (const s of recSkills) console.log(` - ${s}`);
11540
+ }
11480
11541
  }
11481
- console.log(" \u2192 Run `kaddo agents update` or review `kaddo agents status`.");
11482
- }
11483
- if (exp.externalCapsules.length > 0) {
11484
- console.log("");
11485
- console.log("External knowledge:");
11486
- for (const cap of exp.externalCapsules) {
11487
- console.log(` - ${cap.system}${cap.owner ? ` (owner: ${cap.owner})` : ""}`);
11542
+ const td = exp.techDecisions;
11543
+ if (td.candidates > 0 && td.adrs === 0) {
11544
+ console.log("");
11545
+ console.log(`Tech decisions: ${td.candidates} decision candidate(s) not yet materialized as ADRs.`);
11546
+ console.log(" \u2192 Use the adr-writing skill to create ADR drafts from `knowledge/tech/decision-candidates.md`");
11547
+ console.log(" into `knowledge/tech/decisions/` before implementing affected technical Work Items (`kaddo adr`).");
11548
+ }
11549
+ const rqi = exp.roadmapQuality.initiatives;
11550
+ if (rqi.needs_refinement) {
11551
+ console.log("");
11552
+ console.log(`Roadmap quality: ${rqi.grounded}/${rqi.total} initiatives grounded.`);
11553
+ console.log(" \u2192 Use roadmap-agent to ground roadmap initiatives in capability domains, gaps and source signals");
11554
+ console.log(" before `kaddo create --from roadmap`.");
11555
+ } else if (rqi.total > 0 && rqi.grounded === rqi.total && exp.roadmap.materialized_work_items === 0) {
11556
+ console.log("");
11557
+ console.log("Roadmap initiatives are grounded. \u2192 Run `kaddo create --from roadmap` to materialize the first Work Item.");
11558
+ }
11559
+ const ia = exp.installedAssets;
11560
+ const outdatedRecommended = ia.agents.items.filter(
11561
+ (a) => (a.state === "outdated" || a.state === "unknown-version") && assessment.recommendedAgents.includes(a.name)
11562
+ );
11563
+ if (outdatedRecommended.length > 0) {
11564
+ console.log("");
11565
+ for (const a of outdatedRecommended) {
11566
+ console.log(`Recommended agent ${a.name} is ${a.state} (installed ${a.installed ?? "unknown"}, available ${a.available}).`);
11567
+ }
11568
+ console.log(" \u2192 Run `kaddo agents update` or review `kaddo agents status`.");
11569
+ }
11570
+ if (exp.externalCapsules.length > 0) {
11571
+ console.log("");
11572
+ console.log("External knowledge:");
11573
+ for (const cap of exp.externalCapsules) {
11574
+ console.log(` - ${cap.system}${cap.owner ? ` (owner: ${cap.owner})` : ""}`);
11575
+ }
11576
+ console.log(" \u2192 Review the relevant capsule before changing integration behavior with it.");
11488
11577
  }
11489
- console.log(" \u2192 Review the relevant capsule before changing integration behavior with it.");
11490
11578
  }
11491
11579
  const graphHints = loadGraphHints(dir);
11492
11580
  if (assessment.phase === "Active Delivery" && graphHints && graphHints.activeWorkItemHints > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/cli",
3
- "version": "3.49.0",
3
+ "version": "3.51.0",
4
4
  "description": "Knowledge Driven Development toolkit",
5
5
  "license": "MIT",
6
6
  "repository": {