@kaddo/cli 3.0.0 → 3.1.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 (4) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1 -0
  3. package/dist/index.js +278 -53
  4. package/package.json +1 -1
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Judlup Luna
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Judlup Luna
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -432,6 +432,7 @@ create --from roadmap → owners → guard → explain`.
432
432
  | v2.7 | Multirepo hardening: module artifacts from the template registry, module-aware `context`/`explain`, opt-in `guard --workspace` |
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
+ | v3.1 | Minimum Sufficient Knowledge: bootstrap one consolidated file per layer; progressive `add agents` by group (state default, `--all`, `--group`) |
435
436
 
436
437
  **Optional modules (installed with `kaddo add`):**
437
438
 
package/dist/index.js CHANGED
@@ -566,8 +566,8 @@ function loadConfig(dir) {
566
566
  const parsed = configSchema.safeParse(raw ?? {});
567
567
  if (!parsed.success) {
568
568
  const issues = parsed.error.issues.map((i) => {
569
- const path6 = i.path.join(".");
570
- return path6 ? ` - ${path6}: ${i.message}` : ` - ${i.message}`;
569
+ const path5 = i.path.join(".");
570
+ return path5 ? ` - ${path5}: ${i.message}` : ` - ${i.message}`;
571
571
  }).join("\n");
572
572
  throw new ConfigError(`Invalid .kaddo/config.yml:
