@kaddo/cli 3.3.0 → 3.5.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 (3) hide show
  1. package/README.md +2 -0
  2. package/dist/index.js +225 -74
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -435,6 +435,8 @@ create --from roadmap → owners → guard → explain`.
435
435
  | v3.1 | Minimum Sufficient Knowledge: bootstrap one consolidated file per layer; progressive `add agents` by group (state default, `--all`, `--group`) |
436
436
  | v3.2 | New-project flow hardening: agents in per-layer folders; `new` recommends capability+architecture agents; explain Work Item parser fix; intent vs reality (codebase vs current-state) |
437
437
  | v3.3 | Work Item delivery lifecycle: `understand` shows branch → scan → ownership → guard → knowledge → commit for active Work Items (suggestions only; Kaddo never runs git) |
438
+ | v3.4 | Delivery protocol in the `work-item-agent`: branch first per the Git strategy, commit only with human confirmation (CLI never touches git) |
439
+ | v3.5 | Knowledge discovery by front-matter type with per-layer maturity (explain/understand/context); context pack carries Operating Rules so agents never commit without confirmation |
438
440
 
439
441
  **Optional modules (installed with `kaddo add`):**
440
442
 
package/dist/index.js CHANGED
@@ -1950,6 +1950,24 @@ A refined Work Item intended to be saved as \`knowledge/delivery/work-items/*.md
1950
1950
 
1951
1951
  Save the output as a file under \`knowledge/delivery/work-items/\`.
1952
1952
 
1953
+ ## Delivery workflow
1954
+
1955
+ When this Work Item is **implemented** (by you or the coding agent), follow the project's
1956
+ delivery protocol. **Never run git mutating commands without the human's confirmation.**
1957
+
1958
+ 1. **Branch first.** Before changing any code, create a branch following the project's Git
1959
+ strategy (\`.kaddo/git.yml\` \u2192 \`branchNaming.pattern\`, default
1960
+ \`feature/<work-item-id>-<slug>\`; also \`bugfix/\`, \`hotfix/\`, \`spike/\`). This keeps work
1961
+ off the default branch so nothing lands on \`main\` by accident.
1962
+ 2. Implement the change.
1963
+ 3. Run \`kaddo scan\` after adding modules, migrations, contracts or significant structure.
1964
+ 4. Run \`kaddo owners suggest\` and confirm the \`code:\` globs.
1965
+ 5. Run \`kaddo guard\` before committing to detect possible knowledge drift.
1966
+ 6. Update the affected knowledge (ADR / capabilities.md / current-state.md).
1967
+ 7. **Commit only with explicit human confirmation.** Never commit, push or merge on your
1968
+ own \u2014 suggest a Conventional Commit message and wait for the human. The Kaddo CLI itself
1969
+ never touches git.
1970
+
1953
1971
  ## Quality Checklist
1954
1972
 
1955
1973
  - The problem is one clear sentence.
@@ -1957,6 +1975,7 @@ Save the output as a file under \`knowledge/delivery/work-items/\`.
1957
1975
  - Knowledge Level is justified.
1958
1976
  - Acceptance criteria are testable.
1959
1977
  - Open questions are explicit.
1978
+ - Delivery: branch first, commit only with human confirmation.
1960
1979
  `;
