@kaddo/cli 3.1.0 → 3.3.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 +188 -71
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -433,6 +433,8 @@ create --from roadmap → owners → guard → explain`.
433
433
  | v2.8 | `kaddo bootstrap` for new projects (Business → Product → Tech → Delivery); business templates + bootstrap agents |
434
434
  | v3.0 | Knowledge-centric realignment: `architecture/` → `knowledge/` with layers Business → Product → Tech → Delivery; context/explain by layer (breaking) |
435
435
  | v3.1 | Minimum Sufficient Knowledge: bootstrap one consolidated file per layer; progressive `add agents` by group (state default, `--all`, `--group`) |
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
+ | v3.3 | Work Item delivery lifecycle: `understand` shows branch → scan → ownership → guard → knowledge → commit for active Work Items (suggestions only; Kaddo never runs git) |
436
438
 
437
439
  **Optional modules (installed with `kaddo add`):**
438
440
 
package/dist/index.js CHANGED
@@ -2487,6 +2487,81 @@ var AGENT_PROMPTS = [
2487
2487
  { fileName: "codebase-agent.md", content: CODEBASE_FOUNDATION_AGENT }
2488
2488
  ];
2489
2489
 
2490
+ // src/agents/groups.ts
2491
+ var AGENT_GROUPS = {
2492
+ business: ["business-agent.md"],
2493
+ product: ["bootstrap-agent.md", "capability-agent.md"],
2494
+ tech: [
2495
+ "architecture-agent.md",
2496
+ "codebase-agent.md",
2497
+ "stack-agent.md",
2498
+ "security-agent.md",
2499
+ "standards-agent.md",
2500
+ "module-design-agent.md",
2501
+ "adr-agent.md"
2502
+ ],
2503
+ delivery: ["roadmap-agent.md", "work-item-agent.md", "git-strategy-agent.md"],
2504
+ utilities: ["legacy-agent.md"]
2505
+ };
2506
+ var AGENT_GROUP_NAMES = Object.keys(AGENT_GROUPS);
2507
+ function agentGroupOf(fileName) {
2508
+ for (const g of AGENT_GROUP_NAMES) {
2509
+ if (AGENT_GROUPS[g].includes(fileName)) return g;
2510
+ }
2511
+ return "utilities";
2512
+ }
2513
+ function agentInstallPath(fileName) {
2514
+ return `knowledge/agents/${agentGroupOf(fileName)}/${fileName}`;
2515
+ }
2516
+ var RECOMMENDED_BY_STATE = {
2517
+ new: [
2518
+ "business-agent.md",
2519
+ "bootstrap-agent.md",
2520
+ "capability-agent.md",
2521
+ "architecture-agent.md",
2522
+ "codebase-agent.md",
2523
+ "roadmap-agent.md",
2524
+ "work-item-agent.md",
2525
+ "adr-agent.md"
2526
+ ],
2527
+ "pre-ai": [
2528
+ "capability-agent.md",
2529
+ "architecture-agent.md",
2530
+ "roadmap-agent.md",
2531
+ "work-item-agent.md"
2532
+ ],
2533
+ legacy: [
2534
+ "legacy-agent.md",
2535
+ "architecture-agent.md",
2536
+ "capability-agent.md",
2537
+ "roadmap-agent.md",
2538
+ "work-item-agent.md"
2539
+ ]
2540
+ };
2541
+ function recommendedAgents(state) {
2542
+ return RECOMMENDED_BY_STATE[state ?? "pre-ai"] ?? RECOMMENDED_BY_STATE["pre-ai"];
2543
+ }
2544
+ function selectAgentFiles(opts) {
2545
+ if (opts.all) {
2546
+ const all = AGENT_GROUP_NAMES.flatMap((g) => AGENT_GROUPS[g]);
2547
+ return { files: all, label: "all agents" };
2548
+ }
2549
+ if (opts.group) {
2550
+ const group = opts.group;
2551
+ const files = AGENT_GROUPS[group];
2552
+ if (!files) {
2553
+ throw new Error(
2554
+ `Unknown agent group "${opts.group}". Valid groups: ${AGENT_GROUP_NAMES.join(", ")}.`
2555
+ );
2556
+ }
2557
+ return { files, label: `group: ${group}` };
2558
+ }
2559
+ return {
2560
+ files: recommendedAgents(opts.state),
2561
+ label: `recommended for state: ${opts.state ?? "pre-ai"}`
2562
+ };
2563
+ }
2564
+
2490
2565
  // src/modules/agents.ts
2491
2566
  var agentReadme = {
2492
2567
  path: "knowledge/agents/README.md",
@@ -2538,7 +2613,7 @@ var agentReadme = {
2538
2613
  ].join("\n")
2539
2614
  };
2540
2615
  var agentFiles = AGENT_PROMPTS.map((a) => ({
2541
- path: `knowledge/agents/${a.fileName}`,
2616
+ path: agentInstallPath(a.fileName),
2542
2617
  content: a.content
2543
2618
  }));
2544
2619
  var agentsModule = {
@@ -4261,7 +4336,18 @@ function loadScan(dir) {
4261
4336
  function hasAgents(dir) {
4262
4337
  const agentsDir = join(dir, ARCH_DIR3, "agents");
4263
4338
  if (!exists(agentsDir)) return false;
4264
- return readDir(agentsDir).some((e) => e.endsWith(".md") && isFile(join(agentsDir, e)));
4339
+ function hasAgentMd(d) {
4340
+ for (const e of readDir(d)) {
4341
+ const full = join(d, e);
4342
+ if (isFile(full)) {
4343
+ if (e.endsWith("-agent.md")) return true;
4344
+ } else if (hasAgentMd(full)) {
4345
+ return true;
4346
+ }
4347
+ }
4348
+ return false;
4349
+ }
4350
+ return hasAgentMd(agentsDir);
4265
4351
  }
4266
4352
  function buildProjectExplanation(dir) {
4267
4353
  const config = loadConfig(dir);
@@ -4293,9 +4379,10 @@ function buildProjectExplanation(dir) {
4293
4379
  };
4294
4380
  const archDir = join(dir, ARCH_DIR3);
4295
4381
  const allArtifacts = exists(archDir) ? readArtifacts(archDir) : [];
4296
- const workItemArtifacts = allArtifacts.filter(
4297
- (a) => a.type !== "current-state" && a.type !== "roadmap"
4298
- );
4382
+ const workItemArtifacts = allArtifacts.filter((a) => {
4383
+ const p2 = a.filePath.replace(/\\/g, "/");
4384
+ return p2.includes("/delivery/work-items/") && Boolean(a.type);
4385
+ });
4299
4386
  const items = workItemArtifacts.map((a) => ({
4300
4387
  id: a.id || a.title,
4301
4388
  title: a.title,
@@ -4525,7 +4612,7 @@ function explainForHuman(dir, artifacts, opts) {
4525
4612
  console.log("");
4526
4613
  }
4527
4614
  const workItems = artifacts.filter(
4528
- (a) => a.type !== "current-state" && a.type !== "roadmap" && a.status === "in-progress"
4615
+ (a) => a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/") && Boolean(a.type) && a.status === "in-progress"
4529
4616
  );
4530
4617
  if (workItems.length > 0) {
4531
4618
  console.log("## Active work items");
@@ -4945,6 +5032,9 @@ function runContext(opts = {}) {
4945
5032
  }
4946
5033
 
4947
5034
  // src/core/understand.ts
5035
+ function agentIsInstalled(dir, fileName) {
5036
+ return exists(join(dir, agentInstallPath(fileName))) || exists(join(dir, "knowledge", "agents", fileName));
5037
+ }
4948
5038
  function flowForState(state) {
4949
5039
  switch (state) {
4950
5040
  case "new":
@@ -4972,7 +5062,7 @@ function buildUnderstandPlan(dir, config) {
4972
5062
  const state = config.project.state;
4973
5063
  const flow = flowForState(state);
4974
5064
  const steps = flow.map((s) => {
4975
- const installed = exists(join(dir, "knowledge", "agents", s.agent));
5065
+ const installed = agentIsInstalled(dir, s.agent);
4976
5066
  return { agent: s.agent, output: s.output, installed };
4977
5067
  });
4978
5068
  const missingAgents = steps.filter((s) => !s.installed).map((s) => s.agent);
@@ -5095,67 +5185,64 @@ function renderUnderstandTerminal(plan) {
5095
5185
  return lines.join("\n");
5096
5186
  }
5097
5187
 
5098
- // src/agents/groups.ts
5099
- var AGENT_GROUPS = {
5100
- business: ["business-agent.md"],
5101
- product: ["bootstrap-agent.md", "capability-agent.md"],
5102
- tech: [
5103
- "architecture-agent.md",
5104
- "codebase-agent.md",
5105
- "stack-agent.md",
5106
- "security-agent.md",
5107
- "standards-agent.md",
5108
- "module-design-agent.md",
5109
- "adr-agent.md"
5110
- ],
5111
- delivery: ["roadmap-agent.md", "work-item-agent.md", "git-strategy-agent.md"],
5112
- utilities: ["legacy-agent.md"]
5113
- };
5114
- var AGENT_GROUP_NAMES = Object.keys(AGENT_GROUPS);
5115
- var RECOMMENDED_BY_STATE = {
5116
- new: [
5117
- "business-agent.md",
5118
- "bootstrap-agent.md",
5119
- "codebase-agent.md",
5120
- "roadmap-agent.md",
5121
- "work-item-agent.md"
5122
- ],
5123
- "pre-ai": [
5124
- "capability-agent.md",
5125
- "architecture-agent.md",
5126
- "roadmap-agent.md",
5127
- "work-item-agent.md"
5128
- ],
5129
- legacy: [
5130
- "legacy-agent.md",
5131
- "architecture-agent.md",
5132
- "capability-agent.md",
5133
- "roadmap-agent.md",
5134
- "work-item-agent.md"
5135
- ]
5136
- };
5137
- function recommendedAgents(state) {
5138
- return RECOMMENDED_BY_STATE[state ?? "pre-ai"] ?? RECOMMENDED_BY_STATE["pre-ai"];
5188
+ // src/core/delivery.ts
5189
+ function slugify2(s) {
5190
+ return s.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
5139
5191
  }
5140
- function selectAgentFiles(opts) {
5141
- if (opts.all) {
5142
- const all = AGENT_GROUP_NAMES.flatMap((g) => AGENT_GROUPS[g]);
5143
- return { files: all, label: "all agents" };
5192
+ function isWorkItem(a) {
5193
+ return a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/") && Boolean(a.type);
5194
+ }
5195
+ function activeWorkItems(dir) {
5196
+ const archDir = join(dir, "knowledge");
5197
+ 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
+ });
5202
+ }
5203
+ function branchPrefix(type) {
5204
+ switch (type) {
5205
+ case "bugfix":
5206
+ return "bugfix";
5207
+ case "hotfix":
5208
+ return "hotfix";
5209
+ case "spike":
5210
+ return "spike";
5211
+ default:
5212
+ return "feature";
5144
5213
  }
5145
- if (opts.group) {
5146
- const group = opts.group;
5147
- const files = AGENT_GROUPS[group];
5148
- if (!files) {
5149
- throw new Error(
5150
- `Unknown agent group "${opts.group}". Valid groups: ${AGENT_GROUP_NAMES.join(", ")}.`
5151
- );
5152
- }
5153
- return { files, label: `group: ${group}` };
5214
+ }
5215
+ function commitPrefix(type) {
5216
+ switch (type) {
5217
+ case "bugfix":
5218
+ case "hotfix":
5219
+ return "fix";
5220
+ case "spike":
5221
+ return "chore";
5222
+ default:
5223
+ return "feat";
5154
5224
  }
5155
- return {
5156
- files: recommendedAgents(opts.state),
5157
- label: `recommended for state: ${opts.state ?? "pre-ai"}`
5158
- };
5225
+ }
5226
+ function suggestedBranch(wi) {
5227
+ return `${branchPrefix(wi.type)}/${wi.id}-${wi.slug}`;
5228
+ }
5229
+ function suggestedCommit(wi) {
5230
+ return `${commitPrefix(wi.type)}: ${wi.title.toLowerCase()}`;
5231
+ }
5232
+ function renderDeliveryLifecycle(wi) {
5233
+ return [
5234
+ `Active work item: ${wi.id} \u2014 ${wi.title}`,
5235
+ "",
5236
+ "Delivery lifecycle (Kaddo never runs git for you):",
5237
+ ` 1. Create a branch e.g. ${suggestedBranch(wi)}`,
5238
+ " 2. Implement the work item",
5239
+ " 3. Run `kaddo scan` (after new modules/migrations/contracts)",
5240
+ " 4. Run `kaddo owners suggest` \u2192 confirm code: globs",
5241
+ " 5. Run `kaddo guard` before committing (detect knowledge drift)",
5242
+ " 6. Update knowledge ADR / capabilities.md / current-state.md as needed",
5243
+ " 7. Review (human)",
5244
+ ` 8. Commit e.g. ${suggestedCommit(wi)}`
5245
+ ];
5159
5246
  }
5160
5247
 
5161
5248
  // src/commands/understand.ts
@@ -5193,11 +5280,41 @@ function runUnderstand() {
5193
5280
  const phase = currentPhase(knowledgeLayers(dir));
5194
5281
  const group = phase.toLowerCase();
5195
5282
  const groupAgents = (AGENT_GROUPS[group] ?? []).map((a) => a.replace(/\.md$/, ""));
5283
+ const NEXT_STEPS = {
5284
+ business: ["Use business-agent \u2192 refine knowledge/business/business.md"],
5285
+ product: [
5286
+ "Use bootstrap-agent \u2192 refine knowledge/product/product.md",
5287
+ "Use capability-agent \u2192 knowledge/product/capabilities.md"
5288
+ ],
5289
+ tech: [
5290
+ "Use architecture-agent \u2192 knowledge/tech/current-state.md (reality)",
5291
+ "Use codebase-agent \u2192 knowledge/tech/codebase.md (intent)",
5292
+ "Record decisions as ADRs in knowledge/tech/decisions/"
5293
+ ],
5294
+ delivery: [
5295
+ "Use roadmap-agent \u2192 knowledge/delivery/roadmap.md",
5296
+ "Run `kaddo create --from roadmap`, then `kaddo owners suggest`"
5297
+ ],
5298
+ utilities: ["Use legacy-agent to surface risks and unknowns"]
5299
+ };
5300
+ console.log("");
5301
+ console.log(`Current phase: ${phase}`);
5302
+ console.log("Recommended next steps:");
5303
+ console.log(" 1. Run `kaddo scan` (technical signals \u2192 knowledge/inventory.md)");
5304
+ console.log(" 2. Run `kaddo context` (package knowledge for your LLM)");
5305
+ let n = 3;
5306
+ for (const step of NEXT_STEPS[group] ?? []) console.log(` ${n++}. ${step}`);
5196
5307
  if (groupAgents.length > 0) {
5308
+ console.log(`Agents for this phase: ${groupAgents.join(", ")}`);
5309
+ }
5310
+ const active = activeWorkItems(dir);
5311
+ if (active.length > 0) {
5197
5312
  console.log("");
5198
- console.log(`Current phase: ${phase}`);
5199
- console.log("Recommended agents for this phase:");
5200
- for (const a of groupAgents) console.log(` - ${a}`);
5313
+ for (const line of renderDeliveryLifecycle(active[0])) console.log(line);
5314
+ if (active.length > 1) {
5315
+ console.log("");
5316
+ console.log(`Other active work items: ${active.slice(1).map((w) => w.id).join(", ")}`);
5317
+ }
5201
5318
  }
5202
5319
  writeFile(join(dir, ".kaddo", "understand.md"), renderUnderstand(plan));
5203
5320
  log2.success("Wrote .kaddo/understand.md");
@@ -7590,7 +7707,7 @@ var MODULE_TYPES = [
7590
7707
  "data",
7591
7708
  "unknown"
7592
7709
  ];
7593
- function slugify2(name) {
7710
+ function slugify3(name) {
7594
7711
  return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
7595
7712
  }
7596
7713
  function readModulesDescriptor(dir) {
@@ -7610,7 +7727,7 @@ function moduleDir(id) {
7610
7727
  return `knowledge/tech/modules/${id}`;
7611
7728
  }
7612
7729
  function buildModule(input) {
7613
- const id = slugify2(input.name);
7730
+ const id = slugify3(input.name);
7614
7731
  const base = moduleDir(id);
7615
7732
  return {
7616
7733
  id,
@@ -7877,7 +7994,7 @@ async function runBootstrap(dir = cwd()) {
7877
7994
 
7878
7995
  // src/index.ts
7879
7996
  var program = new Command();
7880
- program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.1.0");
7997
+ program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.3.0");
7881
7998
  program.command("init").description("Initialize Kaddo in the current project").action(async () => {
7882
7999
  await runInit();
7883
8000
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/cli",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "Knowledge Driven Development toolkit",
5
5
  "license": "MIT",
6
6
  "repository": {