@kody-ade/kody-engine 0.3.74 → 0.3.76

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 +47 -7
  2. package/package.json +1 -1
package/dist/bin/kody.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@kody-ade/kody-engine",
6
- version: "0.3.74",
6
+ version: "0.3.76",
7
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",
@@ -676,10 +676,16 @@ async function waitForNextUserMessage(opts) {
676
676
  if (now - idleStart >= opts.idleTimeoutMs) return { kind: "idle-timeout" };
677
677
  if (!opts.skipPull) {
678
678
  try {
679
- execFileSync("git", ["pull", "--ff-only", "--quiet", "origin", "HEAD"], {
680
- cwd: opts.cwd,
681
- stdio: "pipe"
682
- });
679
+ const branch = currentBranch(opts.cwd);
680
+ if (branch) {
681
+ execFileSync("git", ["fetch", "--quiet", "origin", branch], { cwd: opts.cwd, stdio: "pipe" });
682
+ execFileSync("git", ["merge", "--ff-only", "--quiet", `origin/${branch}`], {
683
+ cwd: opts.cwd,
684
+ stdio: "pipe"
685
+ });
686
+ } else {
687
+ execFileSync("git", ["fetch", "--quiet", "--all"], { cwd: opts.cwd, stdio: "pipe" });
688
+ }
683
689
  } catch (err) {
684
690
  const msg = err instanceof Error ? err.message : String(err);
685
691
  logger.warn(`git pull failed (will retry): ${msg}`);
@@ -702,6 +708,18 @@ async function waitForNextUserMessage(opts) {
702
708
  function sleep(ms) {
703
709
  return new Promise((resolve4) => setTimeout(resolve4, ms));
704
710
  }
711
+ function currentBranch(cwd) {
712
+ try {
713
+ const out = execFileSync("git", ["symbolic-ref", "--short", "HEAD"], {
714
+ cwd,
715
+ stdio: ["ignore", "pipe", "ignore"]
716
+ });
717
+ const branch = out.toString("utf-8").trim();
718
+ return branch || null;
719
+ } catch {
720
+ return null;
721
+ }
722
+ }
705
723
 
706
724
  // src/chat/modes/interactive.ts
707
725
  var DEFAULT_IDLE_EXIT_MS = 5 * 6e4;
@@ -736,10 +754,12 @@ async function runInteractiveMode(opts) {
736
754
  });
737
755
  if (result.kind === "idle-timeout") {
738
756
  await emitExit(opts, "idle-timeout", turnsCompleted);
757
+ if (!opts.skipGit) commitTurn(opts.cwd, opts.sessionId, opts.verbose ?? false);
739
758
  return { exitCode: 0, reason: "idle-timeout", turnsCompleted };
740
759
  }
741
760
  if (result.kind === "deadline") {
742
761
  await emitExit(opts, "deadline", turnsCompleted);
762
+ if (!opts.skipGit) commitTurn(opts.cwd, opts.sessionId, opts.verbose ?? false);
743
763
  return { exitCode: 0, reason: "deadline", turnsCompleted };
744
764
  }
745
765
  }
@@ -760,6 +780,7 @@ async function runInteractiveMode(opts) {
760
780
  const msg = err instanceof Error ? err.message : String(err);
761
781
  await emit2(opts.sink, "chat.error", opts.sessionId, `loop-${turnsCompleted}`, { error: msg });
762
782
  await emitExit(opts, "fatal", turnsCompleted);
783
+ if (!opts.skipGit) commitTurn(opts.cwd, opts.sessionId, opts.verbose ?? false);
763
784
  return { exitCode: 99, reason: "fatal", turnsCompleted };
764
785
  }
765
786
  if (turnResult.exitCode === 64) {
@@ -785,7 +806,7 @@ function commitTurn(cwd, sessionId, verbose) {
785
806
  if (paths.length === 0) return;
786
807
  const stdio = verbose ? "inherit" : "pipe";
787
808
  try {
788
- execFileSync2("git", ["add", ...paths], { cwd, stdio });
809
+ execFileSync2("git", ["add", "-f", ...paths], { cwd, stdio });
789
810
  execFileSync2("git", ["commit", "--quiet", "-m", `chat: interactive turn for ${sessionId}`], { cwd, stdio });
790
811
  execFileSync2("git", ["push", "--quiet", "origin", "HEAD"], { cwd, stdio });
791
812
  } catch (err) {
@@ -5650,6 +5671,11 @@ var persistFlowState = async (ctx) => {
5650
5671
  };
5651
5672
 
5652
5673
  // src/scripts/postIssueComment.ts
5674
+ var FAILED_LABEL_SPEC = {
5675
+ label: "kody:failed",
5676
+ color: "e11d21",
5677
+ description: "kody: flow failed"
5678
+ };
5653
5679
  var postIssueComment2 = async (ctx) => {
5654
5680
  if (ctx.skipAgent && ctx.output.exitCode !== void 0) return;
5655
5681
  const targetType = ctx.data.commentTargetType;
@@ -5662,12 +5688,14 @@ var postIssueComment2 = async (ctx) => {
5662
5688
  if (!commitResult?.committed && !hasCommits) {
5663
5689
  const reason = "no changes to commit";
5664
5690
  postWith(targetType, targetNumber, `\u26A0\uFE0F kody FAILED: ${reason}`, ctx.cwd);
5691
+ markRunFailed(ctx);
5665
5692
  ctx.output.exitCode = 3;
5666
5693
  ctx.output.reason = reason;
5667
5694
  return;
5668
5695
  }
5669
5696
  if (ctx.output.exitCode === 4 && ctx.data.prCrashReason) {
5670
5697
  postWith(targetType, targetNumber, `\u26A0\uFE0F kody FAILED: ${truncate2(ctx.data.prCrashReason, 1500)}`, ctx.cwd);
5698
+ markRunFailed(ctx);
5671
5699
  ctx.output.reason = ctx.data.prCrashReason;
5672
5700
  return;
5673
5701
  }
@@ -5692,9 +5720,21 @@ var postIssueComment2 = async (ctx) => {
5692
5720
  const misses = ctx.data.coverageMisses ?? [];
5693
5721
  if (!agentDone || misses.length > 0) exitCode = 1;
5694
5722
  else if (!verifyOk) exitCode = 2;
5723
+ if (exitCode !== 0) markRunFailed(ctx);
5695
5724
  ctx.output.exitCode = exitCode;
5696
5725
  ctx.output.reason = failureReason || void 0;
5697
5726
  };
5727
+ function markRunFailed(ctx) {
5728
+ const issueNumber = ctx.args.issue;
5729
+ if (typeof issueNumber === "number" && Number.isFinite(issueNumber)) {
5730
+ setKodyLabel(issueNumber, FAILED_LABEL_SPEC, ctx.cwd);
5731
+ }
5732
+ const targetType = ctx.data.commentTargetType;
5733
+ const targetNumber = Number(ctx.data.commentTargetNumber ?? 0);
5734
+ if (targetType === "pr" && targetNumber > 0 && targetNumber !== issueNumber) {
5735
+ setKodyLabel(targetNumber, FAILED_LABEL_SPEC, ctx.cwd);
5736
+ }
5737
+ }
5698
5738
  function computeFailureSuffix(input) {
5699
5739
  if (input.prUrl) {
5700
5740
  return input.prAction === "updated" ? ` \u2014 PR: ${input.prUrl}` : ` \u2014 draft PR: ${input.prUrl}`;
@@ -8077,7 +8117,7 @@ function commitChatFiles(cwd, sessionId, verbose) {
8077
8117
  if (paths.length === 0) return;
8078
8118
  const opts = { cwd, stdio: verbose ? "inherit" : "pipe" };
8079
8119
  try {
8080
- execFileSync28("git", ["add", ...paths], opts);
8120
+ execFileSync28("git", ["add", "-f", ...paths], opts);
8081
8121
  execFileSync28("git", ["commit", "--quiet", "-m", `chat: reply for ${sessionId}`], opts);
8082
8122
  execFileSync28("git", ["push", "--quiet", "origin", "HEAD"], opts);
8083
8123
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.3.74",
3
+ "version": "0.3.76",
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",