1961
1980
  var GIT_STRATEGY_AGENT = `# Git Strategy Agent
1962
1981
 
@@ -2573,6 +2592,14 @@ var agentReadme = {
2573
2592
  "",
2574
2593
  "**Kaddo does not execute these agents.** The CLI prepares context; the LLM interprets.",
2575
2594
  "",
2595
+ "## Operating rules (apply to every agent)",
2596
+ "",
2597
+ "- **Never run `git commit`, `git push` or `git merge` without explicit human confirmation.**",
2598
+ "- Never push or merge automatically. Suggest a Conventional Commit message and wait.",
2599
+ "- When implementing a Work Item, create a branch first (per the Git strategy in",
2600
+ " `.kaddo/git.yml`); never work directly on `main`.",
2601
+ "- The Kaddo CLI never calls an LLM and never runs git \u2014 every git action is the human\u2019s.",
2602
+ "",
2576
2603
  "## How to use",
2577
2604
  "",
2578
2605
  "1. Run `kaddo scan` then `kaddo context` to generate `.kaddo/context-pack.md`.",
@@ -4244,59 +4271,158 @@ function runIgnoreRemove(artifactId) {
4244
4271
  import matter2 from "gray-matter";
4245
4272
  import { parse as parseYaml8 } from "yaml";
4246
4273
 
4247
- // src/core/layers.ts
4274
+ // src/core/knowledge-discovery.ts
4248
4275
  var KNOWLEDGE = "knowledge";
4249
- var LAYER_SPEC = [
4250
- {
4251
- layer: "Business",
4252
- items: [
4253
- { name: "problem", path: `${KNOWLEDGE}/business/problem.md` },
4254
- { name: "users", path: `${KNOWLEDGE}/business/users.md` },
4255
- { name: "value-proposition", path: `${KNOWLEDGE}/business/value-proposition.md` },
4256
- { name: "constraints", path: `${KNOWLEDGE}/business/constraints.md` },
4257
- { name: "business-rules", path: `${KNOWLEDGE}/business/business-rules.md` }
4258
- ]
4259
- },
4260
- {
4261
- layer: "Product",
4262
- items: [
4263
- { name: "product brief", path: `${KNOWLEDGE}/product/product-brief.md` },
4264
- { name: "capabilities", path: `${KNOWLEDGE}/product/capabilities.md` }
4265
- ]
4266
- },
4267
- {
4268
- layer: "Tech",
4269
- items: [
4270
- { name: "codebase", path: `${KNOWLEDGE}/tech/codebase.md` },
4271
- { name: "current-state", path: `${KNOWLEDGE}/tech/current-state.md` },
4272
- { name: "decisions", path: `${KNOWLEDGE}/tech/decisions` }
4273
- ]
4274
- },
4275
- {
4276
- layer: "Delivery",
4277
- items: [
4278
- { name: "roadmap", path: `${KNOWLEDGE}/delivery/roadmap.md` },
4279
- { name: "work items", path: `${KNOWLEDGE}/delivery/work-items` }
4280
- ]
4276
+ var CONSOLIDATED_TYPE = {
4277
+ Business: "business",
4278
+ Product: "product",
4279
+ Tech: "codebase"
4280
+ };
4281
+ var STRUCTURED_TYPES = {
4282
+ Business: /* @__PURE__ */ new Set(["problem", "users", "value-proposition", "business-rules", "constraints", "glossary"]),
4283
+ Product: /* @__PURE__ */ new Set(["product-brief", "capabilities"]),
4284
+ Tech: /* @__PURE__ */ new Set([
4285
+ "current-state",
4286
+ "architecture-notes",
4287
+ "decision-candidates",
4288
+ "quality-attributes",
4289
+ "stack",
4290
+ "standards",
4291
+ "security",
4292
+ "git-strategy",
4293
+ "module-design",
4294
+ "adr",
4295
+ "decision"
4296
+ ]),
4297
+ Delivery: /* @__PURE__ */ new Set([])
4298
+ };
4299
+ var WORK_ITEM_TYPES = /* @__PURE__ */ new Set([
4300
+ "work-item",
4301
+ "feature",
4302
+ "bugfix",
4303
+ "hotfix",
4304
+ "spike"
4305
+ ]);
4306
+ function layerForType(type) {
4307
+ if (!type) return null;
4308
+ if (type === CONSOLIDATED_TYPE.Business || STRUCTURED_TYPES.Business.has(type)) return "Business";
4309
+ if (type === CONSOLIDATED_TYPE.Product || STRUCTURED_TYPES.Product.has(type)) return "Product";
4310
+ if (type === CONSOLIDATED_TYPE.Tech || STRUCTURED_TYPES.Tech.has(type) || type === "knowledge")
4311
+ return "Tech";
4312
+ if (type === "roadmap" || WORK_ITEM_TYPES.has(type)) return "Delivery";
4313
+ return null;
4314
+ }
4315
+ function layerFromPath(filePath) {
4316
+ const p2 = filePath.replace(/\\/g, "/");
4317
+ if (p2.includes(`/${KNOWLEDGE}/business/`)) return "Business";
4318
+ if (p2.includes(`/${KNOWLEDGE}/product/`)) return "Product";
4319
+ if (p2.includes(`/${KNOWLEDGE}/tech/`)) return "Tech";
4320
+ if (p2.includes(`/${KNOWLEDGE}/delivery/`)) return "Delivery";
4321
+ return null;
4322
+ }
4323
+ function basename(p2) {
4324
+ return p2.replace(/\\/g, "/").split("/").pop() ?? p2;
4325
+ }
4326
+ function discoverLayers(dir) {
4327
+ const acc = {
4328
+ Business: blank(),
4329
+ Product: blank(),
4330
+ Tech: blank(),
4331
+ Delivery: blank()
4332
+ };
4333
+ const archDir = join(dir, KNOWLEDGE);
4334
+ const artifacts = exists(archDir) ? readArtifacts(archDir) : [];
4335
+ for (const a of artifacts) {
4336
+ const type = a.type;
4337
+ const layer = layerForType(type) ?? layerFromPath(a.filePath);
4338
+ if (!layer) continue;
4339
+ const slot = acc[layer];
4340
+ slot.detected.add(basename(a.filePath));
4341
+ if (layer === "Delivery") {
4342
+ if (type === "roadmap" || basename(a.filePath) === "roadmap.md") slot.hasRoadmap = true;
4343
+ if (WORK_ITEM_TYPES.has(type) || a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/")) {
4344
+ if (a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/")) slot.hasWorkItem = true;
4345
+ }
4346
+ continue;
4347
+ }
4348
+ if (type === CONSOLIDATED_TYPE[layer]) slot.consolidated = true;
4349
+ else if (STRUCTURED_TYPES[layer].has(type)) slot.structured = true;
4350
+ else if (!type) {
4351
+ slot.consolidated = true;
4352
+ }
4353
+ if (type === "adr" || type === "decision") slot.hasDecision = true;
4281
4354
  }
4282
- ];
4283
- function knowledgeLayers(dir) {
4284
- return LAYER_SPEC.map(({ layer, items }) => ({
4355
+ if (existsDirWithMd(join(dir, KNOWLEDGE, "tech", "decisions"))) acc.Tech.structured = true;
4356
+ return ["Business", "Product", "Tech", "Delivery"].map((layer) => ({
4285
4357
  layer,
4286
- items: items.map((it) => ({ name: it.name, present: exists(join(dir, it.path)) }))
4358
+ status: statusFor(layer, acc[layer]),
4359
+ detected: [...acc[layer].detected].sort()
4287
4360
  }));
4288
4361
  }
4362
+ function blank() {
4363
+ return {
4364
+ consolidated: false,
4365
+ structured: false,
4366
+ hasRoadmap: false,
4367
+ hasWorkItem: false,
4368
+ hasDecision: false,
4369
+ detected: /* @__PURE__ */ new Set()
4370
+ };
4371
+ }
4372
+ function existsDirWithMd(d) {
4373
+ if (!exists(d)) return false;
4374
+ try {
4375
+ return readDir(d).some((e) => e.endsWith(".md") && isFile(join(d, e)));
4376
+ } catch {
4377
+ return false;
4378
+ }
4379
+ }
4380
+ function statusFor(layer, a) {
4381
+ if (layer === "Delivery") {
4382
+ if (a.hasWorkItem) return "Traceable";
4383
+ if (a.hasRoadmap) return "Partial";
4384
+ return "Missing";
4385
+ }
4386
+ if (a.structured) return "Structured";
4387
+ if (a.consolidated) return "Consolidated";
4388
+ return "Missing";
4389
+ }
4390
+ function roadmapHasUnmaterializedCandidates(dir) {
4391
+ const roadmap = join(dir, KNOWLEDGE, "delivery", "roadmap.md");
4392
+ if (!exists(roadmap)) return false;
4393
+ let hasCandidates = false;
4394
+ try {
4395
+ hasCandidates = /WI-[A-Z0-9-]*\d/i.test(readFile(roadmap));
4396
+ } catch {
4397
+ return false;
4398
+ }
4399
+ if (!hasCandidates) return false;
4400
+ const wiDir = join(dir, KNOWLEDGE, "delivery", "work-items");
4401
+ return !existsDirWithMd(wiDir);
4402
+ }
4403
+
4404
+ // src/core/layers.ts
4405
+ function knowledgeLayers(dir) {
4406
+ return discoverLayers(dir);
4407
+ }
4408
+ var COMPLETE = {
4409
+ Business: (s) => s !== "Missing",
4410
+ Product: (s) => s !== "Missing",
4411
+ Tech: (s) => s !== "Missing",
4412
+ Delivery: (s) => s === "Traceable"
4413
+ };
4289
4414
  function currentPhase(layers) {
4290
- for (const { layer, items } of layers) {
4291
- if (items.some((i) => !i.present)) return layer;
4415
+ for (const l of layers) {
4416
+ if (!COMPLETE[l.layer](l.status)) return l.layer;
4292
4417
  }
4293
4418
  return "Delivery";
4294
4419
  }
4295
4420
  function renderLayersMarkdown(layers) {
4296
4421
  const lines = [];
4297
- for (const { layer, items } of layers) {
4298
- lines.push(`### ${layer}`);
4299
- for (const it of items) lines.push(`- ${it.present ? "\u2713" : "\u2717"} ${it.name}`);
4422
+ for (const { layer, status, detected } of layers) {
4423
+ lines.push(`### ${layer} \u2014 ${status}`);
4424
+ if (detected.length > 0) for (const d of detected) lines.push(`- \u2713 ${d}`);
4425
+ else lines.push("- \u2717 none");
4300
4426
  lines.push("");
4301
4427
  }