573
573
  ${issues}`);
@@ -3518,9 +3518,8 @@ function readArtifacts(archDir) {
3518
3518
 
3519
3519
  // src/core/diff-analysis.ts
3520
3520
  import { minimatch } from "minimatch";
3521
- import path3 from "path";
3522
3521
  function normalizePath(p2) {
3523
- return p2.split(path3.sep).join("/");
3522
+ return p2.replace(/\\/g, "/");
3524
3523
  }
3525
3524
  function fileMatchesGlob(file, glob) {
3526
3525
  return minimatch(normalizePath(file), glob, { matchBase: false, dot: true });
@@ -3578,10 +3577,10 @@ function analyzeGuard(touchedFiles, artifacts, silentWithoutOwnership) {
3578
3577
  import { parse as parseYaml4, stringify as stringifyYaml2 } from "yaml";
3579
3578
  var IGNORE_FILE = ".kaddo/ignores.yml";
3580
3579
  function loadIgnores(dir) {
3581
- const path6 = join(dir, IGNORE_FILE);
3582
- if (!exists(path6)) return [];
3580
+ const path5 = join(dir, IGNORE_FILE);
3581
+ if (!exists(path5)) return [];
3583
3582
  try {
3584
- const raw = readFile(path6);
3583
+ const raw = readFile(path5);
3585
3584
  const parsed = parseYaml4(raw);
3586
3585
  return Array.isArray(parsed) ? parsed : [];
3587
3586
  } catch {
@@ -3589,7 +3588,7 @@ function loadIgnores(dir) {
3589
3588
  }
3590
3589
  }
3591
3590
  function saveIgnore(dir, entry) {
3592
- const path6 = join(dir, IGNORE_FILE);
3591
+ const path5 = join(dir, IGNORE_FILE);
3593
3592
  const existing = loadIgnores(dir);
3594
3593
  const idx = existing.findIndex((e) => e.artifact_id === entry.artifact_id);
3595
3594
  if (idx >= 0) {
@@ -3597,17 +3596,17 @@ function saveIgnore(dir, entry) {
3597
3596
  } else {
3598
3597
  existing.push(entry);
3599
3598
  }
3600
- writeFile(path6, stringifyYaml2(existing));
3599
+ writeFile(path5, stringifyYaml2(existing));
3601
3600
  }
3602
3601
  function isIgnored(ignores, artifactId) {
3603
3602
  return ignores.find((e) => e.artifact_id === artifactId);
3604
3603
  }
3605
3604
  function removeIgnore(dir, artifactId) {
3606
- const path6 = join(dir, IGNORE_FILE);
3605
+ const path5 = join(dir, IGNORE_FILE);
3607
3606
  const existing = loadIgnores(dir);
3608
3607
  const filtered = existing.filter((e) => e.artifact_id !== artifactId);
3609
3608
  if (filtered.length === existing.length) return false;
3610
- writeFile(path6, stringifyYaml2(filtered));
3609
+ writeFile(path5, stringifyYaml2(filtered));
3611
3610
  return true;
3612
3611
  }
3613
3612
 
@@ -3629,11 +3628,11 @@ function moduleArtifactCoverage(dir, id) {
3629
3628
  };
3630
3629
  }
3631
3630
  function loadMappedModules(dir) {
3632
- const path6 = join(dir, DESCRIPTOR_PATH);
3633
- if (!exists(path6)) return [];
3631
+ const path5 = join(dir, DESCRIPTOR_PATH);
3632
+ if (!exists(path5)) return [];
3634
3633
  let parsed;
3635
3634
  try {
3636
- parsed = parseYaml5(readFile(path6));
3635
+ parsed = parseYaml5(readFile(path5));
3637
3636
  } catch {
3638
3637
  return [];
3639
3638
  }
@@ -3725,7 +3724,7 @@ async function collectWorkspaceChanges(dir, mode = "head", deps = defaultDeps) {
3725
3724
  }
3726
3725
 
3727
3726
  // src/commands/guard.ts
3728
- import path4 from "path";
3727
+ import path3 from "path";
3729
3728
  import { parse as parseYaml7 } from "yaml";
3730
3729
 
3731
3730
  // src/plugins/prisma.ts
@@ -3929,7 +3928,7 @@ function printHeader(touchedFiles) {
3929
3928
  function artifactLabel(artifact, dir) {
3930
3929
  if (artifact.id) return artifact.id;
3931
3930
  if (artifact.title) return artifact.title;
3932
- const rel = path4.relative(dir, artifact.filePath).split(path4.sep).join("/");
3931
+ const rel = path3.relative(dir, artifact.filePath).split(path3.sep).join("/");
3933
3932
  return rel || artifact.filePath;
3934
3933
  }
3935
3934
  function printWorkspaceHeader(scan2) {
@@ -4212,6 +4211,12 @@ function knowledgeLayers(dir) {
4212
4211
  items: items.map((it) => ({ name: it.name, present: exists(join(dir, it.path)) }))
4213
4212
  }));
4214
4213
  }
4214
+ function currentPhase(layers) {
4215
+ for (const { layer, items } of layers) {
4216
+ if (items.some((i) => !i.present)) return layer;
4217
+ }
4218
+ return "Delivery";
4219
+ }
4215
4220
  function renderLayersMarkdown(layers) {
4216
4221
  const lines = [];
4217
4222
  for (const { layer, items } of layers) {
@@ -5090,6 +5095,69 @@ function renderUnderstandTerminal(plan) {
5090
5095
  return lines.join("\n");
5091
5096
  }
5092
5097
 
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"];
5139
+ }
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" };
5144
+ }
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}` };
5154
+ }
5155
+ return {
5156
+ files: recommendedAgents(opts.state),
5157
+ label: `recommended for state: ${opts.state ?? "pre-ai"}`
5158
+ };
5159
+ }
5160
+
5093
5161
  // src/commands/understand.ts
5094
5162
  function runUnderstand() {
5095
5163
  const dir = cwd();
@@ -5122,13 +5190,22 @@ function runUnderstand() {
5122
5190
  );
5123
5191
  }
5124
5192
  console.log(renderUnderstandTerminal(plan));
