@kaddo/cli 3.2.0 → 3.4.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 +103 -13
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -434,6 +434,8 @@ create --from roadmap → owners → guard → explain`.
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
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) |
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) |
437
439
 
438
440
  **Optional modules (installed with `kaddo add`):**
439
441
 
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
 
@@ -5185,6 +5204,68 @@ function renderUnderstandTerminal(plan) {
5185
5204
  return lines.join("\n");
5186
5205
  }
5187
5206
 
5207
+ // src/core/delivery.ts
5208
+ import { parse as parseYaml9 } from "yaml";
5209
+ function slugify2(s) {
5210
+ return s.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
5211
+ }
5212
+ function isWorkItem(a) {
5213
+ return a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/") && Boolean(a.type);
5214
+ }
5215
+ function toActive(a) {
5216
+ const id = a.id || a.title || "WI";
5217
+ return { id, title: a.title || id, type: a.type, slug: slugify2(a.title || id) };
5218
+ }
5219
+ function activeWorkItems(dir) {
5220
+ const archDir = join(dir, "knowledge");
5221
+ if (!exists(archDir)) return [];
5222
+ return readArtifacts(archDir).filter((a) => isWorkItem(a) && a.status === "in-progress").map(toActive);
5223
+ }
5224
+ function branchPrefix(type) {
5225
+ switch (type) {
5226
+ case "bugfix":
5227
+ return "bugfix";
5228
+ case "hotfix":
5229
+ return "hotfix";
5230
+ case "spike":
5231
+ return "spike";
5232
+ default:
5233
+ return "feature";
5234
+ }
5235
+ }
5236
+ function commitPrefix(type) {
5237
+ switch (type) {
5238
+ case "bugfix":
5239
+ case "hotfix":
5240
+ return "fix";
5241
+ case "spike":
5242
+ return "chore";
5243
+ default:
5244
+ return "feat";
5245
+ }
5246
+ }
5247
+ function suggestedBranch(wi) {
5248
+ return `${branchPrefix(wi.type)}/${wi.id}-${wi.slug}`;
5249
+ }
5250
+ function suggestedCommit(wi) {
5251
+ return `${commitPrefix(wi.type)}: ${wi.title.toLowerCase()}`;
5252
+ }
5253
+ function renderDeliveryLifecycle(wi) {
5254
+ return [
5255
+ `Active work item: ${wi.id} \u2014 ${wi.title}`,
5256
+ "",
5257
+ "Delivery lifecycle (the building agent follows this; Kaddo CLI never touches git):",
5258
+ ` 1. Create a branch ${suggestedBranch(wi)} (per your Git strategy)`,
5259
+ " 2. Implement the work item",
5260
+ " 3. Run `kaddo scan` (after new modules/migrations/contracts)",
5261
+ " 4. Run `kaddo owners suggest` \u2192 confirm code: globs",
5262
+ " 5. Run `kaddo guard` before committing (detect knowledge drift)",
5263
+ " 6. Update knowledge ADR / capabilities.md / current-state.md as needed",
5264
+ " 7. Review (human)",
5265
+ ` 8. Commit only with human confirmation e.g. ${suggestedCommit(wi)}`
5266
+ ];
5267
+ }
5268
+
5188
5269
  // src/commands/understand.ts
5189
5270
  function runUnderstand() {
5190
5271
  const dir = cwd();
@@ -5247,6 +5328,15 @@ function runUnderstand() {
5247
5328
  if (groupAgents.length > 0) {
5248
5329
  console.log(`Agents for this phase: ${groupAgents.join(", ")}`);
5249
5330
  }
5331
+ const active = activeWorkItems(dir);
5332
+ if (active.length > 0) {
5333
+ console.log("");
5334
+ for (const line of renderDeliveryLifecycle(active[0])) console.log(line);
5335
+ if (active.length > 1) {
5336
+ console.log("");
5337
+ console.log(`Other active work items: ${active.slice(1).map((w) => w.id).join(", ")}`);
5338
+ }
5339
+ }
5250
5340
  writeFile(join(dir, ".kaddo", "understand.md"), renderUnderstand(plan));
5251
5341
  log2.success("Wrote .kaddo/understand.md");
5252
5342
  outro2("Handoff ready. CLI prepares context \u2014 your LLM creates the understanding.");
@@ -5470,14 +5560,14 @@ async function runClassify(opts = {}) {
5470
5560
  }
5471
5561
 
5472
5562
  // src/commands/status.ts
5473
- import { parse as parseYaml9 } from "yaml";
5563
+ import { parse as parseYaml10 } from "yaml";
5474
5564
  var ARCH_DIR7 = "knowledge";
5475
5565
  var CONFIG_PATH4 = ".kaddo/config.yml";
5476
5566
  function loadConfig3(dir) {
5477
5567
  const p2 = join(dir, CONFIG_PATH4);
5478
5568
  if (!exists(p2)) return {};
5479
5569
  try {
5480
- return parseYaml9(readFile(p2));
5570
+ return parseYaml10(readFile(p2));
5481
5571
  } catch {
5482
5572
  return {};
5483
5573
  }
@@ -5679,13 +5769,13 @@ function runHistory(opts = {}) {
5679
5769
  }
5680
5770
 
5681
5771
  // src/commands/add.ts
5682
- import { parse as parseYaml10, stringify as stringifyYaml3 } from "yaml";
5772
+ import { parse as parseYaml11, stringify as stringifyYaml3 } from "yaml";
5683
5773
  var CONFIG_PATH5 = ".kaddo/config.yml";
5684
5774
  function readProjectState(dir) {
5685
5775
  const configPath = join(dir, CONFIG_PATH5);
5686
5776
  if (!exists(configPath)) return void 0;
5687
5777
  try {
5688
- const config = parseYaml10(readFile(configPath));
5778
+ const config = parseYaml11(readFile(configPath));
5689
5779
  return config.project?.state;
5690
5780
  } catch {
5691
5781
  return void 0;
@@ -5703,7 +5793,7 @@ function markModuleInstalled(dir, configKey, moduleName) {
5703
5793
  const configPath = join(dir, CONFIG_PATH5);
5704
5794
  if (!exists(configPath)) return;
5705
5795
  try {
5706
- const config = parseYaml10(readFile(configPath));
5796
+ const config = parseYaml11(readFile(configPath));
5707
5797
  config[configKey] = { installed: true, installed_at: (/* @__PURE__ */ new Date()).toISOString().split("T")[0] };
5708
5798
  const modules = config.modules ?? [];
5709
5799
  if (!modules.includes(moduleName)) modules.push(moduleName);
@@ -5716,7 +5806,7 @@ function isModuleInstalled(dir, configKey) {
5716
5806
  const configPath = join(dir, CONFIG_PATH5);
5717
5807
  if (!exists(configPath)) return false;
5718
5808
  try {
5719
- const config = parseYaml10(readFile(configPath));
5809
+ const config = parseYaml11(readFile(configPath));
5720
5810
  const moduleConfig = config[configKey];
5721
5811
  return moduleConfig?.installed === true;
5722
5812
  } catch {
@@ -6040,13 +6130,13 @@ ${globs.map((g) => ` - ${g}`).join("\n")}`);
6040
6130
  }
