@kaddo/cli 3.26.0 → 3.27.1
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 +238 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -517,6 +517,8 @@ create --from roadmap → owners → guard → explain`.
|
|
|
517
517
|
| v3.25 | Guard history & drift trend: `kaddo guard --record`, `kaddo drift`; feeds impact Guard Activity + savings Drift Prevention; MCP drift/guard-history resources + tool |
|
|
518
518
|
| v3.25.1 | Savings guard-history messaging fix: distinguishes "no history" from "history with 0 resolved warnings" (drift prevention available at 0 h) |
|
|
519
519
|
| v3.26 | Open-questions readiness gate: `kaddo questions`/`readiness`, blocking/important/deferred classification; MCP open-questions + roadmap-readiness resources + tool; roadmap/work-item/implementation/bootstrap agents check it |
|
|
520
|
+
| v3.27 | Codex adapter: `kaddo adapters install codex` (alias `kaddo export codex`) generates a compact `AGENTS.md` projection (`--dry-run`/`--force`) |
|
|
521
|
+
| v3.27.1 | Codex adapter command fallbacks: AGENTS.md tells Codex to try `corepack pnpm exec` / `pnpm exec` / `npx` kaddo when the global binary isn't on PATH |
|
|
520
522
|
|
|
521
523
|
**Optional modules (installed with `kaddo add`):**
|
|
522
524
|
|
package/dist/index.js
CHANGED
|
@@ -700,6 +700,10 @@ var COMMAND_HELP = {
|
|
|
700
700
|
questions: {
|
|
701
701
|
question: "Are there open questions to decide before the roadmap?",
|
|
702
702
|
next: "Resolve, assume or defer blocking questions, then generate the roadmap"
|
|
703
|
+
},
|
|
704
|
+
"adapters install codex": {
|
|
705
|
+
question: "How does Codex work with this Kaddo project?",
|
|
706
|
+
next: "Open AGENTS.md, or regenerate it after knowledge changes"
|
|
703
707
|
}
|
|
704
708
|
};
|
|
705
709
|
function commandFooterLines(name) {
|
|
@@ -12295,6 +12299,233 @@ function runQuestions(opts = {}) {
|
|
|
12295
12299
|
printCommandFooter("questions");
|
|
12296
12300
|
}
|
|
12297
12301
|
|
|
12302
|
+
// src/core/codex-adapter.ts
|
|
12303
|
+
var KNOWLEDGE_PATHS = [
|
|
12304
|
+
"knowledge/business/",
|
|
12305
|
+
"knowledge/product/",
|
|
12306
|
+
"knowledge/tech/",
|
|
12307
|
+
"knowledge/delivery/",
|
|
12308
|
+
"knowledge/agents/",
|
|
12309
|
+
"knowledge/skills/"
|
|
12310
|
+
];
|
|
12311
|
+
var GENERATED_PATHS = [
|
|
12312
|
+
".kaddo/context-pack.md",
|
|
12313
|
+
".kaddo/understand.md",
|
|
12314
|
+
".kaddo/explain.md",
|
|
12315
|
+
".kaddo/graph.json",
|
|
12316
|
+
".kaddo/reports/"
|
|
12317
|
+
];
|
|
12318
|
+
function discoverAgents(dir) {
|
|
12319
|
+
const base = join(dir, "knowledge", "agents");
|
|
12320
|
+
if (!exists(base) || !isDir(base)) return [];
|
|
12321
|
+
const out = /* @__PURE__ */ new Set();
|
|
12322
|
+
const walk = (d) => {
|
|
12323
|
+
for (const e of readDir(d)) {
|
|
12324
|
+
const full = join(d, e);
|
|
12325
|
+
if (isDir(full)) walk(full);
|
|
12326
|
+
else if (e.endsWith("-agent.md")) out.add(e.replace(/\.md$/, ""));
|
|
12327
|
+
}
|
|
12328
|
+
};
|
|
12329
|
+
walk(base);
|
|
12330
|
+
return [...out].sort();
|
|
12331
|
+
}
|
|
12332
|
+
function buildCodexAdapterContext(dir) {
|
|
12333
|
+
const config = loadConfig(dir);
|
|
12334
|
+
const agents = discoverAgents(dir);
|
|
12335
|
+
const skills = discoverInstalledSkills(dir).map((s) => s.id);
|
|
12336
|
+
return {
|
|
12337
|
+
projectName: config?.project.name,
|
|
12338
|
+
projectType: config?.project.state,
|
|
12339
|
+
language: config ? config.project.language : void 0,
|
|
12340
|
+
hasAgents: agents.length > 0,
|
|
12341
|
+
agents,
|
|
12342
|
+
hasSkills: skills.length > 0,
|
|
12343
|
+
skills,
|
|
12344
|
+
hasMcpHint: detectMcpHint(dir),
|
|
12345
|
+
knowledgePaths: KNOWLEDGE_PATHS.filter((p2) => exists(join(dir, p2))),
|
|
12346
|
+
generatedPaths: GENERATED_PATHS
|
|
12347
|
+
};
|
|
12348
|
+
}
|
|
12349
|
+
function detectMcpHint(dir) {
|
|
12350
|
+
for (const f of [".mcp.json", "mcp.json", ".cursor/mcp.json"]) {
|
|
12351
|
+
if (exists(join(dir, f))) return true;
|
|
12352
|
+
}
|
|
12353
|
+
return false;
|
|
12354
|
+
}
|
|
12355
|
+
var ROLE_HINTS = {
|
|
12356
|
+
"roadmap-agent": "use before creating or refining the roadmap.",
|
|
12357
|
+
"work-item-agent": "use before refining Work Items.",
|
|
12358
|
+
"implementation-agent": "use before implementing Work Items.",
|
|
12359
|
+
"bootstrap-agent": "use when refining initial knowledge.",
|
|
12360
|
+
"ownership-agent": "use to propose precise `code:` ownership globs.",
|
|
12361
|
+
"graph-agent": "use to turn graph hints into front matter.",
|
|
12362
|
+
"capsule-agent": "use to refine a Knowledge Capsule for sharing."
|
|
12363
|
+
};
|
|
12364
|
+
function renderAgentsMd(ctx) {
|
|
12365
|
+
const L = [];
|
|
12366
|
+
L.push("<!-- Generated by `kaddo adapters install codex`. Kaddo is the source of truth \u2014");
|
|
12367
|
+
L.push(" regenerate this file instead of editing it by hand. Do not treat it as primary. -->");
|
|
12368
|
+
L.push("# AGENTS.md", "");
|
|
12369
|
+
L.push("## Project guidance", "");
|
|
12370
|
+
if (ctx.projectName) L.push(`Project: **${ctx.projectName}**${ctx.projectType ? ` (${ctx.projectType})` : ""}.`, "");
|
|
12371
|
+
L.push("This repository uses **Kaddo** for Knowledge Driven Development. Kaddo keeps business,");
|
|
12372
|
+
L.push("product, technical and delivery knowledge close to the code.");
|
|
12373
|
+
L.push("");
|
|
12374
|
+
L.push("Before making changes, read the relevant Kaddo knowledge files instead of relying only on");
|
|
12375
|
+
L.push("source code.");
|
|
12376
|
+
L.push("");
|
|
12377
|
+
L.push("## Kaddo knowledge map", "");
|
|
12378
|
+
L.push("Primary knowledge lives in:", "");
|
|
12379
|
+
for (const p2 of ctx.knowledgePaths.length > 0 ? ctx.knowledgePaths : KNOWLEDGE_PATHS) L.push(`- \`${p2}\``);
|
|
12380
|
+
L.push("");
|
|
12381
|
+
L.push("Derived context (generated \u2014 do not edit by hand) lives in:", "");
|
|
12382
|
+
for (const p2 of ctx.generatedPaths) L.push(`- \`${p2}\``);
|
|
12383
|
+
L.push("");
|
|
12384
|
+
L.push("## Operating rules", "");
|
|
12385
|
+
L.push("- Do not generate a roadmap without checking open-questions readiness.");
|
|
12386
|
+
L.push("- Do not implement without reading the active Work Item.");
|
|
12387
|
+
L.push("- Do not assume missing product or business decisions \u2014 prefer explicit assumptions.");
|
|
12388
|
+
L.push("- Keep knowledge updated when implementation changes scope.");
|
|
12389
|
+
L.push("- Do not modify `.kaddo/` manually; it is generated output.");
|
|
12390
|
+
L.push("- Do not commit without user confirmation.");
|
|
12391
|
+
L.push("");
|
|
12392
|
+
L.push("## Before roadmap work", "");
|
|
12393
|
+
L.push("Read `knowledge/business/business.md`, `knowledge/product/product.md`,");
|
|
12394
|
+
L.push("`knowledge/tech/codebase.md`, and `.kaddo/reports/questions-report.md` if available.");
|
|
12395
|
+
L.push("");
|
|
12396
|
+
L.push("Check open-questions readiness first. **If blocking open questions exist, ask the user to");
|
|
12397
|
+
L.push("resolve, assume or defer them before generating the roadmap** \u2014 never build the roadmap on");
|
|
12398
|
+
L.push("invisible assumptions.");
|
|
12399
|
+
L.push("");
|
|
12400
|
+
L.push("## Before implementation", "");
|
|
12401
|
+
L.push("Read the target Work Item in `knowledge/delivery/work-items/`, `.kaddo/context-pack.md`,");
|
|
12402
|
+
L.push("`.kaddo/understand.md`, and the related knowledge and skills files.");
|
|
12403
|
+
L.push("");
|
|
12404
|
+
L.push("Do not implement outside the scope of the active Work Item unless the user confirms.");
|
|
12405
|
+
L.push("");
|
|
12406
|
+
L.push("## After implementation", "");
|
|
12407
|
+
L.push("Suggest running, as validation (not mandatory):", "");
|
|
12408
|
+
L.push("```bash");
|
|
12409
|
+
L.push("kaddo guard");
|
|
12410
|
+
L.push("kaddo impact");
|
|
12411
|
+
L.push("kaddo savings");
|
|
12412
|
+
L.push("kaddo drift");
|
|
12413
|
+
L.push("```");
|
|
12414
|
+
L.push("");
|
|
12415
|
+
L.push("Before finishing a change, suggest `kaddo guard`. If warnings appear, explain the possible");
|
|
12416
|
+
L.push("knowledge drift and ask the user whether to update the related knowledge \u2014 never update it");
|
|
12417
|
+
L.push("automatically.");
|
|
12418
|
+
L.push("");
|
|
12419
|
+
if (ctx.hasAgents) {
|
|
12420
|
+
L.push("## Available Kaddo agents", "");
|
|
12421
|
+
L.push("Installed under `knowledge/agents/`. Use them as role-specific guidance when relevant:", "");
|
|
12422
|
+
for (const a of ctx.agents) {
|
|
12423
|
+
const hint = ROLE_HINTS[a];
|
|
12424
|
+
L.push(`- \`${a}\`${hint ? `: ${hint}` : ""}`);
|
|
12425
|
+
}
|
|
12426
|
+
L.push("");
|
|
12427
|
+
}
|
|
12428
|
+
if (ctx.hasSkills) {
|
|
12429
|
+
L.push("## Available Kaddo skills", "");
|
|
12430
|
+
L.push("Reusable skills under `knowledge/skills/`. Read only the skills relevant to the current");
|
|
12431
|
+
L.push("task \u2014 do not load every skill by default.", "");
|
|
12432
|
+
for (const s of ctx.skills) L.push(`- \`${s}\``);
|
|
12433
|
+
L.push("");
|
|
12434
|
+
}
|
|
12435
|
+
if (ctx.hasMcpHint) {
|
|
12436
|
+
L.push("## MCP", "");
|
|
12437
|
+
L.push("A Kaddo MCP server appears to be configured. Prefer MCP resources over manually scanning");
|
|
12438
|
+
L.push("generated files:", "");
|
|
12439
|
+
for (const r of ["kaddo://context-pack", "kaddo://understand", "kaddo://explain", "kaddo://open-questions", "kaddo://roadmap-readiness", "kaddo://impact-report", "kaddo://savings-report", "kaddo://drift-report"]) {
|
|
12440
|
+
L.push(`- \`${r}\``);
|
|
12441
|
+
}
|
|
12442
|
+
L.push("");
|
|
12443
|
+
}
|
|
12444
|
+
L.push("## Command fallback", "");
|
|
12445
|
+
L.push("Prefer the direct command when available:", "");
|
|
12446
|
+
L.push("```bash");
|
|
12447
|
+
L.push("kaddo <command>");
|
|
12448
|
+
L.push("```");
|
|
12449
|
+
L.push("");
|
|
12450
|
+
L.push("If the global `kaddo` command is not available in `PATH`, try the local project runner");
|
|
12451
|
+
L.push("before reporting that Kaddo is unavailable:", "");
|
|
12452
|
+
L.push("```bash");
|
|
12453
|
+
L.push("corepack pnpm exec kaddo <command>");
|
|
12454
|
+
L.push("```");
|
|
12455
|
+
L.push("");
|
|
12456
|
+
L.push("If that is not available, try:", "");
|
|
12457
|
+
L.push("```bash");
|
|
12458
|
+
L.push("pnpm exec kaddo <command>");
|
|
12459
|
+
L.push("```");
|
|
12460
|
+
L.push("");
|
|
12461
|
+
L.push("As a last resort (may resolve/download the package):", "");
|
|
12462
|
+
L.push("```bash");
|
|
12463
|
+
L.push("npx kaddo <command>");
|
|
12464
|
+
L.push("```");
|
|
12465
|
+
L.push("");
|
|
12466
|
+
L.push("Do not assume Kaddo is unavailable until these local fallbacks have been attempted. When you");
|
|
12467
|
+
L.push('use a fallback, mention it briefly (e.g. "the global `kaddo` was not available, so I used');
|
|
12468
|
+
L.push('`corepack pnpm exec kaddo`").');
|
|
12469
|
+
L.push("");
|
|
12470
|
+
L.push("## Useful Kaddo commands", "");
|
|
12471
|
+
L.push("```bash");
|
|
12472
|
+
for (const c of ["kaddo context", "kaddo understand", "kaddo explain", "kaddo graph export", "kaddo questions", "kaddo guard", "kaddo impact", "kaddo savings", "kaddo drift"]) {
|
|
12473
|
+
L.push(c);
|
|
12474
|
+
}
|
|
12475
|
+
L.push("```");
|
|
12476
|
+
L.push("");
|
|
12477
|
+
L.push("## Agent behavior", "");
|
|
12478
|
+
const steps = [
|
|
12479
|
+
"Identify the current task or Work Item.",
|
|
12480
|
+
"Read the related Kaddo knowledge.",
|
|
12481
|
+
"Check readiness gates (open questions).",
|
|
12482
|
+
"Implement only the requested scope.",
|
|
12483
|
+
"Validate with tests or checks.",
|
|
12484
|
+
"Suggest knowledge updates if implementation changed the original understanding.",
|
|
12485
|
+
"Ask before committing."
|
|
12486
|
+
];
|
|
12487
|
+
steps.forEach((s, i) => L.push(`${i + 1}. ${s}`));
|
|
12488
|
+
L.push("");
|
|
12489
|
+
L.push("## Safety limits", "");
|
|
12490
|
+
L.push("Do not: rewrite the Kaddo methodology, delete knowledge files, manually edit generated");
|
|
12491
|
+
L.push("`.kaddo/` artifacts, bypass readiness gates, generate a roadmap from source code alone, or");
|
|
12492
|
+
L.push("implement broad changes without an active Work Item.");
|
|
12493
|
+
L.push("");
|
|
12494
|
+
return L.join("\n");
|
|
12495
|
+
}
|
|
12496
|
+
|
|
12497
|
+
// src/commands/adapters.ts
|
|
12498
|
+
function runAdaptersInstall(adapter, opts = {}) {
|
|
12499
|
+
const dir = cwd();
|
|
12500
|
+
requireConfig(dir);
|
|
12501
|
+
if (adapter !== "codex") {
|
|
12502
|
+
console.error(`Unknown adapter: "${adapter}". Available: codex.`);
|
|
12503
|
+
process.exit(1);
|
|
12504
|
+
}
|
|
12505
|
+
const content = renderAgentsMd(buildCodexAdapterContext(dir));
|
|
12506
|
+
if (opts.dryRun) {
|
|
12507
|
+
console.log("# AGENTS.md preview", "");
|
|
12508
|
+
console.log(content);
|
|
12509
|
+
return;
|
|
12510
|
+
}
|
|
12511
|
+
intro2("kaddo adapters install codex");
|
|
12512
|
+
const rel = "AGENTS.md";
|
|
12513
|
+
const full = join(dir, rel);
|
|
12514
|
+
const existed = exists(full);
|
|
12515
|
+
if (existed && !opts.force) {
|
|
12516
|
+
log2.warn("AGENTS.md already exists.");
|
|
12517
|
+
log2.info("Use `kaddo adapters install codex --force` to overwrite,");
|
|
12518
|
+
log2.info("or `kaddo adapters install codex --dry-run` to preview.");
|
|
12519
|
+
outro2("Nothing changed.");
|
|
12520
|
+
return;
|
|
12521
|
+
}
|
|
12522
|
+
writeFile(full, content);
|
|
12523
|
+
log2.success(`${existed ? "Overwrote" : "Created"} AGENTS.md for Codex.`);
|
|
12524
|
+
log2.info("Source: Kaddo project knowledge. Regenerate it instead of editing by hand.");
|
|
12525
|
+
printCommandFooter("adapters install codex");
|
|
12526
|
+
outro2("AGENTS.md ready.");
|
|
12527
|
+
}
|
|
12528
|
+
|
|
12298
12529
|
// src/index.ts
|
|
12299
12530
|
var require2 = createRequire(import.meta.url);
|
|
12300
12531
|
var { version } = require2("../package.json");
|
|
@@ -12348,6 +12579,13 @@ program.command("drift").description("Drift Trend Report from recorded `kaddo gu
|
|
|
12348
12579
|
var questionsAction = (opts) => runQuestions(opts);
|
|
12349
12580
|
program.command("questions").description("Open-questions readiness gate: blocking/important/deferred decisions before the roadmap").option("--json", "Output JSON instead of a summary").option("--output <path>", "Write the report to a file (e.g. .kaddo/reports/questions-report.md)").action(questionsAction);
|
|
12350
12581
|
program.command("readiness").description("Alias for `kaddo questions`").option("--json", "Output JSON instead of a summary").option("--output <path>", "Write the report to a file").action(questionsAction);
|
|
12582
|
+
var adaptersCmd = program.command("adapters").description("Generate adapters that project Kaddo knowledge for external coding agents");
|
|
12583
|
+
adaptersCmd.command("install <adapter>").description("Generate an adapter file (codex \u2192 AGENTS.md) from Kaddo knowledge").option("--force", "Overwrite an existing output file").option("--dry-run", "Print the content without writing files").action((adapter, opts) => {
|
|
12584
|
+
runAdaptersInstall(adapter, opts);
|
|
12585
|
+
});
|
|
12586
|
+
program.command("export <adapter>").description("Alias for `kaddo adapters install <adapter>` (codex \u2192 AGENTS.md)").option("--force", "Overwrite an existing output file").option("--dry-run", "Print the content without writing files").action((adapter, opts) => {
|
|
12587
|
+
runAdaptersInstall(adapter, opts);
|
|
12588
|
+
});
|
|
12351
12589
|
program.command("guard").description("Check if modified code has related artifacts that were not updated").option("--staged", "Check only staged files").option("--no-interactive", "Disable interactive ignore prompts").option("--ci", "CI mode: output JSON, no prompts, non-blocking").option("--json", "Output JSON (alias for --ci)").option("--workspace", "Also check local mapped module repos from .kaddo/modules.yml (opt-in)").option("--include-archived", "Include archived Work Items in ownership matching (excluded by default)").option("--record", "Record this run to .kaddo/history/ for drift trend reporting").action(async (opts) => {
|
|
12352
12590
|
await runGuard(opts);
|
|
12353
12591
|
});
|