4302
4428
  return lines.join("\n").trimEnd();
@@ -4367,14 +4493,16 @@ function buildProjectExplanation(dir) {
4367
4493
  contractFiles: scan2.contractFiles,
4368
4494
  infrastructureFiles: scan2.infrastructureFiles
4369
4495
  } : null;
4496
+ const layers = knowledgeLayers(dir);
4497
+ const layerStatus = (name) => layers.find((l) => l.layer === name)?.status ?? "Missing";
4370
4498
  const knowledge = {
4371
4499
  hasScan: scan2 !== null,
4372
4500
  hasInventory: exists(join(dir, ARCH_DIR3, "inventory.md")),
4373
4501
  hasContextPack: exists(join(dir, ".kaddo", "context-pack.md")),
4374
4502
  hasUnderstand: exists(join(dir, ".kaddo", "understand.md")),
4375
- hasCapabilities: exists(join(dir, ARCH_DIR3, "product", "capabilities.md")),
4376
- hasArchitecture: exists(join(dir, ARCH_DIR3, "tech", "current-state.md")),
4377
- hasRoadmap: exists(join(dir, ARCH_DIR3, "delivery", "roadmap.md")),
4503
+ hasCapabilities: layerStatus("Product") !== "Missing",
4504
+ hasArchitecture: layerStatus("Tech") !== "Missing",
4505
+ hasRoadmap: layerStatus("Delivery") !== "Missing",
4378
4506
  hasAgents: hasAgents(dir)
4379
4507
  };
