@kody-ade/kody-engine 0.3.12 → 0.3.13
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
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.13",
|
|
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",
|
|
@@ -1163,11 +1163,187 @@ function parseScriptList(p, key, raw) {
|
|
|
1163
1163
|
return out;
|
|
1164
1164
|
}
|
|
1165
1165
|
|
|
1166
|
+
// src/commit.ts
|
|
1167
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
1168
|
+
import * as fs9 from "fs";
|
|
1169
|
+
import * as path8 from "path";
|
|
1170
|
+
var FORBIDDEN_PATH_PREFIXES = [
|
|
1171
|
+
".kody/",
|
|
1172
|
+
".kody-engine/",
|
|
1173
|
+
".kody/",
|
|
1174
|
+
".kody-lean/",
|
|
1175
|
+
// back-compat: stale runtime dir from kody-lean v0.5.x
|
|
1176
|
+
"node_modules/",
|
|
1177
|
+
"dist/",
|
|
1178
|
+
"build/"
|
|
1179
|
+
];
|
|
1180
|
+
var FORBIDDEN_PATH_EXACT = /* @__PURE__ */ new Set([".env", ".kody-pip-requirements.txt"]);
|
|
1181
|
+
var FORBIDDEN_PATH_SUFFIXES = [".log"];
|
|
1182
|
+
var CONVENTIONAL_PREFIXES = [
|
|
1183
|
+
"feat:",
|
|
1184
|
+
"fix:",
|
|
1185
|
+
"chore:",
|
|
1186
|
+
"docs:",
|
|
1187
|
+
"refactor:",
|
|
1188
|
+
"test:",
|
|
1189
|
+
"perf:",
|
|
1190
|
+
"ci:",
|
|
1191
|
+
"style:",
|
|
1192
|
+
"build:",
|
|
1193
|
+
"revert:"
|
|
1194
|
+
];
|
|
1195
|
+
function git(args, cwd) {
|
|
1196
|
+
try {
|
|
1197
|
+
return execFileSync2("git", args, {
|
|
1198
|
+
encoding: "utf-8",
|
|
1199
|
+
timeout: 12e4,
|
|
1200
|
+
cwd,
|
|
1201
|
+
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
1202
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1203
|
+
}).trim();
|
|
1204
|
+
} catch (err) {
|
|
1205
|
+
const e = err;
|
|
1206
|
+
const stderr = e.stderr?.toString().trim() ?? "";
|
|
1207
|
+
const stdout = e.stdout?.toString().trim() ?? "";
|
|
1208
|
+
const status = e.status ?? "?";
|
|
1209
|
+
const detail = stderr || stdout || e.message || "(no output)";
|
|
1210
|
+
throw new Error(`git ${args.join(" ")} (exit ${status}):
|
|
1211
|
+
${detail}`);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
function tryGit(args, cwd) {
|
|
1215
|
+
try {
|
|
1216
|
+
git(args, cwd);
|
|
1217
|
+
return true;
|
|
1218
|
+
} catch {
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
function abortUnfinishedGitOps(cwd) {
|
|
1223
|
+
const aborted = [];
|
|
1224
|
+
const gitDir = path8.join(cwd ?? process.cwd(), ".git");
|
|
1225
|
+
if (!fs9.existsSync(gitDir)) return aborted;
|
|
1226
|
+
if (fs9.existsSync(path8.join(gitDir, "MERGE_HEAD"))) {
|
|
1227
|
+
if (tryGit(["merge", "--abort"], cwd)) aborted.push("merge");
|
|
1228
|
+
}
|
|
1229
|
+
if (fs9.existsSync(path8.join(gitDir, "CHERRY_PICK_HEAD"))) {
|
|
1230
|
+
if (tryGit(["cherry-pick", "--abort"], cwd)) aborted.push("cherry-pick");
|
|
1231
|
+
}
|
|
1232
|
+
if (fs9.existsSync(path8.join(gitDir, "REVERT_HEAD"))) {
|
|
1233
|
+
if (tryGit(["revert", "--abort"], cwd)) aborted.push("revert");
|
|
1234
|
+
}
|
|
1235
|
+
if (fs9.existsSync(path8.join(gitDir, "rebase-merge")) || fs9.existsSync(path8.join(gitDir, "rebase-apply"))) {
|
|
1236
|
+
if (tryGit(["rebase", "--abort"], cwd)) aborted.push("rebase");
|
|
1237
|
+
}
|
|
1238
|
+
try {
|
|
1239
|
+
const unmerged = git(["diff", "--name-only", "--diff-filter=U"], cwd);
|
|
1240
|
+
if (unmerged) {
|
|
1241
|
+
tryGit(["reset", "--mixed", "HEAD"], cwd);
|
|
1242
|
+
aborted.push("unmerged-paths-reset");
|
|
1243
|
+
}
|
|
1244
|
+
} catch {
|
|
1245
|
+
}
|
|
1246
|
+
return aborted;
|
|
1247
|
+
}
|
|
1248
|
+
function isForbiddenPath(p) {
|
|
1249
|
+
if (FORBIDDEN_PATH_EXACT.has(p)) return true;
|
|
1250
|
+
for (const pre of FORBIDDEN_PATH_PREFIXES) if (p.startsWith(pre)) return true;
|
|
1251
|
+
for (const suf of FORBIDDEN_PATH_SUFFIXES) if (p.endsWith(suf)) return true;
|
|
1252
|
+
return false;
|
|
1253
|
+
}
|
|
1254
|
+
function listChangedFiles(cwd) {
|
|
1255
|
+
const raw = execFileSync2("git", ["status", "--porcelain=v1", "-z"], {
|
|
1256
|
+
encoding: "utf-8",
|
|
1257
|
+
cwd,
|
|
1258
|
+
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
1259
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1260
|
+
});
|
|
1261
|
+
if (!raw) return [];
|
|
1262
|
+
const entries = raw.split("\0").filter((e) => e.length > 0);
|
|
1263
|
+
return entries.map((e) => e.slice(3)).filter(Boolean);
|
|
1264
|
+
}
|
|
1265
|
+
function listFilesInCommit(ref = "HEAD", cwd) {
|
|
1266
|
+
try {
|
|
1267
|
+
const raw = execFileSync2("git", ["show", "--name-only", "--pretty=format:", "-z", ref], {
|
|
1268
|
+
encoding: "utf-8",
|
|
1269
|
+
cwd,
|
|
1270
|
+
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
1271
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1272
|
+
});
|
|
1273
|
+
return raw.split("\0").map((s) => s.trim()).filter(Boolean);
|
|
1274
|
+
} catch {
|
|
1275
|
+
return [];
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
function normalizeCommitMessage(raw) {
|
|
1279
|
+
const trimmed = raw.trim().replace(/^['"]|['"]$/g, "").trim();
|
|
1280
|
+
if (!trimmed) return "chore: kody update";
|
|
1281
|
+
const firstLine2 = trimmed.split("\n")[0];
|
|
1282
|
+
for (const prefix of CONVENTIONAL_PREFIXES) {
|
|
1283
|
+
if (firstLine2.toLowerCase().startsWith(prefix)) return trimmed;
|
|
1284
|
+
}
|
|
1285
|
+
return `chore: ${trimmed}`;
|
|
1286
|
+
}
|
|
1287
|
+
function commitAndPush(branch, agentMessage, cwd) {
|
|
1288
|
+
const allChanged = listChangedFiles(cwd);
|
|
1289
|
+
const allowedFiles = allChanged.filter((f) => !isForbiddenPath(f));
|
|
1290
|
+
const mergeHeadExists = fs9.existsSync(path8.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
|
|
1291
|
+
if (allowedFiles.length === 0 && !mergeHeadExists) {
|
|
1292
|
+
return { committed: false, pushed: false, sha: "", message: "" };
|
|
1293
|
+
}
|
|
1294
|
+
for (const f of allowedFiles) {
|
|
1295
|
+
try {
|
|
1296
|
+
git(["add", "--", f], cwd);
|
|
1297
|
+
} catch {
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
const message = normalizeCommitMessage(agentMessage);
|
|
1301
|
+
try {
|
|
1302
|
+
git(["commit", "--no-gpg-sign", "-m", message], cwd);
|
|
1303
|
+
} catch (err) {
|
|
1304
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1305
|
+
if (/nothing to commit/i.test(msg)) {
|
|
1306
|
+
return { committed: false, pushed: false, sha: "", message };
|
|
1307
|
+
}
|
|
1308
|
+
throw err;
|
|
1309
|
+
}
|
|
1310
|
+
const sha = git(["rev-parse", "HEAD"], cwd).slice(0, 7);
|
|
1311
|
+
try {
|
|
1312
|
+
git(["push", "-u", "origin", branch], cwd);
|
|
1313
|
+
} catch {
|
|
1314
|
+
git(["push", "--force-with-lease", "-u", "origin", branch], cwd);
|
|
1315
|
+
}
|
|
1316
|
+
return { committed: true, pushed: true, sha, message };
|
|
1317
|
+
}
|
|
1318
|
+
function hasCommitsAhead(branch, defaultBranch, cwd) {
|
|
1319
|
+
try {
|
|
1320
|
+
const out = git(["rev-list", "--count", `origin/${defaultBranch}..${branch}`], cwd);
|
|
1321
|
+
return parseInt(out, 10) > 0;
|
|
1322
|
+
} catch {
|
|
1323
|
+
try {
|
|
1324
|
+
const out = git(["rev-list", "--count", `${defaultBranch}..${branch}`], cwd);
|
|
1325
|
+
return parseInt(out, 10) > 0;
|
|
1326
|
+
} catch {
|
|
1327
|
+
return false;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
// src/scripts/abortUnfinishedGitOps.ts
|
|
1333
|
+
var abortUnfinishedGitOps2 = async (ctx) => {
|
|
1334
|
+
if (ctx.data.agentDone === false) return;
|
|
1335
|
+
const aborted = abortUnfinishedGitOps(ctx.cwd);
|
|
1336
|
+
if (aborted.length > 0) {
|
|
1337
|
+
process.stderr.write(`[kody] cleaned up unfinished git ops: ${aborted.join(", ")}
|
|
1338
|
+
`);
|
|
1339
|
+
}
|
|
1340
|
+
};
|
|
1341
|
+
|
|
1166
1342
|
// src/scripts/advanceFlow.ts
|
|
1167
|
-
import { execFileSync as
|
|
1343
|
+
import { execFileSync as execFileSync4 } from "child_process";
|
|
1168
1344
|
|
|
1169
1345
|
// src/state.ts
|
|
1170
|
-
import { execFileSync as
|
|
1346
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
1171
1347
|
var STATE_BEGIN = "<!-- kody:state:v1:begin -->";
|
|
1172
1348
|
var STATE_END = "<!-- kody:state:v1:end -->";
|
|
1173
1349
|
var HISTORY_MAX_ENTRIES = 20;
|
|
@@ -1193,7 +1369,7 @@ function ghToken() {
|
|
|
1193
1369
|
function gh(args, input, cwd) {
|
|
1194
1370
|
const token = ghToken();
|
|
1195
1371
|
const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
|
|
1196
|
-
return
|
|
1372
|
+
return execFileSync3("gh", args, {
|
|
1197
1373
|
encoding: "utf-8",
|
|
1198
1374
|
timeout: API_TIMEOUT_MS,
|
|
1199
1375
|
cwd,
|
|
@@ -1396,7 +1572,7 @@ var advanceFlow = async (ctx, profile) => {
|
|
|
1396
1572
|
}
|
|
1397
1573
|
const body = `@kody ${flow.name}`;
|
|
1398
1574
|
try {
|
|
1399
|
-
|
|
1575
|
+
execFileSync4("gh", ["issue", "comment", String(flow.issueNumber), "--body", body], {
|
|
1400
1576
|
timeout: API_TIMEOUT_MS2,
|
|
1401
1577
|
cwd: ctx.cwd,
|
|
1402
1578
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -1410,21 +1586,21 @@ var advanceFlow = async (ctx, profile) => {
|
|
|
1410
1586
|
};
|
|
1411
1587
|
|
|
1412
1588
|
// src/scripts/buildSyntheticPlugin.ts
|
|
1413
|
-
import * as
|
|
1589
|
+
import * as fs10 from "fs";
|
|
1414
1590
|
import * as os2 from "os";
|
|
1415
|
-
import * as
|
|
1591
|
+
import * as path9 from "path";
|
|
1416
1592
|
function getPluginsCatalogRoot() {
|
|
1417
|
-
const here =
|
|
1593
|
+
const here = path9.dirname(new URL(import.meta.url).pathname);
|
|
1418
1594
|
const candidates = [
|
|
1419
|
-
|
|
1595
|
+
path9.join(here, "..", "plugins"),
|
|
1420
1596
|
// dev: src/scripts → src/plugins
|
|
1421
|
-
|
|
1597
|
+
path9.join(here, "..", "..", "plugins"),
|
|
1422
1598
|
// built: dist/scripts → dist/plugins
|
|
1423
|
-
|
|
1599
|
+
path9.join(here, "..", "..", "src", "plugins")
|
|
1424
1600
|
// fallback
|
|
1425
1601
|
];
|
|
1426
1602
|
for (const c of candidates) {
|
|
1427
|
-
if (
|
|
1603
|
+
if (fs10.existsSync(c) && fs10.statSync(c).isDirectory()) return c;
|
|
1428
1604
|
}
|
|
1429
1605
|
return candidates[0];
|
|
1430
1606
|
}
|
|
@@ -1434,50 +1610,50 @@ var buildSyntheticPlugin = async (ctx, profile) => {
|
|
|
1434
1610
|
if (!needsSynthetic) return;
|
|
1435
1611
|
const catalog = getPluginsCatalogRoot();
|
|
1436
1612
|
const runId = `${profile.name}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1437
|
-
const root =
|
|
1438
|
-
|
|
1613
|
+
const root = path9.join(os2.tmpdir(), `kody-synth-${runId}`);
|
|
1614
|
+
fs10.mkdirSync(path9.join(root, ".claude-plugin"), { recursive: true });
|
|
1439
1615
|
if (cc.skills.length > 0) {
|
|
1440
|
-
const dst =
|
|
1441
|
-
|
|
1616
|
+
const dst = path9.join(root, "skills");
|
|
1617
|
+
fs10.mkdirSync(dst, { recursive: true });
|
|
1442
1618
|
for (const name of cc.skills) {
|
|
1443
|
-
const src =
|
|
1444
|
-
if (!
|
|
1445
|
-
copyDir(src,
|
|
1619
|
+
const src = path9.join(catalog, "skills", name);
|
|
1620
|
+
if (!fs10.existsSync(src)) throw new Error(`buildSyntheticPlugin: skill not found in catalog: ${name}`);
|
|
1621
|
+
copyDir(src, path9.join(dst, name));
|
|
1446
1622
|
}
|
|
1447
1623
|
}
|
|
1448
1624
|
if (cc.commands.length > 0) {
|
|
1449
|
-
const dst =
|
|
1450
|
-
|
|
1625
|
+
const dst = path9.join(root, "commands");
|
|
1626
|
+
fs10.mkdirSync(dst, { recursive: true });
|
|
1451
1627
|
for (const name of cc.commands) {
|
|
1452
|
-
const src =
|
|
1453
|
-
if (!
|
|
1454
|
-
|
|
1628
|
+
const src = path9.join(catalog, "commands", `${name}.md`);
|
|
1629
|
+
if (!fs10.existsSync(src)) throw new Error(`buildSyntheticPlugin: command not found in catalog: ${name}`);
|
|
1630
|
+
fs10.copyFileSync(src, path9.join(dst, `${name}.md`));
|
|
1455
1631
|
}
|
|
1456
1632
|
}
|
|
1457
1633
|
if (cc.subagents.length > 0) {
|
|
1458
|
-
const dst =
|
|
1459
|
-
|
|
1634
|
+
const dst = path9.join(root, "agents");
|
|
1635
|
+
fs10.mkdirSync(dst, { recursive: true });
|
|
1460
1636
|
for (const name of cc.subagents) {
|
|
1461
|
-
const src =
|
|
1462
|
-
if (!
|
|
1463
|
-
|
|
1637
|
+
const src = path9.join(catalog, "agents", `${name}.md`);
|
|
1638
|
+
if (!fs10.existsSync(src)) throw new Error(`buildSyntheticPlugin: subagent not found in catalog: ${name}`);
|
|
1639
|
+
fs10.copyFileSync(src, path9.join(dst, `${name}.md`));
|
|
1464
1640
|
}
|
|
1465
1641
|
}
|
|
1466
1642
|
if (cc.hooks.length > 0) {
|
|
1467
|
-
const dst =
|
|
1468
|
-
|
|
1643
|
+
const dst = path9.join(root, "hooks");
|
|
1644
|
+
fs10.mkdirSync(dst, { recursive: true });
|
|
1469
1645
|
const merged = { hooks: {} };
|
|
1470
1646
|
for (const name of cc.hooks) {
|
|
1471
|
-
const src =
|
|
1472
|
-
if (!
|
|
1473
|
-
const parsed = JSON.parse(
|
|
1647
|
+
const src = path9.join(catalog, "hooks", `${name}.json`);
|
|
1648
|
+
if (!fs10.existsSync(src)) throw new Error(`buildSyntheticPlugin: hook not found in catalog: ${name}`);
|
|
1649
|
+
const parsed = JSON.parse(fs10.readFileSync(src, "utf-8"));
|
|
1474
1650
|
for (const [event, entries] of Object.entries(parsed.hooks ?? {})) {
|
|
1475
1651
|
if (!Array.isArray(entries)) continue;
|
|
1476
1652
|
if (!merged.hooks[event]) merged.hooks[event] = [];
|
|
1477
1653
|
merged.hooks[event].push(...entries);
|
|
1478
1654
|
}
|
|
1479
1655
|
}
|
|
1480
|
-
|
|
1656
|
+
fs10.writeFileSync(path9.join(dst, "hooks.json"), `${JSON.stringify(merged, null, 2)}
|
|
1481
1657
|
`);
|
|
1482
1658
|
}
|
|
1483
1659
|
const manifest = {
|
|
@@ -1488,22 +1664,22 @@ var buildSyntheticPlugin = async (ctx, profile) => {
|
|
|
1488
1664
|
if (cc.skills.length > 0) manifest.skills = ["./skills/"];
|
|
1489
1665
|
if (cc.commands.length > 0) manifest.commands = ["./commands/"];
|
|
1490
1666
|
if (cc.subagents.length > 0) manifest.agents = cc.subagents.map((n) => `./agents/${n}.md`);
|
|
1491
|
-
|
|
1667
|
+
fs10.writeFileSync(path9.join(root, ".claude-plugin", "plugin.json"), `${JSON.stringify(manifest, null, 2)}
|
|
1492
1668
|
`);
|
|
1493
1669
|
ctx.data.syntheticPluginPath = root;
|
|
1494
1670
|
};
|
|
1495
1671
|
function copyDir(src, dst) {
|
|
1496
|
-
|
|
1497
|
-
for (const ent of
|
|
1498
|
-
const s =
|
|
1499
|
-
const d =
|
|
1672
|
+
fs10.mkdirSync(dst, { recursive: true });
|
|
1673
|
+
for (const ent of fs10.readdirSync(src, { withFileTypes: true })) {
|
|
1674
|
+
const s = path9.join(src, ent.name);
|
|
1675
|
+
const d = path9.join(dst, ent.name);
|
|
1500
1676
|
if (ent.isDirectory()) copyDir(s, d);
|
|
1501
|
-
else if (ent.isFile())
|
|
1677
|
+
else if (ent.isFile()) fs10.copyFileSync(s, d);
|
|
1502
1678
|
}
|
|
1503
1679
|
}
|
|
1504
1680
|
|
|
1505
1681
|
// src/coverage.ts
|
|
1506
|
-
import { execFileSync as
|
|
1682
|
+
import { execFileSync as execFileSync5 } from "child_process";
|
|
1507
1683
|
function patternToRegex(pattern) {
|
|
1508
1684
|
let s = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
1509
1685
|
s = s.replace(/\*\*\//g, "\xA7S").replace(/\*\*/g, "\xA7A").replace(/\*/g, "[^/]*");
|
|
@@ -1521,7 +1697,7 @@ function renderSiblingPath(file, requireSibling) {
|
|
|
1521
1697
|
}
|
|
1522
1698
|
function safeGit(args, cwd) {
|
|
1523
1699
|
try {
|
|
1524
|
-
return
|
|
1700
|
+
return execFileSync5("git", args, { encoding: "utf-8", cwd, env: { ...process.env, HUSKY: "0" } }).trim();
|
|
1525
1701
|
} catch {
|
|
1526
1702
|
return "";
|
|
1527
1703
|
}
|
|
@@ -1564,18 +1740,18 @@ function formatMissesForFeedback(misses) {
|
|
|
1564
1740
|
}
|
|
1565
1741
|
|
|
1566
1742
|
// src/prompt.ts
|
|
1567
|
-
import * as
|
|
1568
|
-
import * as
|
|
1743
|
+
import * as fs11 from "fs";
|
|
1744
|
+
import * as path10 from "path";
|
|
1569
1745
|
var CONVENTIONS_PER_FILE_MAX_BYTES = 3e4;
|
|
1570
1746
|
var CONVENTION_FILES = ["CLAUDE.md", "AGENTS.md"];
|
|
1571
1747
|
function loadProjectConventions(projectDir) {
|
|
1572
1748
|
const out = [];
|
|
1573
1749
|
for (const rel of CONVENTION_FILES) {
|
|
1574
|
-
const abs =
|
|
1575
|
-
if (!
|
|
1750
|
+
const abs = path10.join(projectDir, rel);
|
|
1751
|
+
if (!fs11.existsSync(abs)) continue;
|
|
1576
1752
|
let content;
|
|
1577
1753
|
try {
|
|
1578
|
-
content =
|
|
1754
|
+
content = fs11.readFileSync(abs, "utf-8");
|
|
1579
1755
|
} catch {
|
|
1580
1756
|
continue;
|
|
1581
1757
|
}
|
|
@@ -1735,176 +1911,8 @@ function defaultLabelMap() {
|
|
|
1735
1911
|
}
|
|
1736
1912
|
|
|
1737
1913
|
// src/scripts/commitAndPush.ts
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
// src/commit.ts
|
|
1741
|
-
import { execFileSync as execFileSync5 } from "child_process";
|
|
1742
|
-
import * as fs11 from "fs";
|
|
1743
|
-
import * as path10 from "path";
|
|
1744
|
-
var FORBIDDEN_PATH_PREFIXES = [
|
|
1745
|
-
".kody/",
|
|
1746
|
-
".kody-engine/",
|
|
1747
|
-
".kody/",
|
|
1748
|
-
".kody-lean/",
|
|
1749
|
-
// back-compat: stale runtime dir from kody-lean v0.5.x
|
|
1750
|
-
"node_modules/",
|
|
1751
|
-
"dist/",
|
|
1752
|
-
"build/"
|
|
1753
|
-
];
|
|
1754
|
-
var FORBIDDEN_PATH_EXACT = /* @__PURE__ */ new Set([".env", ".kody-pip-requirements.txt"]);
|
|
1755
|
-
var FORBIDDEN_PATH_SUFFIXES = [".log"];
|
|
1756
|
-
var CONVENTIONAL_PREFIXES = [
|
|
1757
|
-
"feat:",
|
|
1758
|
-
"fix:",
|
|
1759
|
-
"chore:",
|
|
1760
|
-
"docs:",
|
|
1761
|
-
"refactor:",
|
|
1762
|
-
"test:",
|
|
1763
|
-
"perf:",
|
|
1764
|
-
"ci:",
|
|
1765
|
-
"style:",
|
|
1766
|
-
"build:",
|
|
1767
|
-
"revert:"
|
|
1768
|
-
];
|
|
1769
|
-
function git(args, cwd) {
|
|
1770
|
-
try {
|
|
1771
|
-
return execFileSync5("git", args, {
|
|
1772
|
-
encoding: "utf-8",
|
|
1773
|
-
timeout: 12e4,
|
|
1774
|
-
cwd,
|
|
1775
|
-
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
1776
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1777
|
-
}).trim();
|
|
1778
|
-
} catch (err) {
|
|
1779
|
-
const e = err;
|
|
1780
|
-
const stderr = e.stderr?.toString().trim() ?? "";
|
|
1781
|
-
const stdout = e.stdout?.toString().trim() ?? "";
|
|
1782
|
-
const status = e.status ?? "?";
|
|
1783
|
-
const detail = stderr || stdout || e.message || "(no output)";
|
|
1784
|
-
throw new Error(`git ${args.join(" ")} (exit ${status}):
|
|
1785
|
-
${detail}`);
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
function tryGit(args, cwd) {
|
|
1789
|
-
try {
|
|
1790
|
-
git(args, cwd);
|
|
1791
|
-
return true;
|
|
1792
|
-
} catch {
|
|
1793
|
-
return false;
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
function abortUnfinishedGitOps(cwd) {
|
|
1797
|
-
const aborted = [];
|
|
1798
|
-
const gitDir = path10.join(cwd ?? process.cwd(), ".git");
|
|
1799
|
-
if (!fs11.existsSync(gitDir)) return aborted;
|
|
1800
|
-
if (fs11.existsSync(path10.join(gitDir, "MERGE_HEAD"))) {
|
|
1801
|
-
if (tryGit(["merge", "--abort"], cwd)) aborted.push("merge");
|
|
1802
|
-
}
|
|
1803
|
-
if (fs11.existsSync(path10.join(gitDir, "CHERRY_PICK_HEAD"))) {
|
|
1804
|
-
if (tryGit(["cherry-pick", "--abort"], cwd)) aborted.push("cherry-pick");
|
|
1805
|
-
}
|
|
1806
|
-
if (fs11.existsSync(path10.join(gitDir, "REVERT_HEAD"))) {
|
|
1807
|
-
if (tryGit(["revert", "--abort"], cwd)) aborted.push("revert");
|
|
1808
|
-
}
|
|
1809
|
-
if (fs11.existsSync(path10.join(gitDir, "rebase-merge")) || fs11.existsSync(path10.join(gitDir, "rebase-apply"))) {
|
|
1810
|
-
if (tryGit(["rebase", "--abort"], cwd)) aborted.push("rebase");
|
|
1811
|
-
}
|
|
1812
|
-
try {
|
|
1813
|
-
const unmerged = git(["diff", "--name-only", "--diff-filter=U"], cwd);
|
|
1814
|
-
if (unmerged) {
|
|
1815
|
-
tryGit(["reset", "--mixed", "HEAD"], cwd);
|
|
1816
|
-
aborted.push("unmerged-paths-reset");
|
|
1817
|
-
}
|
|
1818
|
-
} catch {
|
|
1819
|
-
}
|
|
1820
|
-
return aborted;
|
|
1821
|
-
}
|
|
1822
|
-
function isForbiddenPath(p) {
|
|
1823
|
-
if (FORBIDDEN_PATH_EXACT.has(p)) return true;
|
|
1824
|
-
for (const pre of FORBIDDEN_PATH_PREFIXES) if (p.startsWith(pre)) return true;
|
|
1825
|
-
for (const suf of FORBIDDEN_PATH_SUFFIXES) if (p.endsWith(suf)) return true;
|
|
1826
|
-
return false;
|
|
1827
|
-
}
|
|
1828
|
-
function listChangedFiles(cwd) {
|
|
1829
|
-
const raw = execFileSync5("git", ["status", "--porcelain=v1", "-z"], {
|
|
1830
|
-
encoding: "utf-8",
|
|
1831
|
-
cwd,
|
|
1832
|
-
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
1833
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1834
|
-
});
|
|
1835
|
-
if (!raw) return [];
|
|
1836
|
-
const entries = raw.split("\0").filter((e) => e.length > 0);
|
|
1837
|
-
return entries.map((e) => e.slice(3)).filter(Boolean);
|
|
1838
|
-
}
|
|
1839
|
-
function listFilesInCommit(ref = "HEAD", cwd) {
|
|
1840
|
-
try {
|
|
1841
|
-
const raw = execFileSync5("git", ["show", "--name-only", "--pretty=format:", "-z", ref], {
|
|
1842
|
-
encoding: "utf-8",
|
|
1843
|
-
cwd,
|
|
1844
|
-
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
1845
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1846
|
-
});
|
|
1847
|
-
return raw.split("\0").map((s) => s.trim()).filter(Boolean);
|
|
1848
|
-
} catch {
|
|
1849
|
-
return [];
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
function normalizeCommitMessage(raw) {
|
|
1853
|
-
const trimmed = raw.trim().replace(/^['"]|['"]$/g, "").trim();
|
|
1854
|
-
if (!trimmed) return "chore: kody update";
|
|
1855
|
-
const firstLine2 = trimmed.split("\n")[0];
|
|
1856
|
-
for (const prefix of CONVENTIONAL_PREFIXES) {
|
|
1857
|
-
if (firstLine2.toLowerCase().startsWith(prefix)) return trimmed;
|
|
1858
|
-
}
|
|
1859
|
-
return `chore: ${trimmed}`;
|
|
1860
|
-
}
|
|
1861
|
-
function commitAndPush(branch, agentMessage, cwd) {
|
|
1862
|
-
const allChanged = listChangedFiles(cwd);
|
|
1863
|
-
const allowedFiles = allChanged.filter((f) => !isForbiddenPath(f));
|
|
1864
|
-
const mergeHeadExists = fs11.existsSync(path10.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
|
|
1865
|
-
if (allowedFiles.length === 0 && !mergeHeadExists) {
|
|
1866
|
-
return { committed: false, pushed: false, sha: "", message: "" };
|
|
1867
|
-
}
|
|
1868
|
-
for (const f of allowedFiles) {
|
|
1869
|
-
try {
|
|
1870
|
-
git(["add", "--", f], cwd);
|
|
1871
|
-
} catch {
|
|
1872
|
-
}
|
|
1873
|
-
}
|
|
1874
|
-
const message = normalizeCommitMessage(agentMessage);
|
|
1875
|
-
try {
|
|
1876
|
-
git(["commit", "--no-gpg-sign", "-m", message], cwd);
|
|
1877
|
-
} catch (err) {
|
|
1878
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1879
|
-
if (/nothing to commit/i.test(msg)) {
|
|
1880
|
-
return { committed: false, pushed: false, sha: "", message };
|
|
1881
|
-
}
|
|
1882
|
-
throw err;
|
|
1883
|
-
}
|
|
1884
|
-
const sha = git(["rev-parse", "HEAD"], cwd).slice(0, 7);
|
|
1885
|
-
try {
|
|
1886
|
-
git(["push", "-u", "origin", branch], cwd);
|
|
1887
|
-
} catch {
|
|
1888
|
-
git(["push", "--force-with-lease", "-u", "origin", branch], cwd);
|
|
1889
|
-
}
|
|
1890
|
-
return { committed: true, pushed: true, sha, message };
|
|
1891
|
-
}
|
|
1892
|
-
function hasCommitsAhead(branch, defaultBranch, cwd) {
|
|
1893
|
-
try {
|
|
1894
|
-
const out = git(["rev-list", "--count", `origin/${defaultBranch}..${branch}`], cwd);
|
|
1895
|
-
return parseInt(out, 10) > 0;
|
|
1896
|
-
} catch {
|
|
1897
|
-
try {
|
|
1898
|
-
const out = git(["rev-list", "--count", `${defaultBranch}..${branch}`], cwd);
|
|
1899
|
-
return parseInt(out, 10) > 0;
|
|
1900
|
-
} catch {
|
|
1901
|
-
return false;
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
|
|
1906
|
-
// src/scripts/commitAndPush.ts
|
|
1907
|
-
var commitAndPush2 = async (ctx, profile) => {
|
|
1914
|
+
var DEFAULT_COMMIT_MESSAGE = "chore: kody changes";
|
|
1915
|
+
var commitAndPush2 = async (ctx) => {
|
|
1908
1916
|
const branch = ctx.data.branch;
|
|
1909
1917
|
if (!branch) {
|
|
1910
1918
|
ctx.data.commitResult = { committed: false, pushed: false };
|
|
@@ -1915,21 +1923,7 @@ var commitAndPush2 = async (ctx, profile) => {
|
|
|
1915
1923
|
ctx.data.hasCommitsAhead = hasCommitsAhead(branch, ctx.config.git.defaultBranch, ctx.cwd);
|
|
1916
1924
|
return;
|
|
1917
1925
|
}
|
|
1918
|
-
const
|
|
1919
|
-
if (kind === "resolve") {
|
|
1920
|
-
try {
|
|
1921
|
-
execFileSync6("git", ["add", "-A"], { cwd: ctx.cwd, env: { ...process.env, HUSKY: "0" }, stdio: "pipe" });
|
|
1922
|
-
} catch {
|
|
1923
|
-
}
|
|
1924
|
-
} else {
|
|
1925
|
-
const aborted = abortUnfinishedGitOps(ctx.cwd);
|
|
1926
|
-
if (aborted.length > 0) {
|
|
1927
|
-
process.stderr.write(`[kody] cleaned up unfinished git ops: ${aborted.join(", ")}
|
|
1928
|
-
`);
|
|
1929
|
-
}
|
|
1930
|
-
}
|
|
1931
|
-
const fallbackMsg = defaultCommitMessage(kind, ctx.data);
|
|
1932
|
-
const message = ctx.data.commitMessage || fallbackMsg;
|
|
1926
|
+
const message = ctx.data.commitMessage || DEFAULT_COMMIT_MESSAGE;
|
|
1933
1927
|
try {
|
|
1934
1928
|
const result = commitAndPush(branch, message, ctx.cwd);
|
|
1935
1929
|
ctx.data.commitResult = result;
|
|
@@ -1941,20 +1935,6 @@ var commitAndPush2 = async (ctx, profile) => {
|
|
|
1941
1935
|
}
|
|
1942
1936
|
ctx.data.hasCommitsAhead = hasCommitsAhead(branch, ctx.config.git.defaultBranch, ctx.cwd);
|
|
1943
1937
|
};
|
|
1944
|
-
function defaultCommitMessage(mode, data) {
|
|
1945
|
-
switch (mode) {
|
|
1946
|
-
case "run":
|
|
1947
|
-
return `chore: kody changes for #${data.commentTargetNumber}`;
|
|
1948
|
-
case "fix":
|
|
1949
|
-
return `chore(fix): kody fix for PR #${data.commentTargetNumber}`;
|
|
1950
|
-
case "fix-ci":
|
|
1951
|
-
return `fix(ci): kody fix-ci for PR #${data.commentTargetNumber}`;
|
|
1952
|
-
case "resolve":
|
|
1953
|
-
return `fix: resolve merge conflicts with ${data.baseBranch}`;
|
|
1954
|
-
default:
|
|
1955
|
-
return `chore: kody changes`;
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
1938
|
|
|
1959
1939
|
// src/scripts/composePrompt.ts
|
|
1960
1940
|
import * as fs12 from "fs";
|
|
@@ -2055,7 +2035,7 @@ function formatToolsUsage(profile) {
|
|
|
2055
2035
|
}
|
|
2056
2036
|
|
|
2057
2037
|
// src/scripts/diagMcp.ts
|
|
2058
|
-
import { execFileSync as
|
|
2038
|
+
import { execFileSync as execFileSync6 } from "child_process";
|
|
2059
2039
|
import * as fs13 from "fs";
|
|
2060
2040
|
import * as os3 from "os";
|
|
2061
2041
|
import * as path12 from "path";
|
|
@@ -2075,7 +2055,7 @@ var diagMcp = async (_ctx) => {
|
|
|
2075
2055
|
process.stderr.write(`[kody diag] chromium present: ${hasChromium ? "yes" : "no"}
|
|
2076
2056
|
`);
|
|
2077
2057
|
try {
|
|
2078
|
-
const v =
|
|
2058
|
+
const v = execFileSync6(
|
|
2079
2059
|
"npx",
|
|
2080
2060
|
["-y", "--package=@playwright/mcp@latest", "--", "playwright-mcp", "--version"],
|
|
2081
2061
|
{ stdio: "pipe", timeout: 6e4, encoding: "utf8" }
|
|
@@ -2575,7 +2555,7 @@ var discoverQaContext = async (ctx) => {
|
|
|
2575
2555
|
};
|
|
2576
2556
|
|
|
2577
2557
|
// src/scripts/dispatch.ts
|
|
2578
|
-
import { execFileSync as
|
|
2558
|
+
import { execFileSync as execFileSync7 } from "child_process";
|
|
2579
2559
|
var API_TIMEOUT_MS3 = 3e4;
|
|
2580
2560
|
var dispatch = async (ctx, _profile, _agentResult, args) => {
|
|
2581
2561
|
const next = args?.next;
|
|
@@ -2598,7 +2578,7 @@ var dispatch = async (ctx, _profile, _agentResult, args) => {
|
|
|
2598
2578
|
const sub = usePr ? "pr" : "issue";
|
|
2599
2579
|
const body = `@kody ${next}`;
|
|
2600
2580
|
try {
|
|
2601
|
-
|
|
2581
|
+
execFileSync7("gh", [sub, "comment", String(targetNumber), "--body", body], {
|
|
2602
2582
|
timeout: API_TIMEOUT_MS3,
|
|
2603
2583
|
cwd: ctx.cwd,
|
|
2604
2584
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -2618,7 +2598,7 @@ function parsePr(url) {
|
|
|
2618
2598
|
}
|
|
2619
2599
|
|
|
2620
2600
|
// src/issue.ts
|
|
2621
|
-
import { execFileSync as
|
|
2601
|
+
import { execFileSync as execFileSync8 } from "child_process";
|
|
2622
2602
|
var API_TIMEOUT_MS4 = 3e4;
|
|
2623
2603
|
function ghToken2() {
|
|
2624
2604
|
return process.env.GH_PAT?.trim() || process.env.GH_TOKEN;
|
|
@@ -2626,7 +2606,7 @@ function ghToken2() {
|
|
|
2626
2606
|
function gh2(args, options) {
|
|
2627
2607
|
const token = ghToken2();
|
|
2628
2608
|
const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
|
|
2629
|
-
return
|
|
2609
|
+
return execFileSync8("gh", args, {
|
|
2630
2610
|
encoding: "utf-8",
|
|
2631
2611
|
timeout: API_TIMEOUT_MS4,
|
|
2632
2612
|
cwd: options?.cwd,
|
|
@@ -2930,7 +2910,7 @@ function computeFailureReason(ctx) {
|
|
|
2930
2910
|
}
|
|
2931
2911
|
|
|
2932
2912
|
// src/scripts/finishFlow.ts
|
|
2933
|
-
import { execFileSync as
|
|
2913
|
+
import { execFileSync as execFileSync9 } from "child_process";
|
|
2934
2914
|
|
|
2935
2915
|
// src/lifecycleLabels.ts
|
|
2936
2916
|
var KODY_NAMESPACE = "kody";
|
|
@@ -3089,7 +3069,7 @@ var finishFlow = async (ctx, _profile, _agentResult, args) => {
|
|
|
3089
3069
|
**PR:** ${state.core.prUrl}` : "";
|
|
3090
3070
|
const body = `${icon} kody flow \`${flowName}\` finished \u2014 \`${reason}\`${prSuffix}`;
|
|
3091
3071
|
try {
|
|
3092
|
-
|
|
3072
|
+
execFileSync9("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
3093
3073
|
timeout: API_TIMEOUT_MS5,
|
|
3094
3074
|
cwd: ctx.cwd,
|
|
3095
3075
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -3103,7 +3083,7 @@ var finishFlow = async (ctx, _profile, _agentResult, args) => {
|
|
|
3103
3083
|
};
|
|
3104
3084
|
|
|
3105
3085
|
// src/branch.ts
|
|
3106
|
-
import { execFileSync as
|
|
3086
|
+
import { execFileSync as execFileSync10 } from "child_process";
|
|
3107
3087
|
var UncommittedChangesError = class extends Error {
|
|
3108
3088
|
constructor(branch) {
|
|
3109
3089
|
super(`Uncommitted changes on branch '${branch}' \u2014 refusing to run to protect work in progress`);
|
|
@@ -3113,7 +3093,7 @@ var UncommittedChangesError = class extends Error {
|
|
|
3113
3093
|
branch;
|
|
3114
3094
|
};
|
|
3115
3095
|
function git2(args, cwd) {
|
|
3116
|
-
return
|
|
3096
|
+
return execFileSync10("git", args, {
|
|
3117
3097
|
encoding: "utf-8",
|
|
3118
3098
|
timeout: 3e4,
|
|
3119
3099
|
cwd,
|
|
@@ -3138,7 +3118,7 @@ function checkoutPrBranch(prNumber, cwd) {
|
|
|
3138
3118
|
SKIP_HOOKS: "1",
|
|
3139
3119
|
GH_TOKEN: process.env.GH_PAT?.trim() || process.env.GH_TOKEN || ""
|
|
3140
3120
|
};
|
|
3141
|
-
|
|
3121
|
+
execFileSync10("gh", ["pr", "checkout", String(prNumber)], {
|
|
3142
3122
|
cwd,
|
|
3143
3123
|
env,
|
|
3144
3124
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -3205,7 +3185,7 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch, cwd) {
|
|
|
3205
3185
|
}
|
|
3206
3186
|
|
|
3207
3187
|
// src/gha.ts
|
|
3208
|
-
import { execFileSync as
|
|
3188
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
3209
3189
|
import * as fs16 from "fs";
|
|
3210
3190
|
function getRunUrl() {
|
|
3211
3191
|
const server = process.env.GITHUB_SERVER_URL;
|
|
@@ -3248,7 +3228,7 @@ function reactToTriggerComment(cwd) {
|
|
|
3248
3228
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
3249
3229
|
if (attempt > 0) sleepMs(attempt === 1 ? 500 : 1500);
|
|
3250
3230
|
try {
|
|
3251
|
-
|
|
3231
|
+
execFileSync11("gh", args, opts);
|
|
3252
3232
|
return;
|
|
3253
3233
|
} catch (err) {
|
|
3254
3234
|
lastErr = err;
|
|
@@ -3261,13 +3241,13 @@ function reactToTriggerComment(cwd) {
|
|
|
3261
3241
|
}
|
|
3262
3242
|
function sleepMs(ms) {
|
|
3263
3243
|
try {
|
|
3264
|
-
|
|
3244
|
+
execFileSync11("sleep", [(ms / 1e3).toString()], { stdio: "ignore", timeout: ms + 1e3 });
|
|
3265
3245
|
} catch {
|
|
3266
3246
|
}
|
|
3267
3247
|
}
|
|
3268
3248
|
|
|
3269
3249
|
// src/workflow.ts
|
|
3270
|
-
import { execFileSync as
|
|
3250
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
3271
3251
|
var GH_TIMEOUT_MS = 3e4;
|
|
3272
3252
|
function ghToken3() {
|
|
3273
3253
|
return process.env.GH_PAT?.trim() || process.env.GH_TOKEN;
|
|
@@ -3275,7 +3255,7 @@ function ghToken3() {
|
|
|
3275
3255
|
function gh3(args, cwd) {
|
|
3276
3256
|
const token = ghToken3();
|
|
3277
3257
|
const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
|
|
3278
|
-
return
|
|
3258
|
+
return execFileSync12("gh", args, {
|
|
3279
3259
|
encoding: "utf-8",
|
|
3280
3260
|
timeout: GH_TIMEOUT_MS,
|
|
3281
3261
|
cwd,
|
|
@@ -3459,7 +3439,7 @@ function tryPostPr2(prNumber, body, cwd) {
|
|
|
3459
3439
|
}
|
|
3460
3440
|
|
|
3461
3441
|
// src/scripts/initFlow.ts
|
|
3462
|
-
import { execFileSync as
|
|
3442
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
3463
3443
|
import * as fs18 from "fs";
|
|
3464
3444
|
import * as path16 from "path";
|
|
3465
3445
|
|
|
@@ -3500,7 +3480,7 @@ function qualityCommandsFor(pm) {
|
|
|
3500
3480
|
function detectOwnerRepo(cwd) {
|
|
3501
3481
|
let url;
|
|
3502
3482
|
try {
|
|
3503
|
-
url =
|
|
3483
|
+
url = execFileSync13("git", ["remote", "get-url", "origin"], {
|
|
3504
3484
|
cwd,
|
|
3505
3485
|
encoding: "utf-8",
|
|
3506
3486
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -3584,7 +3564,7 @@ jobs:
|
|
|
3584
3564
|
`;
|
|
3585
3565
|
function defaultBranchFromGit(cwd) {
|
|
3586
3566
|
try {
|
|
3587
|
-
const ref =
|
|
3567
|
+
const ref = execFileSync13("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], {
|
|
3588
3568
|
cwd,
|
|
3589
3569
|
encoding: "utf-8",
|
|
3590
3570
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -3592,7 +3572,7 @@ function defaultBranchFromGit(cwd) {
|
|
|
3592
3572
|
return ref.replace("refs/remotes/origin/", "");
|
|
3593
3573
|
} catch {
|
|
3594
3574
|
try {
|
|
3595
|
-
return
|
|
3575
|
+
return execFileSync13("git", ["branch", "--show-current"], {
|
|
3596
3576
|
cwd,
|
|
3597
3577
|
encoding: "utf-8",
|
|
3598
3578
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -3977,7 +3957,7 @@ var persistFlowState = async (ctx) => {
|
|
|
3977
3957
|
};
|
|
3978
3958
|
|
|
3979
3959
|
// src/scripts/postClassification.ts
|
|
3980
|
-
import { execFileSync as
|
|
3960
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
3981
3961
|
var API_TIMEOUT_MS6 = 3e4;
|
|
3982
3962
|
var VALID_CLASSES2 = /* @__PURE__ */ new Set(["feature", "bug", "spec", "chore"]);
|
|
3983
3963
|
var postClassification = async (ctx) => {
|
|
@@ -4007,7 +3987,7 @@ var postClassification = async (ctx) => {
|
|
|
4007
3987
|
ctx.cwd
|
|
4008
3988
|
);
|
|
4009
3989
|
try {
|
|
4010
|
-
|
|
3990
|
+
execFileSync14("gh", ["issue", "comment", String(issueNumber), "--body", `@kody ${classification}`], {
|
|
4011
3991
|
cwd: ctx.cwd,
|
|
4012
3992
|
timeout: API_TIMEOUT_MS6,
|
|
4013
3993
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -4041,7 +4021,7 @@ function parseClassification(prSummary) {
|
|
|
4041
4021
|
}
|
|
4042
4022
|
function tryAuditComment(issueNumber, body, cwd) {
|
|
4043
4023
|
try {
|
|
4044
|
-
|
|
4024
|
+
execFileSync14("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
4045
4025
|
cwd,
|
|
4046
4026
|
timeout: API_TIMEOUT_MS6,
|
|
4047
4027
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -4225,7 +4205,7 @@ REVIEW_POSTED=https://github.com/${ctx.config.github.owner}/${ctx.config.github.
|
|
|
4225
4205
|
};
|
|
4226
4206
|
|
|
4227
4207
|
// src/scripts/releaseFlow.ts
|
|
4228
|
-
import { execFileSync as
|
|
4208
|
+
import { execFileSync as execFileSync15, spawnSync } from "child_process";
|
|
4229
4209
|
import * as fs19 from "fs";
|
|
4230
4210
|
import * as path17 from "path";
|
|
4231
4211
|
function notifyIssue(issueNumber, body, cwd) {
|
|
@@ -4265,7 +4245,7 @@ function generateChangelog(cwd, newVersion, lastTag) {
|
|
|
4265
4245
|
else logArgs.splice(1, 0, `-n${FIRST_RELEASE_COMMIT_CAP}`, "HEAD");
|
|
4266
4246
|
let log = "";
|
|
4267
4247
|
try {
|
|
4268
|
-
log =
|
|
4248
|
+
log = execFileSync15("git", logArgs, {
|
|
4269
4249
|
cwd,
|
|
4270
4250
|
encoding: "utf-8",
|
|
4271
4251
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -4322,7 +4302,7 @@ ${entry}${prior.slice(idx + 1)}`);
|
|
|
4322
4302
|
}
|
|
4323
4303
|
}
|
|
4324
4304
|
function git3(args, cwd, timeout = 6e4) {
|
|
4325
|
-
return
|
|
4305
|
+
return execFileSync15("git", args, {
|
|
4326
4306
|
encoding: "utf-8",
|
|
4327
4307
|
timeout,
|
|
4328
4308
|
cwd,
|
|
@@ -4699,7 +4679,7 @@ var resolveArtifacts = async (ctx, profile) => {
|
|
|
4699
4679
|
};
|
|
4700
4680
|
|
|
4701
4681
|
// src/scripts/resolveFlow.ts
|
|
4702
|
-
import { execFileSync as
|
|
4682
|
+
import { execFileSync as execFileSync16 } from "child_process";
|
|
4703
4683
|
var CONFLICT_DIFF_MAX_BYTES = 4e4;
|
|
4704
4684
|
var resolveFlow = async (ctx) => {
|
|
4705
4685
|
const prNumber = ctx.args.pr;
|
|
@@ -4769,7 +4749,7 @@ function buildPreferBlock(prefer, baseBranch) {
|
|
|
4769
4749
|
}
|
|
4770
4750
|
function getConflictedFiles(cwd) {
|
|
4771
4751
|
try {
|
|
4772
|
-
const out =
|
|
4752
|
+
const out = execFileSync16("git", ["diff", "--name-only", "--diff-filter=U"], {
|
|
4773
4753
|
encoding: "utf-8",
|
|
4774
4754
|
cwd,
|
|
4775
4755
|
env: { ...process.env, HUSKY: "0" }
|
|
@@ -4784,7 +4764,7 @@ function getConflictMarkersPreview(files, cwd, maxBytes = CONFLICT_DIFF_MAX_BYTE
|
|
|
4784
4764
|
let total = 0;
|
|
4785
4765
|
for (const f of files) {
|
|
4786
4766
|
try {
|
|
4787
|
-
const content =
|
|
4767
|
+
const content = execFileSync16("cat", [f], { encoding: "utf-8", cwd }).toString();
|
|
4788
4768
|
const snippet = `### ${f}
|
|
4789
4769
|
|
|
4790
4770
|
\`\`\`
|
|
@@ -4947,6 +4927,20 @@ var skipAgent = async (ctx) => {
|
|
|
4947
4927
|
ctx.skipAgent = true;
|
|
4948
4928
|
};
|
|
4949
4929
|
|
|
4930
|
+
// src/scripts/stageMergeConflicts.ts
|
|
4931
|
+
import { execFileSync as execFileSync17 } from "child_process";
|
|
4932
|
+
var stageMergeConflicts = async (ctx) => {
|
|
4933
|
+
if (ctx.data.agentDone === false) return;
|
|
4934
|
+
try {
|
|
4935
|
+
execFileSync17("git", ["add", "-A"], {
|
|
4936
|
+
cwd: ctx.cwd,
|
|
4937
|
+
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
4938
|
+
stdio: "pipe"
|
|
4939
|
+
});
|
|
4940
|
+
} catch {
|
|
4941
|
+
}
|
|
4942
|
+
};
|
|
4943
|
+
|
|
4950
4944
|
// src/scripts/startFlow.ts
|
|
4951
4945
|
import { execFileSync as execFileSync18 } from "child_process";
|
|
4952
4946
|
var API_TIMEOUT_MS7 = 3e4;
|
|
@@ -5300,6 +5294,8 @@ var postflightScripts = {
|
|
|
5300
5294
|
requirePlanDeviations,
|
|
5301
5295
|
verify,
|
|
5302
5296
|
checkCoverageWithRetry,
|
|
5297
|
+
abortUnfinishedGitOps: abortUnfinishedGitOps2,
|
|
5298
|
+
stageMergeConflicts,
|
|
5303
5299
|
commitAndPush: commitAndPush2,
|
|
5304
5300
|
ensurePr: ensurePr2,
|
|
5305
5301
|
postIssueComment: postIssueComment2,
|
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.13",
|
|
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",
|