5193
+ const phase = currentPhase(knowledgeLayers(dir));
5194
+ const group = phase.toLowerCase();
5195
+ const groupAgents = (AGENT_GROUPS[group] ?? []).map((a) => a.replace(/\.md$/, ""));
5196
+ if (groupAgents.length > 0) {
5197
+ 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}`);
5201
+ }
5125
5202
  writeFile(join(dir, ".kaddo", "understand.md"), renderUnderstand(plan));
5126
5203
  log2.success("Wrote .kaddo/understand.md");
5127
5204
  outro2("Handoff ready. CLI prepares context \u2014 your LLM creates the understanding.");
5128
5205
  }
5129
5206
 
5130
5207
  // src/core/classifier.ts
5131
- import path5 from "path";
5208
+ import path4 from "path";
5132
5209
  var MIGRATION_PATTERNS = [
5133
5210
  /supabase\/migrations\//,
5134
5211
  /prisma\/migrations\//,
@@ -5167,7 +5244,7 @@ var DEP_PATTERNS = [
5167
5244
  /^pom\.xml$/
5168
5245
  ];
5169
5246
  function normalizePath2(p2) {
5170
- return p2.split(path5.sep).join("/");
5247
+ return p2.split(path4.sep).join("/");
5171
5248
  }
5172
5249
  function matchesAny(file, patterns) {
5173
5250
  const normalized = normalizePath2(file);
@@ -5556,6 +5633,24 @@ function runHistory(opts = {}) {
5556
5633
  // src/commands/add.ts
5557
5634
  import { parse as parseYaml10, stringify as stringifyYaml3 } from "yaml";
5558
5635
  var CONFIG_PATH5 = ".kaddo/config.yml";
5636
+ function readProjectState(dir) {
5637
+ const configPath = join(dir, CONFIG_PATH5);
5638
+ if (!exists(configPath)) return void 0;
5639
+ try {
5640
+ const config = parseYaml10(readFile(configPath));
5641
+ return config.project?.state;
5642
+ } catch {
5643
+ return void 0;
5644
+ }
5645
+ }
5646
+ function selectAgentModuleFiles(files, opts, state) {
5647
+ const { files: names, label } = selectAgentFiles({ all: opts.all, group: opts.group, state });
5648
+ const wanted = new Set(names);
5649
+ const selected = files.filter(
5650
+ (f) => f.path.endsWith("README.md") || names.some((n) => f.path.endsWith(n)) || wanted.has(f.path)
5651
+ );
5652
+ return { files: selected, label };
5653
+ }
5559
5654
  function markModuleInstalled(dir, configKey, moduleName) {
5560
5655
  const configPath = join(dir, CONFIG_PATH5);
5561
5656
  if (!exists(configPath)) return;
@@ -5580,7 +5675,7 @@ function isModuleInstalled(dir, configKey) {
5580
5675
  return false;
5581
5676
  }
5582
5677
  }
5583
- function runAdd(moduleName, dir = cwd()) {
5678
+ function runAdd(moduleName, opts = {}, dir = cwd()) {
5584
5679
  if (!moduleName) {
5585
5680
  console.log("");
5586
5681
  console.log("Available modules:");
@@ -5606,9 +5701,20 @@ function runAdd(moduleName, dir = cwd()) {
5606
5701
  for (const d of mod.dirs) {
5607
5702
  ensureDir(join(dir, d));
5608
5703
  }
5704
+ let filesToInstall = mod.files;
5705
+ if (mod.name === "agents") {
5706
+ try {
5707
+ const sel = selectAgentModuleFiles(mod.files, opts, readProjectState(dir));
5708
+ filesToInstall = sel.files;
5709
+ log2.info(`Installing agents (${sel.label}).`);
5710
+ } catch (err) {
5711
+ console.error(err instanceof Error ? err.message : String(err));
5712
+ process.exit(1);
5713
+ }
5714
+ }
5609
5715
  const written = [];
5610
5716
  const skipped = [];
5611
- for (const file of mod.files) {
5717
+ for (const file of filesToInstall) {
5612
5718
  const fullPath = join(dir, file.path);
5613
5719
  if (exists(fullPath)) {
5614
5720
  skipped.push(file.path);
@@ -5631,6 +5737,7 @@ function runAdd(moduleName, dir = cwd()) {
5631
5737
  console.log(" 2. Open your preferred LLM chat");
5632
5738
  console.log(" 3. Paste `.kaddo/context-pack.md`");
5633
5739
  console.log(" 4. Use the recommended agent for your project state");
5740
+ log2.info("More agents: `kaddo add agents --all` or `--group <business|product|tech|delivery|utilities>`.");
5634
5741
  outro2("Agents installed. Kaddo prepares context \u2014 your LLM does the interpretation.");
5635
5742
  return;
5636
5743
  }
@@ -5888,10 +5995,10 @@ ${globs.map((g) => ` - ${g}`).join("\n")}`);
5888
5995
  import { parse as parseYaml11, stringify as stringifyYaml4 } from "yaml";
