@kody-ade/kody-engine 0.2.63 → 0.3.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.
Files changed (32) hide show
  1. package/README.md +24 -24
  2. package/dist/bin/{kody2.js → kody.js} +270 -164
  3. package/dist/executables/bug/profile.json +6 -6
  4. package/dist/executables/chore/profile.json +6 -6
  5. package/dist/executables/classify/profile.json +1 -1
  6. package/dist/executables/feature/profile.json +6 -6
  7. package/dist/executables/fix/profile.json +20 -3
  8. package/dist/executables/fix/prompt.md +1 -1
  9. package/dist/executables/fix-ci/profile.json +1 -1
  10. package/dist/executables/init/profile.json +1 -1
  11. package/dist/executables/plan/profile.json +23 -3
  12. package/dist/executables/plan/prompt.md +117 -9
  13. package/dist/executables/plan-verify/profile.json +2 -2
  14. package/dist/executables/plan-verify/prompt.md +1 -1
  15. package/dist/executables/research/profile.json +25 -3
  16. package/dist/executables/research/prompt.md +4 -0
  17. package/dist/executables/resolve/profile.json +1 -1
  18. package/dist/executables/review/profile.json +20 -3
  19. package/dist/executables/run/profile.json +1 -1
  20. package/dist/executables/run/prompt.md +2 -2
  21. package/dist/executables/spec/profile.json +4 -4
  22. package/dist/executables/sync/profile.json +1 -1
  23. package/dist/executables/types.ts +3 -3
  24. package/dist/executables/ui-review/profile.json +10 -4
  25. package/dist/executables/ui-review/prompt.md +8 -8
  26. package/dist/plugins/commands/kody-live-probe.md +2 -2
  27. package/dist/plugins/skills/kody-live-marker/SKILL.md +3 -3
  28. package/dist/plugins/test-plugin/.claude-plugin/plugin.json +2 -2
  29. package/dist/plugins/test-plugin/skills/kody-plugin-marker/SKILL.md +2 -2
  30. package/kody.config.schema.json +3 -3
  31. package/package.json +4 -4
  32. package/templates/{kody2.yml → kody.yml} +16 -16
@@ -3,12 +3,12 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@kody-ade/kody-engine",
6
- version: "0.2.63",
7
- description: "kody2 \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
6
+ version: "0.3.1",
7
+ description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
8
8
  license: "MIT",
9
9
  type: "module",
10
10
  bin: {
11
- kody2: "dist/bin/kody2.js"
11
+ kody: "dist/bin/kody.js"
12
12
  },
