@kaddo/cli 3.30.0 → 3.32.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 +144 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -526,6 +526,8 @@ create --from roadmap → owners → guard → explain`.
|
|
|
526
526
|
| v3.28.2 | Adapter inject guard: `--inject` on a fully Kaddo-generated AGENTS.md/CLAUDE.md does nothing (suggests `--force`), preventing duplicated Kaddo guidance |
|
|
527
527
|
| v3.29 | OpenCode adapter: `kaddo adapters install opencode` (alias `kaddo export opencode`) generates an `AGENTS.md` projection reusing the shared adapter common core (`--dry-run`/`--force`/`--inject` + inject guard) |
|
|
528
528
|
| v3.30 | Antigravity adapter: `kaddo adapters install antigravity` (alias `kaddo export antigravity`) generates an `AGENTS.md` projection reusing the shared adapter common core (`--dry-run`/`--force`/`--inject` + inject guard) |
|
|
529
|
+
| v3.31 | Kiro adapter: `kaddo adapters install kiro` (alias `kaddo export kiro`) generates an `AGENTS.md` projection reusing the shared adapter common core (`--dry-run`/`--force`/`--inject` + inject guard) |
|
|
530
|
+
| v3.32 | Adapter discovery & status: `kaddo adapters list` (alias `ls`) and `kaddo adapters status` (alias `check`) — read-only catalog + per-adapter install state (missing/team-owned/injected/legacy-injected/full-generated/broken-markers), shared-`AGENTS.md` origin detection, `--json` |
|
|
529
531
|
|
|
530
532
|
**Optional modules (installed with `kaddo add`):**
|
|
531
533
|
|
package/dist/index.js
CHANGED
|
@@ -12408,7 +12408,8 @@ var TARGET_FILE = {
|
|
|
12408
12408
|
codex: "AGENTS.md",
|
|
12409
12409
|
claude: "CLAUDE.md",
|
|
12410
12410
|
opencode: "AGENTS.md",
|
|
12411
|
-
antigravity: "AGENTS.md"
|
|
12411
|
+
antigravity: "AGENTS.md",
|
|
12412
|
+
kiro: "AGENTS.md"
|
|
12412
12413
|
};
|
|
12413
12414
|
function renderAdapterMarkdown(ctx, target) {
|
|
12414
12415
|
const file = TARGET_FILE[target];
|
|
@@ -12609,20 +12610,92 @@ function injectKaddoBlock(existing, ctx) {
|
|
|
12609
12610
|
${sep}${block}
|
|
12610
12611
|
`, status: "injected" };
|
|
12611
12612
|
}
|
|
12613
|
+
var ADAPTERS = [
|
|
12614
|
+
{ id: "codex", label: "Codex", file: "AGENTS.md", supportsInject: true },
|
|
12615
|
+
{ id: "claude", label: "Claude Code", file: "CLAUDE.md", supportsInject: true },
|
|
12616
|
+
{ id: "opencode", label: "OpenCode", file: "AGENTS.md", supportsInject: true },
|
|
12617
|
+
{ id: "antigravity", label: "Antigravity", file: "AGENTS.md", supportsInject: true },
|
|
12618
|
+
{ id: "kiro", label: "Kiro", file: "AGENTS.md", supportsInject: true }
|
|
12619
|
+
];
|
|
12620
|
+
function findAdapter(id) {
|
|
12621
|
+
return ADAPTERS.find((a) => a.id === id);
|
|
12622
|
+
}
|
|
12623
|
+
function parseOriginAdapter(content) {
|
|
12624
|
+
const m = content.match(/Generated by `kaddo adapters install (\w+)`/);
|
|
12625
|
+
const id = m?.[1];
|
|
12626
|
+
return id && findAdapter(id) ? id : null;
|
|
12627
|
+
}
|
|
12628
|
+
function classifyAdapterState(content) {
|
|
12629
|
+
const base = detectAgentsState(content);
|
|
12630
|
+
switch (base) {
|
|
12631
|
+
case "missing":
|
|
12632
|
+
return "missing";
|
|
12633
|
+
case "invalid_kaddo_block":
|
|
12634
|
+
return "broken-markers";
|
|
12635
|
+
case "generated_by_kaddo":
|
|
12636
|
+
return "full-generated";
|
|
12637
|
+
case "existing_with_kaddo_block":
|
|
12638
|
+
return content.includes(LEGACY_BEGIN_MARKER) ? "legacy-injected" : "injected";
|
|
12639
|
+
default:
|
|
12640
|
+
return "team-owned";
|
|
12641
|
+
}
|
|
12642
|
+
}
|
|
12643
|
+
function recommendedAction(a, state) {
|
|
12644
|
+
const cmd = `kaddo adapters install ${a.id}`;
|
|
12645
|
+
switch (state) {
|
|
12646
|
+
case "missing":
|
|
12647
|
+
return cmd;
|
|
12648
|
+
case "team-owned":
|
|
12649
|
+
return `${cmd} --inject`;
|
|
12650
|
+
case "injected":
|
|
12651
|
+
return "No action needed (run --inject to update the Kaddo block).";
|
|
12652
|
+
case "legacy-injected":
|
|
12653
|
+
return `${cmd} --inject (migrates legacy markers to neutral)`;
|
|
12654
|
+
case "full-generated":
|
|
12655
|
+
return `No action needed. Use \`${cmd} --force\` only to regenerate for ${a.label}.`;
|
|
12656
|
+
case "broken-markers":
|
|
12657
|
+
return "Fix the incomplete Kaddo adapter markers before running --inject.";
|
|
12658
|
+
}
|
|
12659
|
+
}
|
|
12660
|
+
function buildAdapterStatuses(dir) {
|
|
12661
|
+
const cache = /* @__PURE__ */ new Map();
|
|
12662
|
+
const read = (file) => {
|
|
12663
|
+
if (!cache.has(file)) {
|
|
12664
|
+
const full = join(dir, file);
|
|
12665
|
+
cache.set(file, exists(full) ? readFile(full) : null);
|
|
12666
|
+
}
|
|
12667
|
+
return cache.get(file);
|
|
12668
|
+
};
|
|
12669
|
+
return ADAPTERS.map((a) => {
|
|
12670
|
+
const content = read(a.file);
|
|
12671
|
+
const state = classifyAdapterState(content);
|
|
12672
|
+
const originAdapter = content ? parseOriginAdapter(content) : null;
|
|
12673
|
+
return { ...a, state, originAdapter, recommendedAction: recommendedAction(a, state) };
|
|
12674
|
+
});
|
|
12675
|
+
}
|
|
12676
|
+
function buildSharedFileStatuses(statuses) {
|
|
12677
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
12678
|
+
for (const s of statuses) {
|
|
12679
|
+
const arr = byFile.get(s.file) ?? [];
|
|
12680
|
+
arr.push(s);
|
|
12681
|
+
byFile.set(s.file, arr);
|
|
12682
|
+
}
|
|
12683
|
+
return [...byFile.entries()].filter(([, arr]) => arr.length > 1).map(([file, arr]) => ({
|
|
12684
|
+
file,
|
|
12685
|
+
adapters: arr.map((s) => s.id),
|
|
12686
|
+
state: arr[0].state,
|
|
12687
|
+
originAdapter: arr[0].originAdapter
|
|
12688
|
+
}));
|
|
12689
|
+
}
|
|
12612
12690
|
|
|
12613
12691
|
// src/commands/adapters.ts
|
|
12614
|
-
var
|
|
12615
|
-
codex: { target: "codex", file: "AGENTS.md", label: "Codex", supportsInject: true },
|
|
12616
|
-
claude: { target: "claude", file: "CLAUDE.md", label: "Claude Code", supportsInject: true },
|
|
12617
|
-
opencode: { target: "opencode", file: "AGENTS.md", label: "OpenCode", supportsInject: true },
|
|
12618
|
-
antigravity: { target: "antigravity", file: "AGENTS.md", label: "Antigravity", supportsInject: true }
|
|
12619
|
-
};
|
|
12692
|
+
var ADAPTER_LIST = ADAPTERS.map((a) => a.id).join(", ");
|
|
12620
12693
|
function runAdaptersInstall(adapter, opts = {}) {
|
|
12621
12694
|
const dir = cwd();
|
|
12622
12695
|
requireConfig(dir);
|
|
12623
|
-
const spec =
|
|
12696
|
+
const spec = findAdapter(adapter);
|
|
12624
12697
|
if (!spec) {
|
|
12625
|
-
console.error(`Unknown adapter: "${adapter}". Available: ${
|
|
12698
|
+
console.error(`Unknown adapter: "${adapter}". Available: ${ADAPTER_LIST}.`);
|
|
12626
12699
|
process.exit(1);
|
|
12627
12700
|
return;
|
|
12628
12701
|
}
|
|
@@ -12651,7 +12724,7 @@ function runAdaptersInstall(adapter, opts = {}) {
|
|
|
12651
12724
|
return;
|
|
12652
12725
|
}
|
|
12653
12726
|
if (existing === null) {
|
|
12654
|
-
const content2 = renderAdapterMarkdown(ctx, spec.
|
|
12727
|
+
const content2 = renderAdapterMarkdown(ctx, spec.id);
|
|
12655
12728
|
if (opts.dryRun) {
|
|
12656
12729
|
console.log(`# ${rel} preview`, "");
|
|
12657
12730
|
console.log(content2);
|
|
@@ -12682,7 +12755,7 @@ function runAdaptersInstall(adapter, opts = {}) {
|
|
|
12682
12755
|
outro2(`${rel} ready.`);
|
|
12683
12756
|
return;
|
|
12684
12757
|
}
|
|
12685
|
-
const content = renderAdapterMarkdown(ctx, spec.
|
|
12758
|
+
const content = renderAdapterMarkdown(ctx, spec.id);
|
|
12686
12759
|
if (opts.dryRun) {
|
|
12687
12760
|
console.log(`# ${rel} preview`, "");
|
|
12688
12761
|
console.log(content);
|
|
@@ -12702,6 +12775,58 @@ function runAdaptersInstall(adapter, opts = {}) {
|
|
|
12702
12775
|
printCommandFooter("adapters install codex");
|
|
12703
12776
|
outro2(`${rel} ready.`);
|
|
12704
12777
|
}
|
|
12778
|
+
function runAdaptersList(opts = {}) {
|
|
12779
|
+
if (opts.json) {
|
|
12780
|
+
console.log(JSON.stringify({ adapters: ADAPTERS.map((a) => ({ id: a.id, label: a.label, file: a.file, supports_inject: a.supportsInject })) }, null, 2));
|
|
12781
|
+
return;
|
|
12782
|
+
}
|
|
12783
|
+
const pad = Math.max(...ADAPTERS.map((a) => a.id.length));
|
|
12784
|
+
console.log("Available adapters:\n");
|
|
12785
|
+
for (const a of ADAPTERS) {
|
|
12786
|
+
console.log(` ${a.id.padEnd(pad)} ${a.file.padEnd(10)} ${a.supportsInject ? "Supports --inject" : ""}`.trimEnd());
|
|
12787
|
+
}
|
|
12788
|
+
console.log("\nInstall one with:\n kaddo adapters install <adapter>");
|
|
12789
|
+
console.log("\nPreview with:\n kaddo adapters install <adapter> --dry-run");
|
|
12790
|
+
}
|
|
12791
|
+
function runAdaptersStatus(opts = {}) {
|
|
12792
|
+
const dir = cwd();
|
|
12793
|
+
requireConfig(dir);
|
|
12794
|
+
const statuses = buildAdapterStatuses(dir);
|
|
12795
|
+
if (opts.json) {
|
|
12796
|
+
console.log(JSON.stringify({
|
|
12797
|
+
adapters: statuses.map((s) => ({
|
|
12798
|
+
id: s.id,
|
|
12799
|
+
label: s.label,
|
|
12800
|
+
file: s.file,
|
|
12801
|
+
state: s.state,
|
|
12802
|
+
origin_adapter: s.originAdapter,
|
|
12803
|
+
supports_inject: s.supportsInject,
|
|
12804
|
+
recommended_action: s.recommendedAction
|
|
12805
|
+
})),
|
|
12806
|
+
shared_files: buildSharedFileStatuses(statuses).map((f) => ({
|
|
12807
|
+
file: f.file,
|
|
12808
|
+
adapters: f.adapters,
|
|
12809
|
+
state: f.state,
|
|
12810
|
+
origin_adapter: f.originAdapter
|
|
12811
|
+
}))
|
|
12812
|
+
}, null, 2));
|
|
12813
|
+
return;
|
|
12814
|
+
}
|
|
12815
|
+
const idPad = Math.max(...statuses.map((s) => s.id.length));
|
|
12816
|
+
console.log("Adapter status:\n");
|
|
12817
|
+
for (const s of statuses) {
|
|
12818
|
+
const origin = s.originAdapter && s.originAdapter !== s.id ? ` by ${s.originAdapter}` : "";
|
|
12819
|
+
console.log(` ${s.id.padEnd(idPad)} ${s.file.padEnd(10)} ${s.state}${origin}`);
|
|
12820
|
+
}
|
|
12821
|
+
const actionable = statuses.filter((s) => s.state !== "injected" && s.state !== "full-generated");
|
|
12822
|
+
if (actionable.length > 0) {
|
|
12823
|
+
console.log("\nRecommended actions:\n");
|
|
12824
|
+
for (const s of actionable) console.log(` ${s.id}:
|
|
12825
|
+
${s.recommendedAction}`);
|
|
12826
|
+
} else {
|
|
12827
|
+
console.log("\nAll adapters are installed or up to date.");
|
|
12828
|
+
}
|
|
12829
|
+
}
|
|
12705
12830
|
|
|
12706
12831
|
// src/index.ts
|
|
12707
12832
|
var require2 = createRequire(import.meta.url);
|
|
@@ -12757,10 +12882,16 @@ var questionsAction = (opts) => runQuestions(opts);
|
|
|
12757
12882
|
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);
|
|
12758
12883
|
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);
|
|
12759
12884
|
var adaptersCmd = program.command("adapters").description("Generate adapters that project Kaddo knowledge for external coding agents");
|
|
12760
|
-
adaptersCmd.command("install <adapter>").description("Generate an adapter file (codex/opencode/antigravity \u2192 AGENTS.md, claude \u2192 CLAUDE.md) from Kaddo knowledge").option("--force", "Overwrite an existing output file").option("--inject", "Add or update only the Kaddo block in an existing file, preserving the rest").option("--dry-run", "Print the content without writing files").action((adapter, opts) => {
|
|
12885
|
+
adaptersCmd.command("install <adapter>").description("Generate an adapter file (codex/opencode/antigravity/kiro \u2192 AGENTS.md, claude \u2192 CLAUDE.md) from Kaddo knowledge").option("--force", "Overwrite an existing output file").option("--inject", "Add or update only the Kaddo block in an existing file, preserving the rest").option("--dry-run", "Print the content without writing files").action((adapter, opts) => {
|
|
12761
12886
|
runAdaptersInstall(adapter, opts);
|
|
12762
12887
|
});
|
|
12763
|
-
|
|
12888
|
+
adaptersCmd.command("list").alias("ls").description("List the supported adapters and their target files").option("--json", "Output JSON").action((opts) => {
|
|
12889
|
+
runAdaptersList(opts);
|
|
12890
|
+
});
|
|
12891
|
+
adaptersCmd.command("status").alias("check").description("Show the install state of each adapter in this project (read-only)").option("--json", "Output JSON").action((opts) => {
|
|
12892
|
+
runAdaptersStatus(opts);
|
|
12893
|
+
});
|
|
12894
|
+
program.command("export <adapter>").description("Alias for `kaddo adapters install <adapter>` (codex/opencode/antigravity/kiro \u2192 AGENTS.md, claude \u2192 CLAUDE.md)").option("--force", "Overwrite an existing output file").option("--inject", "Add or update only the Kaddo block in an existing file, preserving the rest").option("--dry-run", "Print the content without writing files").action((adapter, opts) => {
|
|
12764
12895
|
runAdaptersInstall(adapter, opts);
|
|
12765
12896
|
});
|
|
12766
12897
|
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) => {
|