@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.
- package/README.md +2 -0
- package/dist/index.js +188 -71
- 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:
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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 =
|
|
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/
|
|
5099
|
-
|
|
5100
|
-
|
|
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
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
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
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
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
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
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(
|
|
5199
|
-
|
|
5200
|
-
|
|
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
|
|
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 =
|
|
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.
|
|
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
|
});
|