@kaddo/cli 3.3.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 +1 -0
  2. package/dist/index.js +39 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -435,6 +435,7 @@ 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) |
438
439
 
439
440
  **Optional modules (installed with `kaddo add`):**
440
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
 
@@ -5186,19 +5205,21 @@ function renderUnderstandTerminal(plan) {
5186
5205
  }
5187
5206
 
5188
5207
  // src/core/delivery.ts
5208
+ import { parse as parseYaml9 } from "yaml";
5189
5209
  function slugify2(s) {
5190
5210
  return s.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
5191
5211
  }
5192
5212
  function isWorkItem(a) {
5193
5213
  return a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/") && Boolean(a.type);
5194
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
+ }
5195
5219
  function activeWorkItems(dir) {
5196
5220
  const archDir = join(dir, "knowledge");
5197
5221
  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
- });
5222
+ return readArtifacts(archDir).filter((a) => isWorkItem(a) && a.status === "in-progress").map(toActive);
5202
5223
  }
5203
5224
  function branchPrefix(type) {
5204
5225
  switch (type) {
@@ -5233,15 +5254,15 @@ function renderDeliveryLifecycle(wi) {
5233
5254
  return [
5234
5255
  `Active work item: ${wi.id} \u2014 ${wi.title}`,
5235
5256
  "",
5236
- "Delivery lifecycle (Kaddo never runs git for you):",
5237
- ` 1. Create a branch e.g. ${suggestedBranch(wi)}`,
5257
+ "Delivery lifecycle (the building agent follows this; Kaddo CLI never touches git):",
5258
+ ` 1. Create a branch ${suggestedBranch(wi)} (per your Git strategy)`,
5238
5259
  " 2. Implement the work item",
5239
5260
  " 3. Run `kaddo scan` (after new modules/migrations/contracts)",
5240
5261
  " 4. Run `kaddo owners suggest` \u2192 confirm code: globs",
5241
5262
  " 5. Run `kaddo guard` before committing (detect knowledge drift)",
5242
5263
  " 6. Update knowledge ADR / capabilities.md / current-state.md as needed",
5243
5264
  " 7. Review (human)",
5244
- ` 8. Commit e.g. ${suggestedCommit(wi)}`
5265
+ ` 8. Commit only with human confirmation e.g. ${suggestedCommit(wi)}`
5245
5266
  ];
5246
5267
  }
5247
5268
 
@@ -5539,14 +5560,14 @@ async function runClassify(opts = {}) {
5539
5560
  }
5540
5561
 
5541
5562
  // src/commands/status.ts
5542
- import { parse as parseYaml9 } from "yaml";
5563
+ import { parse as parseYaml10 } from "yaml";
5543
5564
  var ARCH_DIR7 = "knowledge";
5544
5565
  var CONFIG_PATH4 = ".kaddo/config.yml";
5545
5566
  function loadConfig3(dir) {
5546
5567
  const p2 = join(dir, CONFIG_PATH4);
5547
5568
  if (!exists(p2)) return {};
5548
5569
  try {
5549
- return parseYaml9(readFile(p2));
5570
+ return parseYaml10(readFile(p2));
5550
5571
  } catch {
5551
5572
  return {};
5552
5573
  }
@@ -5748,13 +5769,13 @@ function runHistory(opts = {}) {
5748
5769
  }
5749
5770
 
5750
5771
  // src/commands/add.ts
5751
- import { parse as parseYaml10, stringify as stringifyYaml3 } from "yaml";
5772
+ import { parse as parseYaml11, stringify as stringifyYaml3 } from "yaml";
5752
5773
  var CONFIG_PATH5 = ".kaddo/config.yml";
5753
5774
  function readProjectState(dir) {
5754
5775
  const configPath = join(dir, CONFIG_PATH5);
5755
5776
  if (!exists(configPath)) return void 0;
5756
5777
  try {
5757
- const config = parseYaml10(readFile(configPath));
5778
+ const config = parseYaml11(readFile(configPath));
5758
5779
  return config.project?.state;
5759
5780
  } catch {
5760
5781
  return void 0;
@@ -5772,7 +5793,7 @@ function markModuleInstalled(dir, configKey, moduleName) {
5772
5793
  const configPath = join(dir, CONFIG_PATH5);
5773
5794
  if (!exists(configPath)) return;
5774
5795
  try {
5775
- const config = parseYaml10(readFile(configPath));
5796
+ const config = parseYaml11(readFile(configPath));
5776
5797
  config[configKey] = { installed: true, installed_at: (/* @__PURE__ */ new Date()).toISOString().split("T")[0] };
5777
5798
  const modules = config.modules ?? [];
5778
5799
  if (!modules.includes(moduleName)) modules.push(moduleName);
@@ -5785,7 +5806,7 @@ function isModuleInstalled(dir, configKey) {
5785
5806
  const configPath = join(dir, CONFIG_PATH5);
5786
5807
  if (!exists(configPath)) return false;
5787
5808
  try {
5788
- const config = parseYaml10(readFile(configPath));
5809
+ const config = parseYaml11(readFile(configPath));
5789
5810
  const moduleConfig = config[configKey];
5790
5811
  return moduleConfig?.installed === true;
5791
5812
  } catch {
@@ -6109,13 +6130,13 @@ ${globs.map((g) => ` - ${g}`).join("\n")}`);
6109
6130
  }
6110
6131
 
6111
6132
  // src/commands/module-descriptor.ts
6112
- import { parse as parseYaml11, stringify as stringifyYaml4 } from "yaml";
6133
+ import { parse as parseYaml12, stringify as stringifyYaml4 } from "yaml";
6113
6134
  var DESCRIPTOR_PATH2 = "knowledge/module.yml";
6114
6135
  function readDescriptor(dir) {
6115
6136
  const path5 = join(dir, DESCRIPTOR_PATH2);
6116
6137
  if (!exists(path5)) return null;
6117
6138
  try {
6118
- return parseYaml11(readFile(path5));
6139
+ return parseYaml12(readFile(path5));
6119
6140
  } catch {
6120
6141
  return null;
6121
6142
  }
@@ -6216,7 +6237,7 @@ function printDescriptor(d) {
6216
6237
  }
6217
6238
 
6218
6239
  // src/commands/modules-map.ts
6219
- import { parse as parseYaml12, stringify as stringifyYaml5 } from "yaml";
6240
+ import { parse as parseYaml13, stringify as stringifyYaml5 } from "yaml";
6220
6241
 
6221
6242
  // src/templates/registry.ts
6222
6243
  var QUALITY = "## Quality checklist";
@@ -7714,7 +7735,7 @@ function readModulesDescriptor(dir) {
7714
7735
  const path5 = join(dir, DESCRIPTOR_PATH3);
7715
7736
  if (!exists(path5)) return { version: 1, modules: [] };
7716
7737
  try {
7717
- const parsed = parseYaml12(readFile(path5));
7738
+ const parsed = parseYaml13(readFile(path5));
7718
7739
  return { version: parsed.version ?? 1, modules: parsed.modules ?? [] };
7719
7740
  } catch {
7720
7741
  return { version: 1, modules: [] };
@@ -7994,7 +8015,7 @@ async function runBootstrap(dir = cwd()) {
7994
8015
 
7995
8016
  // src/index.ts
7996
8017
  var program = new Command();
7997
- program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.3.0");
8018
+ program.name("kaddo").description("Knowledge Driven Development toolkit").version("3.4.0");
7998
8019
  program.command("init").description("Initialize Kaddo in the current project").action(async () => {
7999
8020
  await runInit();
8000
8021
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/cli",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "description": "Knowledge Driven Development toolkit",
5
5
  "license": "MIT",
6
6
  "repository": {