@kody-ade/kody-engine 0.2.63 → 0.3.0
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/README.md +24 -24
- package/dist/bin/{kody2.js → kody.js} +159 -159
- package/dist/executables/bug/profile.json +6 -6
- package/dist/executables/chore/profile.json +6 -6
- package/dist/executables/classify/profile.json +1 -1
- package/dist/executables/feature/profile.json +6 -6
- package/dist/executables/fix/profile.json +1 -1
- package/dist/executables/fix/prompt.md +1 -1
- package/dist/executables/fix-ci/profile.json +1 -1
- package/dist/executables/init/profile.json +1 -1
- package/dist/executables/plan/profile.json +1 -1
- package/dist/executables/plan-verify/profile.json +2 -2
- package/dist/executables/plan-verify/prompt.md +1 -1
- package/dist/executables/research/profile.json +1 -1
- package/dist/executables/resolve/profile.json +1 -1
- package/dist/executables/review/profile.json +1 -1
- package/dist/executables/run/profile.json +1 -1
- package/dist/executables/run/prompt.md +2 -2
- package/dist/executables/spec/profile.json +4 -4
- package/dist/executables/sync/profile.json +1 -1
- package/dist/executables/types.ts +3 -3
- package/dist/executables/ui-review/profile.json +3 -3
- package/dist/executables/ui-review/prompt.md +8 -8
- package/dist/plugins/commands/kody-live-probe.md +2 -2
- package/dist/plugins/skills/kody-live-marker/SKILL.md +3 -3
- package/dist/plugins/test-plugin/.claude-plugin/plugin.json +2 -2
- package/dist/plugins/test-plugin/skills/kody-plugin-marker/SKILL.md +2 -2
- package/kody.config.schema.json +3 -3
- package/package.json +4 -4
- package/templates/{kody2.yml → kody.yml} +16 -16
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@kody-ade/kody-engine",
|
|
6
|
-
version: "0.
|
|
7
|
-
description: "
|
|
6
|
+
version: "0.3.0",
|
|
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",
|
|
10
10
|
bin: {
|
|
11
|
-
|
|
11
|
+
kody: "dist/bin/kody.js"
|
|
12
12
|
},
|
|
13
13
|
files: [
|
|
14
14
|
"dist",
|
|
@@ -16,7 +16,7 @@ var package_default = {
|
|
|
16
16
|
"kody.config.schema.json"
|
|
17
17
|
],
|
|
18
18
|
scripts: {
|
|
19
|
-
|
|
19
|
+
kody: "tsx bin/kody.ts",
|
|
20
20
|
build: "tsup && node scripts/copy-assets.cjs",
|
|
21
21
|
test: "vitest run tests/unit tests/int --no-coverage",
|
|
22
22
|
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
@@ -73,7 +73,7 @@ var FileSink = class {
|
|
|
73
73
|
};
|
|
74
74
|
var HttpSink = class {
|
|
75
75
|
constructor(baseUrl, sessionId, logger = {
|
|
76
|
-
warn: (m) => process.stderr.write(`[
|
|
76
|
+
warn: (m) => process.stderr.write(`[kody:chat] ${m}
|
|
77
77
|
`)
|
|
78
78
|
}) {
|
|
79
79
|
this.baseUrl = baseUrl;
|
|
@@ -340,7 +340,7 @@ function formatBytes(bytes) {
|
|
|
340
340
|
// src/agent.ts
|
|
341
341
|
var DEFAULT_ALLOWED_TOOLS = ["Bash", "Edit", "Read", "Write", "Glob", "Grep"];
|
|
342
342
|
async function runAgent(opts) {
|
|
343
|
-
const ndjsonDir = opts.ndjsonDir ?? path3.join(opts.cwd, ".
|
|
343
|
+
const ndjsonDir = opts.ndjsonDir ?? path3.join(opts.cwd, ".kody");
|
|
344
344
|
fs3.mkdirSync(ndjsonDir, { recursive: true });
|
|
345
345
|
const ndjsonPath = path3.join(ndjsonDir, "last-run.jsonl");
|
|
346
346
|
const fullLog = fs3.createWriteStream(ndjsonPath, { flags: "w" });
|
|
@@ -544,7 +544,7 @@ async function emit(sink, type, sessionId, suffix, payload) {
|
|
|
544
544
|
});
|
|
545
545
|
}
|
|
546
546
|
|
|
547
|
-
// src/
|
|
547
|
+
// src/kody-cli.ts
|
|
548
548
|
import { execFileSync as execFileSync20 } from "child_process";
|
|
549
549
|
import * as fs21 from "fs";
|
|
550
550
|
import * as path18 from "path";
|
|
@@ -623,9 +623,9 @@ function asDispatch(executable, target) {
|
|
|
623
623
|
return { executable, cliArgs: { issue: target }, target };
|
|
624
624
|
}
|
|
625
625
|
function extractAfterTag(body) {
|
|
626
|
-
const idx = body.indexOf("@
|
|
626
|
+
const idx = body.indexOf("@kody");
|
|
627
627
|
if (idx === -1) return body;
|
|
628
|
-
return body.slice(idx + "@
|
|
628
|
+
return body.slice(idx + "@kody".length).trim();
|
|
629
629
|
}
|
|
630
630
|
function extractSubcommand(afterTag) {
|
|
631
631
|
const match = afterTag.match(/^([a-z][a-z0-9-]{1,40})\b/);
|
|
@@ -685,13 +685,13 @@ async function startLitellmIfNeeded(model, projectDir, url = LITELLM_DEFAULT_URL
|
|
|
685
685
|
throw new Error("litellm not installed \u2014 run: pip install 'litellm[proxy]'");
|
|
686
686
|
}
|
|
687
687
|
}
|
|
688
|
-
const configPath = path5.join(os.tmpdir(), `
|
|
688
|
+
const configPath = path5.join(os.tmpdir(), `kody-litellm-${Date.now()}.yaml`);
|
|
689
689
|
fs6.writeFileSync(configPath, generateLitellmConfigYaml(model));
|
|
690
690
|
const portMatch = url.match(/:(\d+)/);
|
|
691
691
|
const port = portMatch ? portMatch[1] : "4000";
|
|
692
692
|
const args = cmd === "litellm" ? ["--config", configPath, "--port", port] : ["-m", "litellm", "--config", configPath, "--port", port];
|
|
693
693
|
const dotenvVars = readDotenvApiKeys(projectDir);
|
|
694
|
-
const logPath = path5.join(os.tmpdir(), `
|
|
694
|
+
const logPath = path5.join(os.tmpdir(), `kody-litellm-${Date.now()}.log`);
|
|
695
695
|
const outFd = fs6.openSync(logPath, "w");
|
|
696
696
|
const child = spawn(cmd, args, {
|
|
697
697
|
stdio: ["ignore", outFd, outFd],
|
|
@@ -1000,8 +1000,8 @@ import { execFileSync as execFileSync3 } from "child_process";
|
|
|
1000
1000
|
|
|
1001
1001
|
// src/state.ts
|
|
1002
1002
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
1003
|
-
var STATE_BEGIN = "<!--
|
|
1004
|
-
var STATE_END = "<!--
|
|
1003
|
+
var STATE_BEGIN = "<!-- kody:state:v1:begin -->";
|
|
1004
|
+
var STATE_END = "<!-- kody:state:v1:end -->";
|
|
1005
1005
|
var HISTORY_MAX_ENTRIES = 20;
|
|
1006
1006
|
var API_TIMEOUT_MS = 3e4;
|
|
1007
1007
|
function emptyState() {
|
|
@@ -1117,7 +1117,7 @@ function noteFromAction(action) {
|
|
|
1117
1117
|
}
|
|
1118
1118
|
function renderStateComment(state) {
|
|
1119
1119
|
const lines = [];
|
|
1120
|
-
lines.push("## \u{1F4CB}
|
|
1120
|
+
lines.push("## \u{1F4CB} kody task state");
|
|
1121
1121
|
lines.push("");
|
|
1122
1122
|
if (state.flow) {
|
|
1123
1123
|
lines.push(`- **Flow:** \`${state.flow.name}\` (step: \`${state.flow.step}\`)`);
|
|
@@ -1197,7 +1197,7 @@ function writeTaskState(target, number, state, cwd) {
|
|
|
1197
1197
|
}
|
|
1198
1198
|
} catch (err) {
|
|
1199
1199
|
process.stderr.write(
|
|
1200
|
-
`[
|
|
1200
|
+
`[kody state] failed to write state on ${target} #${number}: ${err instanceof Error ? err.message : String(err)}
|
|
1201
1201
|
`
|
|
1202
1202
|
);
|
|
1203
1203
|
}
|
|
@@ -1221,12 +1221,12 @@ var advanceFlow = async (ctx, profile) => {
|
|
|
1221
1221
|
writeTaskState("issue", flow.issueNumber, next, ctx.cwd);
|
|
1222
1222
|
} catch (err) {
|
|
1223
1223
|
process.stderr.write(
|
|
1224
|
-
`[
|
|
1224
|
+
`[kody advanceFlow] failed to mirror action to issue #${flow.issueNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
1225
1225
|
`
|
|
1226
1226
|
);
|
|
1227
1227
|
}
|
|
1228
1228
|
}
|
|
1229
|
-
const body = `@
|
|
1229
|
+
const body = `@kody ${flow.name}`;
|
|
1230
1230
|
try {
|
|
1231
1231
|
execFileSync3("gh", ["issue", "comment", String(flow.issueNumber), "--body", body], {
|
|
1232
1232
|
timeout: API_TIMEOUT_MS2,
|
|
@@ -1235,7 +1235,7 @@ var advanceFlow = async (ctx, profile) => {
|
|
|
1235
1235
|
});
|
|
1236
1236
|
} catch (err) {
|
|
1237
1237
|
process.stderr.write(
|
|
1238
|
-
`[
|
|
1238
|
+
`[kody advanceFlow] failed to re-trigger orchestrator on issue #${flow.issueNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
1239
1239
|
`
|
|
1240
1240
|
);
|
|
1241
1241
|
}
|
|
@@ -1266,7 +1266,7 @@ var buildSyntheticPlugin = async (ctx, profile) => {
|
|
|
1266
1266
|
if (!needsSynthetic) return;
|
|
1267
1267
|
const catalog = getPluginsCatalogRoot();
|
|
1268
1268
|
const runId = `${profile.name}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1269
|
-
const root = path7.join(os2.tmpdir(), `
|
|
1269
|
+
const root = path7.join(os2.tmpdir(), `kody-synth-${runId}`);
|
|
1270
1270
|
fs8.mkdirSync(path7.join(root, ".claude-plugin"), { recursive: true });
|
|
1271
1271
|
if (cc.skills.length > 0) {
|
|
1272
1272
|
const dst = path7.join(root, "skills");
|
|
@@ -1313,9 +1313,9 @@ var buildSyntheticPlugin = async (ctx, profile) => {
|
|
|
1313
1313
|
`);
|
|
1314
1314
|
}
|
|
1315
1315
|
const manifest = {
|
|
1316
|
-
name: `
|
|
1316
|
+
name: `kody-synth-${profile.name}`,
|
|
1317
1317
|
version: "1.0.0",
|
|
1318
|
-
description: `Synthetic plugin assembled by
|
|
1318
|
+
description: `Synthetic plugin assembled by Kody for profile '${profile.name}' at runtime.`
|
|
1319
1319
|
};
|
|
1320
1320
|
if (cc.skills.length > 0) manifest.skills = ["./skills/"];
|
|
1321
1321
|
if (cc.commands.length > 0) manifest.commands = ["./commands/"];
|
|
@@ -1508,7 +1508,7 @@ var checkCoverageWithRetry = async (ctx) => {
|
|
|
1508
1508
|
ctx.data.coverageMisses = misses;
|
|
1509
1509
|
return;
|
|
1510
1510
|
}
|
|
1511
|
-
process.stderr.write(`[
|
|
1511
|
+
process.stderr.write(`[kody] coverage check found ${misses.length} missing test(s); retrying agent once
|
|
1512
1512
|
`);
|
|
1513
1513
|
const retryPrompt = `${basePrompt}
|
|
1514
1514
|
|
|
@@ -1570,14 +1570,14 @@ import * as path9 from "path";
|
|
|
1570
1570
|
var FORBIDDEN_PATH_PREFIXES = [
|
|
1571
1571
|
".kody/",
|
|
1572
1572
|
".kody-engine/",
|
|
1573
|
-
".
|
|
1573
|
+
".kody/",
|
|
1574
1574
|
".kody-lean/",
|
|
1575
1575
|
// back-compat: stale runtime dir from kody-lean v0.5.x
|
|
1576
1576
|
"node_modules/",
|
|
1577
1577
|
"dist/",
|
|
1578
1578
|
"build/"
|
|
1579
1579
|
];
|
|
1580
|
-
var FORBIDDEN_PATH_EXACT = /* @__PURE__ */ new Set([".env", ".
|
|
1580
|
+
var FORBIDDEN_PATH_EXACT = /* @__PURE__ */ new Set([".env", ".kody-pip-requirements.txt"]);
|
|
1581
1581
|
var FORBIDDEN_PATH_SUFFIXES = [".log"];
|
|
1582
1582
|
var CONVENTIONAL_PREFIXES = [
|
|
1583
1583
|
"feat:",
|
|
@@ -1677,7 +1677,7 @@ function listFilesInCommit(ref = "HEAD", cwd) {
|
|
|
1677
1677
|
}
|
|
1678
1678
|
function normalizeCommitMessage(raw) {
|
|
1679
1679
|
const trimmed = raw.trim().replace(/^['"]|['"]$/g, "").trim();
|
|
1680
|
-
if (!trimmed) return "chore:
|
|
1680
|
+
if (!trimmed) return "chore: kody update";
|
|
1681
1681
|
const firstLine2 = trimmed.split("\n")[0];
|
|
1682
1682
|
for (const prefix of CONVENTIONAL_PREFIXES) {
|
|
1683
1683
|
if (firstLine2.toLowerCase().startsWith(prefix)) return trimmed;
|
|
@@ -1750,7 +1750,7 @@ var commitAndPush2 = async (ctx, profile) => {
|
|
|
1750
1750
|
} else {
|
|
1751
1751
|
const aborted = abortUnfinishedGitOps(ctx.cwd);
|
|
1752
1752
|
if (aborted.length > 0) {
|
|
1753
|
-
process.stderr.write(`[
|
|
1753
|
+
process.stderr.write(`[kody] cleaned up unfinished git ops: ${aborted.join(", ")}
|
|
1754
1754
|
`);
|
|
1755
1755
|
}
|
|
1756
1756
|
}
|
|
@@ -1770,15 +1770,15 @@ var commitAndPush2 = async (ctx, profile) => {
|
|
|
1770
1770
|
function defaultCommitMessage(mode, data) {
|
|
1771
1771
|
switch (mode) {
|
|
1772
1772
|
case "run":
|
|
1773
|
-
return `chore:
|
|
1773
|
+
return `chore: kody changes for #${data.commentTargetNumber}`;
|
|
1774
1774
|
case "fix":
|
|
1775
|
-
return `chore(fix):
|
|
1775
|
+
return `chore(fix): kody fix for PR #${data.commentTargetNumber}`;
|
|
1776
1776
|
case "fix-ci":
|
|
1777
|
-
return `fix(ci):
|
|
1777
|
+
return `fix(ci): kody fix-ci for PR #${data.commentTargetNumber}`;
|
|
1778
1778
|
case "resolve":
|
|
1779
1779
|
return `fix: resolve merge conflicts with ${data.baseBranch}`;
|
|
1780
1780
|
default:
|
|
1781
|
-
return `chore:
|
|
1781
|
+
return `chore: kody changes`;
|
|
1782
1782
|
}
|
|
1783
1783
|
}
|
|
1784
1784
|
|
|
@@ -2301,7 +2301,7 @@ function generateQaGuideTemplate(d) {
|
|
|
2301
2301
|
const lines = [];
|
|
2302
2302
|
lines.push("# QA guide");
|
|
2303
2303
|
lines.push("");
|
|
2304
|
-
lines.push("This file is read by `
|
|
2304
|
+
lines.push("This file is read by `kody ui-review`. Fill in the credential placeholders");
|
|
2305
2305
|
lines.push("below and commit \u2014 the agent uses them to log in to your preview deployment.");
|
|
2306
2306
|
lines.push("");
|
|
2307
2307
|
lines.push("## Test accounts");
|
|
@@ -2371,13 +2371,13 @@ var API_TIMEOUT_MS3 = 3e4;
|
|
|
2371
2371
|
var dispatch = async (ctx, _profile, _agentResult, args) => {
|
|
2372
2372
|
const next = args?.next;
|
|
2373
2373
|
if (!next) {
|
|
2374
|
-
process.stderr.write("[
|
|
2374
|
+
process.stderr.write("[kody dispatch] missing `with.next` \u2014 skipping\n");
|
|
2375
2375
|
return;
|
|
2376
2376
|
}
|
|
2377
2377
|
const target = args?.target ?? "issue";
|
|
2378
2378
|
const issueNumber = ctx.args.issue;
|
|
2379
2379
|
if (!issueNumber) {
|
|
2380
|
-
process.stderr.write("[
|
|
2380
|
+
process.stderr.write("[kody dispatch] no --issue arg \u2014 skipping\n");
|
|
2381
2381
|
return;
|
|
2382
2382
|
}
|
|
2383
2383
|
const state = ctx.data.taskState;
|
|
@@ -2387,7 +2387,7 @@ var dispatch = async (ctx, _profile, _agentResult, args) => {
|
|
|
2387
2387
|
const usePr = target === "pr" && state?.core.prUrl;
|
|
2388
2388
|
const targetNumber = usePr ? parsePr(state.core.prUrl) ?? issueNumber : issueNumber;
|
|
2389
2389
|
const sub = usePr ? "pr" : "issue";
|
|
2390
|
-
const body = `@
|
|
2390
|
+
const body = `@kody ${next}`;
|
|
2391
2391
|
try {
|
|
2392
2392
|
execFileSync7("gh", [sub, "comment", String(targetNumber), "--body", body], {
|
|
2393
2393
|
timeout: API_TIMEOUT_MS3,
|
|
@@ -2396,7 +2396,7 @@ var dispatch = async (ctx, _profile, _agentResult, args) => {
|
|
|
2396
2396
|
});
|
|
2397
2397
|
} catch (err) {
|
|
2398
2398
|
process.stderr.write(
|
|
2399
|
-
`[
|
|
2399
|
+
`[kody dispatch] failed to post @kody ${next} on ${sub} #${targetNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
2400
2400
|
`
|
|
2401
2401
|
);
|
|
2402
2402
|
}
|
|
@@ -2444,15 +2444,15 @@ function getIssue(issueNumber, cwd) {
|
|
|
2444
2444
|
labels: Array.isArray(parsed.labels) ? parsed.labels.map((l) => l.name ?? "").filter((n) => n.length > 0) : []
|
|
2445
2445
|
};
|
|
2446
2446
|
}
|
|
2447
|
-
function
|
|
2448
|
-
return body.replace(/(@)(
|
|
2447
|
+
function stripKodyMentions(body) {
|
|
2448
|
+
return body.replace(/(@)(kody)/gi, "$1\u200B$2");
|
|
2449
2449
|
}
|
|
2450
2450
|
function postIssueComment(issueNumber, body, cwd) {
|
|
2451
2451
|
try {
|
|
2452
|
-
gh2(["issue", "comment", String(issueNumber), "--body-file", "-"], { input:
|
|
2452
|
+
gh2(["issue", "comment", String(issueNumber), "--body-file", "-"], { input: stripKodyMentions(body), cwd });
|
|
2453
2453
|
} catch (err) {
|
|
2454
2454
|
process.stderr.write(
|
|
2455
|
-
`[
|
|
2455
|
+
`[kody] failed to post comment on #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
2456
2456
|
`
|
|
2457
2457
|
);
|
|
2458
2458
|
}
|
|
@@ -2483,7 +2483,7 @@ function getPrDiff(prNumber, cwd) {
|
|
|
2483
2483
|
return gh2(["pr", "diff", String(prNumber)], { cwd });
|
|
2484
2484
|
} catch (err) {
|
|
2485
2485
|
process.stderr.write(
|
|
2486
|
-
`[
|
|
2486
|
+
`[kody] failed to fetch diff for PR #${prNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
2487
2487
|
`
|
|
2488
2488
|
);
|
|
2489
2489
|
return "";
|
|
@@ -2534,10 +2534,10 @@ function getPrLatestReviewBody(prNumber, cwd) {
|
|
|
2534
2534
|
}
|
|
2535
2535
|
function postPrReviewComment(prNumber, body, cwd) {
|
|
2536
2536
|
try {
|
|
2537
|
-
gh2(["pr", "comment", String(prNumber), "--body-file", "-"], { input:
|
|
2537
|
+
gh2(["pr", "comment", String(prNumber), "--body-file", "-"], { input: stripKodyMentions(body), cwd });
|
|
2538
2538
|
} catch (err) {
|
|
2539
2539
|
process.stderr.write(
|
|
2540
|
-
`[
|
|
2540
|
+
`[kody] failed to post review comment on PR #${prNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
2541
2541
|
`
|
|
2542
2542
|
);
|
|
2543
2543
|
}
|
|
@@ -2600,7 +2600,7 @@ function buildPrBody(opts) {
|
|
|
2600
2600
|
lines.push("");
|
|
2601
2601
|
}
|
|
2602
2602
|
lines.push("---");
|
|
2603
|
-
lines.push("_Opened by
|
|
2603
|
+
lines.push("_Opened by kody (single-session autonomous run)._ ");
|
|
2604
2604
|
return lines.join("\n");
|
|
2605
2605
|
}
|
|
2606
2606
|
function firstLine(s) {
|
|
@@ -2671,7 +2671,7 @@ var ensurePr2 = async (ctx) => {
|
|
|
2671
2671
|
const issue = ctx.data.issue;
|
|
2672
2672
|
const pr = ctx.data.pr;
|
|
2673
2673
|
const targetNumber = Number(ctx.data.commentTargetNumber ?? 0);
|
|
2674
|
-
const title = issue?.title ?? pr?.title ?? `
|
|
2674
|
+
const title = issue?.title ?? pr?.title ?? `kody changes`;
|
|
2675
2675
|
try {
|
|
2676
2676
|
const result = ensurePr({
|
|
2677
2677
|
branch,
|
|
@@ -2843,7 +2843,7 @@ function setKodyLabel(issueNumber, spec, cwd) {
|
|
|
2843
2843
|
const target = spec.label;
|
|
2844
2844
|
if (!target.startsWith(KODY_NAMESPACE)) {
|
|
2845
2845
|
process.stderr.write(
|
|
2846
|
-
`[
|
|
2846
|
+
`[kody] setKodyLabel: refusing to set non-kody label "${target}"
|
|
2847
2847
|
`
|
|
2848
2848
|
);
|
|
2849
2849
|
return;
|
|
@@ -2865,14 +2865,14 @@ function setKodyLabel(issueNumber, spec, cwd) {
|
|
|
2865
2865
|
return;
|
|
2866
2866
|
} catch (retryErr) {
|
|
2867
2867
|
process.stderr.write(
|
|
2868
|
-
`[
|
|
2868
|
+
`[kody] setKodyLabel: create+retry failed for ${target} on #${issueNumber}: ${errMsg(retryErr)}
|
|
2869
2869
|
`
|
|
2870
2870
|
);
|
|
2871
2871
|
return;
|
|
2872
2872
|
}
|
|
2873
2873
|
}
|
|
2874
2874
|
process.stderr.write(
|
|
2875
|
-
`[
|
|
2875
|
+
`[kody] setKodyLabel: failed to add ${target} on #${issueNumber}: ${errMsg(err)}
|
|
2876
2876
|
`
|
|
2877
2877
|
);
|
|
2878
2878
|
}
|
|
@@ -2923,7 +2923,7 @@ var finishFlow = async (ctx, _profile, _agentResult, args) => {
|
|
|
2923
2923
|
const prSuffix = state?.core.prUrl ? `
|
|
2924
2924
|
|
|
2925
2925
|
**PR:** ${state.core.prUrl}` : "";
|
|
2926
|
-
const body = `${icon}
|
|
2926
|
+
const body = `${icon} kody flow \`${flowName}\` finished \u2014 \`${reason}\`${prSuffix}`;
|
|
2927
2927
|
try {
|
|
2928
2928
|
execFileSync9("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
2929
2929
|
timeout: API_TIMEOUT_MS5,
|
|
@@ -2932,7 +2932,7 @@ var finishFlow = async (ctx, _profile, _agentResult, args) => {
|
|
|
2932
2932
|
});
|
|
2933
2933
|
} catch (err) {
|
|
2934
2934
|
process.stderr.write(
|
|
2935
|
-
`[
|
|
2935
|
+
`[kody finishFlow] failed to post final summary on issue #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
2936
2936
|
`
|
|
2937
2937
|
);
|
|
2938
2938
|
}
|
|
@@ -3091,7 +3091,7 @@ function reactToTriggerComment(cwd) {
|
|
|
3091
3091
|
}
|
|
3092
3092
|
}
|
|
3093
3093
|
process.stderr.write(
|
|
3094
|
-
`[
|
|
3094
|
+
`[kody] \u{1F440} reaction failed after 3 attempts on comment ${commentId}: ${lastErr instanceof Error ? lastErr.message : String(lastErr)}
|
|
3095
3095
|
`
|
|
3096
3096
|
);
|
|
3097
3097
|
}
|
|
@@ -3167,13 +3167,13 @@ function getFailedRunLogTail(runId, maxBytes, cwd) {
|
|
|
3167
3167
|
return "";
|
|
3168
3168
|
}
|
|
3169
3169
|
}
|
|
3170
|
-
function
|
|
3171
|
-
return workflowName.trim().toLowerCase() === "
|
|
3170
|
+
function isKodyDispatchWorkflow(workflowName) {
|
|
3171
|
+
return workflowName.trim().toLowerCase() === "kody";
|
|
3172
3172
|
}
|
|
3173
3173
|
function pickFailedRunForFixCi(prNumber, maxBytes, limit, cwd) {
|
|
3174
3174
|
const runs = getRecentFailedRunsForPr(prNumber, limit, cwd);
|
|
3175
3175
|
for (const run of runs) {
|
|
3176
|
-
if (
|
|
3176
|
+
if (isKodyDispatchWorkflow(run.workflowName)) continue;
|
|
3177
3177
|
const logTail = getFailedRunLogTail(run.id, maxBytes, cwd);
|
|
3178
3178
|
if (logTail) return { run, logTail };
|
|
3179
3179
|
}
|
|
@@ -3217,7 +3217,7 @@ var fixCiFlow = async (ctx) => {
|
|
|
3217
3217
|
bail(
|
|
3218
3218
|
ctx,
|
|
3219
3219
|
prNumber,
|
|
3220
|
-
`no actionable failed workflow run found on PR #${prNumber}'s branch (looked at last ${RUN_LOOKBACK} failed runs \u2014 all were either
|
|
3220
|
+
`no actionable failed workflow run found on PR #${prNumber}'s branch (looked at last ${RUN_LOOKBACK} failed runs \u2014 all were either kody's own dispatch workflow or had no fetchable logs; pass --run-id to target a specific run)`
|
|
3221
3221
|
);
|
|
3222
3222
|
return;
|
|
3223
3223
|
}
|
|
@@ -3232,10 +3232,10 @@ var fixCiFlow = async (ctx) => {
|
|
|
3232
3232
|
ctx.data.failedLogTail = logTail;
|
|
3233
3233
|
ctx.data.prDiff = getPrDiff(prNumber, ctx.cwd);
|
|
3234
3234
|
const runUrl = getRunUrl();
|
|
3235
|
-
const runSuffix = runUrl ? `,
|
|
3235
|
+
const runSuffix = runUrl ? `, kody run ${runUrl}` : "";
|
|
3236
3236
|
tryPostPr(
|
|
3237
3237
|
prNumber,
|
|
3238
|
-
`\u2699\uFE0F
|
|
3238
|
+
`\u2699\uFE0F kody fix-ci started on \`${ctx.data.branch}\`${runSuffix} \u2014 analyzing workflow run ${runId}`,
|
|
3239
3239
|
ctx.cwd
|
|
3240
3240
|
);
|
|
3241
3241
|
};
|
|
@@ -3245,7 +3245,7 @@ function bail(ctx, prNumber, reason) {
|
|
|
3245
3245
|
ctx.skipAgent = true;
|
|
3246
3246
|
const runUrl = getRunUrl();
|
|
3247
3247
|
const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
|
|
3248
|
-
tryPostPr(prNumber, `\u274C
|
|
3248
|
+
tryPostPr(prNumber, `\u274C kody fix-ci could not run${runSuffix}: ${reason}`, ctx.cwd);
|
|
3249
3249
|
}
|
|
3250
3250
|
function tryPostPr(prNumber, body, cwd) {
|
|
3251
3251
|
try {
|
|
@@ -3283,7 +3283,7 @@ var fixFlow = async (ctx) => {
|
|
|
3283
3283
|
const runSuffix = runUrl ? `, run ${runUrl}` : "";
|
|
3284
3284
|
tryPostPr2(
|
|
3285
3285
|
prNumber,
|
|
3286
|
-
`\u2699\uFE0F
|
|
3286
|
+
`\u2699\uFE0F kody fix started on \`${ctx.data.branch}\`${runSuffix} \u2014 applying feedback (${truncate2(feedback.replace(/\n/g, " "), 200)})`,
|
|
3287
3287
|
ctx.cwd
|
|
3288
3288
|
);
|
|
3289
3289
|
};
|
|
@@ -3302,7 +3302,7 @@ import * as path15 from "path";
|
|
|
3302
3302
|
// src/scripts/loadQaGuide.ts
|
|
3303
3303
|
import * as fs16 from "fs";
|
|
3304
3304
|
import * as path14 from "path";
|
|
3305
|
-
var QA_GUIDE_REL_PATH = ".
|
|
3305
|
+
var QA_GUIDE_REL_PATH = ".kody/qa-guide.md";
|
|
3306
3306
|
var loadQaGuide = async (ctx) => {
|
|
3307
3307
|
const full = path14.join(ctx.cwd, QA_GUIDE_REL_PATH);
|
|
3308
3308
|
if (!fs16.existsSync(full)) {
|
|
@@ -3362,20 +3362,20 @@ function makeConfig(pm, ownerRepo, defaultBranch) {
|
|
|
3362
3362
|
}
|
|
3363
3363
|
};
|
|
3364
3364
|
}
|
|
3365
|
-
var WORKFLOW_TEMPLATE = `# Drop this file at .github/workflows/
|
|
3365
|
+
var WORKFLOW_TEMPLATE = `# Drop this file at .github/workflows/kody.yml in your repo.
|
|
3366
3366
|
#
|
|
3367
|
-
# Triggers: @
|
|
3367
|
+
# Triggers: @kody comment on an issue or PR, or manual workflow_dispatch.
|
|
3368
3368
|
# Everything else (install deps, set up LiteLLM, run the agent, open the PR)
|
|
3369
3369
|
# is handled inside the @kody-ade/kody-engine package.
|
|
3370
3370
|
#
|
|
3371
3371
|
# Required repo secrets: at least one model provider key (e.g. MINIMAX_API_KEY,
|
|
3372
|
-
# ANTHROPIC_API_KEY).
|
|
3372
|
+
# ANTHROPIC_API_KEY). kody reads any *_API_KEY secret automatically via
|
|
3373
3373
|
# toJSON(secrets) \u2014 no need to list them here.
|
|
3374
3374
|
#
|
|
3375
3375
|
# Recommended: KODY_TOKEN secret \u2014 a PAT or GitHub App token with repo
|
|
3376
|
-
# scope so
|
|
3376
|
+
# scope so kody's pushes trigger downstream CI and PR-body edits succeed.
|
|
3377
3377
|
|
|
3378
|
-
name:
|
|
3378
|
+
name: kody
|
|
3379
3379
|
|
|
3380
3380
|
on:
|
|
3381
3381
|
workflow_dispatch:
|
|
@@ -3393,7 +3393,7 @@ jobs:
|
|
|
3393
3393
|
\${{ github.event_name == 'workflow_dispatch' ||
|
|
3394
3394
|
(github.event_name == 'issue_comment' &&
|
|
3395
3395
|
!github.event.issue.pull_request &&
|
|
3396
|
-
contains(github.event.comment.body, '@
|
|
3396
|
+
contains(github.event.comment.body, '@kody')) }}
|
|
3397
3397
|
runs-on: ubuntu-latest
|
|
3398
3398
|
timeout-minutes: 60
|
|
3399
3399
|
permissions:
|
|
@@ -3416,7 +3416,7 @@ jobs:
|
|
|
3416
3416
|
|
|
3417
3417
|
- env:
|
|
3418
3418
|
ALL_SECRETS: \${{ toJSON(secrets) }}
|
|
3419
|
-
run: npx -y -p @kody-ade/kody-engine@latest
|
|
3419
|
+
run: npx -y -p @kody-ade/kody-engine@latest kody ci --issue \${{ github.event.inputs.issue_number || github.event.issue.number }}
|
|
3420
3420
|
`;
|
|
3421
3421
|
function defaultBranchFromGit(cwd) {
|
|
3422
3422
|
try {
|
|
@@ -3454,13 +3454,13 @@ function performInit(cwd, force) {
|
|
|
3454
3454
|
wrote.push("kody.config.json");
|
|
3455
3455
|
}
|
|
3456
3456
|
const workflowDir = path15.join(cwd, ".github", "workflows");
|
|
3457
|
-
const workflowPath = path15.join(workflowDir, "
|
|
3457
|
+
const workflowPath = path15.join(workflowDir, "kody.yml");
|
|
3458
3458
|
if (fs17.existsSync(workflowPath) && !force) {
|
|
3459
|
-
skipped.push(".github/workflows/
|
|
3459
|
+
skipped.push(".github/workflows/kody.yml");
|
|
3460
3460
|
} else {
|
|
3461
3461
|
fs17.mkdirSync(workflowDir, { recursive: true });
|
|
3462
3462
|
fs17.writeFileSync(workflowPath, WORKFLOW_TEMPLATE);
|
|
3463
|
-
wrote.push(".github/workflows/
|
|
3463
|
+
wrote.push(".github/workflows/kody.yml");
|
|
3464
3464
|
}
|
|
3465
3465
|
const hasUi = fs17.existsSync(path15.join(cwd, "src/app")) || fs17.existsSync(path15.join(cwd, "app")) || fs17.existsSync(path15.join(cwd, "pages"));
|
|
3466
3466
|
if (hasUi) {
|
|
@@ -3482,13 +3482,13 @@ function performInit(cwd, force) {
|
|
|
3482
3482
|
continue;
|
|
3483
3483
|
}
|
|
3484
3484
|
if (profile.kind !== "scheduled" || !profile.schedule) continue;
|
|
3485
|
-
const target = path15.join(workflowDir, `
|
|
3485
|
+
const target = path15.join(workflowDir, `kody-${exe.name}.yml`);
|
|
3486
3486
|
if (fs17.existsSync(target) && !force) {
|
|
3487
|
-
skipped.push(`.github/workflows/
|
|
3487
|
+
skipped.push(`.github/workflows/kody-${exe.name}.yml`);
|
|
3488
3488
|
continue;
|
|
3489
3489
|
}
|
|
3490
3490
|
fs17.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
|
|
3491
|
-
wrote.push(`.github/workflows/
|
|
3491
|
+
wrote.push(`.github/workflows/kody-${exe.name}.yml`);
|
|
3492
3492
|
}
|
|
3493
3493
|
let labels;
|
|
3494
3494
|
try {
|
|
@@ -3499,11 +3499,11 @@ function performInit(cwd, force) {
|
|
|
3499
3499
|
return { wrote, skipped, labels };
|
|
3500
3500
|
}
|
|
3501
3501
|
function renderScheduledWorkflow(name, cron) {
|
|
3502
|
-
return `# Scheduled
|
|
3503
|
-
# Generated by \`
|
|
3502
|
+
return `# Scheduled kody executable: ${name}
|
|
3503
|
+
# Generated by \`kody init\`. Regenerate with \`kody init --force\`.
|
|
3504
3504
|
# Edit the cron below or the executable's profile.json#schedule.
|
|
3505
3505
|
|
|
3506
|
-
name:
|
|
3506
|
+
name: kody ${name}
|
|
3507
3507
|
|
|
3508
3508
|
on:
|
|
3509
3509
|
schedule:
|
|
@@ -3527,14 +3527,14 @@ jobs:
|
|
|
3527
3527
|
node-version: 22
|
|
3528
3528
|
- env:
|
|
3529
3529
|
GH_TOKEN: \${{ secrets.KODY_TOKEN || github.token }}
|
|
3530
|
-
run: npx -y -p @kody-ade/kody-engine@latest
|
|
3530
|
+
run: npx -y -p @kody-ade/kody-engine@latest kody ${name}
|
|
3531
3531
|
`;
|
|
3532
3532
|
}
|
|
3533
3533
|
var initFlow = async (ctx) => {
|
|
3534
3534
|
const force = ctx.args.force === true;
|
|
3535
3535
|
const cwd = ctx.cwd;
|
|
3536
3536
|
const { wrote, skipped, labels } = performInit(cwd, force);
|
|
3537
|
-
process.stdout.write("\u2192
|
|
3537
|
+
process.stdout.write("\u2192 kody init\n");
|
|
3538
3538
|
for (const f of wrote) process.stdout.write(` wrote ${f}
|
|
3539
3539
|
`);
|
|
3540
3540
|
for (const f of skipped) process.stdout.write(` skipped ${f} (already exists; pass --force to overwrite)
|
|
@@ -3567,7 +3567,7 @@ var loadConventions = async (ctx) => {
|
|
|
3567
3567
|
const conventions = loadProjectConventions(ctx.cwd);
|
|
3568
3568
|
ctx.data.conventions = conventions;
|
|
3569
3569
|
if (conventions.length > 0) {
|
|
3570
|
-
process.stderr.write(`[
|
|
3570
|
+
process.stderr.write(`[kody] loaded conventions: ${conventions.map((c) => c.path).join(", ")}
|
|
3571
3571
|
`);
|
|
3572
3572
|
}
|
|
3573
3573
|
};
|
|
@@ -3631,7 +3631,7 @@ var mirrorStateToPr = async (ctx) => {
|
|
|
3631
3631
|
writeTaskState("pr", prNumber, state, ctx.cwd);
|
|
3632
3632
|
} catch (err) {
|
|
3633
3633
|
process.stderr.write(
|
|
3634
|
-
`[
|
|
3634
|
+
`[kody mirrorStateToPr] failed to mirror state to PR #${prNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
3635
3635
|
`
|
|
3636
3636
|
);
|
|
3637
3637
|
}
|
|
@@ -3714,7 +3714,7 @@ var persistFlowState = async (ctx) => {
|
|
|
3714
3714
|
writeTaskState("issue", issueNumber, state, ctx.cwd);
|
|
3715
3715
|
} catch (err) {
|
|
3716
3716
|
process.stderr.write(
|
|
3717
|
-
`[
|
|
3717
|
+
`[kody persistFlowState] failed to write state on issue #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
3718
3718
|
`
|
|
3719
3719
|
);
|
|
3720
3720
|
}
|
|
@@ -3740,25 +3740,25 @@ var postClassification = async (ctx) => {
|
|
|
3740
3740
|
}
|
|
3741
3741
|
if (!classification) {
|
|
3742
3742
|
ctx.data.action = failedAction("classification missing or invalid");
|
|
3743
|
-
tryAuditComment(issueNumber, "\u26A0\uFE0F
|
|
3743
|
+
tryAuditComment(issueNumber, "\u26A0\uFE0F kody classifier could not decide \u2014 please re-run with an explicit `@kody <type>`.", ctx.cwd);
|
|
3744
3744
|
ctx.output.exitCode = 1;
|
|
3745
3745
|
ctx.output.reason = "classify: no decision";
|
|
3746
3746
|
return;
|
|
3747
3747
|
}
|
|
3748
3748
|
tryAuditComment(
|
|
3749
3749
|
issueNumber,
|
|
3750
|
-
`\u{1F50E}
|
|
3750
|
+
`\u{1F50E} kody classified as \`${classification}\`${reason ? ` \u2014 ${reason}` : ""}`,
|
|
3751
3751
|
ctx.cwd
|
|
3752
3752
|
);
|
|
3753
3753
|
try {
|
|
3754
|
-
execFileSync14("gh", ["issue", "comment", String(issueNumber), "--body", `@
|
|
3754
|
+
execFileSync14("gh", ["issue", "comment", String(issueNumber), "--body", `@kody ${classification}`], {
|
|
3755
3755
|
cwd: ctx.cwd,
|
|
3756
3756
|
timeout: API_TIMEOUT_MS6,
|
|
3757
3757
|
stdio: ["ignore", "pipe", "pipe"]
|
|
3758
3758
|
});
|
|
3759
3759
|
} catch (err) {
|
|
3760
3760
|
process.stderr.write(
|
|
3761
|
-
`[
|
|
3761
|
+
`[kody postClassification] failed to dispatch @kody ${classification}: ${err instanceof Error ? err.message : String(err)}
|
|
3762
3762
|
`
|
|
3763
3763
|
);
|
|
3764
3764
|
ctx.data.action = failedAction("dispatch post failed");
|
|
@@ -3812,22 +3812,22 @@ var postIssueComment2 = async (ctx) => {
|
|
|
3812
3812
|
const prAction = ctx.data.prResult?.action;
|
|
3813
3813
|
if (!commitResult?.committed && !hasCommits) {
|
|
3814
3814
|
const reason = "no changes to commit";
|
|
3815
|
-
postWith(targetType, targetNumber, `\u26A0\uFE0F
|
|
3815
|
+
postWith(targetType, targetNumber, `\u26A0\uFE0F kody FAILED: ${reason}`, ctx.cwd);
|
|
3816
3816
|
ctx.output.exitCode = 3;
|
|
3817
3817
|
ctx.output.reason = reason;
|
|
3818
3818
|
return;
|
|
3819
3819
|
}
|
|
3820
3820
|
if (ctx.output.exitCode === 4 && ctx.data.prCrashReason) {
|
|
3821
|
-
postWith(targetType, targetNumber, `\u26A0\uFE0F
|
|
3821
|
+
postWith(targetType, targetNumber, `\u26A0\uFE0F kody FAILED: ${truncate2(ctx.data.prCrashReason, 1500)}`, ctx.cwd);
|
|
3822
3822
|
ctx.output.reason = ctx.data.prCrashReason;
|
|
3823
3823
|
return;
|
|
3824
3824
|
}
|
|
3825
3825
|
const failureReason = computeFailureReason2(ctx);
|
|
3826
3826
|
const isFailure = failureReason.length > 0;
|
|
3827
3827
|
const justPushedToExistingPr = prAction === "updated" && commitResult?.committed === true;
|
|
3828
|
-
const successMsg = justPushedToExistingPr ? `\u2705
|
|
3828
|
+
const successMsg = justPushedToExistingPr ? `\u2705 kody pushed to ${prUrl}` : prAction === "updated" ? `\u2139\uFE0F kody made no changes \u2014 PR: ${prUrl}` : `\u2705 kody PR opened: ${prUrl}`;
|
|
3829
3829
|
const failurePrSuffix = prUrl ? prAction === "updated" ? ` \u2014 PR: ${prUrl}` : ` \u2014 draft PR: ${prUrl}` : "";
|
|
3830
|
-
const msg = isFailure ? `\u26A0\uFE0F
|
|
3830
|
+
const msg = isFailure ? `\u26A0\uFE0F kody FAILED: ${truncate2(failureReason, 1500)}${failurePrSuffix}` : successMsg;
|
|
3831
3831
|
postWith(targetType, targetNumber, msg, ctx.cwd);
|
|
3832
3832
|
let exitCode = 0;
|
|
3833
3833
|
const agentDone = Boolean(ctx.data.agentDone);
|
|
@@ -3883,7 +3883,7 @@ _Orchestrator will advance to the next step automatically._`;
|
|
|
3883
3883
|
return `${head}
|
|
3884
3884
|
|
|
3885
3885
|
---
|
|
3886
|
-
Comment \`
|
|
3886
|
+
Comment \`kody run\` (prefixed with \`@\`) to execute this plan.`;
|
|
3887
3887
|
}
|
|
3888
3888
|
|
|
3889
3889
|
// src/scripts/postResearchComment.ts
|
|
@@ -3928,7 +3928,7 @@ var postReviewResult = async (ctx, _profile, agentResult) => {
|
|
|
3928
3928
|
if (!agentResult || agentResult.outcome !== "completed") {
|
|
3929
3929
|
const reason = agentResult?.error ?? "agent did not complete";
|
|
3930
3930
|
try {
|
|
3931
|
-
postPrReviewComment(prNumber, `\u26A0\uFE0F
|
|
3931
|
+
postPrReviewComment(prNumber, `\u26A0\uFE0F kody review FAILED: ${truncate2(reason, 1e3)}`, ctx.cwd);
|
|
3932
3932
|
} catch {
|
|
3933
3933
|
}
|
|
3934
3934
|
ctx.output.exitCode = 1;
|
|
@@ -3939,7 +3939,7 @@ var postReviewResult = async (ctx, _profile, agentResult) => {
|
|
|
3939
3939
|
const reviewBody = agentResult.finalText.trim();
|
|
3940
3940
|
if (!reviewBody) {
|
|
3941
3941
|
try {
|
|
3942
|
-
postPrReviewComment(prNumber, `\u26A0\uFE0F
|
|
3942
|
+
postPrReviewComment(prNumber, `\u26A0\uFE0F kody review FAILED: agent produced no review body`, ctx.cwd);
|
|
3943
3943
|
} catch {
|
|
3944
3944
|
}
|
|
3945
3945
|
ctx.output.exitCode = 1;
|
|
@@ -4156,11 +4156,11 @@ async function runPrepare(args) {
|
|
|
4156
4156
|
}
|
|
4157
4157
|
const base = ctx.config.git.defaultBranch;
|
|
4158
4158
|
const title = `chore: release ${tag}`;
|
|
4159
|
-
const body = `Automated release PR opened by
|
|
4159
|
+
const body = `Automated release PR opened by kody.
|
|
4160
4160
|
|
|
4161
4161
|
${entry}
|
|
4162
4162
|
|
|
4163
|
-
Merge this and then run \`
|
|
4163
|
+
Merge this and then run \`kody release --mode finalize\`.`;
|
|
4164
4164
|
let prUrl = "";
|
|
4165
4165
|
try {
|
|
4166
4166
|
prUrl = gh2(["pr", "create", "--head", releaseBranch, "--base", base, "--title", title, "--body-file", "-"], {
|
|
@@ -4231,19 +4231,19 @@ async function runFinalize(args) {
|
|
|
4231
4231
|
const r = runShell(cmd, cwd, timeoutMs);
|
|
4232
4232
|
publishStatus = r.exitCode === 0 ? "ok" : "failed";
|
|
4233
4233
|
if (r.exitCode !== 0) {
|
|
4234
|
-
process.stderr.write(`[
|
|
4234
|
+
process.stderr.write(`[kody release] publishCommand exit ${r.exitCode}
|
|
4235
4235
|
${truncate2(r.stderr, 2e3)}
|
|
4236
4236
|
`);
|
|
4237
4237
|
}
|
|
4238
4238
|
}
|
|
4239
4239
|
let releaseUrl = "";
|
|
4240
4240
|
try {
|
|
4241
|
-
const releaseArgs = ["release", "create", tag, "--title", tag, "--notes", `Release ${tag} \u2014 automated by
|
|
4241
|
+
const releaseArgs = ["release", "create", tag, "--title", tag, "--notes", `Release ${tag} \u2014 automated by kody.`];
|
|
4242
4242
|
if (releaseCfg.draftRelease) releaseArgs.push("--draft");
|
|
4243
4243
|
releaseUrl = gh2(releaseArgs, { cwd }).trim();
|
|
4244
4244
|
} catch (err) {
|
|
4245
4245
|
process.stderr.write(
|
|
4246
|
-
`[
|
|
4246
|
+
`[kody release] gh release create failed: ${err instanceof Error ? err.message : String(err)}
|
|
4247
4247
|
`
|
|
4248
4248
|
);
|
|
4249
4249
|
}
|
|
@@ -4382,14 +4382,14 @@ var resolveFlow = async (ctx) => {
|
|
|
4382
4382
|
ctx.output.exitCode = 0;
|
|
4383
4383
|
ctx.output.reason = `already up to date with origin/${baseBranch} \u2014 nothing to resolve`;
|
|
4384
4384
|
ctx.skipAgent = true;
|
|
4385
|
-
tryPostPr3(prNumber, `\u2139\uFE0F
|
|
4385
|
+
tryPostPr3(prNumber, `\u2139\uFE0F kody resolve: ${ctx.output.reason}`, ctx.cwd);
|
|
4386
4386
|
return;
|
|
4387
4387
|
}
|
|
4388
4388
|
if (mergeStatus === "error") {
|
|
4389
4389
|
ctx.output.exitCode = 99;
|
|
4390
4390
|
ctx.output.reason = `failed to merge origin/${baseBranch} (non-conflict error); see runner log`;
|
|
4391
4391
|
ctx.skipAgent = true;
|
|
4392
|
-
tryPostPr3(prNumber, `\u26A0\uFE0F
|
|
4392
|
+
tryPostPr3(prNumber, `\u26A0\uFE0F kody resolve FAILED: ${ctx.output.reason}`, ctx.cwd);
|
|
4393
4393
|
return;
|
|
4394
4394
|
}
|
|
4395
4395
|
const conflictedFiles = getConflictedFiles(ctx.cwd);
|
|
@@ -4405,7 +4405,7 @@ var resolveFlow = async (ctx) => {
|
|
|
4405
4405
|
const runSuffix = runUrl ? `, run ${runUrl}` : "";
|
|
4406
4406
|
tryPostPr3(
|
|
4407
4407
|
prNumber,
|
|
4408
|
-
`\u2699\uFE0F
|
|
4408
|
+
`\u2699\uFE0F kody resolve started on \`${ctx.data.branch}\`${runSuffix} \u2014 ${conflictedFiles.length} conflicted file(s)`,
|
|
4409
4409
|
ctx.cwd
|
|
4410
4410
|
);
|
|
4411
4411
|
};
|
|
@@ -4485,7 +4485,7 @@ var reviewFlow = async (ctx) => {
|
|
|
4485
4485
|
ctx.data.prDiff = getPrDiff(prNumber, ctx.cwd);
|
|
4486
4486
|
const runUrl = getRunUrl();
|
|
4487
4487
|
const runSuffix = runUrl ? `, run ${runUrl}` : "";
|
|
4488
|
-
tryPostPr4(prNumber, `\u{1F440}
|
|
4488
|
+
tryPostPr4(prNumber, `\u{1F440} kody review started on PR #${prNumber}${runSuffix}`, ctx.cwd);
|
|
4489
4489
|
};
|
|
4490
4490
|
function tryPostPr4(prNumber, body, cwd) {
|
|
4491
4491
|
try {
|
|
@@ -4509,13 +4509,13 @@ var runFlow = async (ctx) => {
|
|
|
4509
4509
|
ctx.output.exitCode = 5;
|
|
4510
4510
|
ctx.output.reason = err.message;
|
|
4511
4511
|
ctx.skipAgent = true;
|
|
4512
|
-
tryPost(issueNumber, `\u26A0\uFE0F
|
|
4512
|
+
tryPost(issueNumber, `\u26A0\uFE0F kody refused to start: ${err.message}`, ctx.cwd);
|
|
4513
4513
|
return;
|
|
4514
4514
|
}
|
|
4515
4515
|
throw err;
|
|
4516
4516
|
}
|
|
4517
4517
|
const runUrl = getRunUrl();
|
|
4518
|
-
const startMsg = runUrl ? `\u2699\uFE0F
|
|
4518
|
+
const startMsg = runUrl ? `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\`, run ${runUrl}` : `\u2699\uFE0F kody started \u2014 branch \`${ctx.data.branch}\``;
|
|
4519
4519
|
tryPost(issueNumber, startMsg, ctx.cwd);
|
|
4520
4520
|
};
|
|
4521
4521
|
function tryPost(issueNumber, body, cwd) {
|
|
@@ -4559,7 +4559,7 @@ var setLifecycleLabel = async (ctx, _profile, args) => {
|
|
|
4559
4559
|
const label = args?.label;
|
|
4560
4560
|
if (typeof label !== "string" || !label.startsWith(KODY_NAMESPACE)) {
|
|
4561
4561
|
process.stderr.write(
|
|
4562
|
-
`[
|
|
4562
|
+
`[kody] setLifecycleLabel: missing or invalid "label" arg (must start with "${KODY_NAMESPACE}"): ${String(label)}
|
|
4563
4563
|
`
|
|
4564
4564
|
);
|
|
4565
4565
|
return;
|
|
@@ -4595,14 +4595,14 @@ var API_TIMEOUT_MS7 = 3e4;
|
|
|
4595
4595
|
var startFlow = async (ctx, profile, _agentResult, args) => {
|
|
4596
4596
|
const entry = args?.entry;
|
|
4597
4597
|
if (!entry) {
|
|
4598
|
-
process.stderr.write("[
|
|
4598
|
+
process.stderr.write("[kody startFlow] missing `with.entry` \u2014 skipping\n");
|
|
4599
4599
|
return;
|
|
4600
4600
|
}
|
|
4601
4601
|
const target = args?.target ?? "issue";
|
|
4602
4602
|
const flowName = profile.name;
|
|
4603
4603
|
const issueNumber = ctx.args.issue;
|
|
4604
4604
|
if (!issueNumber) {
|
|
4605
|
-
process.stderr.write("[
|
|
4605
|
+
process.stderr.write("[kody startFlow] no --issue arg \u2014 skipping\n");
|
|
4606
4606
|
return;
|
|
4607
4607
|
}
|
|
4608
4608
|
const state = ctx.data.taskState;
|
|
@@ -4617,12 +4617,12 @@ var startFlow = async (ctx, profile, _agentResult, args) => {
|
|
|
4617
4617
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4618
4618
|
};
|
|
4619
4619
|
}
|
|
4620
|
-
|
|
4620
|
+
postKodyComment(target, issueNumber, state, entry, ctx.cwd);
|
|
4621
4621
|
};
|
|
4622
|
-
function
|
|
4622
|
+
function postKodyComment(target, issueNumber, state, next, cwd) {
|
|
4623
4623
|
const targetNumber = target === "pr" && state?.core.prUrl ? parsePr2(state.core.prUrl) ?? issueNumber : issueNumber;
|
|
4624
4624
|
const sub = target === "pr" && state?.core.prUrl ? "pr" : "issue";
|
|
4625
|
-
const body = `@
|
|
4625
|
+
const body = `@kody ${next}`;
|
|
4626
4626
|
try {
|
|
4627
4627
|
execFileSync17("gh", [sub, "comment", String(targetNumber), "--body", body], {
|
|
4628
4628
|
timeout: API_TIMEOUT_MS7,
|
|
@@ -4631,7 +4631,7 @@ function postKody2Comment(target, issueNumber, state, next, cwd) {
|
|
|
4631
4631
|
});
|
|
4632
4632
|
} catch (err) {
|
|
4633
4633
|
process.stderr.write(
|
|
4634
|
-
`[
|
|
4634
|
+
`[kody startFlow] failed to post @kody ${next} on ${sub} #${targetNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
4635
4635
|
`
|
|
4636
4636
|
);
|
|
4637
4637
|
}
|
|
@@ -4670,7 +4670,7 @@ var syncFlow = async (ctx) => {
|
|
|
4670
4670
|
bail2(
|
|
4671
4671
|
ctx,
|
|
4672
4672
|
prNumber,
|
|
4673
|
-
`merge from origin/${baseBranch} produced conflicts \u2014 run \`@
|
|
4673
|
+
`merge from origin/${baseBranch} produced conflicts \u2014 run \`@kody resolve\` to let kody resolve them`
|
|
4674
4674
|
);
|
|
4675
4675
|
return;
|
|
4676
4676
|
}
|
|
@@ -4678,7 +4678,7 @@ var syncFlow = async (ctx) => {
|
|
|
4678
4678
|
if (headAfter === headBefore) {
|
|
4679
4679
|
ctx.output.exitCode = 0;
|
|
4680
4680
|
ctx.output.reason = `already up to date with origin/${baseBranch}`;
|
|
4681
|
-
tryPostPr5(prNumber, `\u2139\uFE0F
|
|
4681
|
+
tryPostPr5(prNumber, `\u2139\uFE0F kody sync: already up to date with origin/${baseBranch}`, ctx.cwd);
|
|
4682
4682
|
return;
|
|
4683
4683
|
}
|
|
4684
4684
|
try {
|
|
@@ -4692,14 +4692,14 @@ var syncFlow = async (ctx) => {
|
|
|
4692
4692
|
ctx.output.reason = `merged origin/${baseBranch} into ${ctx.data.branch}`;
|
|
4693
4693
|
const runUrl = getRunUrl();
|
|
4694
4694
|
const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
|
|
4695
|
-
tryPostPr5(prNumber, `\u2705
|
|
4695
|
+
tryPostPr5(prNumber, `\u2705 kody sync: merged \`origin/${baseBranch}\` into \`${ctx.data.branch}\`${runSuffix}`, ctx.cwd);
|
|
4696
4696
|
};
|
|
4697
4697
|
function bail2(ctx, prNumber, reason) {
|
|
4698
4698
|
ctx.output.exitCode = 1;
|
|
4699
4699
|
ctx.output.reason = reason;
|
|
4700
4700
|
const runUrl = getRunUrl();
|
|
4701
4701
|
const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
|
|
4702
|
-
tryPostPr5(prNumber, `\u274C
|
|
4702
|
+
tryPostPr5(prNumber, `\u274C kody sync could not complete${runSuffix}: ${reason}`, ctx.cwd);
|
|
4703
4703
|
}
|
|
4704
4704
|
function revParseHead(cwd) {
|
|
4705
4705
|
try {
|
|
@@ -4847,10 +4847,10 @@ function findStalePrs(cwd, staleDays, now = /* @__PURE__ */ new Date()) {
|
|
|
4847
4847
|
}
|
|
4848
4848
|
function formatStaleReport(stale, staleDays) {
|
|
4849
4849
|
if (stale.length === 0) {
|
|
4850
|
-
return `\u{1F7E2} **
|
|
4850
|
+
return `\u{1F7E2} **kody watch-stale-prs** \u2014 no open PRs untouched for more than ${staleDays} days. \u2728`;
|
|
4851
4851
|
}
|
|
4852
4852
|
const lines = [
|
|
4853
|
-
`\u{1F7E1} **
|
|
4853
|
+
`\u{1F7E1} **kody watch-stale-prs** \u2014 ${stale.length} PR(s) untouched for > ${staleDays} days:`,
|
|
4854
4854
|
""
|
|
4855
4855
|
];
|
|
4856
4856
|
for (const pr of stale.slice(0, 50)) {
|
|
@@ -4871,7 +4871,7 @@ var watchStalePrsFlow = async (ctx) => {
|
|
|
4871
4871
|
postIssueComment(reportIssueNumber, report, ctx.cwd);
|
|
4872
4872
|
} catch (err) {
|
|
4873
4873
|
process.stderr.write(
|
|
4874
|
-
`[
|
|
4874
|
+
`[kody watch] failed to post to issue #${reportIssueNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
4875
4875
|
`
|
|
4876
4876
|
);
|
|
4877
4877
|
}
|
|
@@ -4894,7 +4894,7 @@ var writeRunSummary = async (ctx, profile) => {
|
|
|
4894
4894
|
const reason = ctx.output.reason;
|
|
4895
4895
|
const status = exitCode === 0 ? "\u2705 success" : exitCode === 3 ? "\u23ED\uFE0F no-op" : "\u26A0\uFE0F failed";
|
|
4896
4896
|
const lines = [];
|
|
4897
|
-
lines.push(`##
|
|
4897
|
+
lines.push(`## kody ${executable} \u2014 ${status}`);
|
|
4898
4898
|
lines.push("");
|
|
4899
4899
|
lines.push(`- **Executable:** \`${executable}\``);
|
|
4900
4900
|
lines.push(`- **Target:** ${target}`);
|
|
@@ -5064,7 +5064,7 @@ async function runExecutable(profileName, input) {
|
|
|
5064
5064
|
data: {},
|
|
5065
5065
|
output: { exitCode: 0 }
|
|
5066
5066
|
};
|
|
5067
|
-
const ndjsonDir = path17.join(input.cwd, ".
|
|
5067
|
+
const ndjsonDir = path17.join(input.cwd, ".kody");
|
|
5068
5068
|
const invokeAgent = async (prompt) => {
|
|
5069
5069
|
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path17.isAbsolute(p) ? p : path17.resolve(profile.dir, p)).filter((p) => p.length > 0);
|
|
5070
5070
|
const syntheticPath = ctx.data.syntheticPluginPath;
|
|
@@ -5114,7 +5114,7 @@ async function runExecutable(profileName, input) {
|
|
|
5114
5114
|
await fn(ctx, profile, agentResult, entry.with);
|
|
5115
5115
|
} catch (err) {
|
|
5116
5116
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5117
|
-
process.stderr.write(`[
|
|
5117
|
+
process.stderr.write(`[kody] postflight script "${entry.script}" crashed: ${msg}
|
|
5118
5118
|
`);
|
|
5119
5119
|
if (!ctx.output.reason) ctx.output.reason = `postflight ${entry.script} crashed: ${msg}`;
|
|
5120
5120
|
if (ctx.output.exitCode === 0) ctx.output.exitCode = 99;
|
|
@@ -5234,11 +5234,11 @@ function finish(out) {
|
|
|
5234
5234
|
return out;
|
|
5235
5235
|
}
|
|
5236
5236
|
|
|
5237
|
-
// src/
|
|
5238
|
-
var CI_HELP = `
|
|
5237
|
+
// src/kody-cli.ts
|
|
5238
|
+
var CI_HELP = `kody ci \u2014 minimal-YAML autonomous engineer (CI preflight + run)
|
|
5239
5239
|
|
|
5240
5240
|
Usage:
|
|
5241
|
-
|
|
5241
|
+
kody ci --issue <N> [--cwd <path>] [--verbose|--quiet]
|
|
5242
5242
|
[--skip-install] [--skip-litellm] [--package-manager pnpm|yarn|bun|npm]
|
|
5243
5243
|
|
|
5244
5244
|
Options:
|
|
@@ -5254,7 +5254,7 @@ Environment:
|
|
|
5254
5254
|
ALL_SECRETS JSON blob of all GitHub secrets (auto-populated in CI)
|
|
5255
5255
|
KODY_TOKEN|GH_TOKEN|GITHUB_TOKEN|GH_PAT auth token for gh/git operations
|
|
5256
5256
|
|
|
5257
|
-
Exit codes (inherited from
|
|
5257
|
+
Exit codes (inherited from kody run):
|
|
5258
5258
|
0 success (PR opened, verify passed)
|
|
5259
5259
|
1 agent reported FAILED (draft PR opened)
|
|
5260
5260
|
2 verify failed (draft PR opened)
|
|
@@ -5347,7 +5347,7 @@ function isOnPath(bin) {
|
|
|
5347
5347
|
}
|
|
5348
5348
|
function ensurePackageManagerInstalled(pm, cwd) {
|
|
5349
5349
|
if (pm === "npm" || isOnPath(pm)) return 0;
|
|
5350
|
-
process.stdout.write(`\u2192
|
|
5350
|
+
process.stdout.write(`\u2192 kody: ${pm} not on PATH \u2014 installing via npm install -g ${pm}
|
|
5351
5351
|
`);
|
|
5352
5352
|
return shellOut("npm", ["install", "-g", pm], cwd);
|
|
5353
5353
|
}
|
|
@@ -5367,18 +5367,18 @@ function installLitellmIfNeeded(cwd) {
|
|
|
5367
5367
|
const cfg = loadConfig(cwd);
|
|
5368
5368
|
const model = parseProviderModel(cfg.agent.model);
|
|
5369
5369
|
if (!needsLitellmProxy(model)) {
|
|
5370
|
-
process.stdout.write("\u2192
|
|
5370
|
+
process.stdout.write("\u2192 kody: provider is anthropic/claude, skipping LiteLLM install\n");
|
|
5371
5371
|
return 0;
|
|
5372
5372
|
}
|
|
5373
5373
|
} catch {
|
|
5374
5374
|
}
|
|
5375
5375
|
try {
|
|
5376
5376
|
execFileSync20("python3", ["-c", "import litellm"], { stdio: "pipe" });
|
|
5377
|
-
process.stdout.write("\u2192
|
|
5377
|
+
process.stdout.write("\u2192 kody: litellm already installed\n");
|
|
5378
5378
|
return 0;
|
|
5379
5379
|
} catch {
|
|
5380
5380
|
}
|
|
5381
|
-
process.stdout.write("\u2192
|
|
5381
|
+
process.stdout.write("\u2192 kody: installing litellm (pip install 'litellm[proxy]')\n");
|
|
5382
5382
|
return shellOut("pip", ["install", "litellm[proxy]"], cwd);
|
|
5383
5383
|
}
|
|
5384
5384
|
function configureGitIdentity(cwd) {
|
|
@@ -5401,7 +5401,7 @@ function configureGitIdentity(cwd) {
|
|
|
5401
5401
|
}
|
|
5402
5402
|
function postFailureTail(issueNumber, cwd, reason) {
|
|
5403
5403
|
if (!issueNumber) return;
|
|
5404
|
-
const logPath = path18.join(cwd, ".
|
|
5404
|
+
const logPath = path18.join(cwd, ".kody", "last-run.jsonl");
|
|
5405
5405
|
let tail = "";
|
|
5406
5406
|
try {
|
|
5407
5407
|
if (fs21.existsSync(logPath)) {
|
|
@@ -5410,7 +5410,7 @@ function postFailureTail(issueNumber, cwd, reason) {
|
|
|
5410
5410
|
}
|
|
5411
5411
|
} catch {
|
|
5412
5412
|
}
|
|
5413
|
-
const body = tail ? `\u26A0\uFE0F
|
|
5413
|
+
const body = tail ? `\u26A0\uFE0F kody preflight failed: ${truncate2(reason, 500)}
|
|
5414
5414
|
|
|
5415
5415
|
<details><summary>Last-run log tail</summary>
|
|
5416
5416
|
|
|
@@ -5418,7 +5418,7 @@ function postFailureTail(issueNumber, cwd, reason) {
|
|
|
5418
5418
|
${tail}
|
|
5419
5419
|
\`\`\`
|
|
5420
5420
|
|
|
5421
|
-
</details>` : `\u26A0\uFE0F
|
|
5421
|
+
</details>` : `\u26A0\uFE0F kody preflight failed: ${truncate2(reason, 1500)}`;
|
|
5422
5422
|
try {
|
|
5423
5423
|
postIssueComment(issueNumber, body, cwd);
|
|
5424
5424
|
} catch {
|
|
@@ -5454,16 +5454,16 @@ ${CI_HELP}`);
|
|
|
5454
5454
|
target: args.issueNumber
|
|
5455
5455
|
};
|
|
5456
5456
|
const issueNumber = dispatch2.target;
|
|
5457
|
-
process.stdout.write(`\u2192
|
|
5457
|
+
process.stdout.write(`\u2192 kody preflight (cwd=${cwd}, executable=${dispatch2.executable}, target=${issueNumber})
|
|
5458
5458
|
`);
|
|
5459
5459
|
try {
|
|
5460
5460
|
const n = unpackAllSecrets();
|
|
5461
|
-
if (n > 0) process.stdout.write(`\u2192
|
|
5461
|
+
if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
|
|
5462
5462
|
`);
|
|
5463
5463
|
resolveAuthToken();
|
|
5464
5464
|
reactToTriggerComment(cwd);
|
|
5465
5465
|
const pm = args.packageManager ?? detectPackageManager2(cwd);
|
|
5466
|
-
process.stdout.write(`\u2192
|
|
5466
|
+
process.stdout.write(`\u2192 kody: package manager = ${pm}
|
|
5467
5467
|
`);
|
|
5468
5468
|
if (!args.skipInstall) {
|
|
5469
5469
|
const code = installDeps(pm, cwd);
|
|
@@ -5472,7 +5472,7 @@ ${CI_HELP}`);
|
|
|
5472
5472
|
return 99;
|
|
5473
5473
|
}
|
|
5474
5474
|
} else {
|
|
5475
|
-
process.stdout.write("\u2192
|
|
5475
|
+
process.stdout.write("\u2192 kody: skipping dep install (--skip-install)\n");
|
|
5476
5476
|
}
|
|
5477
5477
|
if (!args.skipLitellm) {
|
|
5478
5478
|
const code = installLitellmIfNeeded(cwd);
|
|
@@ -5481,17 +5481,17 @@ ${CI_HELP}`);
|
|
|
5481
5481
|
return 99;
|
|
5482
5482
|
}
|
|
5483
5483
|
} else {
|
|
5484
|
-
process.stdout.write("\u2192
|
|
5484
|
+
process.stdout.write("\u2192 kody: skipping LiteLLM install (--skip-litellm)\n");
|
|
5485
5485
|
}
|
|
5486
5486
|
configureGitIdentity(cwd);
|
|
5487
5487
|
} catch (err) {
|
|
5488
5488
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5489
|
-
process.stderr.write(`[
|
|
5489
|
+
process.stderr.write(`[kody] preflight crashed: ${msg}
|
|
5490
5490
|
`);
|
|
5491
5491
|
postFailureTail(issueNumber, cwd, `preflight crashed: ${msg}`);
|
|
5492
5492
|
return 99;
|
|
5493
5493
|
}
|
|
5494
|
-
process.stdout.write(`\u2192
|
|
5494
|
+
process.stdout.write(`\u2192 kody: preflight done, handing off to kody ${dispatch2.executable}
|
|
5495
5495
|
|
|
5496
5496
|
`);
|
|
5497
5497
|
try {
|
|
@@ -5509,7 +5509,7 @@ ${CI_HELP}`);
|
|
|
5509
5509
|
return result.exitCode;
|
|
5510
5510
|
} catch (err) {
|
|
5511
5511
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5512
|
-
process.stderr.write(`[
|
|
5512
|
+
process.stderr.write(`[kody] run crashed: ${msg}
|
|
5513
5513
|
`);
|
|
5514
5514
|
if (err instanceof Error && err.stack) process.stderr.write(`${err.stack}
|
|
5515
5515
|
`);
|
|
@@ -5520,10 +5520,10 @@ ${CI_HELP}`);
|
|
|
5520
5520
|
|
|
5521
5521
|
// src/chat-cli.ts
|
|
5522
5522
|
var DEFAULT_MODEL = "claude/claude-haiku-4-5-20251001";
|
|
5523
|
-
var CHAT_HELP = `
|
|
5523
|
+
var CHAT_HELP = `kody chat \u2014 dashboard-driven chat session
|
|
5524
5524
|
|
|
5525
5525
|
Usage:
|
|
5526
|
-
|
|
5526
|
+
kody chat [--session <id>] [--message <text>] [--model <provider/model>]
|
|
5527
5527
|
[--dashboard-url <url>] [--cwd <path>] [--verbose|--quiet]
|
|
5528
5528
|
|
|
5529
5529
|
All inputs may also come from env: SESSION_ID, INIT_MESSAGE, MODEL, DASHBOARD_URL.
|
|
@@ -5574,7 +5574,7 @@ function commitChatFiles(cwd, sessionId, verbose) {
|
|
|
5574
5574
|
execFileSync21("git", ["push", "--quiet", "origin", "HEAD"], opts);
|
|
5575
5575
|
} catch (err) {
|
|
5576
5576
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5577
|
-
process.stderr.write(`[
|
|
5577
|
+
process.stderr.write(`[kody:chat] commit/push skipped: ${msg}
|
|
5578
5578
|
`);
|
|
5579
5579
|
}
|
|
5580
5580
|
}
|
|
@@ -5607,7 +5607,7 @@ ${CHAT_HELP}`);
|
|
|
5607
5607
|
const sessionId = args.sessionId;
|
|
5608
5608
|
const unpackedSecrets = unpackAllSecrets();
|
|
5609
5609
|
if (unpackedSecrets > 0) {
|
|
5610
|
-
process.stdout.write(`\u2192
|
|
5610
|
+
process.stdout.write(`\u2192 kody: unpacked ${unpackedSecrets} secret(s) from ALL_SECRETS
|
|
5611
5611
|
`);
|
|
5612
5612
|
}
|
|
5613
5613
|
resolveAuthToken();
|
|
@@ -5669,19 +5669,19 @@ ${CHAT_HELP}`);
|
|
|
5669
5669
|
}
|
|
5670
5670
|
|
|
5671
5671
|
// src/entry.ts
|
|
5672
|
-
var HELP_TEXT = `
|
|
5672
|
+
var HELP_TEXT = `kody \u2014 single-session autonomous engineer
|
|
5673
5673
|
|
|
5674
5674
|
Usage:
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5675
|
+
kody run --issue <N> [--cwd <path>] [--verbose|--quiet]
|
|
5676
|
+
kody fix --pr <N> [--feedback "..."] [--cwd <path>] [--verbose|--quiet]
|
|
5677
|
+
kody fix-ci --pr <N> [--run-id <ID>] [--cwd <path>] [--verbose|--quiet]
|
|
5678
|
+
kody resolve --pr <N> [--cwd <path>] [--verbose|--quiet]
|
|
5679
|
+
kody review --pr <N> [--cwd <path>] [--verbose|--quiet]
|
|
5680
|
+
kody <other> [--cwd <path>] [--verbose|--quiet]
|
|
5681
|
+
kody ci --issue <N> [preflight flags \u2014 see: kody ci --help]
|
|
5682
|
+
kody chat [chat flags \u2014 see: kody chat --help]
|
|
5683
|
+
kody help
|
|
5684
|
+
kody version
|
|
5685
5685
|
|
|
5686
5686
|
Each top-level command (run, fix, fix-ci, resolve, review, \u2026) is a discovered
|
|
5687
5687
|
executable under \`src/executables/<name>/profile.json\`. Drop in a new
|
|
@@ -5737,7 +5737,7 @@ ${HELP_TEXT}`);
|
|
|
5737
5737
|
return 0;
|
|
5738
5738
|
}
|
|
5739
5739
|
if (args.command === "version") {
|
|
5740
|
-
process.stdout.write(`
|
|
5740
|
+
process.stdout.write(`kody ${package_default.version}
|
|
5741
5741
|
`);
|
|
5742
5742
|
return 0;
|
|
5743
5743
|
}
|
|
@@ -5746,7 +5746,7 @@ ${HELP_TEXT}`);
|
|
|
5746
5746
|
return await runCi(args.ciArgv ?? []);
|
|
5747
5747
|
} catch (err) {
|
|
5748
5748
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5749
|
-
process.stderr.write(`[
|
|
5749
|
+
process.stderr.write(`[kody] fatal: ${msg}
|
|
5750
5750
|
`);
|
|
5751
5751
|
if (err instanceof Error && err.stack) process.stderr.write(`${err.stack}
|
|
5752
5752
|
`);
|
|
@@ -5758,7 +5758,7 @@ ${HELP_TEXT}`);
|
|
|
5758
5758
|
return await runChat(args.chatArgv ?? []);
|
|
5759
5759
|
} catch (err) {
|
|
5760
5760
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5761
|
-
process.stderr.write(`[
|
|
5761
|
+
process.stderr.write(`[kody] fatal: ${msg}
|
|
5762
5762
|
`);
|
|
5763
5763
|
if (err instanceof Error && err.stack) process.stderr.write(`${err.stack}
|
|
5764
5764
|
`);
|
|
@@ -5783,7 +5783,7 @@ ${HELP_TEXT}`);
|
|
|
5783
5783
|
return result.exitCode;
|
|
5784
5784
|
} catch (err) {
|
|
5785
5785
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5786
|
-
process.stderr.write(`[
|
|
5786
|
+
process.stderr.write(`[kody] ${args.executableName} crashed: ${msg}
|
|
5787
5787
|
`);
|
|
5788
5788
|
if (err instanceof Error && err.stack) process.stderr.write(`${err.stack}
|
|
5789
5789
|
`);
|
|
@@ -5793,11 +5793,11 @@ ${HELP_TEXT}`);
|
|
|
5793
5793
|
}
|
|
5794
5794
|
}
|
|
5795
5795
|
|
|
5796
|
-
// bin/
|
|
5796
|
+
// bin/kody.ts
|
|
5797
5797
|
main().then((code) => {
|
|
5798
5798
|
process.exit(code);
|
|
5799
5799
|
}).catch((err) => {
|
|
5800
|
-
process.stderr.write(`[
|
|
5800
|
+
process.stderr.write(`[kody] fatal: ${err instanceof Error ? err.message : String(err)}
|
|
5801
5801
|
`);
|
|
5802
5802
|
process.exit(99);
|
|
5803
5803
|
});
|