@kody-ade/kody-engine 0.4.153 → 0.4.154

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 (2) hide show
  1. package/dist/bin/kody.js +135 -110
  2. package/package.json +1 -1
package/dist/bin/kody.js CHANGED
@@ -1061,7 +1061,7 @@ var init_loadPriorArt = __esm({
1061
1061
  // package.json
1062
1062
  var package_default = {
1063
1063
  name: "@kody-ade/kody-engine",
1064
- version: "0.4.153",
1064
+ version: "0.4.154",
1065
1065
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
1066
1066
  license: "MIT",
1067
1067
  type: "module",
@@ -1117,7 +1117,7 @@ var package_default = {
1117
1117
  };
1118
1118
 
1119
1119
  // src/chat-cli.ts
1120
- import { execFileSync as execFileSync30 } from "child_process";
1120
+ import { execFileSync as execFileSync31 } from "child_process";
1121
1121
  import * as fs42 from "fs";
1122
1122
  import * as path38 from "path";
1123
1123
 
@@ -1376,7 +1376,7 @@ function loadConfig(projectDir = process.cwd()) {
1376
1376
  throw new Error(`kody.config.json is invalid JSON: ${msg}`);
1377
1377
  }
1378
1378
  const quality = raw.quality ?? {};
1379
- const git4 = raw.git ?? {};
1379
+ const git5 = raw.git ?? {};
1380
1380
  const github = raw.github ?? {};
1381
1381
  const agent = raw.agent ?? {};
1382
1382
  if (!agent.model || typeof agent.model !== "string") {
@@ -1393,7 +1393,7 @@ function loadConfig(projectDir = process.cwd()) {
1393
1393
  testUnit: typeof quality.testUnit === "string" ? quality.testUnit : ""
1394
1394
  },
1395
1395
  git: {
1396
- defaultBranch: typeof git4.defaultBranch === "string" ? git4.defaultBranch : "main"
1396
+ defaultBranch: typeof git5.defaultBranch === "string" ? git5.defaultBranch : "main"
1397
1397
  },
1398
1398
  github: {
1399
1399
  owner: String(github.owner),
@@ -2755,7 +2755,7 @@ async function emit2(sink, type, sessionId, suffix, payload) {
2755
2755
  }
2756
2756
 
2757
2757
  // src/kody-cli.ts
2758
- import { execFileSync as execFileSync29 } from "child_process";
2758
+ import { execFileSync as execFileSync30 } from "child_process";
2759
2759
  import * as fs41 from "fs";
2760
2760
  import * as path37 from "path";
2761
2761
 
@@ -3156,7 +3156,7 @@ function coerceBare(spec, value) {
3156
3156
  }
3157
3157
 
3158
3158
  // src/executor.ts
3159
- import { execFileSync as execFileSync28, spawn as spawn9 } from "child_process";
3159
+ import { execFileSync as execFileSync29, spawn as spawn9 } from "child_process";
3160
3160
  import * as fs40 from "fs";
3161
3161
  import * as path36 from "path";
3162
3162
 
@@ -7529,6 +7529,7 @@ var dispatchNextTask = async (ctx) => {
7529
7529
 
7530
7530
  // src/pr.ts
7531
7531
  init_issue();
7532
+ import { execFileSync as execFileSync13 } from "child_process";
7532
7533
  function prMergeStatus(prNumber, cwd) {
7533
7534
  try {
7534
7535
  const out = gh(
@@ -7648,6 +7649,51 @@ function recoverSourceIssueNumber(existingBody, branch, prNumber) {
7648
7649
  }
7649
7650
  return null;
7650
7651
  }
7652
+ var ALREADY_EXISTS_RE = /pull request .*already exists|already exists for/i;
7653
+ function isAlreadyExistsError(err) {
7654
+ const msg = err instanceof Error ? err.message : String(err);
7655
+ return ALREADY_EXISTS_RE.test(msg);
7656
+ }
7657
+ function git2(args, cwd) {
7658
+ return execFileSync13("git", args, {
7659
+ encoding: "utf-8",
7660
+ timeout: 3e4,
7661
+ cwd,
7662
+ env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
7663
+ stdio: ["pipe", "pipe", "pipe"]
7664
+ }).trim();
7665
+ }
7666
+ function updateExistingPr(existing, body, draft, cwd) {
7667
+ const stripped = existing.url.replace(/^https:\/\/github\.com\//, "");
7668
+ const [owner, repo] = stripped.split("/");
7669
+ try {
7670
+ gh(["api", "--method", "PATCH", `repos/${owner}/${repo}/pulls/${existing.number}`, "-f", `body=${body}`], { cwd });
7671
+ } catch (err) {
7672
+ throw new Error(`gh api PATCH #${existing.number} failed: ${err instanceof Error ? err.message : String(err)}`);
7673
+ }
7674
+ return { url: existing.url, number: existing.number, draft, action: "updated" };
7675
+ }
7676
+ function createPr(branch, base, title, body, draft, cwd) {
7677
+ const args = ["pr", "create", "--head", branch, "--base", base, "--title", title, "--body-file", "-"];
7678
+ if (draft) args.push("--draft");
7679
+ const url = gh(args, { input: body, cwd }).trim();
7680
+ const match = url.match(/\/pull\/(\d+)$/);
7681
+ const number = match ? parseInt(match[1], 10) : 0;
7682
+ return { url, number, draft, action: "created" };
7683
+ }
7684
+ function recoverFromExistingPr(branch, base, title, body, draft, cwd) {
7685
+ const raced = findExistingPr(branch, cwd);
7686
+ if (raced) return updateExistingPr(raced, body, draft, cwd);
7687
+ try {
7688
+ git2(["push", "origin", "--delete", branch], cwd);
7689
+ } catch {
7690
+ }
7691
+ const push = pushWithRetry({ cwd, branch, setUpstream: true });
7692
+ if (!push.ok) {
7693
+ throw new Error(`re-push after deleting orphaned branch '${branch}' failed: ${push.reason}`);
7694
+ }
7695
+ return createPr(branch, base, title, body, draft, cwd);
7696
+ }
7651
7697
  function ensurePr(opts) {
7652
7698
  const existing = findExistingPr(opts.branch, opts.cwd);
7653
7699
  const effectiveIssueNumber = existing ? recoverSourceIssueNumber(existing.body, opts.branch, existing.number) ?? opts.issueNumber : opts.issueNumber;
@@ -7655,36 +7701,15 @@ function ensurePr(opts) {
7655
7701
  const title = buildPrTitle(effectiveOpts.issueNumber, effectiveOpts.issueTitle, effectiveOpts.draft);
7656
7702
  const body = buildPrBody(effectiveOpts);
7657
7703
  if (existing) {
7658
- const stripped = existing.url.replace(/^https:\/\/github\.com\//, "");
7659
- const [owner, repo] = stripped.split("/");
7660
- try {
7661
- gh(["api", "--method", "PATCH", `repos/${owner}/${repo}/pulls/${existing.number}`, "-f", `body=${body}`], {
7662
- cwd: opts.cwd
7663
- });
7664
- } catch (err) {
7665
- throw new Error(`gh api PATCH #${existing.number} failed: ${err instanceof Error ? err.message : String(err)}`);
7666
- }
7667
- return { url: existing.url, number: existing.number, draft: opts.draft, action: "updated" };
7704
+ return updateExistingPr(existing, body, opts.draft, opts.cwd);
7668
7705
  }
7669
7706
  const base = opts.baseBranch && opts.baseBranch.length > 0 ? opts.baseBranch : opts.defaultBranch;
7670
- const args = [
7671
- "pr",
7672
- "create",
7673
- "--head",
7674
- opts.branch,
7675
- "--base",
7676
- base,
7677
- "--title",
7678
- title,
7679
- "--body-file",
7680
- "-"
7681
- ];
7682
- if (opts.draft) args.push("--draft");
7683
- const output = gh(args, { input: body, cwd: opts.cwd });
7684
- const url = output.trim();
7685
- const match = url.match(/\/pull\/(\d+)$/);
7686
- const number = match ? parseInt(match[1], 10) : 0;
7687
- return { url, number, draft: opts.draft, action: "created" };
7707
+ try {
7708
+ return createPr(opts.branch, base, title, body, opts.draft, opts.cwd);
7709
+ } catch (err) {
7710
+ if (!isAlreadyExistsError(err)) throw err;
7711
+ return recoverFromExistingPr(opts.branch, base, title, body, opts.draft, opts.cwd);
7712
+ }
7688
7713
  }
7689
7714
 
7690
7715
  // src/scripts/ensurePr.ts
@@ -7961,7 +7986,7 @@ var finalizeTerminal = async (ctx) => {
7961
7986
 
7962
7987
  // src/scripts/finishFlow.ts
7963
7988
  init_issue();
7964
- import { execFileSync as execFileSync13 } from "child_process";
7989
+ import { execFileSync as execFileSync14 } from "child_process";
7965
7990
  var TERMINAL_PHASE = {
7966
7991
  "review-passed": { phase: "shipped", status: "succeeded" },
7967
7992
  "fix-applied": { phase: "shipped", status: "succeeded" },
@@ -8001,7 +8026,7 @@ var finishFlow = async (ctx, profile, _agentResult, args) => {
8001
8026
  **PR:** ${state.core.prUrl}` : "";
8002
8027
  const body = `${icon} kody flow \`${flowName}\` finished \u2014 \`${reason}\`${prSuffix}`;
8003
8028
  try {
8004
- execFileSync13("gh", ["issue", "comment", String(issueNumber), "--body", body], {
8029
+ execFileSync14("gh", ["issue", "comment", String(issueNumber), "--body", body], {
8005
8030
  timeout: API_TIMEOUT_MS6,
8006
8031
  cwd: ctx.cwd,
8007
8032
  stdio: ["ignore", "pipe", "pipe"]
@@ -8031,9 +8056,9 @@ var finishFlow = async (ctx, profile, _agentResult, args) => {
8031
8056
  };
8032
8057
 
8033
8058
  // src/branch.ts
8034
- import { execFileSync as execFileSync14 } from "child_process";
8035
- function git2(args, cwd) {
8036
- return execFileSync14("git", args, {
8059
+ import { execFileSync as execFileSync15 } from "child_process";
8060
+ function git3(args, cwd) {
8061
+ return execFileSync15("git", args, {
8037
8062
  encoding: "utf-8",
8038
8063
  timeout: 3e4,
8039
8064
  cwd,
@@ -8046,15 +8071,15 @@ function deriveBranchName(issueNumber, title) {
8046
8071
  return slug ? `${issueNumber}-${slug}` : `${issueNumber}-task`;
8047
8072
  }
8048
8073
  function getCurrentBranch(cwd) {
8049
- return git2(["branch", "--show-current"], cwd);
8074
+ return git3(["branch", "--show-current"], cwd);
8050
8075
  }
8051
8076
  function resetWorkingTree(cwd) {
8052
8077
  try {
8053
- execFileSync14("git", ["reset", "--hard", "HEAD"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
8078
+ execFileSync15("git", ["reset", "--hard", "HEAD"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
8054
8079
  } catch {
8055
8080
  }
8056
8081
  try {
8057
- execFileSync14("git", ["clean", "-fd"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
8082
+ execFileSync15("git", ["clean", "-fd"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
8058
8083
  } catch {
8059
8084
  }
8060
8085
  }
@@ -8066,14 +8091,14 @@ function checkoutPrBranch(prNumber, cwd) {
8066
8091
  GH_TOKEN: process.env.GH_PAT?.trim() || process.env.GH_TOKEN || ""
8067
8092
  };
8068
8093
  try {
8069
- execFileSync14("git", ["reset", "--hard", "HEAD"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
8094
+ execFileSync15("git", ["reset", "--hard", "HEAD"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
8070
8095
  } catch {
8071
8096
  }
8072
8097
  try {
8073
- execFileSync14("git", ["clean", "-fd"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
8098
+ execFileSync15("git", ["clean", "-fd"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
8074
8099
  } catch {
8075
8100
  }
8076
- execFileSync14("gh", ["pr", "checkout", String(prNumber)], {
8101
+ execFileSync15("gh", ["pr", "checkout", String(prNumber)], {
8077
8102
  cwd,
8078
8103
  env,
8079
8104
  stdio: ["ignore", "pipe", "pipe"],
@@ -8083,21 +8108,21 @@ function checkoutPrBranch(prNumber, cwd) {
8083
8108
  }
8084
8109
  function mergeBase(baseBranch, cwd) {
8085
8110
  try {
8086
- git2(["fetch", "origin", baseBranch], cwd);
8111
+ git3(["fetch", "origin", baseBranch], cwd);
8087
8112
  } catch {
8088
8113
  return "error";
8089
8114
  }
8090
8115
  try {
8091
- git2(["merge", `origin/${baseBranch}`, "--no-edit", "--no-ff"], cwd);
8116
+ git3(["merge", `origin/${baseBranch}`, "--no-edit", "--no-ff"], cwd);
8092
8117
  return "clean";
8093
8118
  } catch {
8094
8119
  try {
8095
- const unmerged = git2(["diff", "--name-only", "--diff-filter=U"], cwd);
8120
+ const unmerged = git3(["diff", "--name-only", "--diff-filter=U"], cwd);
8096
8121
  if (unmerged.length > 0) return "conflict";
8097
8122
  } catch {
8098
8123
  }
8099
8124
  try {
8100
- git2(["merge", "--abort"], cwd);
8125
+ git3(["merge", "--abort"], cwd);
8101
8126
  } catch {
8102
8127
  }
8103
8128
  return "error";
@@ -8111,26 +8136,26 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
8111
8136
  return { branch: branchName, created: false };
8112
8137
  }
8113
8138
  try {
8114
- git2(["fetch", "origin"], cwd);
8139
+ git3(["fetch", "origin"], cwd);
8115
8140
  } catch {
8116
8141
  }
8117
8142
  let originBranchExists = false;
8118
8143
  try {
8119
- git2(["rev-parse", "--verify", "--quiet", `refs/remotes/origin/${branchName}`], cwd);
8144
+ git3(["rev-parse", "--verify", "--quiet", `refs/remotes/origin/${branchName}`], cwd);
8120
8145
  originBranchExists = true;
8121
8146
  } catch {
8122
8147
  }
8123
8148
  if (originBranchExists && baseBranch && baseBranch !== defaultBranch2) {
8124
8149
  let baseExists = false;
8125
8150
  try {
8126
- git2(["rev-parse", "--verify", `origin/${baseBranch}`], cwd);
8151
+ git3(["rev-parse", "--verify", `origin/${baseBranch}`], cwd);
8127
8152
  baseExists = true;
8128
8153
  } catch {
8129
8154
  }
8130
8155
  if (baseExists) {
8131
8156
  let descendsFromBase = false;
8132
8157
  try {
8133
- git2(["merge-base", "--is-ancestor", `origin/${baseBranch}`, `origin/${branchName}`], cwd);
8158
+ git3(["merge-base", "--is-ancestor", `origin/${baseBranch}`, `origin/${branchName}`], cwd);
8134
8159
  descendsFromBase = true;
8135
8160
  } catch {
8136
8161
  }
@@ -8140,15 +8165,15 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
8140
8165
  `
8141
8166
  );
8142
8167
  try {
8143
- git2(["push", "origin", "--delete", branchName], cwd);
8168
+ git3(["push", "origin", "--delete", branchName], cwd);
8144
8169
  } catch {
8145
8170
  }
8146
8171
  try {
8147
- git2(["update-ref", "-d", `refs/remotes/origin/${branchName}`], cwd);
8172
+ git3(["update-ref", "-d", `refs/remotes/origin/${branchName}`], cwd);
8148
8173
  } catch {
8149
8174
  }
8150
8175
  try {
8151
- git2(["branch", "-D", branchName], cwd);
8176
+ git3(["branch", "-D", branchName], cwd);
8152
8177
  } catch {
8153
8178
  }
8154
8179
  originBranchExists = false;
@@ -8156,17 +8181,17 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
8156
8181
  }
8157
8182
  }
8158
8183
  if (originBranchExists) {
8159
- git2(["checkout", branchName], cwd);
8184
+ git3(["checkout", branchName], cwd);
8160
8185
  try {
8161
- git2(["pull", "origin", branchName], cwd);
8186
+ git3(["pull", "origin", branchName], cwd);
8162
8187
  } catch {
8163
8188
  }
8164
8189
  if (!baseBranch || baseBranch === defaultBranch2) {
8165
8190
  try {
8166
- git2(["merge", "--no-edit", `origin/${defaultBranch2}`], cwd);
8191
+ git3(["merge", "--no-edit", `origin/${defaultBranch2}`], cwd);
8167
8192
  } catch {
8168
8193
  try {
8169
- git2(["merge", "--abort"], cwd);
8194
+ git3(["merge", "--abort"], cwd);
8170
8195
  } catch {
8171
8196
  }
8172
8197
  throw new Error(
@@ -8177,29 +8202,29 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
8177
8202
  return { branch: branchName, created: false };
8178
8203
  }
8179
8204
  try {
8180
- git2(["rev-parse", "--verify", "--quiet", `refs/heads/${branchName}`], cwd);
8181
- git2(["checkout", branchName], cwd);
8205
+ git3(["rev-parse", "--verify", "--quiet", `refs/heads/${branchName}`], cwd);
8206
+ git3(["checkout", branchName], cwd);
8182
8207
  return { branch: branchName, created: false };
8183
8208
  } catch {
8184
8209
  }
8185
8210
  let forkPoint = defaultBranch2;
8186
8211
  if (baseBranch && baseBranch !== defaultBranch2) {
8187
8212
  try {
8188
- git2(["rev-parse", "--verify", `origin/${baseBranch}`], cwd);
8213
+ git3(["rev-parse", "--verify", `origin/${baseBranch}`], cwd);
8189
8214
  forkPoint = baseBranch;
8190
8215
  } catch {
8191
8216
  }
8192
8217
  }
8193
8218
  try {
8194
- git2(["checkout", "-b", branchName, `origin/${forkPoint}`], cwd);
8219
+ git3(["checkout", "-b", branchName, `origin/${forkPoint}`], cwd);
8195
8220
  } catch {
8196
- git2(["checkout", "-b", branchName], cwd);
8221
+ git3(["checkout", "-b", branchName], cwd);
8197
8222
  }
8198
8223
  return { branch: branchName, created: true };
8199
8224
  }
8200
8225
 
8201
8226
  // src/gha.ts
8202
- import { execFileSync as execFileSync15 } from "child_process";
8227
+ import { execFileSync as execFileSync16 } from "child_process";
8203
8228
  import * as fs29 from "fs";
8204
8229
  function getRunUrl() {
8205
8230
  const server = process.env.GITHUB_SERVER_URL;
@@ -8242,7 +8267,7 @@ function reactToTriggerComment(cwd) {
8242
8267
  for (let attempt = 0; attempt < 3; attempt++) {
8243
8268
  if (attempt > 0) sleepMs(attempt === 1 ? 500 : 1500);
8244
8269
  try {
8245
- execFileSync15("gh", args, opts);
8270
+ execFileSync16("gh", args, opts);
8246
8271
  return;
8247
8272
  } catch (err) {
8248
8273
  lastErr = err;
@@ -8255,7 +8280,7 @@ function reactToTriggerComment(cwd) {
8255
8280
  }
8256
8281
  function sleepMs(ms) {
8257
8282
  try {
8258
- execFileSync15("sleep", [(ms / 1e3).toString()], { stdio: "ignore", timeout: ms + 1e3 });
8283
+ execFileSync16("sleep", [(ms / 1e3).toString()], { stdio: "ignore", timeout: ms + 1e3 });
8259
8284
  } catch {
8260
8285
  }
8261
8286
  }
@@ -8264,7 +8289,7 @@ function sleepMs(ms) {
8264
8289
  init_issue();
8265
8290
 
8266
8291
  // src/workflow.ts
8267
- import { execFileSync as execFileSync16 } from "child_process";
8292
+ import { execFileSync as execFileSync17 } from "child_process";
8268
8293
  var GH_TIMEOUT_MS = 3e4;
8269
8294
  function ghToken3() {
8270
8295
  return process.env.GH_PAT?.trim() || process.env.GH_TOKEN;
@@ -8272,7 +8297,7 @@ function ghToken3() {
8272
8297
  function gh3(args, cwd) {
8273
8298
  const token = ghToken3();
8274
8299
  const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
8275
- return execFileSync16("gh", args, {
8300
+ return execFileSync17("gh", args, {
8276
8301
  encoding: "utf-8",
8277
8302
  timeout: GH_TIMEOUT_MS,
8278
8303
  cwd,
@@ -8507,7 +8532,7 @@ var handleAbandonedGoal = async (ctx) => {
8507
8532
  };
8508
8533
 
8509
8534
  // src/scripts/initFlow.ts
8510
- import { execFileSync as execFileSync17 } from "child_process";
8535
+ import { execFileSync as execFileSync18 } from "child_process";
8511
8536
  import * as fs30 from "fs";
8512
8537
  import * as path28 from "path";
8513
8538
  function detectPackageManager(cwd) {
@@ -8533,7 +8558,7 @@ function schemaUrlFromPkg() {
8533
8558
  function detectOwnerRepo(cwd) {
8534
8559
  let url;
8535
8560
  try {
8536
- url = execFileSync17("git", ["remote", "get-url", "origin"], {
8561
+ url = execFileSync18("git", ["remote", "get-url", "origin"], {
8537
8562
  cwd,
8538
8563
  encoding: "utf-8",
8539
8564
  stdio: ["ignore", "pipe", "pipe"]
@@ -8618,7 +8643,7 @@ jobs:
8618
8643
  `;
8619
8644
  function defaultBranchFromGit(cwd) {
8620
8645
  try {
8621
- const ref = execFileSync17("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], {
8646
+ const ref = execFileSync18("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], {
8622
8647
  cwd,
8623
8648
  encoding: "utf-8",
8624
8649
  stdio: ["ignore", "pipe", "pipe"]
@@ -8626,7 +8651,7 @@ function defaultBranchFromGit(cwd) {
8626
8651
  return ref.replace("refs/remotes/origin/", "");
8627
8652
  } catch {
8628
8653
  try {
8629
- return execFileSync17("git", ["branch", "--show-current"], {
8654
+ return execFileSync18("git", ["branch", "--show-current"], {
8630
8655
  cwd,
8631
8656
  encoding: "utf-8",
8632
8657
  stdio: ["ignore", "pipe", "pipe"]
@@ -9316,7 +9341,7 @@ var mergeFlow = async (ctx) => {
9316
9341
  };
9317
9342
 
9318
9343
  // src/scripts/mergeReleasePr.ts
9319
- import { execFileSync as execFileSync18 } from "child_process";
9344
+ import { execFileSync as execFileSync19 } from "child_process";
9320
9345
  var API_TIMEOUT_MS7 = 6e4;
9321
9346
  var mergeReleasePr = async (ctx) => {
9322
9347
  const state = ctx.data.taskState;
@@ -9335,7 +9360,7 @@ var mergeReleasePr = async (ctx) => {
9335
9360
  process.stderr.write(`[kody mergeReleasePr] merging PR #${prNumber} (${prUrl})
9336
9361
  `);
9337
9362
  try {
9338
- const out = execFileSync18("gh", ["pr", "merge", String(prNumber), "--merge"], {
9363
+ const out = execFileSync19("gh", ["pr", "merge", String(prNumber), "--merge"], {
9339
9364
  timeout: API_TIMEOUT_MS7,
9340
9365
  cwd: ctx.cwd,
9341
9366
  stdio: ["ignore", "pipe", "pipe"]
@@ -10817,7 +10842,7 @@ ${body}`;
10817
10842
  }
10818
10843
 
10819
10844
  // src/scripts/recordClassification.ts
10820
- import { execFileSync as execFileSync19 } from "child_process";
10845
+ import { execFileSync as execFileSync20 } from "child_process";
10821
10846
  var API_TIMEOUT_MS8 = 3e4;
10822
10847
  var VALID_CLASSES3 = /* @__PURE__ */ new Set(["feature", "bug", "spec", "chore"]);
10823
10848
  var recordClassification = async (ctx) => {
@@ -10865,7 +10890,7 @@ function parseClassification(prSummary) {
10865
10890
  }
10866
10891
  function tryAuditComment(issueNumber, body, cwd) {
10867
10892
  try {
10868
- execFileSync19("gh", ["issue", "comment", String(issueNumber), "--body", body], {
10893
+ execFileSync20("gh", ["issue", "comment", String(issueNumber), "--body", body], {
10869
10894
  cwd,
10870
10895
  timeout: API_TIMEOUT_MS8,
10871
10896
  stdio: ["ignore", "pipe", "pipe"]
@@ -10979,7 +11004,7 @@ var resolveArtifacts = async (ctx, profile) => {
10979
11004
  };
10980
11005
 
10981
11006
  // src/scripts/resolveFlow.ts
10982
- import { execFileSync as execFileSync20 } from "child_process";
11007
+ import { execFileSync as execFileSync21 } from "child_process";
10983
11008
  init_issue();
10984
11009
  var CONFLICT_DIFF_MAX_BYTES = 4e4;
10985
11010
  var resolveFlow = async (ctx) => {
@@ -11073,7 +11098,7 @@ function buildPreferBlock(prefer, baseBranch) {
11073
11098
  }
11074
11099
  function getConflictedFiles(cwd) {
11075
11100
  try {
11076
- const out = execFileSync20("git", ["diff", "--name-only", "--diff-filter=U"], {
11101
+ const out = execFileSync21("git", ["diff", "--name-only", "--diff-filter=U"], {
11077
11102
  encoding: "utf-8",
11078
11103
  cwd,
11079
11104
  env: { ...process.env, HUSKY: "0" }
@@ -11088,7 +11113,7 @@ function getConflictMarkersPreview(files, cwd, maxBytes = CONFLICT_DIFF_MAX_BYTE
11088
11113
  let total = 0;
11089
11114
  for (const f of files) {
11090
11115
  try {
11091
- const content = execFileSync20("cat", [f], { encoding: "utf-8", cwd }).toString();
11116
+ const content = execFileSync21("cat", [f], { encoding: "utf-8", cwd }).toString();
11092
11117
  const snippet = `### ${f}
11093
11118
 
11094
11119
  \`\`\`
@@ -11112,12 +11137,12 @@ function tryPostPr3(prNumber, body, cwd) {
11112
11137
  function pushEmptyCommit(branch, cwd) {
11113
11138
  const env = { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" };
11114
11139
  try {
11115
- execFileSync20(
11140
+ execFileSync21(
11116
11141
  "git",
11117
11142
  ["commit", "--allow-empty", "-m", "chore: kody resolve refresh \u2014 empty commit to recompute mergeable status"],
11118
11143
  { cwd, env, stdio: ["ignore", "pipe", "pipe"] }
11119
11144
  );
11120
- execFileSync20("git", ["push", "-u", "origin", branch], {
11145
+ execFileSync21("git", ["push", "-u", "origin", branch], {
11121
11146
  cwd,
11122
11147
  env,
11123
11148
  stdio: ["ignore", "pipe", "pipe"]
@@ -11248,10 +11273,10 @@ var resolvePreviewUrl = async (ctx) => {
11248
11273
  };
11249
11274
 
11250
11275
  // src/scripts/resolveQaUrl.ts
11251
- import { execFileSync as execFileSync21 } from "child_process";
11276
+ import { execFileSync as execFileSync22 } from "child_process";
11252
11277
  function ghQuery(args, cwd) {
11253
11278
  try {
11254
- const out = execFileSync21("gh", args, {
11279
+ const out = execFileSync22("gh", args, {
11255
11280
  cwd,
11256
11281
  stdio: ["ignore", "pipe", "pipe"],
11257
11282
  encoding: "utf-8",
@@ -11321,7 +11346,7 @@ var resolveQaUrl = async (ctx) => {
11321
11346
  };
11322
11347
 
11323
11348
  // src/scripts/revertFlow.ts
11324
- import { execFileSync as execFileSync22 } from "child_process";
11349
+ import { execFileSync as execFileSync23 } from "child_process";
11325
11350
  init_issue();
11326
11351
  var SHA_RE = /^[0-9a-f]{4,40}$/i;
11327
11352
  var revertFlow = async (ctx) => {
@@ -11360,7 +11385,7 @@ var revertFlow = async (ctx) => {
11360
11385
  for (const s of requested) {
11361
11386
  let full;
11362
11387
  try {
11363
- full = git3(["rev-parse", "--verify", `${s}^{commit}`], ctx.cwd);
11388
+ full = git4(["rev-parse", "--verify", `${s}^{commit}`], ctx.cwd);
11364
11389
  } catch {
11365
11390
  unreachable.push(s);
11366
11391
  continue;
@@ -11371,7 +11396,7 @@ var revertFlow = async (ctx) => {
11371
11396
  }
11372
11397
  let subject = "";
11373
11398
  try {
11374
- subject = git3(["log", "-1", "--format=%s", full], ctx.cwd);
11399
+ subject = git4(["log", "-1", "--format=%s", full], ctx.cwd);
11375
11400
  } catch {
11376
11401
  }
11377
11402
  resolved.push({ input: s, full, subject });
@@ -11403,8 +11428,8 @@ function buildCommitMessage(resolved) {
11403
11428
  function buildPrSummary(resolved) {
11404
11429
  return resolved.map((r) => `- Reverted \`${r.full.slice(0, 7)}\`${r.subject ? ` \u2014 ${r.subject}` : ""}`).join("\n");
11405
11430
  }
11406
- function git3(args, cwd) {
11407
- return execFileSync22("git", args, {
11431
+ function git4(args, cwd) {
11432
+ return execFileSync23("git", args, {
11408
11433
  encoding: "utf-8",
11409
11434
  timeout: 3e4,
11410
11435
  cwd,
@@ -11414,7 +11439,7 @@ function git3(args, cwd) {
11414
11439
  }
11415
11440
  function isAncestorOfHead(sha, cwd) {
11416
11441
  try {
11417
- execFileSync22("git", ["merge-base", "--is-ancestor", sha, "HEAD"], {
11442
+ execFileSync23("git", ["merge-base", "--is-ancestor", sha, "HEAD"], {
11418
11443
  cwd,
11419
11444
  env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
11420
11445
  stdio: ["ignore", "ignore", "ignore"]
@@ -12060,11 +12085,11 @@ var skipAgent = async (ctx) => {
12060
12085
  };
12061
12086
 
12062
12087
  // src/scripts/stageMergeConflicts.ts
12063
- import { execFileSync as execFileSync23 } from "child_process";
12088
+ import { execFileSync as execFileSync24 } from "child_process";
12064
12089
  var stageMergeConflicts = async (ctx) => {
12065
12090
  if (ctx.data.agentDone === false) return;
12066
12091
  try {
12067
- execFileSync23("git", ["add", "-A"], {
12092
+ execFileSync24("git", ["add", "-A"], {
12068
12093
  cwd: ctx.cwd,
12069
12094
  env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
12070
12095
  stdio: "pipe"
@@ -12075,7 +12100,7 @@ var stageMergeConflicts = async (ctx) => {
12075
12100
 
12076
12101
  // src/scripts/startFlow.ts
12077
12102
  init_issue();
12078
- import { execFileSync as execFileSync24 } from "child_process";
12103
+ import { execFileSync as execFileSync25 } from "child_process";
12079
12104
  var API_TIMEOUT_MS9 = 3e4;
12080
12105
  var startFlow = async (ctx, profile, _agentResult, args) => {
12081
12106
  const entry = args?.entry;
@@ -12109,7 +12134,7 @@ function postKodyComment(target, issueNumber, state, next, cwd) {
12109
12134
  const sub = target === "pr" && state?.core.prUrl ? "pr" : "issue";
12110
12135
  const body = `@kody ${next}`;
12111
12136
  try {
12112
- execFileSync24("gh", [sub, "comment", String(targetNumber), "--body", body], {
12137
+ execFileSync25("gh", [sub, "comment", String(targetNumber), "--body", body], {
12113
12138
  timeout: API_TIMEOUT_MS9,
12114
12139
  cwd,
12115
12140
  stdio: ["ignore", "pipe", "pipe"]
@@ -12123,7 +12148,7 @@ function postKodyComment(target, issueNumber, state, next, cwd) {
12123
12148
  }
12124
12149
 
12125
12150
  // src/scripts/syncFlow.ts
12126
- import { execFileSync as execFileSync25 } from "child_process";
12151
+ import { execFileSync as execFileSync26 } from "child_process";
12127
12152
  init_issue();
12128
12153
  var DONE2 = {
12129
12154
  label: "kody:done",
@@ -12201,7 +12226,7 @@ function bail2(ctx, prNumber, reason) {
12201
12226
  }
12202
12227
  function revParseHead(cwd) {
12203
12228
  try {
12204
- return execFileSync25("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
12229
+ return execFileSync26("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
12205
12230
  } catch {
12206
12231
  return "";
12207
12232
  }
@@ -12458,7 +12483,7 @@ var verifyWithRetry = async (ctx) => {
12458
12483
 
12459
12484
  // src/scripts/waitForCi.ts
12460
12485
  init_issue();
12461
- import { execFileSync as execFileSync26 } from "child_process";
12486
+ import { execFileSync as execFileSync27 } from "child_process";
12462
12487
  var API_TIMEOUT_MS10 = 3e4;
12463
12488
  var waitForCi = async (ctx, _profile, _agentResult, args) => {
12464
12489
  const timeoutMinutes = numArg(args, "timeoutMinutes", 30);
@@ -12536,7 +12561,7 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
12536
12561
  };
12537
12562
  function fetchChecks(prNumber, cwd) {
12538
12563
  try {
12539
- const raw = execFileSync26("gh", ["pr", "checks", String(prNumber), "--json", "bucket,state,name,workflow,link"], {
12564
+ const raw = execFileSync27("gh", ["pr", "checks", String(prNumber), "--json", "bucket,state,name,workflow,link"], {
12540
12565
  encoding: "utf-8",
12541
12566
  timeout: API_TIMEOUT_MS10,
12542
12567
  cwd,
@@ -13012,7 +13037,7 @@ var allScriptNames = /* @__PURE__ */ new Set([
13012
13037
  ]);
13013
13038
 
13014
13039
  // src/tools.ts
13015
- import { execFileSync as execFileSync27 } from "child_process";
13040
+ import { execFileSync as execFileSync28 } from "child_process";
13016
13041
  function verifyCliTools(tools, cwd) {
13017
13042
  const out = [];
13018
13043
  for (const t of tools) out.push(verifyOne(t, cwd));
@@ -13049,7 +13074,7 @@ function verifyOne(tool4, cwd) {
13049
13074
  }
13050
13075
  function runShell(cmd, cwd, timeoutMs = 3e4) {
13051
13076
  try {
13052
- const stdout = execFileSync27("sh", ["-c", cmd], {
13077
+ const stdout = execFileSync28("sh", ["-c", cmd], {
13053
13078
  cwd,
13054
13079
  stdio: ["ignore", "pipe", "pipe"],
13055
13080
  timeout: timeoutMs,
@@ -13838,7 +13863,7 @@ async function runContainerLoop(profile, ctx, input) {
13838
13863
  }
13839
13864
  function resetWorkingTree2(cwd) {
13840
13865
  try {
13841
- execFileSync28("git", ["reset", "--hard", "HEAD"], {
13866
+ execFileSync29("git", ["reset", "--hard", "HEAD"], {
13842
13867
  cwd,
13843
13868
  stdio: ["ignore", "pipe", "pipe"],
13844
13869
  timeout: 3e4
@@ -14024,7 +14049,7 @@ function detectPackageManager2(cwd) {
14024
14049
  }
14025
14050
  function shellOut(cmd, args, cwd, stream = true) {
14026
14051
  try {
14027
- execFileSync29(cmd, args, {
14052
+ execFileSync30(cmd, args, {
14028
14053
  cwd,
14029
14054
  stdio: stream ? "inherit" : "pipe",
14030
14055
  env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", CI: process.env.CI ?? "1" }
@@ -14037,7 +14062,7 @@ function shellOut(cmd, args, cwd, stream = true) {
14037
14062
  }
14038
14063
  function isOnPath(bin) {
14039
14064
  try {
14040
- execFileSync29("which", [bin], { stdio: "pipe" });
14065
+ execFileSync30("which", [bin], { stdio: "pipe" });
14041
14066
  return true;
14042
14067
  } catch {
14043
14068
  return false;
@@ -14078,7 +14103,7 @@ function installLitellmIfNeeded(cwd) {
14078
14103
  } catch {
14079
14104
  }
14080
14105
  try {
14081
- execFileSync29("python3", ["-c", "import litellm"], { stdio: "pipe" });
14106
+ execFileSync30("python3", ["-c", "import litellm"], { stdio: "pipe" });
14082
14107
  process.stdout.write("\u2192 kody: litellm already installed\n");
14083
14108
  return 0;
14084
14109
  } catch {
@@ -14088,16 +14113,16 @@ function installLitellmIfNeeded(cwd) {
14088
14113
  }
14089
14114
  function configureGitIdentity(cwd) {
14090
14115
  try {
14091
- const name = execFileSync29("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
14116
+ const name = execFileSync30("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
14092
14117
  if (name) return;
14093
14118
  } catch {
14094
14119
  }
14095
14120
  try {
14096
- execFileSync29("git", ["config", "user.name", "github-actions[bot]"], { cwd, stdio: "pipe" });
14121
+ execFileSync30("git", ["config", "user.name", "github-actions[bot]"], { cwd, stdio: "pipe" });
14097
14122
  } catch {
14098
14123
  }
14099
14124
  try {
14100
- execFileSync29("git", ["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"], {
14125
+ execFileSync30("git", ["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"], {
14101
14126
  cwd,
14102
14127
  stdio: "pipe"
14103
14128
  });
@@ -14417,8 +14442,8 @@ function commitChatFiles(cwd, sessionId, verbose) {
14417
14442
  if (paths.length === 0) return;
14418
14443
  const opts = { cwd, stdio: verbose ? "inherit" : "pipe" };
14419
14444
  try {
14420
- execFileSync30("git", ["add", "-f", ...paths], opts);
14421
- execFileSync30("git", ["commit", "--quiet", "-m", `chat: reply for ${sessionId}`], opts);
14445
+ execFileSync31("git", ["add", "-f", ...paths], opts);
14446
+ execFileSync31("git", ["commit", "--quiet", "-m", `chat: reply for ${sessionId}`], opts);
14422
14447
  } catch (err) {
14423
14448
  const msg = err instanceof Error ? err.message : String(err);
14424
14449
  process.stderr.write(`[kody:chat] commit skipped: ${msg}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.153",
3
+ "version": "0.4.154",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",