13
13
  files: [
14
14
  "dist",
@@ -16,7 +16,7 @@ var package_default = {
16
16
  "kody.config.schema.json"
17
17
  ],
18
18
  scripts: {
19
- kody2: "tsx bin/kody2.ts",
19
+ kody: "tsx bin/kody.ts",
20
20
  build: "tsup && node scripts/copy-assets.cjs",
21
21
  test: "vitest run tests/unit tests/int --no-coverage",
22
22
  "test:e2e": "vitest run tests/e2e --no-coverage",
@@ -73,7 +73,7 @@ var FileSink = class {
73
73
  };
74
74
  var HttpSink = class {
75
75
  constructor(baseUrl, sessionId, logger = {
76
- warn: (m) => process.stderr.write(`[kody2:chat] ${m}
76
+ warn: (m) => process.stderr.write(`[kody:chat] ${m}
77
77
  `)
78
78
  }) {
79
79
  this.baseUrl = baseUrl;
@@ -340,7 +340,7 @@ function formatBytes(bytes) {
340
340
  // src/agent.ts
341
341
  var DEFAULT_ALLOWED_TOOLS = ["Bash", "Edit", "Read", "Write", "Glob", "Grep"];
342
342
  async function runAgent(opts) {
343
- const ndjsonDir = opts.ndjsonDir ?? path3.join(opts.cwd, ".kody2");
343
+ const ndjsonDir = opts.ndjsonDir ?? path3.join(opts.cwd, ".kody");
344
344
  fs3.mkdirSync(ndjsonDir, { recursive: true });
345
345
  const ndjsonPath = path3.join(ndjsonDir, "last-run.jsonl");
346
346
  const fullLog = fs3.createWriteStream(ndjsonPath, { flags: "w" });
@@ -366,7 +366,14 @@ async function runAgent(opts) {
366
366
  env
367
367
  };
368
368
  if (opts.mcpServers && opts.mcpServers.length > 0) {
369
- queryOptions.mcpServers = opts.mcpServers;
369
+ queryOptions.mcpServers = Object.fromEntries(
370
+ opts.mcpServers.map((s) => {
371
+ const cfg = { command: s.command };
372
+ if (s.args) cfg.args = s.args;
373
+ if (s.env) cfg.env = s.env;
374
+ return [s.name, cfg];
375
+ })
376
+ );
370
377
  }
371
378
  if (opts.pluginPaths && opts.pluginPaths.length > 0) {
372
379
  queryOptions.plugins = opts.pluginPaths.map((p) => ({ type: "local", path: p }));
@@ -544,7 +551,7 @@ async function emit(sink, type, sessionId, suffix, payload) {
544
551
  });
545
552
  }
546
553
 
547
- // src/kody2-cli.ts
554
+ // src/kody-cli.ts
548
555
  import { execFileSync as execFileSync20 } from "child_process";
549
556
  import * as fs21 from "fs";
550
557
  import * as path18 from "path";
@@ -623,9 +630,9 @@ function asDispatch(executable, target) {
623
630
  return { executable, cliArgs: { issue: target }, target };
624
631
  }
625
632
  function extractAfterTag(body) {
626
- const idx = body.indexOf("@kody2");
633
+ const idx = body.indexOf("@kody");
627
634
  if (idx === -1) return body;
628
- return body.slice(idx + "@kody2".length).trim();
635
+ return body.slice(idx + "@kody".length).trim();
629
636
  }
630
637
  function extractSubcommand(afterTag) {
631
638
  const match = afterTag.match(/^([a-z][a-z0-9-]{1,40})\b/);
@@ -685,13 +692,13 @@ async function startLitellmIfNeeded(model, projectDir, url = LITELLM_DEFAULT_URL
685
692
  throw new Error("litellm not installed \u2014 run: pip install 'litellm[proxy]'");
686
693
  }
687
694
  }
688
- const configPath = path5.join(os.tmpdir(), `kody2-litellm-${Date.now()}.yaml`);
695
+ const configPath = path5.join(os.tmpdir(), `kody-litellm-${Date.now()}.yaml`);
689
696
  fs6.writeFileSync(configPath, generateLitellmConfigYaml(model));
690
697
  const portMatch = url.match(/:(\d+)/);
691
698
  const port = portMatch ? portMatch[1] : "4000";
692
699
  const args = cmd === "litellm" ? ["--config", configPath, "--port", port] : ["-m", "litellm", "--config", configPath, "--port", port];
693
700
  const dotenvVars = readDotenvApiKeys(projectDir);
694
- const logPath = path5.join(os.tmpdir(), `kody2-litellm-${Date.now()}.log`);
701
+ const logPath = path5.join(os.tmpdir(), `kody-litellm-${Date.now()}.log`);
695
702
  const outFd = fs6.openSync(logPath, "w");
696
703
  const child = spawn(cmd, args, {
697
704
  stdio: ["ignore", outFd, outFd],
@@ -1000,8 +1007,8 @@ import { execFileSync as execFileSync3 } from "child_process";
1000
1007
 
1001
1008
  // src/state.ts
1002
1009
  import { execFileSync as execFileSync2 } from "child_process";
1003
- var STATE_BEGIN = "<!-- kody2:state:v1:begin -->";
1004
- var STATE_END = "<!-- kody2:state:v1:end -->";
1010
+ var STATE_BEGIN = "<!-- kody:state:v1:begin -->";
1011
+ var STATE_END = "<!-- kody:state:v1:end -->";
1005
1012
  var HISTORY_MAX_ENTRIES = 20;
1006
1013
  var API_TIMEOUT_MS = 3e4;
1007
1014
  function emptyState() {
@@ -1117,7 +1124,7 @@ function noteFromAction(action) {
1117
1124
  }
1118
1125
  function renderStateComment(state) {
1119
1126
  const lines = [];
1120
- lines.push("## \u{1F4CB} kody2 task state");
1127
+ lines.push("## \u{1F4CB} kody task state");
1121
1128
  lines.push("");
1122
1129
  if (state.flow) {
1123
1130
  lines.push(`- **Flow:** \`${state.flow.name}\` (step: \`${state.flow.step}\`)`);
@@ -1197,7 +1204,7 @@ function writeTaskState(target, number, state, cwd) {
1197
1204
  }
1198
1205
  } catch (err) {
1199
1206
  process.stderr.write(
1200
- `[kody2 state] failed to write state on ${target} #${number}: ${err instanceof Error ? err.message : String(err)}
1207
+ `[kody state] failed to write state on ${target} #${number}: ${err instanceof Error ? err.message : String(err)}
1201
1208
  `
1202
1209
  );
1203
1210
  }
@@ -1221,12 +1228,12 @@ var advanceFlow = async (ctx, profile) => {
1221
1228
  writeTaskState("issue", flow.issueNumber, next, ctx.cwd);
1222
1229
  } catch (err) {
1223
1230
  process.stderr.write(
1224
- `[kody2 advanceFlow] failed to mirror action to issue #${flow.issueNumber}: ${err instanceof Error ? err.message : String(err)}
1231
+ `[kody advanceFlow] failed to mirror action to issue #${flow.issueNumber}: ${err instanceof Error ? err.message : String(err)}
1225
1232
  `
1226
1233
  );
1227
1234
  }
1228
1235
  }
1229
- const body = `@kody2 ${flow.name}`;
1236
+ const body = `@kody ${flow.name}`;
1230
1237
  try {
1231
1238
  execFileSync3("gh", ["issue", "comment", String(flow.issueNumber), "--body", body], {
1232
1239
  timeout: API_TIMEOUT_MS2,
@@ -1235,7 +1242,7 @@ var advanceFlow = async (ctx, profile) => {
1235
1242
  });
1236
1243
  } catch (err) {
1237
1244
  process.stderr.write(
1238
- `[kody2 advanceFlow] failed to re-trigger orchestrator on issue #${flow.issueNumber}: ${err instanceof Error ? err.message : String(err)}
1245
+ `[kody advanceFlow] failed to re-trigger orchestrator on issue #${flow.issueNumber}: ${err instanceof Error ? err.message : String(err)}
1239
1246
  `
1240
1247
  );
1241
1248
  }
@@ -1266,7 +1273,7 @@ var buildSyntheticPlugin = async (ctx, profile) => {
1266
1273
  if (!needsSynthetic) return;
1267
1274
  const catalog = getPluginsCatalogRoot();
1268
1275
  const runId = `${profile.name}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
1269
- const root = path7.join(os2.tmpdir(), `kody2-synth-${runId}`);
1276
+ const root = path7.join(os2.tmpdir(), `kody-synth-${runId}`);
1270
1277
  fs8.mkdirSync(path7.join(root, ".claude-plugin"), { recursive: true });
1271
1278
  if (cc.skills.length > 0) {
1272
1279
  const dst = path7.join(root, "skills");
@@ -1313,9 +1320,9 @@ var buildSyntheticPlugin = async (ctx, profile) => {
1313
1320
  `);
1314
1321
  }
1315
1322
  const manifest = {
1316
- name: `kody2-synth-${profile.name}`,
1323
+ name: `kody-synth-${profile.name}`,
1317
1324
  version: "1.0.0",
1318
- description: `Synthetic plugin assembled by Kody2 for profile '${profile.name}' at runtime.`
1325
+ description: `Synthetic plugin assembled by Kody for profile '${profile.name}' at runtime.`
1319
1326
  };
1320
1327
  if (cc.skills.length > 0) manifest.skills = ["./skills/"];
1321
1328
  if (cc.commands.length > 0) manifest.commands = ["./commands/"];
@@ -1428,6 +1435,7 @@ function parseAgentResult(finalText) {
1428
1435
  prSummary: "",
1429
1436
  feedbackActions: "",
1430
1437
  planDeviations: "",
1438
+ priorArt: "",
1431
1439
  failureReason: "agent produced no final message"
1432
1440
  };
1433
1441
  const failedMatch = text.match(/(?:^|\n)\s*FAILED\s*:\s*(.+?)\s*$/s);
@@ -1438,6 +1446,7 @@ function parseAgentResult(finalText) {
1438
1446
  prSummary: "",
1439
1447
  feedbackActions: "",
1440
1448
  planDeviations: "",
1449
+ priorArt: "",
1441
1450
  failureReason: failedMatch[1].trim()
1442
1451
  };
1443
1452
  }
@@ -1450,6 +1459,7 @@ function parseAgentResult(finalText) {
1450
1459
  prSummary: "",
1451
1460
  feedbackActions: "",
1452
1461
  planDeviations: "",
1462
+ priorArt: "",
1453
1463
  failureReason: "no DONE or FAILED marker in agent output"
1454
1464
  };
1455
1465
  }
@@ -1458,24 +1468,27 @@ function parseAgentResult(finalText) {
1458
1468
  const feedbackActions = extractBlock(
1459
1469
  text,
1460
1470
  /(?:^|\n)[ \t]*FEEDBACK_ACTIONS\s*:[ \t]*\n/i,
1461
- /(?:^|\n)[ \t]*(?:PLAN_DEVIATIONS|COMMIT_MSG|PR_SUMMARY)\s*:/i
1471
+ /(?:^|\n)[ \t]*(?:PLAN_DEVIATIONS|COMMIT_MSG|PR_SUMMARY|PRIOR_ART)\s*:/i
1462
1472
  );
1463
1473
  let planDeviations = extractBlock(
1464
1474
  text,
1465
1475
  /(?:^|\n)[ \t]*PLAN_DEVIATIONS\s*:[ \t]*\n/i,
1466
- /(?:^|\n)[ \t]*(?:COMMIT_MSG|PR_SUMMARY|FEEDBACK_ACTIONS)\s*:/i
1476
+ /(?:^|\n)[ \t]*(?:COMMIT_MSG|PR_SUMMARY|FEEDBACK_ACTIONS|PRIOR_ART)\s*:/i
1467
1477
  );
1468
1478
  if (!planDeviations) {
1469
1479
  const inline = text.match(/(?:^|\n)[ \t]*PLAN_DEVIATIONS\s*:[ \t]*(.+?)[ \t]*(?:\n|$)/i);
1470
1480
  if (inline) planDeviations = inline[1].trim();
1471
1481
  }
1482
+ let priorArt = "";
1483
+ const priorArtInline = text.match(/(?:^|\n)[ \t]*PRIOR_ART\s*:[ \t]*(.+?)[ \t]*(?:\n|$)/i);
1484
+ if (priorArtInline) priorArt = priorArtInline[1].trim();
1472
1485
  const summaryStart = text.search(/(^|\n)[ \t]*PR_SUMMARY\s*:[ \t]*\n/i);
1473
1486
  let prSummary = "";
1474
1487
  if (summaryStart !== -1) {
1475
1488
  const afterMarker = text.slice(summaryStart).replace(/^[\s\S]*?PR_SUMMARY\s*:[ \t]*\n/i, "");
1476
1489
  prSummary = afterMarker.replace(/\n\s*```\s*$/g, "").replace(/```\s*$/g, "").trim();
1477
1490
  }
1478
- return { done: true, commitMessage, prSummary, feedbackActions, planDeviations, failureReason: "" };
1491
+ return { done: true, commitMessage, prSummary, feedbackActions, planDeviations, priorArt, failureReason: "" };
1479
1492
  }
1480
1493
  function extractBlock(text, startMarker, endMarker) {
1481
1494
  const startIdx = text.search(startMarker);
@@ -1508,7 +1521,7 @@ var checkCoverageWithRetry = async (ctx) => {
1508
1521
  ctx.data.coverageMisses = misses;
1509
1522
  return;
1510
1523
  }
1511
- process.stderr.write(`[kody2] coverage check found ${misses.length} missing test(s); retrying agent once
1524
+ process.stderr.write(`[kody] coverage check found ${misses.length} missing test(s); retrying agent once
1512
1525
  `);
1513
1526
  const retryPrompt = `${basePrompt}
1514
1527
 
@@ -1570,14 +1583,14 @@ import * as path9 from "path";
1570
1583
  var FORBIDDEN_PATH_PREFIXES = [
1571
1584
  ".kody/",
1572
1585
  ".kody-engine/",
1573
- ".kody2/",
1586
+ ".kody/",
1574
1587
  ".kody-lean/",
1575
1588
  // back-compat: stale runtime dir from kody-lean v0.5.x
1576
1589
  "node_modules/",
1577
1590
  "dist/",
1578
1591
  "build/"
1579
1592
  ];
1580
- var FORBIDDEN_PATH_EXACT = /* @__PURE__ */ new Set([".env", ".kody2-pip-requirements.txt"]);
1593
+ var FORBIDDEN_PATH_EXACT = /* @__PURE__ */ new Set([".env", ".kody-pip-requirements.txt"]);
1581
1594
  var FORBIDDEN_PATH_SUFFIXES = [".log"];
1582
1595
  var CONVENTIONAL_PREFIXES = [
1583
1596
  "feat:",
@@ -1677,7 +1690,7 @@ function listFilesInCommit(ref = "HEAD", cwd) {
1677
1690
  }
1678
1691
  function normalizeCommitMessage(raw) {
1679
1692
  const trimmed = raw.trim().replace(/^['"]|['"]$/g, "").trim();
1680
- if (!trimmed) return "chore: kody2 update";
1693
+ if (!trimmed) return "chore: kody update";
1681
1694
  const firstLine2 = trimmed.split("\n")[0];
1682
1695
  for (const prefix of CONVENTIONAL_PREFIXES) {
1683
1696
  if (firstLine2.toLowerCase().startsWith(prefix)) return trimmed;
@@ -1750,7 +1763,7 @@ var commitAndPush2 = async (ctx, profile) => {
1750
1763
  } else {
1751
1764
  const aborted = abortUnfinishedGitOps(ctx.cwd);
1752
1765
  if (aborted.length > 0) {
1753
- process.stderr.write(`[kody2] cleaned up unfinished git ops: ${aborted.join(", ")}
1766
+ process.stderr.write(`[kody] cleaned up unfinished git ops: ${aborted.join(", ")}
1754
1767
  `);
1755
1768
  }
1756
1769
  }
@@ -1770,15 +1783,15 @@ var commitAndPush2 = async (ctx, profile) => {
1770
1783
  function defaultCommitMessage(mode, data) {
1771
1784
  switch (mode) {
1772
1785
  case "run":
1773
- return `chore: kody2 changes for #${data.commentTargetNumber}`;
1786
+ return `chore: kody changes for #${data.commentTargetNumber}`;
1774
1787
  case "fix":
1775
- return `chore(fix): kody2 fix for PR #${data.commentTargetNumber}`;
1788
+ return `chore(fix): kody fix for PR #${data.commentTargetNumber}`;
1776
1789
  case "fix-ci":
1777
- return `fix(ci): kody2 fix-ci for PR #${data.commentTargetNumber}`;
1790
+ return `fix(ci): kody fix-ci for PR #${data.commentTargetNumber}`;
1778
1791
  case "resolve":
1779
1792
  return `fix: resolve merge conflicts with ${data.baseBranch}`;
1780
1793
  default:
1781
- return `chore: kody2 changes`;
1794
+ return `chore: kody changes`;
1782
1795
  }
1783
1796
  }
1784
1797
 
@@ -2301,7 +2314,7 @@ function generateQaGuideTemplate(d) {
2301
2314
  const lines = [];
2302
2315
  lines.push("# QA guide");
2303
2316
  lines.push("");
2304
- lines.push("This file is read by `kody2 ui-review`. Fill in the credential placeholders");
2317
+ lines.push("This file is read by `kody ui-review`. Fill in the credential placeholders");
2305
2318
  lines.push("below and commit \u2014 the agent uses them to log in to your preview deployment.");
2306
2319
  lines.push("");
2307
2320
  lines.push("## Test accounts");
@@ -2371,13 +2384,13 @@ var API_TIMEOUT_MS3 = 3e4;
2371
2384
  var dispatch = async (ctx, _profile, _agentResult, args) => {
2372
2385
  const next = args?.next;
2373
2386
  if (!next) {
2374
- process.stderr.write("[kody2 dispatch] missing `with.next` \u2014 skipping\n");
2387
+ process.stderr.write("[kody dispatch] missing `with.next` \u2014 skipping\n");
2375
2388
  return;
2376
2389
  }
2377
2390
  const target = args?.target ?? "issue";
2378
2391
  const issueNumber = ctx.args.issue;
2379
2392
  if (!issueNumber) {
2380
- process.stderr.write("[kody2 dispatch] no --issue arg \u2014 skipping\n");
2393
+ process.stderr.write("[kody dispatch] no --issue arg \u2014 skipping\n");
2381
2394
  return;
2382
2395
  }
2383
2396
  const state = ctx.data.taskState;
@@ -2387,7 +2400,7 @@ var dispatch = async (ctx, _profile, _agentResult, args) => {
2387
2400
  const usePr = target === "pr" && state?.core.prUrl;
2388
2401
  const targetNumber = usePr ? parsePr(state.core.prUrl) ?? issueNumber : issueNumber;
2389
2402
  const sub = usePr ? "pr" : "issue";
2390
- const body = `@kody2 ${next}`;
2403
+ const body = `@kody ${next}`;
2391
2404
  try {
2392
2405
  execFileSync7("gh", [sub, "comment", String(targetNumber), "--body", body], {
2393
2406
  timeout: API_TIMEOUT_MS3,
@@ -2396,7 +2409,7 @@ var dispatch = async (ctx, _profile, _agentResult, args) => {
2396
2409
  });
2397
2410
  } catch (err) {
2398
2411
  process.stderr.write(
2399
- `[kody2 dispatch] failed to post @kody2 ${next} on ${sub} #${targetNumber}: ${err instanceof Error ? err.message : String(err)}
2412
+ `[kody dispatch] failed to post @kody ${next} on ${sub} #${targetNumber}: ${err instanceof Error ? err.message : String(err)}
2400
2413
  `
2401
2414
  );
2402
2415
  }
@@ -2444,15 +2457,15 @@ function getIssue(issueNumber, cwd) {
2444
2457
  labels: Array.isArray(parsed.labels) ? parsed.labels.map((l) => l.name ?? "").filter((n) => n.length > 0) : []
2445
2458
  };
2446
2459
  }
2447
- function stripKody2Mentions(body) {
2448
- return body.replace(/(@)(kody2)/gi, "$1\u200B$2");
2460
+ function stripKodyMentions(body) {
2461
+ return body.replace(/(@)(kody)/gi, "$1\u200B$2");
2449
2462
  }
2450
2463
  function postIssueComment(issueNumber, body, cwd) {
2451
2464
  try {
2452
- gh2(["issue", "comment", String(issueNumber), "--body-file", "-"], { input: stripKody2Mentions(body), cwd });
2465
+ gh2(["issue", "comment", String(issueNumber), "--body-file", "-"], { input: stripKodyMentions(body), cwd });
2453
2466
  } catch (err) {
2454
2467
  process.stderr.write(
2455
- `[kody2] failed to post comment on #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
2468
+ `[kody] failed to post comment on #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
2456
2469
  `
2457
2470
  );
2458
2471
  }
@@ -2483,7 +2496,7 @@ function getPrDiff(prNumber, cwd) {
2483
2496
  return gh2(["pr", "diff", String(prNumber)], { cwd });
2484
2497
  } catch (err) {
2485
2498
  process.stderr.write(
2486
- `[kody2] failed to fetch diff for PR #${prNumber}: ${err instanceof Error ? err.message : String(err)}
2499
+ `[kody] failed to fetch diff for PR #${prNumber}: ${err instanceof Error ? err.message : String(err)}
2487
2500
  `
2488
2501
  );
2489
2502
  return "";
@@ -2534,10 +2547,10 @@ function getPrLatestReviewBody(prNumber, cwd) {
2534
2547
  }
2535
2548
  function postPrReviewComment(prNumber, body, cwd) {
2536
2549
  try {
2537
- gh2(["pr", "comment", String(prNumber), "--body-file", "-"], { input: stripKody2Mentions(body), cwd });
2550
+ gh2(["pr", "comment", String(prNumber), "--body-file", "-"], { input: stripKodyMentions(body), cwd });
2538
2551
  } catch (err) {
2539
2552
  process.stderr.write(
2540
- `[kody2] failed to post review comment on PR #${prNumber}: ${err instanceof Error ? err.message : String(err)}
2553
+ `[kody] failed to post review comment on PR #${prNumber}: ${err instanceof Error ? err.message : String(err)}
2541
2554
  `
2542
2555
  );
2543
2556
  }
@@ -2600,7 +2613,7 @@ function buildPrBody(opts) {
2600
2613
  lines.push("");
2601
2614
  }
2602
2615
  lines.push("---");
2603
- lines.push("_Opened by kody2 (single-session autonomous run)._ ");
2616
+ lines.push("_Opened by kody (single-session autonomous run)._ ");
2604
2617
  return lines.join("\n");
2605
2618
  }
2606
2619
  function firstLine(s) {
@@ -2671,7 +2684,7 @@ var ensurePr2 = async (ctx) => {
2671
2684
  const issue = ctx.data.issue;
2672
2685
  const pr = ctx.data.pr;
2673
2686
  const targetNumber = Number(ctx.data.commentTargetNumber ?? 0);
2674
- const title = issue?.title ?? pr?.title ?? `kody2 changes`;
2687
+ const title = issue?.title ?? pr?.title ?? `kody changes`;
2675
2688
  try {
2676
2689
  const result = ensurePr({
2677
2690
  branch,
@@ -2843,7 +2856,7 @@ function setKodyLabel(issueNumber, spec, cwd) {
2843
2856
  const target = spec.label;
2844
2857
  if (!target.startsWith(KODY_NAMESPACE)) {
2845
2858
  process.stderr.write(
2846
- `[kody2] setKodyLabel: refusing to set non-kody label "${target}"
2859
+ `[kody] setKodyLabel: refusing to set non-kody label "${target}"
2847
2860
  `
2848
2861
  );
2849
2862
  return;
@@ -2865,14 +2878,14 @@ function setKodyLabel(issueNumber, spec, cwd) {
2865
2878
  return;
2866
2879
  } catch (retryErr) {
2867
2880
  process.stderr.write(
2868
- `[kody2] setKodyLabel: create+retry failed for ${target} on #${issueNumber}: ${errMsg(retryErr)}
2881
+ `[kody] setKodyLabel: create+retry failed for ${target} on #${issueNumber}: ${errMsg(retryErr)}
2869
2882
  `
2870
2883
  );
2871
2884
  return;
2872
2885
  }
2873
2886
  }
2874
2887
  process.stderr.write(
2875
- `[kody2] setKodyLabel: failed to add ${target} on #${issueNumber}: ${errMsg(err)}
2888
+ `[kody] setKodyLabel: failed to add ${target} on #${issueNumber}: ${errMsg(err)}
2876
2889
  `
2877
2890
  );
2878
2891
  }
@@ -2923,7 +2936,7 @@ var finishFlow = async (ctx, _profile, _agentResult, args) => {
2923
2936
  const prSuffix = state?.core.prUrl ? `
2924
2937
 
2925
2938
  **PR:** ${state.core.prUrl}` : "";
2926
- const body = `${icon} kody2 flow \`${flowName}\` finished \u2014 \`${reason}\`${prSuffix}`;
2939
+ const body = `${icon} kody flow \`${flowName}\` finished \u2014 \`${reason}\`${prSuffix}`;
2927
2940
  try {
2928
2941
  execFileSync9("gh", ["issue", "comment", String(issueNumber), "--body", body], {
2929
2942
  timeout: API_TIMEOUT_MS5,
@@ -2932,7 +2945,7 @@ var finishFlow = async (ctx, _profile, _agentResult, args) => {
2932
2945
  });
2933
2946
  } catch (err) {
2934
2947
  process.stderr.write(
2935
- `[kody2 finishFlow] failed to post final summary on issue #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
2948
+ `[kody finishFlow] failed to post final summary on issue #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
2936
2949
  `
2937
2950
  );
2938
2951
  }
@@ -3091,7 +3104,7 @@ function reactToTriggerComment(cwd) {
3091
3104
  }
3092
3105
  }
3093
3106
  process.stderr.write(
3094
- `[kody2] \u{1F440} reaction failed after 3 attempts on comment ${commentId}: ${lastErr instanceof Error ? lastErr.message : String(lastErr)}
3107
+ `[kody] \u{1F440} reaction failed after 3 attempts on comment ${commentId}: ${lastErr instanceof Error ? lastErr.message : String(lastErr)}
3095
3108
  `
3096
3109
  );
3097
3110
  }
@@ -3167,13 +3180,13 @@ function getFailedRunLogTail(runId, maxBytes, cwd) {
3167
3180
  return "";
3168
3181
  }
3169
3182
  }
3170
- function isKody2DispatchWorkflow(workflowName) {
3171
- return workflowName.trim().toLowerCase() === "kody2";
3183
+ function isKodyDispatchWorkflow(workflowName) {
3184
+ return workflowName.trim().toLowerCase() === "kody";
3172
3185
  }
3173
3186
  function pickFailedRunForFixCi(prNumber, maxBytes, limit, cwd) {
3174
3187
  const runs = getRecentFailedRunsForPr(prNumber, limit, cwd);
3175
3188
  for (const run of runs) {
3176
- if (isKody2DispatchWorkflow(run.workflowName)) continue;
3189
+ if (isKodyDispatchWorkflow(run.workflowName)) continue;
3177
3190
  const logTail = getFailedRunLogTail(run.id, maxBytes, cwd);
3178
3191
  if (logTail) return { run, logTail };
3179
3192
  }
@@ -3217,7 +3230,7 @@ var fixCiFlow = async (ctx) => {
3217
3230
  bail(
3218
3231
  ctx,
3219
3232
  prNumber,
3220
- `no actionable failed workflow run found on PR #${prNumber}'s branch (looked at last ${RUN_LOOKBACK} failed runs \u2014 all were either kody2's own dispatch workflow or had no fetchable logs; pass --run-id to target a specific run)`
3233
+ `no actionable failed workflow run found on PR #${prNumber}'s branch (looked at last ${RUN_LOOKBACK} failed runs \u2014 all were either kody's own dispatch workflow or had no fetchable logs; pass --run-id to target a specific run)`
3221
3234
  );
3222
3235
  return;
3223
3236
  }
@@ -3232,10 +3245,10 @@ var fixCiFlow = async (ctx) => {
3232
3245
  ctx.data.failedLogTail = logTail;
3233
3246
  ctx.data.prDiff = getPrDiff(prNumber, ctx.cwd);
3234
3247
  const runUrl = getRunUrl();
3235
- const runSuffix = runUrl ? `, kody2 run ${runUrl}` : "";
3248
+ const runSuffix = runUrl ? `, kody run ${runUrl}` : "";
3236
3249
  tryPostPr(
3237
3250
  prNumber,
3238
- `\u2699\uFE0F kody2 fix-ci started on \`${ctx.data.branch}\`${runSuffix} \u2014 analyzing workflow run ${runId}`,
3251
+ `\u2699\uFE0F kody fix-ci started on \`${ctx.data.branch}\`${runSuffix} \u2014 analyzing workflow run ${runId}`,
3239
3252
  ctx.cwd
3240
3253
  );
3241
3254
  };
@@ -3245,7 +3258,7 @@ function bail(ctx, prNumber, reason) {
3245
3258
  ctx.skipAgent = true;
3246
3259
  const runUrl = getRunUrl();
3247
3260
  const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
3248
- tryPostPr(prNumber, `\u274C kody2 fix-ci could not run${runSuffix}: ${reason}`, ctx.cwd);
3261
+ tryPostPr(prNumber, `\u274C kody fix-ci could not run${runSuffix}: ${reason}`, ctx.cwd);
3249
3262
  }
3250
3263
  function tryPostPr(prNumber, body, cwd) {
3251
3264
  try {
@@ -3283,7 +3296,7 @@ var fixFlow = async (ctx) => {
3283
3296
  const runSuffix = runUrl ? `, run ${runUrl}` : "";
3284
3297
  tryPostPr2(
3285
3298
  prNumber,
3286
- `\u2699\uFE0F kody2 fix started on \`${ctx.data.branch}\`${runSuffix} \u2014 applying feedback (${truncate2(feedback.replace(/\n/g, " "), 200)})`,
3299
+ `\u2699\uFE0F kody fix started on \`${ctx.data.branch}\`${runSuffix} \u2014 applying feedback (${truncate2(feedback.replace(/\n/g, " "), 200)})`,
3287
3300
  ctx.cwd
3288
3301
  );
3289
3302
  };
@@ -3302,7 +3315,7 @@ import * as path15 from "path";
3302
3315
  // src/scripts/loadQaGuide.ts
3303
3316
  import * as fs16 from "fs";
3304
3317
  import * as path14 from "path";
3305
- var QA_GUIDE_REL_PATH = ".kody2/qa-guide.md";
3318
+ var QA_GUIDE_REL_PATH = ".kody/qa-guide.md";
3306
3319
  var loadQaGuide = async (ctx) => {
3307
3320
  const full = path14.join(ctx.cwd, QA_GUIDE_REL_PATH);
3308
3321
  if (!fs16.existsSync(full)) {
@@ -3362,20 +3375,20 @@ function makeConfig(pm, ownerRepo, defaultBranch) {
3362
3375
  }
3363
3376
  };
3364
3377
  }
3365
- var WORKFLOW_TEMPLATE = `# Drop this file at .github/workflows/kody2.yml in your repo.
3378
+ var WORKFLOW_TEMPLATE = `# Drop this file at .github/workflows/kody.yml in your repo.
3366
3379
  #
3367
- # Triggers: @kody2 comment on an issue or PR, or manual workflow_dispatch.
3380
+ # Triggers: @kody comment on an issue or PR, or manual workflow_dispatch.
3368
3381
  # Everything else (install deps, set up LiteLLM, run the agent, open the PR)
3369
3382
  # is handled inside the @kody-ade/kody-engine package.
3370
3383
  #
3371
3384
  # Required repo secrets: at least one model provider key (e.g. MINIMAX_API_KEY,
3372
- # ANTHROPIC_API_KEY). kody2 reads any *_API_KEY secret automatically via
3385
+ # ANTHROPIC_API_KEY). kody reads any *_API_KEY secret automatically via
3373
3386
  # toJSON(secrets) \u2014 no need to list them here.
3374
3387
  #
3375
3388
  # Recommended: KODY_TOKEN secret \u2014 a PAT or GitHub App token with repo
3376
- # scope so kody2's pushes trigger downstream CI and PR-body edits succeed.
3389
+ # scope so kody's pushes trigger downstream CI and PR-body edits succeed.
3377
3390
 
3378
- name: kody2
3391
+ name: kody
3379
3392
 
3380
3393
  on:
3381
3394
  workflow_dispatch:
@@ -3393,7 +3406,7 @@ jobs:
3393
3406
  \${{ github.event_name == 'workflow_dispatch' ||
3394
3407
  (github.event_name == 'issue_comment' &&
3395
3408
  !github.event.issue.pull_request &&
3396
- contains(github.event.comment.body, '@kody2')) }}
3409
+ contains(github.event.comment.body, '@kody')) }}
3397
3410
  runs-on: ubuntu-latest
3398
3411
  timeout-minutes: 60
3399
3412
  permissions:
@@ -3416,7 +3429,7 @@ jobs:
3416
3429
 
3417
3430
  - env:
3418
3431
  ALL_SECRETS: \${{ toJSON(secrets) }}
3419
- run: npx -y -p @kody-ade/kody-engine@latest kody2 ci --issue \${{ github.event.inputs.issue_number || github.event.issue.number }}
3432
+ run: npx -y -p @kody-ade/kody-engine@latest kody ci --issue \${{ github.event.inputs.issue_number || github.event.issue.number }}
3420
3433
  `;
3421
3434
  function defaultBranchFromGit(cwd) {
3422
3435
  try {
@@ -3454,13 +3467,13 @@ function performInit(cwd, force) {
3454
3467
  wrote.push("kody.config.json");
3455
3468
  }
3456
3469
  const workflowDir = path15.join(cwd, ".github", "workflows");
3457
- const workflowPath = path15.join(workflowDir, "kody2.yml");
3470
+ const workflowPath = path15.join(workflowDir, "kody.yml");
3458
3471
  if (fs17.existsSync(workflowPath) && !force) {
3459
- skipped.push(".github/workflows/kody2.yml");
3472
+ skipped.push(".github/workflows/kody.yml");
3460
3473
  } else {
3461
3474
  fs17.mkdirSync(workflowDir, { recursive: true });
3462
3475
  fs17.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
3463
- wrote.push(".github/workflows/kody2.yml");
3476
+ wrote.push(".github/workflows/kody.yml");
3464
3477
  }
3465
3478
  const hasUi = fs17.existsSync(path15.join(cwd, "src/app")) || fs17.existsSync(path15.join(cwd, "app")) || fs17.existsSync(path15.join(cwd, "pages"));
3466
3479
  if (hasUi) {
@@ -3482,13 +3495,13 @@ function performInit(cwd, force) {
3482
3495
  continue;
3483
3496
  }
3484
3497
  if (profile.kind !== "scheduled" || !profile.schedule) continue;
3485
- const target = path15.join(workflowDir, `kody2-${exe.name}.yml`);
3498
+ const target = path15.join(workflowDir, `kody-${exe.name}.yml`);
3486
3499
  if (fs17.existsSync(target) && !force) {
3487
- skipped.push(`.github/workflows/kody2-${exe.name}.yml`);
3500
+ skipped.push(`.github/workflows/kody-${exe.name}.yml`);
3488
3501
  continue;
3489
3502
  }
3490
3503
  fs17.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
3491
- wrote.push(`.github/workflows/kody2-${exe.name}.yml`);
3504
+ wrote.push(`.github/workflows/kody-${exe.name}.yml`);
3492
3505
  }
3493
3506
  let labels;
3494
3507
  try {
@@ -3499,11 +3512,11 @@ function performInit(cwd, force) {
3499
3512
  return { wrote, skipped, labels };
3500
3513
  }
3501
3514
  function renderScheduledWorkflow(name, cron) {
3502
- return `# Scheduled kody2 executable: ${name}
3503
- # Generated by \`kody2 init\`. Regenerate with \`kody2 init --force\`.
3515
+ return `# Scheduled kody executable: ${name}
3516
+ # Generated by \`kody init\`. Regenerate with \`kody init --force\`.
3504
3517
  # Edit the cron below or the executable's profile.json#schedule.
3505
3518
 
3506
- name: kody2 ${name}
3519
+ name: kody ${name}
3507
3520
 
3508
3521
  on:
3509
3522
  schedule:
@@ -3527,14 +3540,14 @@ jobs:
3527
3540
  node-version: 22
3528
3541
  - env:
3529
3542
  GH_TOKEN: \${{ secrets.KODY_TOKEN || github.token }}
3530
- run: npx -y -p @kody-ade/kody-engine@latest kody2 ${name}
3543
+ run: npx -y -p @kody-ade/kody-engine@latest kody ${name}
3531
3544
  `;
3532
3545
  }
3533
3546
  var initFlow = async (ctx) => {
3534
3547
  const force = ctx.args.force === true;
3535
3548
  const cwd = ctx.cwd;
3536
3549
  const { wrote, skipped, labels } = performInit(cwd, force);
3537
- process.stdout.write("\u2192 kody2 init\n");
3550
+ process.stdout.write("\u2192 kody init\n");
3538
3551
  for (const f of wrote) process.stdout.write(` wrote ${f}
3539
3552
  `);
3540
3553
  for (const f of skipped) process.stdout.write(` skipped ${f} (already exists; pass --force to overwrite)
@@ -3567,7 +3580,7 @@ var loadConventions = async (ctx) => {
3567
3580
  const conventions = loadProjectConventions(ctx.cwd);
3568
3581
  ctx.data.conventions = conventions;
3569
3582
  if (conventions.length > 0) {
3570
- process.stderr.write(`[kody2] loaded conventions: ${conventions.map((c) => c.path).join(", ")}
3583
+ process.stderr.write(`[kody] loaded conventions: ${conventions.map((c) => c.path).join(", ")}
3571
3584
  `);
3572
3585
  }
3573
3586
  };
@@ -3600,6 +3613,97 @@ var loadIssueContext = async (ctx) => {
3600
3613
  ctx.data.commentTargetNumber = issueNumber;
3601
3614
  };
3602
3615
 
3616
+ // src/scripts/loadPriorArt.ts
3617
+ var PER_PR_DIFF_MAX_BYTES = 8e3;
3618
+ var TOTAL_MAX_BYTES = 3e4;
3619
+ var TRUNCATED_SUFFIX = "\n\n\u2026 (truncated)";
3620
+ var loadPriorArt = async (ctx, _profile, args) => {
3621
+ const artifactName = typeof args?.artifactName === "string" ? args.artifactName : "priorArt";
3622
+ const state = ctx.data.taskState;
3623
+ const artifact = state?.artifacts?.[artifactName];
3624
+ const prNumbers = parsePrNumbers(artifact?.content);
3625
+ if (prNumbers.length === 0) {
3626
+ ctx.data.priorArt = "";
3627
+ return;
3628
+ }
3629
+ const blocks = [];
3630
+ for (const n of prNumbers) {
3631
+ const block = fetchPrBlock(n, ctx.cwd);
3632
+ if (block) blocks.push(block);
3633
+ }
3634
+ const joined = blocks.join("\n\n---\n\n");
3635
+ ctx.data.priorArt = joined.length > TOTAL_MAX_BYTES ? joined.slice(0, TOTAL_MAX_BYTES) + TRUNCATED_SUFFIX : joined;
3636
+ };
3637
+ function parsePrNumbers(raw) {
3638
+ if (!raw) return [];
3639
+ const trimmed = raw.trim();
3640
+ if (!trimmed) return [];
3641
+ try {
3642
+ const parsed = JSON.parse(trimmed);
3643
+ if (!Array.isArray(parsed)) return [];
3644
+ return parsed.filter((n) => typeof n === "number" && Number.isInteger(n) && n > 0);
3645
+ } catch {
3646
+ return [];
3647
+ }
3648
+ }
3649
+ function fetchPrBlock(prNumber, cwd) {
3650
+ try {
3651
+ const metaRaw = gh2(["pr", "view", String(prNumber), "--json", "title,state,url,mergedAt,closedAt"], { cwd });
3652
+ const meta = JSON.parse(metaRaw);
3653
+ const diff = truncate3(safeGh(["pr", "diff", String(prNumber)], cwd), PER_PR_DIFF_MAX_BYTES);
3654
+ const commentsRaw = safeGh(["pr", "view", String(prNumber), "--json", "comments,reviews"], cwd);
3655
+ const commentsBlock = formatReviewComments(commentsRaw);
3656
+ const lines = [
3657
+ `## Prior art: PR #${prNumber} \u2014 ${meta.title ?? "(no title)"} [${meta.state ?? "unknown"}]`,
3658
+ meta.url ? meta.url : "",
3659
+ "",
3660
+ "### Diff",
3661
+ "```diff",
3662
+ diff || "(empty)",
3663
+ "```"
3664
+ ];
3665
+ if (commentsBlock) {
3666
+ lines.push("");
3667
+ lines.push("### Review comments");
3668
+ lines.push(commentsBlock);
3669
+ }
3670
+ return lines.filter((l) => l !== "").join("\n");
3671
+ } catch (err) {
3672
+ return `## Prior art: PR #${prNumber}
3673
+ _Could not fetch \u2014 ${err instanceof Error ? err.message : String(err)}_`;
3674
+ }
3675
+ }
3676
+ function safeGh(args, cwd) {
3677
+ try {
3678
+ return gh2(args, { cwd });
3679
+ } catch {
3680
+ return "";
3681
+ }
3682
+ }
3683
+ function truncate3(s, max) {
3684
+ return s.length <= max ? s : s.slice(0, max) + TRUNCATED_SUFFIX;
3685
+ }
3686
+ function formatReviewComments(raw) {
3687
+ if (!raw) return "";
3688
+ try {
3689
+ const parsed = JSON.parse(raw);
3690
+ const out = [];
3691
+ for (const c of parsed.comments ?? []) {
3692
+ if (!c.body) continue;
3693
+ out.push(`- **${c.author?.login ?? "unknown"}**: ${c.body.replace(/\n/g, " ").slice(0, 500)}`);
3694
+ }
3695
+ for (const r of parsed.reviews ?? []) {
3696
+ if (!r.body && !r.state) continue;
3697
+ const state = r.state ? ` (${r.state})` : "";
3698
+ const body = r.body ? `: ${r.body.replace(/\n/g, " ").slice(0, 500)}` : "";
3699
+ out.push(`- **${r.author?.login ?? "unknown"}**${state}${body}`);
3700
+ }
3701
+ return out.join("\n");
3702
+ } catch {
3703
+ return "";
3704
+ }
3705
+ }
3706
+
3603
3707
  // src/scripts/loadTaskState.ts
3604
3708
  var loadTaskState = async (ctx) => {
3605
3709
  const target = ctx.data.commentTargetType;
@@ -3631,7 +3735,7 @@ var mirrorStateToPr = async (ctx) => {
3631
3735
  writeTaskState("pr", prNumber, state, ctx.cwd);
3632
3736
  } catch (err) {
3633
3737
  process.stderr.write(
3634
- `[kody2 mirrorStateToPr] failed to mirror state to PR #${prNumber}: ${err instanceof Error ? err.message : String(err)}
3738
+ `[kody mirrorStateToPr] failed to mirror state to PR #${prNumber}: ${err instanceof Error ? err.message : String(err)}
3635
3739
  `
3636
3740
  );
3637
3741
  }
@@ -3656,6 +3760,7 @@ var parseAgentResult2 = async (ctx, profile, agentResult) => {
3656
3760
  ctx.data.prSummary = parsed.prSummary;
3657
3761
  ctx.data.feedbackActions = parsed.feedbackActions;
3658
3762
  ctx.data.planDeviations = parsed.planDeviations;
3763
+ ctx.data.priorArt = parsed.priorArt;
3659
3764
  ctx.data.agentFailureReason = parsed.failureReason;
3660
3765
  ctx.data.agentOutcome = agentResult.outcome;
3661
3766
  ctx.data.agentError = agentResult.error;
@@ -3714,7 +3819,7 @@ var persistFlowState = async (ctx) => {
3714
3819
  writeTaskState("issue", issueNumber, state, ctx.cwd);
3715
3820
  } catch (err) {
3716
3821
  process.stderr.write(
3717
- `[kody2 persistFlowState] failed to write state on issue #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
3822
+ `[kody persistFlowState] failed to write state on issue #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
3718
3823
  `
3719
3824
  );
3720
3825
  }
@@ -3740,25 +3845,25 @@ var postClassification = async (ctx) => {
3740
3845
  }
3741
3846
  if (!classification) {
3742
3847
  ctx.data.action = failedAction("classification missing or invalid");
3743
- tryAuditComment(issueNumber, "\u26A0\uFE0F kody2 classifier could not decide \u2014 please re-run with an explicit `@kody2 <type>`.", ctx.cwd);
3848
+ tryAuditComment(issueNumber, "\u26A0\uFE0F kody classifier could not decide \u2014 please re-run with an explicit `@kody <type>`.", ctx.cwd);
3744
3849
  ctx.output.exitCode = 1;
3745
3850
  ctx.output.reason = "classify: no decision";
3746
3851
  return;
3747
3852
  }
3748
3853
  tryAuditComment(
3749
3854
  issueNumber,
3750
- `\u{1F50E} kody2 classified as \`${classification}\`${reason ? ` \u2014 ${reason}` : ""}`,
3855
+ `\u{1F50E} kody classified as \`${classification}\`${reason ? ` \u2014 ${reason}` : ""}`,
3751
3856
  ctx.cwd
3752
3857
  );
3753
3858
  try {
3754
- execFileSync14("gh", ["issue", "comment", String(issueNumber), "--body", `@kody2 ${classification}`], {
3859
+ execFileSync14("gh", ["issue", "comment", String(issueNumber), "--body", `@kody ${classification}`], {
3755
3860
  cwd: ctx.cwd,
3756
3861
  timeout: API_TIMEOUT_MS6,
3757
3862
  stdio: ["ignore", "pipe", "pipe"]
3758
3863
  });
3759
3864
  } catch (err) {
3760
3865
  process.stderr.write(
3761
- `[kody2 postClassification] failed to dispatch @kody2 ${classification}: ${err instanceof Error ? err.message : String(err)}
3866
+ `[kody postClassification] failed to dispatch @kody ${classification}: ${err instanceof Error ? err.message : String(err)}
3762
3867
  `
3763
3868
  );
3764
3869
  ctx.data.action = failedAction("dispatch post failed");
@@ -3812,22 +3917,22 @@ var postIssueComment2 = async (ctx) => {
3812
3917
  const prAction = ctx.data.prResult?.action;
3813
3918
  if (!commitResult?.committed && !hasCommits) {
3814
3919
  const reason = "no changes to commit";
3815
- postWith(targetType, targetNumber, `\u26A0\uFE0F kody2 FAILED: ${reason}`, ctx.cwd);
3920
+ postWith(targetType, targetNumber, `\u26A0\uFE0F kody FAILED: ${reason}`, ctx.cwd);
3816
3921
  ctx.output.exitCode = 3;
3817
3922
  ctx.output.reason = reason;
3818
3923
  return;
3819
3924
  }
3820
3925
  if (ctx.output.exitCode === 4 && ctx.data.prCrashReason) {
3821
- postWith(targetType, targetNumber, `\u26A0\uFE0F kody2 FAILED: ${truncate2(ctx.data.prCrashReason, 1500)}`, ctx.cwd);
3926
+ postWith(targetType, targetNumber, `\u26A0\uFE0F kody FAILED: ${truncate2(ctx.data.prCrashReason, 1500)}`, ctx.cwd);
3822
3927
  ctx.output.reason = ctx.data.prCrashReason;
3823
3928
  return;
3824
3929
  }
3825
3930
  const failureReason = computeFailureReason2(ctx);
3826
3931
  const isFailure = failureReason.length > 0;
3827
3932
  const justPushedToExistingPr = prAction === "updated" && commitResult?.committed === true;
3828
- const successMsg = justPushedToExistingPr ? `\u2705 kody2 pushed to ${prUrl}` : prAction === "updated" ? `\u2139\uFE0F kody2 made no changes \u2014 PR: ${prUrl}` : `\u2705 kody2 PR opened: ${prUrl}`;
3933
+ const successMsg = justPushedToExistingPr ? `\u2705 kody pushed to ${prUrl}` : prAction === "updated" ? `\u2139\uFE0F kody made no changes \u2014 PR: ${prUrl}` : `\u2705 kody PR opened: ${prUrl}`;
3829
3934
  const failurePrSuffix = prUrl ? prAction === "updated" ? ` \u2014 PR: ${prUrl}` : ` \u2014 draft PR: ${prUrl}` : "";
3830
- const msg = isFailure ? `\u26A0\uFE0F kody2 FAILED: ${truncate2(failureReason, 1500)}${failurePrSuffix}` : successMsg;
3935
+ const msg = isFailure ? `\u26A0\uFE0F kody FAILED: ${truncate2(failureReason, 1500)}${failurePrSuffix}` : successMsg;
3831
3936
  postWith(targetType, targetNumber, msg, ctx.cwd);
3832
3937
  let exitCode = 0;
3833
3938
  const agentDone = Boolean(ctx.data.agentDone);
@@ -3883,7 +3988,7 @@ _Orchestrator will advance to the next step automatically._`;
3883
3988
  return `${head}
3884
3989
 
3885
3990
  ---
3886
- Comment \`kody2 run\` (prefixed with \`@\`) to execute this plan.`;
3991
+ Comment \`kody run\` (prefixed with \`@\`) to execute this plan.`;
3887
3992
  }
3888
3993
 
3889
3994
  // src/scripts/postResearchComment.ts
@@ -3928,7 +4033,7 @@ var postReviewResult = async (ctx, _profile, agentResult) => {
3928
4033
  if (!agentResult || agentResult.outcome !== "completed") {
3929
4034
  const reason = agentResult?.error ?? "agent did not complete";
3930
4035
  try {
3931
- postPrReviewComment(prNumber, `\u26A0\uFE0F kody2 review FAILED: ${truncate2(reason, 1e3)}`, ctx.cwd);
4036
+ postPrReviewComment(prNumber, `\u26A0\uFE0F kody review FAILED: ${truncate2(reason, 1e3)}`, ctx.cwd);
3932
4037
  } catch {
3933
4038
  }
3934
4039
  ctx.output.exitCode = 1;
@@ -3939,7 +4044,7 @@ var postReviewResult = async (ctx, _profile, agentResult) => {
3939
4044
  const reviewBody = agentResult.finalText.trim();
3940
4045
  if (!reviewBody) {
3941
4046
  try {
3942
- postPrReviewComment(prNumber, `\u26A0\uFE0F kody2 review FAILED: agent produced no review body`, ctx.cwd);
4047
+ postPrReviewComment(prNumber, `\u26A0\uFE0F kody review FAILED: agent produced no review body`, ctx.cwd);
3943
4048
  } catch {
3944
4049
  }
3945
4050
  ctx.output.exitCode = 1;
@@ -4156,11 +4261,11 @@ async function runPrepare(args) {
4156
4261
  }
4157
4262
  const base = ctx.config.git.defaultBranch;
4158
4263
  const title = `chore: release ${tag}`;
4159
- const body = `Automated release PR opened by kody2.
4264
+ const body = `Automated release PR opened by kody.
4160
4265
 
4161
4266
  ${entry}
4162
4267
 
4163
- Merge this and then run \`kody2 release --mode finalize\`.`;
4268
+ Merge this and then run \`kody release --mode finalize\`.`;
4164
4269
  let prUrl = "";
4165
4270
  try {
4166
4271
  prUrl = gh2(["pr", "create", "--head", releaseBranch, "--base", base, "--title", title, "--body-file", "-"], {
@@ -4231,19 +4336,19 @@ async function runFinalize(args) {
4231
4336
  const r = runShell(cmd, cwd, timeoutMs);
4232
4337
  publishStatus = r.exitCode === 0 ? "ok" : "failed";
4233
4338
  if (r.exitCode !== 0) {
4234
- process.stderr.write(`[kody2 release] publishCommand exit ${r.exitCode}
4339
+ process.stderr.write(`[kody release] publishCommand exit ${r.exitCode}
4235
4340
  ${truncate2(r.stderr, 2e3)}
4236
4341
  `);
4237
4342
  }
4238
4343
  }
4239
4344
  let releaseUrl = "";
4240
4345
  try {
4241
- const releaseArgs = ["release", "create", tag, "--title", tag, "--notes", `Release ${tag} \u2014 automated by kody2.`];
4346
+ const releaseArgs = ["release", "create", tag, "--title", tag, "--notes", `Release ${tag} \u2014 automated by kody.`];
4242
4347
  if (releaseCfg.draftRelease) releaseArgs.push("--draft");
4243
4348
  releaseUrl = gh2(releaseArgs, { cwd }).trim();
4244
4349
  } catch (err) {
4245
4350
  process.stderr.write(
4246
- `[kody2 release] gh release create failed: ${err instanceof Error ? err.message : String(err)}
4351
+ `[kody release] gh release create failed: ${err instanceof Error ? err.message : String(err)}
4247
4352
  `
4248
4353
  );
4249
4354
  }
@@ -4382,14 +4487,14 @@ var resolveFlow = async (ctx) => {
4382
4487
  ctx.output.exitCode = 0;
4383
4488
  ctx.output.reason = `already up to date with origin/${baseBranch} \u2014 nothing to resolve`;
4384
4489
  ctx.skipAgent = true;
4385
- tryPostPr3(prNumber, `\u2139\uFE0F kody2 resolve: ${ctx.output.reason}`, ctx.cwd);
4490
+ tryPostPr3(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
4386
4491
  return;
4387
4492
  }
4388
4493
  if (mergeStatus === "error") {
4389
4494
  ctx.output.exitCode = 99;
4390
4495
  ctx.output.reason = `failed to merge origin/${baseBranch} (non-conflict error); see runner log`;
4391
4496
  ctx.skipAgent = true;
4392
- tryPostPr3(prNumber, `\u26A0\uFE0F kody2 resolve FAILED: ${ctx.output.reason}`, ctx.cwd);
4497
+ tryPostPr3(prNumber, `\u26A0\uFE0F kody resolve FAILED: ${ctx.output.reason}`, ctx.cwd);
4393
4498
  return;
4394
4499
  }
4395
4500
  const conflictedFiles = getConflictedFiles(ctx.cwd);
@@ -4405,7 +4510,7 @@ var resolveFlow = async (ctx) => {
4405
4510
  const runSuffix = runUrl ? `, run ${runUrl}` : "";
4406
4511
  tryPostPr3(
4407
4512
  prNumber,
4408
- `\u2699\uFE0F kody2 resolve started on \`${ctx.data.branch}\`${runSuffix} \u2014 ${conflictedFiles.length} conflicted file(s)`,
4513
+ `\u2699\uFE0F kody resolve started on \`${ctx.data.branch}\`${runSuffix} \u2014 ${conflictedFiles.length} conflicted file(s)`,
4409
4514
  ctx.cwd
4410
4515
  );
4411
4516
  };
@@ -4485,7 +4590,7 @@ var reviewFlow = async (ctx) => {
4485
4590
  ctx.data.prDiff = getPrDiff(prNumber, ctx.cwd);
4486
4591
  const runUrl = getRunUrl();
4487
4592
  const runSuffix = runUrl ? `, run ${runUrl}` : "";
4488
- tryPostPr4(prNumber, `\u{1F440} kody2 review started on PR #${prNumber}${runSuffix}`, ctx.cwd);
4593
+ tryPostPr4(prNumber, `\u{1F440} kody review started on PR #${prNumber}${runSuffix}`, ctx.cwd);
4489
4594
  };
4490
4595
  function tryPostPr4(prNumber, body, cwd) {
4491
4596
  try {
@@ -4509,13 +4614,13 @@ var runFlow = async (ctx) => {
4509
4614
  ctx.output.exitCode = 5;
4510
4615
  ctx.output.reason = err.message;
4511
4616
  ctx.skipAgent = true;
4512
- tryPost(issueNumber, `\u26A0\uFE0F kody2 refused to start: ${err.message}`, ctx.cwd);
4617
+ tryPost(issueNumber, `\u26A0\uFE0F kody refused to start: ${err.message}`, ctx.cwd);
4513
4618
  return;
4514
4619
  }
4515
4620
  throw err;
4516
4621
  }
4517
4622
  const runUrl = getRunUrl();
4518
- const startMsg = runUrl ? `\u2699\uFE0F kody2 started \u2014 branch \`${ctx.data.branch}\`, run ${runUrl}` : `\u2699\uFE0F kody2 started \u2014 branch \`${ctx.data.branch}\``;
4623
+ const startMsg = runUrl ? `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\`, run ${runUrl}` : `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\``;
4519
4624
  tryPost(issueNumber, startMsg, ctx.cwd);
4520
4625
  };
4521
4626
  function tryPost(issueNumber, body, cwd) {
@@ -4559,7 +4664,7 @@ var setLifecycleLabel = async (ctx, _profile, args) => {
4559
4664
  const label = args?.label;
4560
4665
  if (typeof label !== "string" || !label.startsWith(KODY_NAMESPACE)) {
4561
4666
  process.stderr.write(
4562
- `[kody2] setLifecycleLabel: missing or invalid "label" arg (must start with "${KODY_NAMESPACE}"): ${String(label)}
4667
+ `[kody] setLifecycleLabel: missing or invalid "label" arg (must start with "${KODY_NAMESPACE}"): ${String(label)}
4563
4668
  `
4564
4669
  );
4565
4670
  return;
@@ -4595,14 +4700,14 @@ var API_TIMEOUT_MS7 = 3e4;
4595
4700
  var startFlow = async (ctx, profile, _agentResult, args) => {
4596
4701
  const entry = args?.entry;
4597
4702
  if (!entry) {
4598
- process.stderr.write("[kody2 startFlow] missing `with.entry` \u2014 skipping\n");
4703
+ process.stderr.write("[kody startFlow] missing `with.entry` \u2014 skipping\n");
4599
4704
  return;
4600
4705
  }
4601
4706
  const target = args?.target ?? "issue";
4602
4707
  const flowName = profile.name;
4603
4708
  const issueNumber = ctx.args.issue;
4604
4709
  if (!issueNumber) {
4605
- process.stderr.write("[kody2 startFlow] no --issue arg \u2014 skipping\n");
4710
+ process.stderr.write("[kody startFlow] no --issue arg \u2014 skipping\n");
4606
4711
  return;
4607
4712
  }
4608
4713
  const state = ctx.data.taskState;
@@ -4617,12 +4722,12 @@ var startFlow = async (ctx, profile, _agentResult, args) => {
4617
4722
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
4618
4723
  };
4619
4724
  }
4620
- postKody2Comment(target, issueNumber, state, entry, ctx.cwd);
4725
+ postKodyComment(target, issueNumber, state, entry, ctx.cwd);
4621
4726
  };
4622
- function postKody2Comment(target, issueNumber, state, next, cwd) {
4727
+ function postKodyComment(target, issueNumber, state, next, cwd) {
4623
4728
  const targetNumber = target === "pr" && state?.core.prUrl ? parsePr2(state.core.prUrl) ?? issueNumber : issueNumber;
4624
4729
  const sub = target === "pr" && state?.core.prUrl ? "pr" : "issue";
4625
- const body = `@kody2 ${next}`;
4730
+ const body = `@kody ${next}`;
4626
4731
  try {
4627
4732
  execFileSync17("gh", [sub, "comment", String(targetNumber), "--body", body], {
4628
4733
  timeout: API_TIMEOUT_MS7,
@@ -4631,7 +4736,7 @@ function postKody2Comment(target, issueNumber, state, next, cwd) {
4631
4736
  });
4632
4737
  } catch (err) {
4633
4738
  process.stderr.write(
4634
- `[kody2 startFlow] failed to post @kody2 ${next} on ${sub} #${targetNumber}: ${err instanceof Error ? err.message : String(err)}
4739
+ `[kody startFlow] failed to post @kody ${next} on ${sub} #${targetNumber}: ${err instanceof Error ? err.message : String(err)}
4635
4740
  `
4636
4741
  );
4637
4742
  }
@@ -4670,7 +4775,7 @@ var syncFlow = async (ctx) => {
4670
4775
  bail2(
4671
4776
  ctx,
4672
4777
  prNumber,
4673
- `merge from origin/${baseBranch} produced conflicts \u2014 run \`@kody2 resolve\` to let kody2 resolve them`
4778
+ `merge from origin/${baseBranch} produced conflicts \u2014 run \`@kody resolve\` to let kody resolve them`
4674
4779
  );
4675
4780
  return;
4676
4781
  }
@@ -4678,7 +4783,7 @@ var syncFlow = async (ctx) => {
4678
4783
  if (headAfter === headBefore) {
4679
4784
  ctx.output.exitCode = 0;
4680
4785
  ctx.output.reason = `already up to date with origin/${baseBranch}`;
4681
- tryPostPr5(prNumber, `\u2139\uFE0F kody2 sync: already up to date with origin/${baseBranch}`, ctx.cwd);
4786
+ tryPostPr5(prNumber, `\u2139\uFE0F kody sync: already up to date with origin/${baseBranch}`, ctx.cwd);
4682
4787
  return;
4683
4788
  }
4684
4789
  try {
@@ -4692,14 +4797,14 @@ var syncFlow = async (ctx) => {
4692
4797
  ctx.output.reason = `merged origin/${baseBranch} into ${ctx.data.branch}`;
4693
4798
  const runUrl = getRunUrl();
4694
4799
  const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
4695
- tryPostPr5(prNumber, `\u2705 kody2 sync: merged \`origin/${baseBranch}\` into \`${ctx.data.branch}\`${runSuffix}`, ctx.cwd);
4800
+ tryPostPr5(prNumber, `\u2705 kody sync: merged \`origin/${baseBranch}\` into \`${ctx.data.branch}\`${runSuffix}`, ctx.cwd);
4696
4801
  };
4697
4802
  function bail2(ctx, prNumber, reason) {
4698
4803
  ctx.output.exitCode = 1;
4699
4804
  ctx.output.reason = reason;
4700
4805
  const runUrl = getRunUrl();
4701
4806
  const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
4702
- tryPostPr5(prNumber, `\u274C kody2 sync could not complete${runSuffix}: ${reason}`, ctx.cwd);
4807
+ tryPostPr5(prNumber, `\u274C kody sync could not complete${runSuffix}: ${reason}`, ctx.cwd);
4703
4808
  }
4704
4809
  function revParseHead(cwd) {
4705
4810
  try {
@@ -4847,10 +4952,10 @@ function findStalePrs(cwd, staleDays, now = /* @__PURE__ */ new Date()) {
4847
4952
  }
4848
4953
  function formatStaleReport(stale, staleDays) {
4849
4954
  if (stale.length === 0) {
4850
- return `\u{1F7E2} **kody2 watch-stale-prs** \u2014 no open PRs untouched for more than ${staleDays} days. \u2728`;
4955
+ return `\u{1F7E2} **kody watch-stale-prs** \u2014 no open PRs untouched for more than ${staleDays} days. \u2728`;
4851
4956
  }
4852
4957
  const lines = [
4853
- `\u{1F7E1} **kody2 watch-stale-prs** \u2014 ${stale.length} PR(s) untouched for > ${staleDays} days:`,
4958
+ `\u{1F7E1} **kody watch-stale-prs** \u2014 ${stale.length} PR(s) untouched for > ${staleDays} days:`,
4854
4959
  ""
4855
4960
  ];
4856
4961
  for (const pr of stale.slice(0, 50)) {
@@ -4871,7 +4976,7 @@ var watchStalePrsFlow = async (ctx) => {
4871
4976
  postIssueComment(reportIssueNumber, report, ctx.cwd);
4872
4977
  } catch (err) {
4873
4978
  process.stderr.write(
4874
- `[kody2 watch] failed to post to issue #${reportIssueNumber}: ${err instanceof Error ? err.message : String(err)}
4979
+ `[kody watch] failed to post to issue #${reportIssueNumber}: ${err instanceof Error ? err.message : String(err)}
4875
4980
  `
4876
4981
  );
4877
4982
  }
@@ -4894,7 +4999,7 @@ var writeRunSummary = async (ctx, profile) => {
4894
4999
  const reason = ctx.output.reason;
4895
5000
  const status = exitCode === 0 ? "\u2705 success" : exitCode === 3 ? "\u23ED\uFE0F no-op" : "\u26A0\uFE0F failed";
4896
5001
  const lines = [];
4897
- lines.push(`## kody2 ${executable} \u2014 ${status}`);
5002
+ lines.push(`## kody ${executable} \u2014 ${status}`);
4898
5003
  lines.push("");
4899
5004
  lines.push(`- **Executable:** \`${executable}\``);
4900
5005
  lines.push(`- **Target:** ${target}`);
@@ -4924,6 +5029,7 @@ var preflightScripts = {
4924
5029
  loadIssueContext,
4925
5030
  loadConventions,
4926
5031
  loadCoverageRules,
5032
+ loadPriorArt,
4927
5033
  loadQaGuide,
4928
5034
  buildSyntheticPlugin,
4929
5035
  resolveArtifacts,
@@ -5064,7 +5170,7 @@ async function runExecutable(profileName, input) {
5064
5170
  data: {},
5065
5171
  output: { exitCode: 0 }
5066
5172
  };
5067
- const ndjsonDir = path17.join(input.cwd, ".kody2");
5173
+ const ndjsonDir = path17.join(input.cwd, ".kody");
5068
5174
  const invokeAgent = async (prompt) => {
5069
5175
  const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path17.isAbsolute(p) ? p : path17.resolve(profile.dir, p)).filter((p) => p.length > 0);
5070
5176
  const syntheticPath = ctx.data.syntheticPluginPath;
@@ -5079,7 +5185,7 @@ async function runExecutable(profileName, input) {
5079
5185
  ndjsonDir,
5080
5186
  allowedToolsOverride: profile.claudeCode.tools,
5081
5187
  permissionModeOverride: profile.claudeCode.permissionMode,
5082
- mcpServers: profile.claudeCode.mcpServers,
5188
+ mcpServers: profile.claudeCode.mcpServers.length > 0 ? profile.claudeCode.mcpServers : void 0,
5083
5189
  pluginPaths: pluginPaths.length > 0 ? pluginPaths : void 0,
5084
5190
  maxTurns: profile.claudeCode.maxTurns,
5085
5191
  maxThinkingTokens: profile.claudeCode.maxThinkingTokens,
@@ -5114,7 +5220,7 @@ async function runExecutable(profileName, input) {
5114
5220
  await fn(ctx, profile, agentResult, entry.with);
5115
5221
  } catch (err) {
5116
5222
  const msg = err instanceof Error ? err.message : String(err);
5117
- process.stderr.write(`[kody2] postflight script "${entry.script}" crashed: ${msg}
5223
+ process.stderr.write(`[kody] postflight script "${entry.script}" crashed: ${msg}
5118
5224
  `);
5119
5225
  if (!ctx.output.reason) ctx.output.reason = `postflight ${entry.script} crashed: ${msg}`;
5120
5226
  if (ctx.output.exitCode === 0) ctx.output.exitCode = 99;
@@ -5234,11 +5340,11 @@ function finish(out) {
5234
5340
  return out;
5235
5341
  }
5236
5342
 
5237
- // src/kody2-cli.ts
5238
- var CI_HELP = `kody2 ci \u2014 minimal-YAML autonomous engineer (CI preflight + run)
5343
+ // src/kody-cli.ts
5344
+ var CI_HELP = `kody ci \u2014 minimal-YAML autonomous engineer (CI preflight + run)
5239
5345
 
5240
5346
  Usage:
5241
- kody2 ci --issue <N> [--cwd <path>] [--verbose|--quiet]
5347
+ kody ci --issue <N> [--cwd <path>] [--verbose|--quiet]
5242
5348
  [--skip-install] [--skip-litellm] [--package-manager pnpm|yarn|bun|npm]
5243
5349
 
5244
5350
  Options:
@@ -5254,7 +5360,7 @@ Environment:
5254
5360
  ALL_SECRETS JSON blob of all GitHub secrets (auto-populated in CI)
5255
5361
  KODY_TOKEN|GH_TOKEN|GITHUB_TOKEN|GH_PAT auth token for gh/git operations
5256
5362
 
5257
- Exit codes (inherited from kody2 run):
5363
+ Exit codes (inherited from kody run):
5258
5364
  0 success (PR opened, verify passed)
5259
5365
  1 agent reported FAILED (draft PR opened)
5260
5366
  2 verify failed (draft PR opened)
@@ -5347,7 +5453,7 @@ function isOnPath(bin) {
5347
5453
  }
5348
5454
  function ensurePackageManagerInstalled(pm, cwd) {
5349
5455
  if (pm === "npm" || isOnPath(pm)) return 0;
5350
- process.stdout.write(`\u2192 kody2: ${pm} not on PATH \u2014 installing via npm install -g ${pm}
5456
+ process.stdout.write(`\u2192 kody: ${pm} not on PATH \u2014 installing via npm install -g ${pm}
5351
5457
  `);
5352
5458
  return shellOut("npm", ["install", "-g", pm], cwd);
5353
5459
  }
@@ -5367,18 +5473,18 @@ function installLitellmIfNeeded(cwd) {
5367
5473
  const cfg = loadConfig(cwd);
5368
5474
  const model = parseProviderModel(cfg.agent.model);
5369
5475
  if (!needsLitellmProxy(model)) {
5370
- process.stdout.write("\u2192 kody2: provider is anthropic/claude, skipping LiteLLM install\n");
5476
+ process.stdout.write("\u2192 kody: provider is anthropic/claude, skipping LiteLLM install\n");
5371
5477
  return 0;
5372
5478
  }
5373
5479
  } catch {
5374
5480
  }
5375
5481
  try {
5376
5482
  execFileSync20("python3", ["-c", "import litellm"], { stdio: "pipe" });
5377
- process.stdout.write("\u2192 kody2: litellm already installed\n");
5483
+ process.stdout.write("\u2192 kody: litellm already installed\n");
5378
5484
  return 0;
5379
5485
  } catch {
5380
5486
  }
5381
- process.stdout.write("\u2192 kody2: installing litellm (pip install 'litellm[proxy]')\n");
5487
+ process.stdout.write("\u2192 kody: installing litellm (pip install 'litellm[proxy]')\n");
5382
5488
  return shellOut("pip", ["install", "litellm[proxy]"], cwd);
5383
5489
  }
5384
5490
  function configureGitIdentity(cwd) {
@@ -5401,7 +5507,7 @@ function configureGitIdentity(cwd) {
5401
5507
  }
5402
5508
  function postFailureTail(issueNumber, cwd, reason) {
5403
5509
  if (!issueNumber) return;
5404
- const logPath = path18.join(cwd, ".kody2", "last-run.jsonl");
5510
+ const logPath = path18.join(cwd, ".kody", "last-run.jsonl");
5405
5511
  let tail = "";
5406
5512
  try {
5407
5513
  if (fs21.existsSync(logPath)) {
@@ -5410,7 +5516,7 @@ function postFailureTail(issueNumber, cwd, reason) {
5410
5516
  }
5411
5517
  } catch {
5412
5518
  }
5413
- const body = tail ? `\u26A0\uFE0F kody2 preflight failed: ${truncate2(reason, 500)}
5519
+ const body = tail ? `\u26A0\uFE0F kody preflight failed: ${truncate2(reason, 500)}
5414
5520
 
5415
5521
  <details><summary>Last-run log tail</summary>
5416
5522
 
@@ -5418,7 +5524,7 @@ function postFailureTail(issueNumber, cwd, reason) {
5418
5524
  ${tail}
5419
5525
  \`\`\`
5420
5526
 
5421
- </details>` : `\u26A0\uFE0F kody2 preflight failed: ${truncate2(reason, 1500)}`;
5527
+ </details>` : `\u26A0\uFE0F kody preflight failed: ${truncate2(reason, 1500)}`;
5422
5528
  try {
5423
5529
  postIssueComment(issueNumber, body, cwd);
5424
5530
  } catch {
@@ -5454,16 +5560,16 @@ ${CI_HELP}`);
5454
5560
  target: args.issueNumber
5455
5561
  };
5456
5562
  const issueNumber = dispatch2.target;
5457
- process.stdout.write(`\u2192 kody2 preflight (cwd=${cwd}, executable=${dispatch2.executable}, target=${issueNumber})
5563
+ process.stdout.write(`\u2192 kody preflight (cwd=${cwd}, executable=${dispatch2.executable}, target=${issueNumber})
5458
5564
  `);
5459
5565
  try {
5460
5566
  const n = unpackAllSecrets();
5461
- if (n > 0) process.stdout.write(`\u2192 kody2: unpacked ${n} secret(s) from ALL_SECRETS
5567
+ if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
5462
5568
  `);
5463
5569
  resolveAuthToken();
5464
5570
  reactToTriggerComment(cwd);
5465
5571
  const pm = args.packageManager ?? detectPackageManager2(cwd);
5466
- process.stdout.write(`\u2192 kody2: package manager = ${pm}
5572
+ process.stdout.write(`\u2192 kody: package manager = ${pm}
5467
5573
  `);
5468
5574
  if (!args.skipInstall) {
5469
5575
  const code = installDeps(pm, cwd);
@@ -5472,7 +5578,7 @@ ${CI_HELP}`);
5472
5578
  return 99;
5473
5579
  }
5474
5580
  } else {
5475
- process.stdout.write("\u2192 kody2: skipping dep install (--skip-install)\n");
5581
+ process.stdout.write("\u2192 kody: skipping dep install (--skip-install)\n");
5476
5582
  }
5477
5583
  if (!args.skipLitellm) {
5478
5584
  const code = installLitellmIfNeeded(cwd);
@@ -5481,17 +5587,17 @@ ${CI_HELP}`);
5481
5587
  return 99;
5482
5588
  }
5483
5589
  } else {
5484
- process.stdout.write("\u2192 kody2: skipping LiteLLM install (--skip-litellm)\n");
5590
+ process.stdout.write("\u2192 kody: skipping LiteLLM install (--skip-litellm)\n");
5485
5591
  }
5486
5592
  configureGitIdentity(cwd);
5487
5593
  } catch (err) {
5488
5594
  const msg = err instanceof Error ? err.message : String(err);
5489
- process.stderr.write(`[kody2] preflight crashed: ${msg}
5595
+ process.stderr.write(`[kody] preflight crashed: ${msg}
5490
5596
  `);
5491
5597
  postFailureTail(issueNumber, cwd, `preflight crashed: ${msg}`);
5492
5598
  return 99;
5493
5599
  }
5494
- process.stdout.write(`\u2192 kody2: preflight done, handing off to kody2 ${dispatch2.executable}
5600
+ process.stdout.write(`\u2192 kody: preflight done, handing off to kody ${dispatch2.executable}
5495
5601
 
5496
5602
  `);
5497
5603
  try {
@@ -5509,7 +5615,7 @@ ${CI_HELP}`);
5509
5615
  return result.exitCode;
5510
5616
  } catch (err) {
5511
5617
  const msg = err instanceof Error ? err.message : String(err);
5512
- process.stderr.write(`[kody2] run crashed: ${msg}
5618
+ process.stderr.write(`[kody] run crashed: ${msg}
5513
5619
  `);
5514
5620
  if (err instanceof Error && err.stack) process.stderr.write(`${err.stack}
5515
5621
  `);
@@ -5520,10 +5626,10 @@ ${CI_HELP}`);
5520
5626
 
5521
5627
  // src/chat-cli.ts
5522
5628
  var DEFAULT_MODEL = "claude/claude-haiku-4-5-20251001";
5523
- var CHAT_HELP = `kody2 chat \u2014 dashboard-driven chat session
5629
+ var CHAT_HELP = `kody chat \u2014 dashboard-driven chat session
5524
5630
 
5525
5631
  Usage:
5526
- kody2 chat [--session <id>] [--message <text>] [--model <provider/model>]
5632
+ kody chat [--session <id>] [--message <text>] [--model <provider/model>]
5527
5633
  [--dashboard-url <url>] [--cwd <path>] [--verbose|--quiet]
5528
5634
 
5529
5635
  All inputs may also come from env: SESSION_ID, INIT_MESSAGE, MODEL, DASHBOARD_URL.
@@ -5574,7 +5680,7 @@ function commitChatFiles(cwd, sessionId, verbose) {
5574
5680
  execFileSync21("git", ["push", "--quiet", "origin", "HEAD"], opts);
5575
5681
  } catch (err) {
5576
5682
  const msg = err instanceof Error ? err.message : String(err);
5577
- process.stderr.write(`[kody2:chat] commit/push skipped: ${msg}
5683
+ process.stderr.write(`[kody:chat] commit/push skipped: ${msg}
5578
5684
  `);
5579
5685
  }
5580
5686
  }
@@ -5607,7 +5713,7 @@ ${CHAT_HELP}`);
5607
5713
  const sessionId = args.sessionId;
5608
5714
  const unpackedSecrets = unpackAllSecrets();
5609
5715
  if (unpackedSecrets > 0) {
5610
- process.stdout.write(`\u2192 kody2: unpacked ${unpackedSecrets} secret(s) from ALL_SECRETS
5716
+ process.stdout.write(`\u2192 kody: unpacked ${unpackedSecrets} secret(s) from ALL_SECRETS
5611
5717
  `);
5612
5718
  }
5613
5719
  resolveAuthToken();
@@ -5669,19 +5775,19 @@ ${CHAT_HELP}`);
5669
5775
  }
5670
5776
 
5671
5777
  // src/entry.ts
5672
- var HELP_TEXT = `kody2 \u2014 single-session autonomous engineer
5778
+ var HELP_TEXT = `kody \u2014 single-session autonomous engineer
5673
5779
 
5674
5780
  Usage:
5675
- kody2 run --issue <N> [--cwd <path>] [--verbose|--quiet]
5676
- kody2 fix --pr <N> [--feedback "..."] [--cwd <path>] [--verbose|--quiet]
5677
- kody2 fix-ci --pr <N> [--run-id <ID>] [--cwd <path>] [--verbose|--quiet]
5678
- kody2 resolve --pr <N> [--cwd <path>] [--verbose|--quiet]
5679
- kody2 review --pr <N> [--cwd <path>] [--verbose|--quiet]
5680
- kody2 <other> [--cwd <path>] [--verbose|--quiet]
5681
- kody2 ci --issue <N> [preflight flags \u2014 see: kody2 ci --help]
5682
- kody2 chat [chat flags \u2014 see: kody2 chat --help]
5683
- kody2 help
5684
- kody2 version
5781
+ kody run --issue <N> [--cwd <path>] [--verbose|--quiet]
5782
+ kody fix --pr <N> [--feedback "..."] [--cwd <path>] [--verbose|--quiet]
5783
+ kody fix-ci --pr <N> [--run-id <ID>] [--cwd <path>] [--verbose|--quiet]
5784
+ kody resolve --pr <N> [--cwd <path>] [--verbose|--quiet]
5785
+ kody review --pr <N> [--cwd <path>] [--verbose|--quiet]
5786
+ kody <other> [--cwd <path>] [--verbose|--quiet]
5787
+ kody ci --issue <N> [preflight flags \u2014 see: kody ci --help]
5788
+ kody chat [chat flags \u2014 see: kody chat --help]
5789
+ kody help
5790
+ kody version
5685
5791
 
5686
5792
  Each top-level command (run, fix, fix-ci, resolve, review, \u2026) is a discovered
5687
5793
  executable under \`src/executables/<name>/profile.json\`. Drop in a new
@@ -5737,7 +5843,7 @@ ${HELP_TEXT}`);
5737
5843
  return 0;
5738
5844
  }
5739
5845
  if (args.command === "version") {
5740
- process.stdout.write(`kody2 ${package_default.version}
5846
+ process.stdout.write(`kody ${package_default.version}
5741
5847
  `);
5742
5848
  return 0;
5743
5849
  }
@@ -5746,7 +5852,7 @@ ${HELP_TEXT}`);
5746
5852
  return await runCi(args.ciArgv ?? []);
5747
5853
  } catch (err) {
5748
5854
  const msg = err instanceof Error ? err.message : String(err);
5749
- process.stderr.write(`[kody2] fatal: ${msg}
5855
+ process.stderr.write(`[kody] fatal: ${msg}
5750
5856
  `);
5751
5857
  if (err instanceof Error && err.stack) process.stderr.write(`${err.stack}
5752
5858
  `);
@@ -5758,7 +5864,7 @@ ${HELP_TEXT}`);
5758
5864
  return await runChat(args.chatArgv ?? []);
5759
5865
  } catch (err) {
5760
5866
  const msg = err instanceof Error ? err.message : String(err);
5761
- process.stderr.write(`[kody2] fatal: ${msg}
5867
+ process.stderr.write(`[kody] fatal: ${msg}
5762
5868
  `);
5763
5869
  if (err instanceof Error && err.stack) process.stderr.write(`${err.stack}
5764
5870
  `);
@@ -5783,7 +5889,7 @@ ${HELP_TEXT}`);
5783
5889
  return result.exitCode;
5784
5890
  } catch (err) {
5785
5891
  const msg = err instanceof Error ? err.message : String(err);
5786
- process.stderr.write(`[kody2] ${args.executableName} crashed: ${msg}
5892
+ process.stderr.write(`[kody] ${args.executableName} crashed: ${msg}
5787
5893
  `);
5788
5894
  if (err instanceof Error && err.stack) process.stderr.write(`${err.stack}
5789
5895
  `);
@@ -5793,11 +5899,11 @@ ${HELP_TEXT}`);
5793
5899
  }
5794
5900
  }
5795
5901
 
5796
- // bin/kody2.ts
5902
+ // bin/kody.ts
5797
5903
  main().then((code) => {
5798
5904
  process.exit(code);
5799
5905
  }).catch((err) => {
5800
- process.stderr.write(`[kody2] fatal: ${err instanceof Error ? err.message : String(err)}
5906
+ process.stderr.write(`[kody] fatal: ${err instanceof Error ? err.message : String(err)}
5801
5907
  `);
5802
5908
  process.exit(99);
5803
5909
  });