@kody-ade/kody-engine 0.4.67 → 0.4.68
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 +15 -174
- package/dist/executables/ui-review/profile.json +0 -1
- package/package.json +1 -1
package/dist/bin/kody.js
CHANGED
|
@@ -864,7 +864,7 @@ var init_loadPriorArt = __esm({
|
|
|
864
864
|
// package.json
|
|
865
865
|
var package_default = {
|
|
866
866
|
name: "@kody-ade/kody-engine",
|
|
867
|
-
version: "0.4.
|
|
867
|
+
version: "0.4.68",
|
|
868
868
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
869
869
|
license: "MIT",
|
|
870
870
|
type: "module",
|
|
@@ -2328,7 +2328,7 @@ function coerceBare(spec, value) {
|
|
|
2328
2328
|
init_issue();
|
|
2329
2329
|
|
|
2330
2330
|
// src/executor.ts
|
|
2331
|
-
import { execFileSync as execFileSync29, spawn as
|
|
2331
|
+
import { execFileSync as execFileSync29, spawn as spawn5 } from "child_process";
|
|
2332
2332
|
import * as fs31 from "fs";
|
|
2333
2333
|
import * as path29 from "path";
|
|
2334
2334
|
init_events();
|
|
@@ -9038,164 +9038,6 @@ function postKodyComment(target, issueNumber, state, next, cwd) {
|
|
|
9038
9038
|
}
|
|
9039
9039
|
}
|
|
9040
9040
|
|
|
9041
|
-
// src/scripts/startLocalServer.ts
|
|
9042
|
-
import { spawn as spawn3 } from "child_process";
|
|
9043
|
-
import { existsSync as existsSync26, readFileSync as readFileSync24 } from "fs";
|
|
9044
|
-
import { join as join27 } from "path";
|
|
9045
|
-
var READY_TIMEOUT_MS = 12e4;
|
|
9046
|
-
var READY_POLL_MS = 1e3;
|
|
9047
|
-
var INSTALL_TIMEOUT_MS = 3e5;
|
|
9048
|
-
var FETCH_TIMEOUT_MS = 2e3;
|
|
9049
|
-
var DEFAULT_PORT = 3e3;
|
|
9050
|
-
var startLocalServer = async (ctx) => {
|
|
9051
|
-
if (urlAlreadyResolved(ctx)) {
|
|
9052
|
-
process.stderr.write("[kody startLocalServer] preview URL already set \u2014 skipping\n");
|
|
9053
|
-
return;
|
|
9054
|
-
}
|
|
9055
|
-
const pkg = readPackageJson(ctx.cwd);
|
|
9056
|
-
if (!pkg) return;
|
|
9057
|
-
const scriptName = pickScript(pkg.scripts);
|
|
9058
|
-
if (!scriptName) {
|
|
9059
|
-
process.stderr.write("[kody startLocalServer] no dev/start script in package.json \u2014 skipping\n");
|
|
9060
|
-
return;
|
|
9061
|
-
}
|
|
9062
|
-
const pm = detectPackageManager2(ctx.cwd);
|
|
9063
|
-
const port = pickPort();
|
|
9064
|
-
await ensureDependenciesInstalled(pm, ctx.cwd);
|
|
9065
|
-
const url = `http://localhost:${port}`;
|
|
9066
|
-
process.stderr.write(`[kody startLocalServer] spawning '${pm} run ${scriptName}' on ${url}
|
|
9067
|
-
`);
|
|
9068
|
-
const child = spawnServer(pm, scriptName, port, ctx.cwd);
|
|
9069
|
-
registerProcessCleanup(child);
|
|
9070
|
-
const ready = await waitForReady(url, READY_TIMEOUT_MS);
|
|
9071
|
-
if (!ready) {
|
|
9072
|
-
safeKill(child);
|
|
9073
|
-
throw new Error(
|
|
9074
|
-
`startLocalServer: dev server at ${url} did not become reachable within ${READY_TIMEOUT_MS}ms`
|
|
9075
|
-
);
|
|
9076
|
-
}
|
|
9077
|
-
process.env.PREVIEW_URL = url;
|
|
9078
|
-
ctx.data.qaServerPid = child.pid;
|
|
9079
|
-
ctx.data.qaServerScript = scriptName;
|
|
9080
|
-
process.stderr.write(`[kody startLocalServer] ready: ${url}
|
|
9081
|
-
`);
|
|
9082
|
-
};
|
|
9083
|
-
function urlAlreadyResolved(ctx) {
|
|
9084
|
-
const fromFlag = typeof ctx.args.previewUrl === "string" ? ctx.args.previewUrl.trim() : "";
|
|
9085
|
-
if (fromFlag.length > 0) return true;
|
|
9086
|
-
const fromEnv = (process.env.PREVIEW_URL ?? "").trim();
|
|
9087
|
-
return fromEnv.length > 0;
|
|
9088
|
-
}
|
|
9089
|
-
function readPackageJson(cwd) {
|
|
9090
|
-
const path32 = join27(cwd, "package.json");
|
|
9091
|
-
if (!existsSync26(path32)) {
|
|
9092
|
-
process.stderr.write("[kody startLocalServer] no package.json \u2014 skipping\n");
|
|
9093
|
-
return null;
|
|
9094
|
-
}
|
|
9095
|
-
try {
|
|
9096
|
-
const raw = JSON.parse(readFileSync24(path32, "utf8"));
|
|
9097
|
-
return { scripts: raw.scripts ?? {} };
|
|
9098
|
-
} catch (err) {
|
|
9099
|
-
process.stderr.write(
|
|
9100
|
-
`[kody startLocalServer] could not parse package.json: ${err.message}
|
|
9101
|
-
`
|
|
9102
|
-
);
|
|
9103
|
-
return null;
|
|
9104
|
-
}
|
|
9105
|
-
}
|
|
9106
|
-
function pickScript(scripts) {
|
|
9107
|
-
if (typeof scripts.dev === "string" && scripts.dev.length > 0) return "dev";
|
|
9108
|
-
if (typeof scripts.start === "string" && scripts.start.length > 0) return "start";
|
|
9109
|
-
return null;
|
|
9110
|
-
}
|
|
9111
|
-
function detectPackageManager2(cwd) {
|
|
9112
|
-
if (existsSync26(join27(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
9113
|
-
if (existsSync26(join27(cwd, "yarn.lock"))) return "yarn";
|
|
9114
|
-
return "npm";
|
|
9115
|
-
}
|
|
9116
|
-
function pickPort() {
|
|
9117
|
-
const fromEnv = Number((process.env.PREVIEW_PORT ?? "").trim());
|
|
9118
|
-
if (Number.isInteger(fromEnv) && fromEnv > 0) return fromEnv;
|
|
9119
|
-
return DEFAULT_PORT;
|
|
9120
|
-
}
|
|
9121
|
-
async function ensureDependenciesInstalled(pm, cwd) {
|
|
9122
|
-
if (existsSync26(join27(cwd, "node_modules"))) return;
|
|
9123
|
-
process.stderr.write(`[kody startLocalServer] installing dependencies via ${pm}
|
|
9124
|
-
`);
|
|
9125
|
-
await runOnce(pm, installArgs(pm), cwd, INSTALL_TIMEOUT_MS);
|
|
9126
|
-
}
|
|
9127
|
-
function installArgs(pm) {
|
|
9128
|
-
if (pm === "pnpm") return ["install", "--frozen-lockfile"];
|
|
9129
|
-
if (pm === "yarn") return ["install", "--frozen-lockfile"];
|
|
9130
|
-
return ["ci"];
|
|
9131
|
-
}
|
|
9132
|
-
function spawnServer(pm, scriptName, port, cwd) {
|
|
9133
|
-
const child = spawn3(pm, ["run", scriptName], {
|
|
9134
|
-
cwd,
|
|
9135
|
-
env: { ...process.env, PORT: String(port), NODE_ENV: "development" },
|
|
9136
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
9137
|
-
detached: false
|
|
9138
|
-
});
|
|
9139
|
-
child.stdout?.on("data", (b) => process.stderr.write(`[qa-server] ${b.toString("utf8")}`));
|
|
9140
|
-
child.stderr?.on("data", (b) => process.stderr.write(`[qa-server] ${b.toString("utf8")}`));
|
|
9141
|
-
return child;
|
|
9142
|
-
}
|
|
9143
|
-
function registerProcessCleanup(child) {
|
|
9144
|
-
const cleanup = () => safeKill(child);
|
|
9145
|
-
process.on("exit", cleanup);
|
|
9146
|
-
process.on("SIGINT", cleanup);
|
|
9147
|
-
process.on("SIGTERM", cleanup);
|
|
9148
|
-
}
|
|
9149
|
-
function safeKill(child) {
|
|
9150
|
-
try {
|
|
9151
|
-
child.kill("SIGTERM");
|
|
9152
|
-
} catch {
|
|
9153
|
-
}
|
|
9154
|
-
}
|
|
9155
|
-
async function runOnce(cmd, args, cwd, timeoutMs) {
|
|
9156
|
-
await new Promise((resolve4, reject) => {
|
|
9157
|
-
const c = spawn3(cmd, args, { cwd, stdio: "inherit" });
|
|
9158
|
-
const timer = setTimeout(() => {
|
|
9159
|
-
try {
|
|
9160
|
-
c.kill("SIGKILL");
|
|
9161
|
-
} catch {
|
|
9162
|
-
}
|
|
9163
|
-
reject(new Error(`${cmd} ${args.join(" ")} timed out after ${timeoutMs}ms`));
|
|
9164
|
-
}, timeoutMs);
|
|
9165
|
-
c.on("exit", (code) => {
|
|
9166
|
-
clearTimeout(timer);
|
|
9167
|
-
if (code === 0) {
|
|
9168
|
-
resolve4();
|
|
9169
|
-
return;
|
|
9170
|
-
}
|
|
9171
|
-
reject(new Error(`${cmd} ${args.join(" ")} exited with code ${code}`));
|
|
9172
|
-
});
|
|
9173
|
-
c.on("error", (err) => {
|
|
9174
|
-
clearTimeout(timer);
|
|
9175
|
-
reject(err);
|
|
9176
|
-
});
|
|
9177
|
-
});
|
|
9178
|
-
}
|
|
9179
|
-
async function waitForReady(url, timeoutMs) {
|
|
9180
|
-
const deadline = Date.now() + timeoutMs;
|
|
9181
|
-
while (Date.now() < deadline) {
|
|
9182
|
-
if (await probe(url)) return true;
|
|
9183
|
-
await sleep2(READY_POLL_MS);
|
|
9184
|
-
}
|
|
9185
|
-
return false;
|
|
9186
|
-
}
|
|
9187
|
-
async function probe(url) {
|
|
9188
|
-
try {
|
|
9189
|
-
const res = await fetch(url, { method: "GET", signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
|
|
9190
|
-
return res.status < 500;
|
|
9191
|
-
} catch {
|
|
9192
|
-
return false;
|
|
9193
|
-
}
|
|
9194
|
-
}
|
|
9195
|
-
function sleep2(ms) {
|
|
9196
|
-
return new Promise((r) => setTimeout(r, ms));
|
|
9197
|
-
}
|
|
9198
|
-
|
|
9199
9041
|
// src/scripts/syncFlow.ts
|
|
9200
9042
|
import { execFileSync as execFileSync26 } from "child_process";
|
|
9201
9043
|
init_issue();
|
|
@@ -9326,7 +9168,7 @@ var verify = async (ctx) => {
|
|
|
9326
9168
|
};
|
|
9327
9169
|
|
|
9328
9170
|
// src/scripts/verifyReproFails.ts
|
|
9329
|
-
import { spawn as
|
|
9171
|
+
import { spawn as spawn3 } from "child_process";
|
|
9330
9172
|
var TEST_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
9331
9173
|
var TAIL_CHARS2 = 8e3;
|
|
9332
9174
|
var ANSI_RE2 = /\x1B\[[0-?]*[ -/]*[@-~]/g;
|
|
@@ -9395,7 +9237,7 @@ function stripAnsi2(s) {
|
|
|
9395
9237
|
}
|
|
9396
9238
|
function runCommand2(command, cwd) {
|
|
9397
9239
|
return new Promise((resolve4) => {
|
|
9398
|
-
const child =
|
|
9240
|
+
const child = spawn3(command, {
|
|
9399
9241
|
cwd,
|
|
9400
9242
|
shell: true,
|
|
9401
9243
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", CI: process.env.CI ?? "1" },
|
|
@@ -9458,17 +9300,17 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
9458
9300
|
return;
|
|
9459
9301
|
}
|
|
9460
9302
|
const fixCiAttempts = state?.core.attempts?.["fix-ci"] ?? 0;
|
|
9461
|
-
await
|
|
9303
|
+
await sleep2(initialWaitSeconds * 1e3);
|
|
9462
9304
|
const deadline = Date.now() + timeoutMinutes * 6e4;
|
|
9463
9305
|
let lastSummary = "";
|
|
9464
9306
|
while (Date.now() < deadline) {
|
|
9465
9307
|
const rows = fetchChecks(prNumber, ctx.cwd);
|
|
9466
9308
|
if (rows === null) {
|
|
9467
|
-
await
|
|
9309
|
+
await sleep2(pollSeconds * 1e3);
|
|
9468
9310
|
continue;
|
|
9469
9311
|
}
|
|
9470
9312
|
if (rows.length === 0) {
|
|
9471
|
-
await
|
|
9313
|
+
await sleep2(pollSeconds * 1e3);
|
|
9472
9314
|
continue;
|
|
9473
9315
|
}
|
|
9474
9316
|
const summary = summarize(rows);
|
|
@@ -9511,7 +9353,7 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
9511
9353
|
tryPostPr7(prNumber, `\u2705 kody waitForCi: all ${rows.length} checks green on PR #${prNumber}`, ctx.cwd);
|
|
9512
9354
|
return;
|
|
9513
9355
|
}
|
|
9514
|
-
await
|
|
9356
|
+
await sleep2(pollSeconds * 1e3);
|
|
9515
9357
|
}
|
|
9516
9358
|
ctx.data.action = mkAction("CI_TIMEOUT", {
|
|
9517
9359
|
reason: `CI did not complete within ${timeoutMinutes} minutes`,
|
|
@@ -9563,12 +9405,12 @@ function tryPostPr7(prNumber, body, cwd) {
|
|
|
9563
9405
|
} catch {
|
|
9564
9406
|
}
|
|
9565
9407
|
}
|
|
9566
|
-
function
|
|
9408
|
+
function sleep2(ms) {
|
|
9567
9409
|
return new Promise((res) => setTimeout(res, ms));
|
|
9568
9410
|
}
|
|
9569
9411
|
|
|
9570
9412
|
// src/scripts/warmupMcp.ts
|
|
9571
|
-
import { spawn as
|
|
9413
|
+
import { spawn as spawn4 } from "child_process";
|
|
9572
9414
|
var PER_SERVER_TIMEOUT_MS = 6e4;
|
|
9573
9415
|
var PER_REQUEST_TIMEOUT_MS = 2e4;
|
|
9574
9416
|
var warmupMcp = async (_ctx, profile) => {
|
|
@@ -9590,7 +9432,7 @@ var warmupMcp = async (_ctx, profile) => {
|
|
|
9590
9432
|
}
|
|
9591
9433
|
};
|
|
9592
9434
|
async function warmupOne(command, args, env) {
|
|
9593
|
-
const child =
|
|
9435
|
+
const child = spawn4(command, args, {
|
|
9594
9436
|
stdio: ["pipe", "pipe", "pipe"],
|
|
9595
9437
|
env: env ? { ...process.env, ...env } : process.env
|
|
9596
9438
|
});
|
|
@@ -9830,7 +9672,6 @@ var preflightScripts = {
|
|
|
9830
9672
|
buildSyntheticPlugin,
|
|
9831
9673
|
resolveArtifacts,
|
|
9832
9674
|
discoverQaContext,
|
|
9833
|
-
startLocalServer,
|
|
9834
9675
|
resolvePreviewUrl,
|
|
9835
9676
|
resolveQaUrl,
|
|
9836
9677
|
composePrompt,
|
|
@@ -10353,7 +10194,7 @@ async function runShellEntry(entry, ctx, profile) {
|
|
|
10353
10194
|
env[`KODY_CFG_${k}`] = v;
|
|
10354
10195
|
}
|
|
10355
10196
|
const timeoutMs = resolveShellTimeoutMs(entry);
|
|
10356
|
-
const child =
|
|
10197
|
+
const child = spawn5("bash", [shellPath, ...positional], {
|
|
10357
10198
|
cwd: ctx.cwd,
|
|
10358
10199
|
env,
|
|
10359
10200
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -10816,7 +10657,7 @@ function resolveAuthToken(env = process.env) {
|
|
|
10816
10657
|
if (token && !env.GH_TOKEN) env.GH_TOKEN = token;
|
|
10817
10658
|
return token;
|
|
10818
10659
|
}
|
|
10819
|
-
function
|
|
10660
|
+
function detectPackageManager2(cwd) {
|
|
10820
10661
|
if (fs32.existsSync(path30.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
10821
10662
|
if (fs32.existsSync(path30.join(cwd, "yarn.lock"))) return "yarn";
|
|
10822
10663
|
if (fs32.existsSync(path30.join(cwd, "bun.lockb"))) return "bun";
|
|
@@ -11018,7 +10859,7 @@ ${CI_HELP}`);
|
|
|
11018
10859
|
`);
|
|
11019
10860
|
resolveAuthToken();
|
|
11020
10861
|
reactToTriggerComment(cwd);
|
|
11021
|
-
const pm = args.packageManager ??
|
|
10862
|
+
const pm = args.packageManager ?? detectPackageManager2(cwd);
|
|
11022
10863
|
process.stdout.write(`\u2192 kody: package manager = ${pm}
|
|
11023
10864
|
`);
|
|
11024
10865
|
if (!args.skipInstall) {
|
|
@@ -11090,7 +10931,7 @@ async function runScheduledFanOut(cwd, args, opts) {
|
|
|
11090
10931
|
if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
|
|
11091
10932
|
`);
|
|
11092
10933
|
resolveAuthToken();
|
|
11093
|
-
const pm = args.packageManager ??
|
|
10934
|
+
const pm = args.packageManager ?? detectPackageManager2(cwd);
|
|
11094
10935
|
process.stdout.write(`\u2192 kody: package manager = ${pm}
|
|
11095
10936
|
`);
|
|
11096
10937
|
if (!args.skipInstall) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.68",
|
|
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",
|