4380
4508
  const archDir = join(dir, ARCH_DIR3);
@@ -4410,10 +4538,8 @@ function buildProjectExplanation(dir) {
4410
4538
  if (!knowledge.hasScan) missingKnowledge.push("Scan baseline (.kaddo/scan.json)");
4411
4539
  if (!knowledge.hasContextPack) missingKnowledge.push("Context pack (.kaddo/context-pack.md)");
4412
4540
  if (!knowledge.hasInventory) missingKnowledge.push("Inventory (knowledge/inventory.md)");
4413
- if (!knowledge.hasCapabilities)
4414
- missingKnowledge.push("Capabilities (knowledge/product/capabilities.md)");
4415
- if (!knowledge.hasArchitecture)
4416
- missingKnowledge.push("Architecture baseline (knowledge/tech/current-state.md)");
4541
+ if (!knowledge.hasCapabilities) missingKnowledge.push("Product knowledge (knowledge/product/)");
4542
+ if (!knowledge.hasArchitecture) missingKnowledge.push("Tech knowledge (knowledge/tech/)");
4417
4543
  if (!knowledge.hasRoadmap) missingKnowledge.push("Roadmap (knowledge/delivery/roadmap.md)");
4418
4544
  if (!knowledge.hasAgents) missingKnowledge.push("Agents (knowledge/agents/)");
4419
4545
  if (items.length === 0) missingKnowledge.push("Work items (knowledge/delivery/work-items/)");
@@ -4449,7 +4575,7 @@ function buildProjectExplanation(dir) {
4449
4575
  workItems,
4450
4576
  ownership,
4451
4577
  domains,
4452
- layers: knowledgeLayers(dir),
4578
+ layers,
4453
4579
  mappedModules,
4454
4580
  missingKnowledge,
4455
4581
  suggestedNextSteps
@@ -4484,14 +4610,14 @@ function renderExplanationHuman(exp) {
4484
4610
  lines.push(`- Infrastructure: ${exp.stack.infrastructureFiles.join(", ")}`);
4485
4611
  lines.push("");
4486
4612
  }
4613
+ const ls = (name) => exp.layers.find((l) => l.layer === name)?.status ?? "Missing";
4487
4614
  lines.push("## Knowledge Status");
4488
4615
  lines.push(`- Inventory: ${exp.knowledge.hasInventory ? "available" : "missing"}`);
4489
4616
  lines.push(`- Context pack: ${exp.knowledge.hasContextPack ? "available" : "missing"}`);
4490
- lines.push(`- Capabilities: ${exp.knowledge.hasCapabilities ? "available" : "missing"}`);
4491
- lines.push(
4492
- `- Architecture baseline: ${exp.knowledge.hasArchitecture ? "available" : "missing"}`
4493
- );
4494
- lines.push(`- Roadmap: ${exp.knowledge.hasRoadmap ? "available" : "missing"}`);
4617
+ lines.push(`- Business: ${ls("Business")}`);
4618
+ lines.push(`- Product: ${ls("Product")}`);
4619
+ lines.push(`- Tech: ${ls("Tech")}`);
4620
+ lines.push(`- Delivery: ${ls("Delivery")}`);
4495
4621
  lines.push(`- Agents: ${exp.knowledge.hasAgents ? "available" : "missing"}`);
4496
4622
  lines.push(`- Work items: ${exp.workItems.total}`);
4497
4623
  lines.push(
@@ -4799,6 +4925,13 @@ var LLM_INSTRUCTIONS = [
4799
4925
  "First extract: system capabilities, architecture notes, risks, open questions and roadmap candidates.",
4800
4926
  "This pack is deterministic CLI output \u2014 it does not interpret the system. That is your job."
4801
4927
  ];
4928
+ var OPERATING_RULES = [
4929
+ "**Never run `git commit`, `git push` or `git merge` without explicit human confirmation.**",
4930
+ "Never push or merge automatically \u2014 ever. Suggest a Conventional Commit message and wait.",
4931
+ "When implementing a Work Item, create a branch FIRST (per the project Git strategy, `.kaddo/git.yml`, default `feature/<id>-<slug>`). Never work directly on `main`.",
4932
+ "After significant changes run `kaddo scan`, `kaddo owners suggest` and `kaddo guard`, and update the affected knowledge (ADR / capabilities / current-state).",
4933
+ "Kaddo itself never calls an LLM and never runs git \u2014 every git action is the human\u2019s."
4934
+ ];
4802
4935
  function toContextWorkItem(a) {
4803
4936
  return {
4804
4937
  id: a.id,
@@ -4874,7 +5007,8 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
4874
5007
  handoff: {
4875
5008
  recommendedAgents: recommendedAgentsForState(state),
4876
5009
  nextSteps: nextStepsForState2(state),
4877
- instructions: LLM_INSTRUCTIONS
5010
+ instructions: LLM_INSTRUCTIONS,
5011
+ operatingRules: OPERATING_RULES
4878
5012
  }
4879
5013
  };
4880
5014
  }
@@ -4893,6 +5027,8 @@ function renderContextPack(pack) {
4893
5027
  parts.push(
4894
5028
  "> Generated by `kaddo context`. Deterministic CLI output \u2014 not an interpretation of the system.\n"
4895
5029
  );
5030
+ parts.push("## Operating Rules (read first)\n");
5031
+ parts.push(handoff.operatingRules.map((r) => `- ${r}`).join("\n") + "\n");
4896
5032
  parts.push("## Project Metadata\n");
4897
5033
  parts.push(
4898
5034
  [
@@ -4906,6 +5042,9 @@ function renderContextPack(pack) {
4906
5042
  parts.push(
4907
5043
  "Project knowledge is organized in four layers: **Business \u2192 Product \u2192 Tech \u2192 Delivery**.\n"
4908
5044
  );
5045
+ const maturity = pack.layers.map((l) => `${l.layer}: ${l.status}`).join(" \xB7 ");
5046
+ parts.push(`Knowledge maturity \u2014 ${maturity}
5047
+ `);
4909
5048
  parts.push(renderLayersMarkdown(pack.layers) + "\n");
4910
5049
  parts.push("## Technical Inventory\n");
4911
5050
  if (scan2.available) {
@@ -5186,19 +5325,21 @@ function renderUnderstandTerminal(plan) {
5186
5325
  }
5187
5326
 
5188
5327
  // src/core/delivery.ts
5328
+ import { parse as parseYaml9 } from "yaml";
5189
5329
  function slugify2(s) {
5190
5330
  return s.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
5191
5331
  }
5192
5332
  function isWorkItem(a) {
5193
5333
  return a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/") && Boolean(a.type);
5194
5334
  }
5335
+ function toActive(a) {
5336
+ const id = a.id || a.title || "WI";
5337
+ return { id, title: a.title || id, type: a.type, slug: slugify2(a.title || id) };
5338
+ }
5195
5339
  function activeWorkItems(dir) {
5196
5340
  const archDir = join(dir, "knowledge");
5197
5341
  if (!exists(archDir)) return [];
5198
- return readArtifacts(archDir).filter((a) => isWorkItem(a) && a.status === "in-progress").map((a) => {
5199
- const id = a.id || a.title || "WI";
5200
- return { id, title: a.title || id, type: a.type, slug: slugify2(a.title || id) };
5201
- });
5342
+ return readArtifacts(archDir).filter((a) => isWorkItem(a) && a.status === "in-progress").map(toActive);
5202
5343
  }
5203
5344
  function branchPrefix(type) {
5204
5345
  switch (type) {
@@ -5233,15 +5374,15 @@ function renderDeliveryLifecycle(wi) {
5233
5374
  return [
5234
5375
  `Active work item: ${wi.id} \u2014 ${wi.title}`,
5235
5376
  "",
5236
- "Delivery lifecycle (Kaddo never runs git for you):",
5237
- ` 1. Create a branch e.g. ${suggestedBranch(wi)}`,
5377
+ "Delivery lifecycle (the building agent follows this; Kaddo CLI never touches git):",
5378
+ ` 1. Create a branch ${suggestedBranch(wi)} (per your Git strategy)`,
5238
5379
  " 2. Implement the work item",
5239
5380
  " 3. Run `kaddo scan` (after new modules/migrations/contracts)",
5240
5381
  " 4. Run `kaddo owners suggest` \u2192 confirm code: globs",
5241
5382
  " 5. Run `kaddo guard` before committing (detect knowledge drift)",
5242
5383
  " 6. Update knowledge ADR / capabilities.md / current-state.md as needed",
5243
5384
  " 7. Review (human)",
5244
- ` 8. Commit e.g. ${suggestedCommit(wi)}`
5385
+ ` 8. Commit only with human confirmation e.g. ${suggestedCommit(wi)}`
5245
5386
  ];
5246
5387
  }
5247
5388
 
@@ -5297,6 +5438,12 @@ function runUnderstand() {
5297
5438
  ],
5298
5439
  utilities: ["Use legacy-agent to surface risks and unknowns"]
5299
5440
  };
5441
+ if (roadmapHasUnmaterializedCandidates(dir)) {
5442
+ console.log("");
5443
+ console.log("The roadmap has Work Item candidates that are not materialized yet.");
5444
+ console.log(" \u2192 Run `kaddo create --from roadmap`, or use the work-item-agent to");
5445
+ console.log(" materialize them into knowledge/delivery/work-items/.");
5446
+ }
5300
5447
  console.log("");
5301
5448
  console.log(`Current phase: ${phase}`);
5302
5449
  console.log("Recommended next steps:");
@@ -5539,14 +5686,14 @@ async function runClassify(opts = {}) {
5539
5686
  }
5540
5687
 
5541
5688
  // src/commands/status.ts
5542
- import { parse as parseYaml9 } from "yaml";
5689
+ import { parse as parseYaml10 } from "yaml";
5543
5690
  var ARCH_DIR7 = "knowledge";
5544
5691
  var CONFIG_PATH4 = ".kaddo/config.yml";
5545
5692
  function loadConfig3(dir) {
5546
5693
  const p2 = join(dir, CONFIG_PATH4);
5547
5694
  if (!exists(p2)) return {};
5548
5695
  try {
5549
- return parseYaml9(readFile(p2));
5696
+ return parseYaml10(readFile(p2));
5550
5697
  } catch {
5551
5698
  return {};
5552
5699
  }
@@ -5748,13 +5895,13 @@ function runHistory(opts = {}) {
5748
5895
  }
5749
5896
 
5750
5897
  // src/commands/add.ts
5751
- import { parse as parseYaml10, stringify as stringifyYaml3 } from "yaml";
5898
+ import { parse as parseYaml11, stringify as stringifyYaml3 } from "yaml";
5752
5899
  var CONFIG_PATH5 = ".kaddo/config.yml";
5753
5900
  function readProjectState(dir) {
5754
5901
  const configPath = join(dir, CONFIG_PATH5);
5755
5902
  if (!exists(configPath)) return void 0;
5756
5903
  try {
5757
- const config = parseYaml10(readFile(configPath));
5904
+ const config = parseYaml11(readFile(configPath));
5758
5905
  return config.project?.state;
5759
5906
  } catch {
5760
5907
  return void 0;
@@ -5772,7 +5919,7 @@ function markModuleInstalled(dir, configKey, moduleName) {
5772
5919
  const configPath = join(dir, CONFIG_PATH5);
5773
5920
  if (!exists(configPath)) return;
5774
5921
  try {
5775
- const config = parseYaml10(readFile(configPath));
5922
+ const config = parseYaml11(readFile(configPath));
5776
5923
  config[configKey] = { installed: true, installed_at: (/* @__PURE__ */ new Date()).toISOString().split("T")[0] };
5777
5924
  const modules = config.modules ?? [];
5778
5925
  if (!modules.includes(moduleName)) modules.push(moduleName);
@@ -5785,7 +5932,7 @@ function isModuleInstalled(dir, configKey) {
5785
5932
  const configPath = join(dir, CONFIG_PATH5);
5786
5933
  if (!exists(configPath)) return false;
5787
5934
  try {
5788
- const config = parseYaml10(readFile(configPath));
5935
+ const config = parseYaml11(readFile(configPath));
5789
5936
  const moduleConfig = config[configKey];
5790
5937
  return moduleConfig?.installed === true;
5791
5938
  } catch {
@@ -6109,13 +6256,13 @@ ${globs.map((g) => ` - ${g}`).join("\n")}`);
6109
6256
  }
6110
6257
 
6111
6258
  // src/commands/module-descriptor.ts
6112
- import { parse as parseYaml11, stringify as stringifyYaml4 } from "yaml";
6259
+ import { parse as parseYaml12, stringify as stringifyYaml4 } from "yaml";
6113
6260
  var DESCRIPTOR_PATH2 = "knowledge/module.yml";
6114
6261
  function readDescriptor(dir) {
6115
6262
  const path5 = join(dir, DESCRIPTOR_PATH2);
6116
6263
  if (!exists(path5)) return null;
6117
6264
  try {
6118
- return parseYaml11(readFile(path5));
6265
+ return parseYaml12(readFile(path5));
6119
6266
  } catch {
6120
6267
  return null;
6121
6268
  }
@@ -6216,7 +6363,7 @@ function printDescriptor(d) {
6216
6363
  }
6217
6364
 
6218
6365
  // src/commands/modules-map.ts
6219
- import { parse as parseYaml12, stringify as stringifyYaml5 } from "yaml";
6366
+ import { parse as parseYaml13, stringify as stringifyYaml5 } from "yaml";
6220
6367
 
6221
6368
  // src/templates/registry.ts
6222
6369
  var QUALITY = "## Quality checklist";
@@ -7714,7 +7861,7 @@ function readModulesDescriptor(dir) {
7714
7861
  const path5 = join(dir, DESCRIPTOR_PATH3);
7715
7862
  if (!exists(path5)) return { version: 1, modules: [] };
7716
7863
  try {
7717
- const parsed = parseYaml12(readFile(path5));
7864
+ const parsed = parseYaml13(readFile(path5));
7718
7865
  return { version: parsed.version ?? 1, modules: parsed.modules ?? [] };
7719
7866
  } catch {
7720
7867
  return { version: 1, modules: [] };
@@ -7987,6 +8134,10 @@ async function runBootstrap(dir = cwd()) {
7987
8134
  for (const p2 of result.skipped) console.log(` - ${p2}`);
7988
8135
  }
7989
8136
  console.log("");
8137
+ console.log("");
8138
+ log2.info(
8139
+ "When you pass the context pack to your LLM/coding agent, it must never commit, push or merge without your confirmation \u2014 and create a branch before implementing."
8140
+ );
7990
8141
  outro2(
7991
8142
  "Minimal knowledge base ready (Business \u2192 Product \u2192 Tech). Run `kaddo context` and `kaddo add agents`, then refine with the business-agent, bootstrap-agent and codebase-agent. Roadmap and work items come next under knowledge/delivery/."
7992
8143
  );
@@ -7994,7 +8145,7 @@ async function runBootstrap(dir = cwd()) {
7994
8145
 
7995
8146
  // src/index.ts
7996
8147
  var program = new Command();
7997
- program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.3.0");
8148
+ program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.5.0");
7998
8149
  program.command("init").description("Initialize Kaddo in the current project").action(async () => {
7999
8150
  await runInit();
8000
8151
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/cli",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "description": "Knowledge Driven Development toolkit",
5
5
  "license": "MIT",
6
6
  "repository": {