5889
5996
  var DESCRIPTOR_PATH2 = "knowledge/module.yml";
5890
5997
  function readDescriptor(dir) {
5891
- const path6 = join(dir, DESCRIPTOR_PATH2);
5892
- if (!exists(path6)) return null;
5998
+ const path5 = join(dir, DESCRIPTOR_PATH2);
5999
+ if (!exists(path5)) return null;
5893
6000
  try {
5894
- return parseYaml11(readFile(path6));
6001
+ return parseYaml11(readFile(path5));
5895
6002
  } catch {
5896
6003
  return null;
5897
6004
  }
@@ -6920,47 +7027,138 @@ ${QUALITY}
6920
7027
  - [ ] Attributes are prioritized, not all "high".
6921
7028
  - [ ] Trade-offs are explicit.
6922
7029
  `;
7030
+ var BUSINESS_CONSOLIDATED = `---
7031
+ type: business
7032
+ status: draft
7033
+ ---
7034
+
7035
+ # Business
7036
+
7037
+ > Created by \`kaddo bootstrap\`. The minimal **why** of the project. Refine with the
7038
+ > business-agent. As this matures it can split into problem.md, users.md, \u2026
7039
+
7040
+ ## Problem
7041
+
7042
+ TBD
7043
+
7044
+ ## Users
7045
+
7046
+ TBD
7047
+
7048
+ ## Value Proposition
7049
+
7050
+ TBD
7051
+
7052
+ ## Business Rules
7053
+
7054
+ - TBD
7055
+
7056
+ ## Constraints
7057
+
7058
+ - TBD
7059
+
7060
+ ## Assumptions
7061
+
7062
+ - ...
7063
+
7064
+ ## Open Questions
7065
+
7066
+ - ...
7067
+
7068
+ ${QUALITY}
7069
+
7070
+ - [ ] The problem is stated without assuming the solution.
7071
+ - [ ] Users have goals, not just labels.
7072
+ `;
7073
+ var PRODUCT_CONSOLIDATED = `---
7074
+ type: product
7075
+ status: draft
7076
+ ---
7077
+
7078
+ # Product
7079
+
7080
+ > Created by \`kaddo bootstrap\`. The minimal **what** of the project. Refine with the
7081
+ > bootstrap-agent / capability-agent. As this matures it can split into product-brief.md
7082
+ > and capabilities.md.
7083
+
7084
+ ## Product Brief
7085
+
7086
+ TBD
7087
+
7088
+ ## Capabilities
7089
+
7090
+ - TBD
7091
+
7092
+ ## Scope
7093
+
7094
+ - TBD
7095
+
7096
+ ## Out of Scope
7097
+
7098
+ - TBD
7099
+
7100
+ ## Success Criteria
7101
+
7102
+ - TBD
7103
+
7104
+ ## Assumptions
7105
+
7106
+ - ...
7107
+
7108
+ ## Open Questions
7109
+
7110
+ - ...
7111
+
7112
+ ${QUALITY}
7113
+
7114
+ - [ ] The product fits in one page.
7115
+ - [ ] Scope and out-of-scope are explicit.
7116
+ `;
6923
7117
  var CODEBASE_FOUNDATION = `---
6924
- type: codebase-foundation
7118
+ type: codebase
6925
7119
  status: draft
6926
7120
  ---
6927
7121
 
6928
- # Codebase Foundation
7122
+ # Codebase
6929
7123
 
6930
- > Created by \`kaddo bootstrap\`. Refine with the codebase-agent.
6931
- > This describes the intended base \u2014 it does **not** generate code.
7124
+ > Created by \`kaddo bootstrap\`. The minimal **how** of the project. Refine with the
7125
+ > codebase-agent. It describes the intended base \u2014 it does **not** generate code.
6932
7126
 
6933
- ## Suggested structure
7127
+ ## Repository Structure
6934
7128
 
6935
7129
  TBD
6936
7130
 
6937
- ## Initial modules / boundaries
7131
+ ## Candidate Stack
7132
+
7133
+ - TBD
7134
+
7135
+ ## Quality Attributes
6938
7136
 
6939
7137
  - TBD
6940
7138
 
6941
- ## Conventions
7139
+ ## Development Standards
6942
7140
 
6943
7141
  - TBD
6944
7142
 
6945
- ## Git strategy
7143
+ ## Git Strategy
6946
7144
 
6947
- See \`knowledge/tech/git-strategy.md\`.
7145
+ GitHub Flow + Conventional Commits + SemVer (default). See \`kaddo add git-strategy\`.
6948
7146
 
6949
- ## Minimum criteria to start development
7147
+ ## Initial Modules
6950
7148
 
6951
- - [ ] TBD
7149
+ - TBD
6952
7150
 
6953
7151
  ## Assumptions
6954
7152
 
6955
7153
  - ...
6956
7154
 
6957
- ## Open questions
7155
+ ## Open Questions
6958
7156
 
6959
7157
  - ...
6960
7158
 
6961
7159
  ${QUALITY}
6962
7160
 
6963
- - [ ] Structure follows the business and architecture, not a framework default.
7161
+ - [ ] Structure follows business and product, not a framework default.
6964
7162
  - [ ] No production code is described here \u2014 only the foundation.
6965
7163
  `;
6966
7164
  var BOOTSTRAP_SUMMARY = `---
@@ -7034,6 +7232,7 @@ var KADDO_TEMPLATES = [
7034
7232
  description: "What the system can do from the product point of view.",
7035
7233
  whenToUse: "When mapping product capabilities to the system.",
7036
7234
  relatedAgent: "capability-agent",
7235
+ advanced: true,
7037
7236
  content: CAPABILITIES
7038
7237
  },
7039
7238
  {
@@ -7046,7 +7245,30 @@ var KADDO_TEMPLATES = [
7046
7245
  relatedCommand: "kaddo init",
7047
7246
  content: KNOWLEDGE2
7048
7247
  },
7049
- // business (bootstrap)
7248
+ // business / product (bootstrap — consolidated, minimal)
7249
+ {
7250
+ id: "business",
7251
+ name: "Business",
7252
+ category: "business",
7253
+ outputPath: "knowledge/business/business.md",
7254
+ description: "The minimal why: problem, users, value, rules, constraints (one file).",
7255
+ whenToUse: "Generated by kaddo bootstrap for new projects.",
7256
+ relatedCommand: "kaddo bootstrap",
7257
+ relatedAgent: "business-agent",
7258
+ content: BUSINESS_CONSOLIDATED
7259
+ },
7260
+ {
7261
+ id: "product",
7262
+ name: "Product",
7263
+ category: "product",
7264
+ outputPath: "knowledge/product/product.md",
7265
+ description: "The minimal what: product brief, capabilities, scope (one file).",
7266
+ whenToUse: "Generated by kaddo bootstrap for new projects.",
7267
+ relatedCommand: "kaddo bootstrap",
7268
+ relatedAgent: "bootstrap-agent",
7269
+ content: PRODUCT_CONSOLIDATED
7270
+ },
7271
+ // business (advanced — split out as knowledge matures, not generated by bootstrap)
7050
7272
  {
7051
7273
  id: "business-product-brief",
7052
7274
  name: "Product Brief",
@@ -7056,6 +7278,7 @@ var KADDO_TEMPLATES = [
7056
7278
  whenToUse: "At the start of a new project (kaddo bootstrap).",
7057
7279
  relatedCommand: "kaddo bootstrap",
7058
7280
  relatedAgent: "business-agent",
7281
+ advanced: true,
7059
7282
  content: BUSINESS_PRODUCT_BRIEF
7060
7283
  },
7061
7284
  {
@@ -7067,6 +7290,7 @@ var KADDO_TEMPLATES = [
7067
7290
  whenToUse: "When defining a new project (kaddo bootstrap).",
7068
7291
  relatedCommand: "kaddo bootstrap",
7069
7292
  relatedAgent: "business-agent",
7293
+ advanced: true,
7070
7294
  content: BUSINESS_PROBLEM
7071
7295
  },
7072
7296
  {
@@ -7078,6 +7302,7 @@ var KADDO_TEMPLATES = [
7078
7302
  whenToUse: "When defining a new project (kaddo bootstrap).",
7079
7303
  relatedCommand: "kaddo bootstrap",
7080
7304
  relatedAgent: "business-agent",
7305
+ advanced: true,
7081
7306
  content: BUSINESS_USERS
7082
7307
  },
7083
7308
  {
@@ -7089,6 +7314,7 @@ var KADDO_TEMPLATES = [
7089
7314
  whenToUse: "When defining a new project (kaddo bootstrap).",
7090
7315
  relatedCommand: "kaddo bootstrap",
7091
7316
  relatedAgent: "business-agent",
7317
+ advanced: true,
7092
7318
  content: BUSINESS_VALUE_PROPOSITION
7093
7319
  },
7094
7320
  {
@@ -7100,6 +7326,7 @@ var KADDO_TEMPLATES = [
7100
7326
  whenToUse: "When defining a new project (kaddo bootstrap).",
7101
7327
  relatedCommand: "kaddo bootstrap",
7102
7328
  relatedAgent: "business-agent",
7329
+ advanced: true,
7103
7330
  content: BUSINESS_RULES
7104
7331
  },
7105
7332
  {
@@ -7111,6 +7338,7 @@ var KADDO_TEMPLATES = [
7111
7338
  whenToUse: "When defining a new project (kaddo bootstrap).",
7112
7339
  relatedCommand: "kaddo bootstrap",
7113
7340
  relatedAgent: "business-agent",
7341
+ advanced: true,
7114
7342
  content: BUSINESS_CONSTRAINTS
7115
7343
  },
7116
7344
  {
@@ -7122,6 +7350,7 @@ var KADDO_TEMPLATES = [
7122
7350
  whenToUse: "When defining a new project (kaddo bootstrap).",
7123
7351
  relatedCommand: "kaddo bootstrap",
7124
7352
  relatedAgent: "business-agent",
7353
+ advanced: true,
7125
7354
  content: BUSINESS_GLOSSARY
7126
7355
  },
7127
7356
  // architecture
@@ -7163,6 +7392,7 @@ var KADDO_TEMPLATES = [
7163
7392
  whenToUse: "During bootstrap, to record what matters most technically.",
7164
7393
  relatedCommand: "kaddo bootstrap",
7165
7394
  relatedAgent: "bootstrap-agent",
7395
+ advanced: true,
7166
7396
  content: QUALITY_ATTRIBUTES
7167
7397
  },
7168
7398
  {
@@ -7364,10 +7594,10 @@ function slugify2(name) {
7364
7594
  return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
7365
7595
  }
7366
7596
  function readModulesDescriptor(dir) {
7367
- const path6 = join(dir, DESCRIPTOR_PATH3);
7368
- if (!exists(path6)) return { version: 1, modules: [] };
7597
+ const path5 = join(dir, DESCRIPTOR_PATH3);
7598
+ if (!exists(path5)) return { version: 1, modules: [] };
7369
7599
  try {
7370
- const parsed = parseYaml12(readFile(path6));
7600
+ const parsed = parseYaml12(readFile(path5));
7371
7601
  return { version: parsed.version ?? 1, modules: parsed.modules ?? [] };
7372
7602
  } catch {
7373
7603
  return { version: 1, modules: [] };
@@ -7574,16 +7804,11 @@ function runModulesList(dir = cwd()) {
7574
7804
  // src/commands/bootstrap.ts
7575
7805
  var CONFIG_PATH8 = ".kaddo/config.yml";
7576
7806
  var TARGETS = [
7577
- // Business why it exists
7578
- { layer: "Business", path: "knowledge/business/problem.md", templateId: "business-problem" },
7579
- { layer: "Business", path: "knowledge/business/users.md", templateId: "business-users" },
7580
- { layer: "Business", path: "knowledge/business/value-proposition.md", templateId: "business-value-proposition" },
7581
- { layer: "Business", path: "knowledge/business/constraints.md", templateId: "business-constraints" },
7582
- { layer: "Business", path: "knowledge/business/business-rules.md", templateId: "business-rules" },
7583
- // Product — what we build
7584
- { layer: "Product", path: "knowledge/product/product-brief.md", templateId: "business-product-brief" },
7585
- { layer: "Product", path: "knowledge/product/capabilities.md", templateId: "capabilities" },
7586
- // Tech — how we build it
7807
+ // Minimum sufficient knowledge: one consolidated file per layer. Specialized
7808
+ // artifacts (problem.md, users.md, capabilities.md, …) appear later, as the project
7809
+ // matures, via agents and refinement — not at bootstrap.
7810
+ { layer: "Business", path: "knowledge/business/business.md", templateId: "business" },
7811
+ { layer: "Product", path: "knowledge/product/product.md", templateId: "product" },
7587
7812
  { layer: "Tech", path: "knowledge/tech/codebase.md", templateId: "codebase" }
7588
7813
  ];
7589
7814
  var BOOTSTRAP_LAYERS = ["Business", "Product", "Tech"];
@@ -7652,7 +7877,7 @@ async function runBootstrap(dir = cwd()) {
7652
7877
 
7653
7878
  // src/index.ts
7654
7879
  var program = new Command();
7655
- program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.0.0");
7880
+ program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.1.0");
7656
7881
  program.command("init").description("Initialize Kaddo in the current project").action(async () => {
7657
7882
  await runInit();
7658
7883
  });
@@ -7716,8 +7941,8 @@ modulesCmd.command("map").description("Register a secondary repository as a modu
7716
7941
  modulesCmd.command("list").description("List mapped modules").action(() => {
7717
7942
  runModulesList();
7718
7943
  });
7719
- program.command("add [module]").description("Install an optional Kaddo module (adr, incident, rfc, migration, legacy, agents, standards, security, stack, git-strategy)").action((moduleName) => {
7720
- runAdd(moduleName ?? "");
7944
+ program.command("add [module]").description("Install an optional Kaddo module (adr, incident, rfc, migration, legacy, agents, standards, security, stack, git-strategy)").option("--all", "For `add agents`: install every agent (not just the recommended set)").option("--group <name>", "For `add agents`: install one layer group (business, product, tech, delivery, utilities)").action((moduleName, opts) => {
7945
+ runAdd(moduleName ?? "", { all: opts.all, group: opts.group });
7721
7946
  });
7722
7947
  program.parseAsync(process.argv).catch((err) => {
7723
7948
  console.error(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/cli",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Knowledge Driven Development toolkit",
5
5
  "license": "MIT",
6
6
  "repository": {