6041
6131
 
6042
6132
  // src/commands/module-descriptor.ts
6043
- import { parse as parseYaml11, stringify as stringifyYaml4 } from "yaml";
6133
+ import { parse as parseYaml12, stringify as stringifyYaml4 } from "yaml";
6044
6134
  var DESCRIPTOR_PATH2 = "knowledge/module.yml";
6045
6135
  function readDescriptor(dir) {
6046
6136
  const path5 = join(dir, DESCRIPTOR_PATH2);
6047
6137
  if (!exists(path5)) return null;
6048
6138
  try {
6049
- return parseYaml11(readFile(path5));
6139
+ return parseYaml12(readFile(path5));
6050
6140
  } catch {
6051
6141
  return null;
6052
6142
  }
@@ -6147,7 +6237,7 @@ function printDescriptor(d) {
6147
6237
  }
6148
6238
 
6149
6239
  // src/commands/modules-map.ts
6150
- import { parse as parseYaml12, stringify as stringifyYaml5 } from "yaml";
6240
+ import { parse as parseYaml13, stringify as stringifyYaml5 } from "yaml";
6151
6241
 
6152
6242
  // src/templates/registry.ts
6153
6243
  var QUALITY = "## Quality checklist";
@@ -7638,14 +7728,14 @@ var MODULE_TYPES = [
7638
7728
  "data",
7639
7729
  "unknown"
7640
7730
  ];
7641
- function slugify2(name) {
7731
+ function slugify3(name) {
7642
7732
  return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
7643
7733
  }
7644
7734
  function readModulesDescriptor(dir) {
7645
7735
  const path5 = join(dir, DESCRIPTOR_PATH3);
7646
7736
  if (!exists(path5)) return { version: 1, modules: [] };
7647
7737
  try {
7648
- const parsed = parseYaml12(readFile(path5));
7738
+ const parsed = parseYaml13(readFile(path5));
7649
7739
  return { version: parsed.version ?? 1, modules: parsed.modules ?? [] };
7650
7740
  } catch {
7651
7741
  return { version: 1, modules: [] };
@@ -7658,7 +7748,7 @@ function moduleDir(id) {
7658
7748
  return `knowledge/tech/modules/${id}`;
7659
7749
  }
7660
7750
  function buildModule(input) {
7661
- const id = slugify2(input.name);
7751
+ const id = slugify3(input.name);
7662
7752
  const base = moduleDir(id);
7663
7753
  return {
7664
7754
  id,
@@ -7925,7 +8015,7 @@ async function runBootstrap(dir = cwd()) {
7925
8015
 
7926
8016
  // src/index.ts
7927
8017
  var program = new Command();
7928
- program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.2.0");
8018
+ program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.4.0");
7929
8019
  program.command("init").description("Initialize Kaddo in the current project").action(async () => {
7930
8020
  await runInit();
7931
8021
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/cli",
3
- "version": "3.2.0",
3
+ "version": "3.4.0",
4
4
  "description": "Knowledge Driven Development toolkit",
5
5
  "license": "MIT",
6
6
  "repository": {