@kody-ade/kody-engine 0.3.78 → 0.3.79

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 +66 -17
  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.78",
6
+ version: "0.3.79",
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",
@@ -51,7 +51,7 @@ var package_default = {
51
51
  };
52
52
 
53
53
  // src/chat-cli.ts
54
- import { execFileSync as execFileSync28 } from "child_process";
54
+ import { execFileSync as execFileSync29 } from "child_process";
55
55
  import * as fs28 from "fs";
56
56
  import * as path25 from "path";
57
57
 
@@ -731,13 +731,19 @@ async function runInteractiveMode(opts) {
731
731
  const hardCapMs = opts.meta.hardCapMs ?? DEFAULT_HARD_CAP_MS;
732
732
  const startedAt = Date.now();
733
733
  const deadlineMs = startedAt + hardCapMs;
734
- process.stdout.write(`\u2192 kody:chat:interactive: emitting chat.ready (idleExitMs=${idleExitMs}, hardCapMs=${hardCapMs})
734
+ const runId = process.env.GITHUB_RUN_ID;
735
+ const repository = process.env.GITHUB_REPOSITORY;
736
+ const serverUrl = process.env.GITHUB_SERVER_URL ?? "https://github.com";
737
+ const runUrl = runId && repository ? `${serverUrl}/${repository}/actions/runs/${runId}` : void 0;
738
+ process.stdout.write(`\u2192 kody:chat:interactive: emitting chat.ready (idleExitMs=${idleExitMs}, hardCapMs=${hardCapMs}, runUrl=${runUrl ?? "n/a"})
735
739
  `);
736
740
  await emit2(opts.sink, "chat.ready", opts.sessionId, "ready", {
737
741
  sessionId: opts.sessionId,
738
742
  startedAt: new Date(startedAt).toISOString(),
739
743
  idleExitMs,
740
- hardCapMs
744
+ hardCapMs,
745
+ ...runId ? { runId } : {},
746
+ ...runUrl ? { runUrl } : {}
741
747
  });
742
748
  if (!opts.skipGit) {
743
749
  process.stdout.write(`\u2192 kody:chat:interactive: committing chat.ready event to git
@@ -842,7 +848,7 @@ async function emit2(sink, type, sessionId, suffix, payload) {
842
848
  }
843
849
 
844
850
  // src/kody-cli.ts
845
- import { execFileSync as execFileSync27 } from "child_process";
851
+ import { execFileSync as execFileSync28 } from "child_process";
846
852
  import * as fs27 from "fs";
847
853
  import * as path24 from "path";
848
854
 
@@ -1203,7 +1209,7 @@ function coerceBare(spec, value) {
1203
1209
  }
1204
1210
 
1205
1211
  // src/executor.ts
1206
- import { spawn as spawn3 } from "child_process";
1212
+ import { execFileSync as execFileSync27, spawn as spawn3 } from "child_process";
1207
1213
  import * as fs26 from "fs";
1208
1214
  import * as path23 from "path";
1209
1215
 
@@ -7547,6 +7553,7 @@ async function runContainerLoop(profile, ctx, input) {
7547
7553
  const child = children[currentIdx];
7548
7554
  process.stderr.write(`[kody container] step ${iteration}: invoking ${child.exec}
7549
7555
  `);
7556
+ resetWorkingTree(input.cwd);
7550
7557
  const priorState = readContainerState(ctx, child, reader);
7551
7558
  if (priorState.core?.prUrl) knownPrUrl = priorState.core.prUrl;
7552
7559
  const priorAction = priorState.executables?.[child.exec]?.lastAction;
@@ -7603,11 +7610,40 @@ async function runContainerLoop(profile, ctx, input) {
7603
7610
  ctx.output.reason = `child "${child.exec}" crashed: ${msg}`;
7604
7611
  return;
7605
7612
  }
7613
+ const priorAttempts = priorState.core?.attempts?.[child.exec] ?? 0;
7606
7614
  const next = readContainerState(ctx, child, reader);
7607
7615
  if (next.core?.prUrl) knownPrUrl = next.core.prUrl;
7616
+ const nextAttempts = next.core?.attempts?.[child.exec] ?? 0;
7617
+ const nextChildAction = next.executables?.[child.exec]?.lastAction;
7618
+ const childWrote = nextAttempts > priorAttempts && nextChildAction != null;
7619
+ if (childWrote && nextChildAction) {
7620
+ actionType = nextChildAction.type;
7621
+ } else {
7622
+ const childTag = child.exec.toUpperCase().replace(/-/g, "_");
7623
+ actionType = childOut.exitCode === 0 ? `${childTag}_COMPLETED` : `${childTag}_FAILED`;
7624
+ const synthetic = {
7625
+ type: actionType,
7626
+ payload: {
7627
+ synthesized: true,
7628
+ child: child.exec,
7629
+ exitCode: childOut.exitCode,
7630
+ reason: childOut.reason
7631
+ },
7632
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
7633
+ };
7634
+ if (!next.core) {
7635
+ next.core = {
7636
+ phase: "idle",
7637
+ status: "pending",
7638
+ currentExecutable: null,
7639
+ lastOutcome: synthetic,
7640
+ attempts: {}
7641
+ };
7642
+ } else {
7643
+ next.core.lastOutcome = synthetic;
7644
+ }
7645
+ }
7608
7646
  ctx.data.taskState = next;
7609
- const actionFromState = next.core?.lastOutcome?.type;
7610
- actionType = actionFromState ?? (childOut.exitCode === 0 ? "RUN_COMPLETED" : "RUN_FAILED");
7611
7647
  }
7612
7648
  const route = child.next[actionType] ?? child.next["*"];
7613
7649
  if (!route) {
@@ -7641,6 +7677,19 @@ async function runContainerLoop(profile, ctx, input) {
7641
7677
  currentIdx = nextIdx;
7642
7678
  }
7643
7679
  }
7680
+ function resetWorkingTree(cwd) {
7681
+ try {
7682
+ execFileSync27("git", ["reset", "--hard", "HEAD"], {
7683
+ cwd,
7684
+ stdio: ["ignore", "pipe", "pipe"],
7685
+ timeout: 3e4
7686
+ });
7687
+ } catch (err) {
7688
+ const msg = err instanceof Error ? err.message : String(err);
7689
+ process.stderr.write(`[kody container] working-tree reset skipped: ${msg}
7690
+ `);
7691
+ }
7692
+ }
7644
7693
  function readContainerState(ctx, child, reader) {
7645
7694
  const issueNumber = ctx.args.issue;
7646
7695
  const cached = ctx.data.taskState;
@@ -7789,7 +7838,7 @@ function detectPackageManager2(cwd) {
7789
7838
  }
7790
7839
  function shellOut(cmd, args, cwd, stream = true) {
7791
7840
  try {
7792
- execFileSync27(cmd, args, {
7841
+ execFileSync28(cmd, args, {
7793
7842
  cwd,
7794
7843
  stdio: stream ? "inherit" : "pipe",
7795
7844
  env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", CI: process.env.CI ?? "1" }
@@ -7802,7 +7851,7 @@ function shellOut(cmd, args, cwd, stream = true) {
7802
7851
  }
7803
7852
  function isOnPath(bin) {
7804
7853
  try {
7805
- execFileSync27("which", [bin], { stdio: "pipe" });
7854
+ execFileSync28("which", [bin], { stdio: "pipe" });
7806
7855
  return true;
7807
7856
  } catch {
7808
7857
  return false;
@@ -7836,7 +7885,7 @@ function installLitellmIfNeeded(cwd) {
7836
7885
  } catch {
7837
7886
  }
7838
7887
  try {
7839
- execFileSync27("python3", ["-c", "import litellm"], { stdio: "pipe" });
7888
+ execFileSync28("python3", ["-c", "import litellm"], { stdio: "pipe" });
7840
7889
  process.stdout.write("\u2192 kody: litellm already installed\n");
7841
7890
  return 0;
7842
7891
  } catch {
@@ -7846,16 +7895,16 @@ function installLitellmIfNeeded(cwd) {
7846
7895
  }
7847
7896
  function configureGitIdentity(cwd) {
7848
7897
  try {
7849
- const name = execFileSync27("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
7898
+ const name = execFileSync28("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
7850
7899
  if (name) return;
7851
7900
  } catch {
7852
7901
  }
7853
7902
  try {
7854
- execFileSync27("git", ["config", "user.name", "github-actions[bot]"], { cwd, stdio: "pipe" });
7903
+ execFileSync28("git", ["config", "user.name", "github-actions[bot]"], { cwd, stdio: "pipe" });
7855
7904
  } catch {
7856
7905
  }
7857
7906
  try {
7858
- execFileSync27("git", ["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"], {
7907
+ execFileSync28("git", ["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"], {
7859
7908
  cwd,
7860
7909
  stdio: "pipe"
7861
7910
  });
@@ -8126,9 +8175,9 @@ function commitChatFiles(cwd, sessionId, verbose) {
8126
8175
  if (paths.length === 0) return;
8127
8176
  const opts = { cwd, stdio: verbose ? "inherit" : "pipe" };
8128
8177
  try {
8129
- execFileSync28("git", ["add", "-f", ...paths], opts);
8130
- execFileSync28("git", ["commit", "--quiet", "-m", `chat: reply for ${sessionId}`], opts);
8131
- execFileSync28("git", ["push", "--quiet", "origin", "HEAD"], opts);
8178
+ execFileSync29("git", ["add", "-f", ...paths], opts);
8179
+ execFileSync29("git", ["commit", "--quiet", "-m", `chat: reply for ${sessionId}`], opts);
8180
+ execFileSync29("git", ["push", "--quiet", "origin", "HEAD"], opts);
8132
8181
  } catch (err) {
8133
8182
  const msg = err instanceof Error ? err.message : String(err);
8134
8183
  process.stderr.write(`[kody:chat] commit/push skipped: ${msg}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.3.78",
3
+ "version": "0.3.79",
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",