@kody-ade/kody-engine 0.3.77 → 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.
- package/dist/bin/kody.js +84 -17
- 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.
|
|
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
|
|
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,27 @@ 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
|
+
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"})
|
|
739
|
+
`);
|
|
734
740
|
await emit2(opts.sink, "chat.ready", opts.sessionId, "ready", {
|
|
735
741
|
sessionId: opts.sessionId,
|
|
736
742
|
startedAt: new Date(startedAt).toISOString(),
|
|
737
743
|
idleExitMs,
|
|
738
|
-
hardCapMs
|
|
744
|
+
hardCapMs,
|
|
745
|
+
...runId ? { runId } : {},
|
|
746
|
+
...runUrl ? { runUrl } : {}
|
|
739
747
|
});
|
|
740
|
-
if (!opts.skipGit)
|
|
748
|
+
if (!opts.skipGit) {
|
|
749
|
+
process.stdout.write(`\u2192 kody:chat:interactive: committing chat.ready event to git
|
|
750
|
+
`);
|
|
751
|
+
commitTurn(opts.cwd, opts.sessionId, opts.verbose ?? false);
|
|
752
|
+
process.stdout.write(`\u2192 kody:chat:interactive: chat.ready committed; entering poll loop
|
|
753
|
+
`);
|
|
754
|
+
}
|
|
741
755
|
let watermark = 0;
|
|
742
756
|
let turnsCompleted = 0;
|
|
743
757
|
while (true) {
|
|
@@ -834,7 +848,7 @@ async function emit2(sink, type, sessionId, suffix, payload) {
|
|
|
834
848
|
}
|
|
835
849
|
|
|
836
850
|
// src/kody-cli.ts
|
|
837
|
-
import { execFileSync as
|
|
851
|
+
import { execFileSync as execFileSync28 } from "child_process";
|
|
838
852
|
import * as fs27 from "fs";
|
|
839
853
|
import * as path24 from "path";
|
|
840
854
|
|
|
@@ -1195,7 +1209,7 @@ function coerceBare(spec, value) {
|
|
|
1195
1209
|
}
|
|
1196
1210
|
|
|
1197
1211
|
// src/executor.ts
|
|
1198
|
-
import { spawn as spawn3 } from "child_process";
|
|
1212
|
+
import { execFileSync as execFileSync27, spawn as spawn3 } from "child_process";
|
|
1199
1213
|
import * as fs26 from "fs";
|
|
1200
1214
|
import * as path23 from "path";
|
|
1201
1215
|
|
|
@@ -7539,6 +7553,7 @@ async function runContainerLoop(profile, ctx, input) {
|
|
|
7539
7553
|
const child = children[currentIdx];
|
|
7540
7554
|
process.stderr.write(`[kody container] step ${iteration}: invoking ${child.exec}
|
|
7541
7555
|
`);
|
|
7556
|
+
resetWorkingTree(input.cwd);
|
|
7542
7557
|
const priorState = readContainerState(ctx, child, reader);
|
|
7543
7558
|
if (priorState.core?.prUrl) knownPrUrl = priorState.core.prUrl;
|
|
7544
7559
|
const priorAction = priorState.executables?.[child.exec]?.lastAction;
|
|
@@ -7595,11 +7610,40 @@ async function runContainerLoop(profile, ctx, input) {
|
|
|
7595
7610
|
ctx.output.reason = `child "${child.exec}" crashed: ${msg}`;
|
|
7596
7611
|
return;
|
|
7597
7612
|
}
|
|
7613
|
+
const priorAttempts = priorState.core?.attempts?.[child.exec] ?? 0;
|
|
7598
7614
|
const next = readContainerState(ctx, child, reader);
|
|
7599
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
|
+
}
|
|
7600
7646
|
ctx.data.taskState = next;
|
|
7601
|
-
const actionFromState = next.core?.lastOutcome?.type;
|
|
7602
|
-
actionType = actionFromState ?? (childOut.exitCode === 0 ? "RUN_COMPLETED" : "RUN_FAILED");
|
|
7603
7647
|
}
|
|
7604
7648
|
const route = child.next[actionType] ?? child.next["*"];
|
|
7605
7649
|
if (!route) {
|
|
@@ -7633,6 +7677,19 @@ async function runContainerLoop(profile, ctx, input) {
|
|
|
7633
7677
|
currentIdx = nextIdx;
|
|
7634
7678
|
}
|
|
7635
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
|
+
}
|
|
7636
7693
|
function readContainerState(ctx, child, reader) {
|
|
7637
7694
|
const issueNumber = ctx.args.issue;
|
|
7638
7695
|
const cached = ctx.data.taskState;
|
|
@@ -7781,7 +7838,7 @@ function detectPackageManager2(cwd) {
|
|
|
7781
7838
|
}
|
|
7782
7839
|
function shellOut(cmd, args, cwd, stream = true) {
|
|
7783
7840
|
try {
|
|
7784
|
-
|
|
7841
|
+
execFileSync28(cmd, args, {
|
|
7785
7842
|
cwd,
|
|
7786
7843
|
stdio: stream ? "inherit" : "pipe",
|
|
7787
7844
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", CI: process.env.CI ?? "1" }
|
|
@@ -7794,7 +7851,7 @@ function shellOut(cmd, args, cwd, stream = true) {
|
|
|
7794
7851
|
}
|
|
7795
7852
|
function isOnPath(bin) {
|
|
7796
7853
|
try {
|
|
7797
|
-
|
|
7854
|
+
execFileSync28("which", [bin], { stdio: "pipe" });
|
|
7798
7855
|
return true;
|
|
7799
7856
|
} catch {
|
|
7800
7857
|
return false;
|
|
@@ -7828,7 +7885,7 @@ function installLitellmIfNeeded(cwd) {
|
|
|
7828
7885
|
} catch {
|
|
7829
7886
|
}
|
|
7830
7887
|
try {
|
|
7831
|
-
|
|
7888
|
+
execFileSync28("python3", ["-c", "import litellm"], { stdio: "pipe" });
|
|
7832
7889
|
process.stdout.write("\u2192 kody: litellm already installed\n");
|
|
7833
7890
|
return 0;
|
|
7834
7891
|
} catch {
|
|
@@ -7838,16 +7895,16 @@ function installLitellmIfNeeded(cwd) {
|
|
|
7838
7895
|
}
|
|
7839
7896
|
function configureGitIdentity(cwd) {
|
|
7840
7897
|
try {
|
|
7841
|
-
const name =
|
|
7898
|
+
const name = execFileSync28("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
|
|
7842
7899
|
if (name) return;
|
|
7843
7900
|
} catch {
|
|
7844
7901
|
}
|
|
7845
7902
|
try {
|
|
7846
|
-
|
|
7903
|
+
execFileSync28("git", ["config", "user.name", "github-actions[bot]"], { cwd, stdio: "pipe" });
|
|
7847
7904
|
} catch {
|
|
7848
7905
|
}
|
|
7849
7906
|
try {
|
|
7850
|
-
|
|
7907
|
+
execFileSync28("git", ["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"], {
|
|
7851
7908
|
cwd,
|
|
7852
7909
|
stdio: "pipe"
|
|
7853
7910
|
});
|
|
@@ -8118,9 +8175,9 @@ function commitChatFiles(cwd, sessionId, verbose) {
|
|
|
8118
8175
|
if (paths.length === 0) return;
|
|
8119
8176
|
const opts = { cwd, stdio: verbose ? "inherit" : "pipe" };
|
|
8120
8177
|
try {
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
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);
|
|
8124
8181
|
} catch (err) {
|
|
8125
8182
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8126
8183
|
process.stderr.write(`[kody:chat] commit/push skipped: ${msg}
|
|
@@ -8179,11 +8236,15 @@ ${CHAT_HELP}`);
|
|
|
8179
8236
|
return 99;
|
|
8180
8237
|
}
|
|
8181
8238
|
}
|
|
8239
|
+
process.stdout.write(`\u2192 kody:chat: starting litellm proxy (model=${model.provider}/${model.model})
|
|
8240
|
+
`);
|
|
8182
8241
|
let litellm = null;
|
|
8183
8242
|
try {
|
|
8184
8243
|
litellm = await startLitellmIfNeeded(model, cwd);
|
|
8185
8244
|
} catch (err) {
|
|
8186
8245
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8246
|
+
process.stderr.write(`\u2192 kody:chat: litellm startup FAILED: ${msg}
|
|
8247
|
+
`);
|
|
8187
8248
|
const sink2 = buildSink(cwd, sessionId, args.dashboardUrl);
|
|
8188
8249
|
await sink2.emit({
|
|
8189
8250
|
event: "chat.error",
|
|
@@ -8193,10 +8254,16 @@ ${CHAT_HELP}`);
|
|
|
8193
8254
|
});
|
|
8194
8255
|
return 99;
|
|
8195
8256
|
}
|
|
8257
|
+
process.stdout.write(`\u2192 kody:chat: litellm proxy ready (url=${litellm?.url ?? "skipped"})
|
|
8258
|
+
`);
|
|
8196
8259
|
const sessionFile = sessionFilePath(cwd, sessionId);
|
|
8197
8260
|
if (args.initMessage) seedInitialMessage(sessionFile, args.initMessage);
|
|
8198
8261
|
const sink = buildSink(cwd, sessionId, args.dashboardUrl);
|
|
8199
8262
|
const meta = readMeta(sessionFile);
|
|
8263
|
+
process.stdout.write(
|
|
8264
|
+
`\u2192 kody:chat: session file=${sessionFile} exists=${fs28.existsSync(sessionFile)} meta=${meta ? meta.mode : "none"}
|
|
8265
|
+
`
|
|
8266
|
+
);
|
|
8200
8267
|
try {
|
|
8201
8268
|
if (meta?.mode === "interactive") {
|
|
8202
8269
|
const result2 = await runInteractiveMode({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.3.
|
|
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",
|