@kody-ade/kody-engine 0.3.49 → 0.3.51
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.51",
|
|
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",
|
|
@@ -50,7 +50,7 @@ var package_default = {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
// src/chat-cli.ts
|
|
53
|
-
import { execFileSync as
|
|
53
|
+
import { execFileSync as execFileSync26 } from "child_process";
|
|
54
54
|
import * as fs26 from "fs";
|
|
55
55
|
import * as path23 from "path";
|
|
56
56
|
|
|
@@ -154,7 +154,7 @@ function loadConfig(projectDir = process.cwd()) {
|
|
|
154
154
|
throw new Error(`kody.config.json is invalid JSON: ${msg}`);
|
|
155
155
|
}
|
|
156
156
|
const quality = raw.quality ?? {};
|
|
157
|
-
const
|
|
157
|
+
const git5 = raw.git ?? {};
|
|
158
158
|
const github = raw.github ?? {};
|
|
159
159
|
const agent = raw.agent ?? {};
|
|
160
160
|
if (!agent.model || typeof agent.model !== "string") {
|
|
@@ -171,7 +171,7 @@ function loadConfig(projectDir = process.cwd()) {
|
|
|
171
171
|
testUnit: typeof quality.testUnit === "string" ? quality.testUnit : ""
|
|
172
172
|
},
|
|
173
173
|
git: {
|
|
174
|
-
defaultBranch: typeof
|
|
174
|
+
defaultBranch: typeof git5.defaultBranch === "string" ? git5.defaultBranch : "main"
|
|
175
175
|
},
|
|
176
176
|
github: {
|
|
177
177
|
owner: String(github.owner),
|
|
@@ -605,7 +605,7 @@ async function emit(sink, type, sessionId, suffix, payload) {
|
|
|
605
605
|
}
|
|
606
606
|
|
|
607
607
|
// src/kody-cli.ts
|
|
608
|
-
import { execFileSync as
|
|
608
|
+
import { execFileSync as execFileSync25 } from "child_process";
|
|
609
609
|
import * as fs25 from "fs";
|
|
610
610
|
import * as path22 from "path";
|
|
611
611
|
|
|
@@ -4632,6 +4632,14 @@ function walkMd(root, visit) {
|
|
|
4632
4632
|
}
|
|
4633
4633
|
}
|
|
4634
4634
|
|
|
4635
|
+
// src/scripts/markFlowSuccess.ts
|
|
4636
|
+
var markFlowSuccess = async (ctx) => {
|
|
4637
|
+
const exit = ctx.output.exitCode;
|
|
4638
|
+
if (exit === void 0 || exit === 0) {
|
|
4639
|
+
ctx.data.agentDone = true;
|
|
4640
|
+
}
|
|
4641
|
+
};
|
|
4642
|
+
|
|
4635
4643
|
// src/scripts/memorizeFlow.ts
|
|
4636
4644
|
import { execFileSync as execFileSync15 } from "child_process";
|
|
4637
4645
|
import * as fs22 from "fs";
|
|
@@ -4955,8 +4963,7 @@ var parseAgentResult2 = async (ctx, profile, agentResult) => {
|
|
|
4955
4963
|
const modeSeg = (ctx.args.mode ?? profile.name).replace(/-/g, "_").toUpperCase();
|
|
4956
4964
|
if (parsed.done) {
|
|
4957
4965
|
ctx.data.action = makeAction2(`${modeSeg}_COMPLETED`, {
|
|
4958
|
-
commitMessage: parsed.commitMessage
|
|
4959
|
-
prSummary: parsed.prSummary
|
|
4966
|
+
commitMessage: parsed.commitMessage
|
|
4960
4967
|
});
|
|
4961
4968
|
} else {
|
|
4962
4969
|
ctx.data.action = makeAction2(`${modeSeg}_FAILED`, {
|
|
@@ -5559,6 +5566,120 @@ function tryPostPr3(prNumber, body, cwd) {
|
|
|
5559
5566
|
}
|
|
5560
5567
|
}
|
|
5561
5568
|
|
|
5569
|
+
// src/scripts/revertFlow.ts
|
|
5570
|
+
import { execFileSync as execFileSync19 } from "child_process";
|
|
5571
|
+
var SHA_RE = /^[0-9a-f]{4,40}$/i;
|
|
5572
|
+
var revertFlow = async (ctx) => {
|
|
5573
|
+
const prNumber = ctx.args.pr;
|
|
5574
|
+
const pr = getPr(prNumber, ctx.cwd);
|
|
5575
|
+
if (pr.state !== "OPEN") {
|
|
5576
|
+
ctx.output.exitCode = 1;
|
|
5577
|
+
ctx.output.reason = `PR #${prNumber} is not OPEN (state: ${pr.state})`;
|
|
5578
|
+
ctx.skipAgent = true;
|
|
5579
|
+
return;
|
|
5580
|
+
}
|
|
5581
|
+
ctx.data.pr = pr;
|
|
5582
|
+
ctx.data.commentTargetType = "pr";
|
|
5583
|
+
ctx.data.commentTargetNumber = prNumber;
|
|
5584
|
+
checkoutPrBranch(prNumber, ctx.cwd);
|
|
5585
|
+
ctx.data.branch = getCurrentBranch(ctx.cwd);
|
|
5586
|
+
const shasArg = String(ctx.args.shas ?? "").trim();
|
|
5587
|
+
if (!shasArg) {
|
|
5588
|
+
ctx.output.exitCode = 64;
|
|
5589
|
+
ctx.output.reason = "no commit SHAs provided \u2014 usage: @kody revert <sha> [<sha> \u2026]";
|
|
5590
|
+
ctx.skipAgent = true;
|
|
5591
|
+
tryPostPr4(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
|
|
5592
|
+
return;
|
|
5593
|
+
}
|
|
5594
|
+
const requested = shasArg.split(/\s+/).filter((s) => s.length > 0);
|
|
5595
|
+
const bad = requested.filter((s) => !SHA_RE.test(s));
|
|
5596
|
+
if (bad.length > 0) {
|
|
5597
|
+
ctx.output.exitCode = 64;
|
|
5598
|
+
ctx.output.reason = `not valid SHA-shaped tokens: ${bad.join(", ")}`;
|
|
5599
|
+
ctx.skipAgent = true;
|
|
5600
|
+
tryPostPr4(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
|
|
5601
|
+
return;
|
|
5602
|
+
}
|
|
5603
|
+
const resolved = [];
|
|
5604
|
+
const unreachable = [];
|
|
5605
|
+
for (const s of requested) {
|
|
5606
|
+
let full;
|
|
5607
|
+
try {
|
|
5608
|
+
full = git4(["rev-parse", "--verify", `${s}^{commit}`], ctx.cwd);
|
|
5609
|
+
} catch {
|
|
5610
|
+
unreachable.push(s);
|
|
5611
|
+
continue;
|
|
5612
|
+
}
|
|
5613
|
+
if (!isAncestorOfHead(full, ctx.cwd)) {
|
|
5614
|
+
unreachable.push(s);
|
|
5615
|
+
continue;
|
|
5616
|
+
}
|
|
5617
|
+
let subject = "";
|
|
5618
|
+
try {
|
|
5619
|
+
subject = git4(["log", "-1", "--format=%s", full], ctx.cwd);
|
|
5620
|
+
} catch {
|
|
5621
|
+
}
|
|
5622
|
+
resolved.push({ input: s, full, subject });
|
|
5623
|
+
}
|
|
5624
|
+
if (unreachable.length > 0) {
|
|
5625
|
+
ctx.output.exitCode = 64;
|
|
5626
|
+
ctx.output.reason = `commit(s) not found in this PR branch: ${unreachable.join(", ")}`;
|
|
5627
|
+
ctx.skipAgent = true;
|
|
5628
|
+
tryPostPr4(prNumber, `\u26A0\uFE0F kody revert FAILED: ${ctx.output.reason}`, ctx.cwd);
|
|
5629
|
+
return;
|
|
5630
|
+
}
|
|
5631
|
+
ctx.args.shas = resolved.map((r) => r.full).join(" ");
|
|
5632
|
+
ctx.data.commitMessage = buildCommitMessage(resolved);
|
|
5633
|
+
ctx.data.prSummary = buildPrSummary(resolved);
|
|
5634
|
+
ctx.skipAgent = true;
|
|
5635
|
+
const runUrl = getRunUrl();
|
|
5636
|
+
const runSuffix = runUrl ? `, run ${runUrl}` : "";
|
|
5637
|
+
const shaList = resolved.map((r) => `\`${r.full.slice(0, 7)}\``).join(", ");
|
|
5638
|
+
tryPostPr4(
|
|
5639
|
+
prNumber,
|
|
5640
|
+
`\u2699\uFE0F kody revert started on \`${ctx.data.branch}\`${runSuffix} \u2014 reverting ${shaList}`,
|
|
5641
|
+
ctx.cwd
|
|
5642
|
+
);
|
|
5643
|
+
};
|
|
5644
|
+
function buildCommitMessage(resolved) {
|
|
5645
|
+
if (resolved.length === 1) {
|
|
5646
|
+
const { full, subject } = resolved[0];
|
|
5647
|
+
return subject ? `revert: "${subject}" (${full.slice(0, 7)})` : `revert: ${full.slice(0, 7)}`;
|
|
5648
|
+
}
|
|
5649
|
+
const shas = resolved.map((r) => r.full.slice(0, 7)).join(", ");
|
|
5650
|
+
return `revert: ${resolved.length} commit(s) (${shas})`;
|
|
5651
|
+
}
|
|
5652
|
+
function buildPrSummary(resolved) {
|
|
5653
|
+
return resolved.map((r) => `- Reverted \`${r.full.slice(0, 7)}\`${r.subject ? ` \u2014 ${r.subject}` : ""}`).join("\n");
|
|
5654
|
+
}
|
|
5655
|
+
function git4(args, cwd) {
|
|
5656
|
+
return execFileSync19("git", args, {
|
|
5657
|
+
encoding: "utf-8",
|
|
5658
|
+
timeout: 3e4,
|
|
5659
|
+
cwd,
|
|
5660
|
+
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
5661
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
5662
|
+
}).trim();
|
|
5663
|
+
}
|
|
5664
|
+
function isAncestorOfHead(sha, cwd) {
|
|
5665
|
+
try {
|
|
5666
|
+
execFileSync19("git", ["merge-base", "--is-ancestor", sha, "HEAD"], {
|
|
5667
|
+
cwd,
|
|
5668
|
+
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
5669
|
+
stdio: ["ignore", "ignore", "ignore"]
|
|
5670
|
+
});
|
|
5671
|
+
return true;
|
|
5672
|
+
} catch {
|
|
5673
|
+
return false;
|
|
5674
|
+
}
|
|
5675
|
+
}
|
|
5676
|
+
function tryPostPr4(prNumber, body, cwd) {
|
|
5677
|
+
try {
|
|
5678
|
+
postPrReviewComment(prNumber, body, cwd);
|
|
5679
|
+
} catch {
|
|
5680
|
+
}
|
|
5681
|
+
}
|
|
5682
|
+
|
|
5562
5683
|
// src/scripts/resolvePreviewUrl.ts
|
|
5563
5684
|
var DEFAULT_PREVIEW_URL = "http://localhost:3000";
|
|
5564
5685
|
var resolvePreviewUrl = async (ctx) => {
|
|
@@ -5596,9 +5717,9 @@ var reviewFlow = async (ctx) => {
|
|
|
5596
5717
|
ctx.data.prDiff = getPrDiff(prNumber, ctx.cwd);
|
|
5597
5718
|
const runUrl = getRunUrl();
|
|
5598
5719
|
const runSuffix = runUrl ? `, run ${runUrl}` : "";
|
|
5599
|
-
|
|
5720
|
+
tryPostPr5(prNumber, `\u{1F440} kody review started on PR #${prNumber}${runSuffix}`, ctx.cwd);
|
|
5600
5721
|
};
|
|
5601
|
-
function
|
|
5722
|
+
function tryPostPr5(prNumber, body, cwd) {
|
|
5602
5723
|
try {
|
|
5603
5724
|
postPrReviewComment(prNumber, body, cwd);
|
|
5604
5725
|
} catch {
|
|
@@ -5711,11 +5832,11 @@ var skipAgent = async (ctx) => {
|
|
|
5711
5832
|
};
|
|
5712
5833
|
|
|
5713
5834
|
// src/scripts/stageMergeConflicts.ts
|
|
5714
|
-
import { execFileSync as
|
|
5835
|
+
import { execFileSync as execFileSync20 } from "child_process";
|
|
5715
5836
|
var stageMergeConflicts = async (ctx) => {
|
|
5716
5837
|
if (ctx.data.agentDone === false) return;
|
|
5717
5838
|
try {
|
|
5718
|
-
|
|
5839
|
+
execFileSync20("git", ["add", "-A"], {
|
|
5719
5840
|
cwd: ctx.cwd,
|
|
5720
5841
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
5721
5842
|
stdio: "pipe"
|
|
@@ -5725,7 +5846,7 @@ var stageMergeConflicts = async (ctx) => {
|
|
|
5725
5846
|
};
|
|
5726
5847
|
|
|
5727
5848
|
// src/scripts/startFlow.ts
|
|
5728
|
-
import { execFileSync as
|
|
5849
|
+
import { execFileSync as execFileSync21 } from "child_process";
|
|
5729
5850
|
var API_TIMEOUT_MS9 = 3e4;
|
|
5730
5851
|
var startFlow = async (ctx, profile, _agentResult, args) => {
|
|
5731
5852
|
const entry = args?.entry;
|
|
@@ -5759,7 +5880,7 @@ function postKodyComment(target, issueNumber, state, next, cwd) {
|
|
|
5759
5880
|
const sub = target === "pr" && state?.core.prUrl ? "pr" : "issue";
|
|
5760
5881
|
const body = `@kody ${next}`;
|
|
5761
5882
|
try {
|
|
5762
|
-
|
|
5883
|
+
execFileSync21("gh", [sub, "comment", String(targetNumber), "--body", body], {
|
|
5763
5884
|
timeout: API_TIMEOUT_MS9,
|
|
5764
5885
|
cwd,
|
|
5765
5886
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -5773,7 +5894,7 @@ function postKodyComment(target, issueNumber, state, next, cwd) {
|
|
|
5773
5894
|
}
|
|
5774
5895
|
|
|
5775
5896
|
// src/scripts/syncFlow.ts
|
|
5776
|
-
import { execFileSync as
|
|
5897
|
+
import { execFileSync as execFileSync22 } from "child_process";
|
|
5777
5898
|
var syncFlow = async (ctx, _profile, args) => {
|
|
5778
5899
|
const announceOnSuccess = Boolean(args?.announceOnSuccess);
|
|
5779
5900
|
const prNumber = ctx.args.pr;
|
|
@@ -5811,7 +5932,7 @@ var syncFlow = async (ctx, _profile, args) => {
|
|
|
5811
5932
|
if (announceOnSuccess) {
|
|
5812
5933
|
ctx.output.exitCode = 0;
|
|
5813
5934
|
ctx.output.reason = `already up to date with origin/${baseBranch}`;
|
|
5814
|
-
|
|
5935
|
+
tryPostPr6(prNumber, `\u2139\uFE0F kody sync: already up to date with origin/${baseBranch}`, ctx.cwd);
|
|
5815
5936
|
}
|
|
5816
5937
|
return;
|
|
5817
5938
|
}
|
|
@@ -5828,7 +5949,7 @@ var syncFlow = async (ctx, _profile, args) => {
|
|
|
5828
5949
|
ctx.output.reason = `merged origin/${baseBranch} into ${ctx.data.branch}`;
|
|
5829
5950
|
const runUrl = getRunUrl();
|
|
5830
5951
|
const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
|
|
5831
|
-
|
|
5952
|
+
tryPostPr6(
|
|
5832
5953
|
prNumber,
|
|
5833
5954
|
`\u2705 kody sync: merged \`origin/${baseBranch}\` into \`${ctx.data.branch}\`${runSuffix}`,
|
|
5834
5955
|
ctx.cwd
|
|
@@ -5841,11 +5962,11 @@ function bail2(ctx, prNumber, reason) {
|
|
|
5841
5962
|
ctx.output.reason = reason;
|
|
5842
5963
|
const runUrl = getRunUrl();
|
|
5843
5964
|
const runSuffix = runUrl ? ` ([logs](${runUrl}))` : "";
|
|
5844
|
-
|
|
5965
|
+
tryPostPr6(prNumber, `\u274C kody sync could not complete${runSuffix}: ${reason}`, ctx.cwd);
|
|
5845
5966
|
}
|
|
5846
5967
|
function revParseHead(cwd) {
|
|
5847
5968
|
try {
|
|
5848
|
-
return
|
|
5969
|
+
return execFileSync22("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
|
|
5849
5970
|
} catch {
|
|
5850
5971
|
return "";
|
|
5851
5972
|
}
|
|
@@ -5853,16 +5974,16 @@ function revParseHead(cwd) {
|
|
|
5853
5974
|
function pushBranch(branch, cwd) {
|
|
5854
5975
|
const env = { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" };
|
|
5855
5976
|
try {
|
|
5856
|
-
|
|
5977
|
+
execFileSync22("git", ["push", "-u", "origin", branch], { cwd, env, stdio: ["ignore", "pipe", "pipe"] });
|
|
5857
5978
|
} catch {
|
|
5858
|
-
|
|
5979
|
+
execFileSync22("git", ["push", "--force-with-lease", "-u", "origin", branch], {
|
|
5859
5980
|
cwd,
|
|
5860
5981
|
env,
|
|
5861
5982
|
stdio: ["ignore", "pipe", "pipe"]
|
|
5862
5983
|
});
|
|
5863
5984
|
}
|
|
5864
5985
|
}
|
|
5865
|
-
function
|
|
5986
|
+
function tryPostPr6(prNumber, body, cwd) {
|
|
5866
5987
|
try {
|
|
5867
5988
|
postPrReviewComment(prNumber, body, cwd);
|
|
5868
5989
|
} catch {
|
|
@@ -5966,7 +6087,7 @@ var verify = async (ctx) => {
|
|
|
5966
6087
|
};
|
|
5967
6088
|
|
|
5968
6089
|
// src/scripts/waitForCi.ts
|
|
5969
|
-
import { execFileSync as
|
|
6090
|
+
import { execFileSync as execFileSync23 } from "child_process";
|
|
5970
6091
|
var API_TIMEOUT_MS10 = 3e4;
|
|
5971
6092
|
var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
5972
6093
|
const timeoutMinutes = numArg(args, "timeoutMinutes", 30);
|
|
@@ -5997,7 +6118,7 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
5997
6118
|
const summary = summarize(rows);
|
|
5998
6119
|
if (summary !== lastSummary) {
|
|
5999
6120
|
lastSummary = summary;
|
|
6000
|
-
|
|
6121
|
+
tryPostPr7(prNumber, `\u23F3 kody waitForCi: ${summary}`, ctx.cwd);
|
|
6001
6122
|
}
|
|
6002
6123
|
const failed = rows.filter((r) => r.bucket === "fail" || r.bucket === "cancel");
|
|
6003
6124
|
const pending = rows.filter((r) => r.bucket === "pending");
|
|
@@ -6009,7 +6130,7 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
6009
6130
|
failedChecks: detail,
|
|
6010
6131
|
prUrl
|
|
6011
6132
|
});
|
|
6012
|
-
|
|
6133
|
+
tryPostPr7(
|
|
6013
6134
|
prNumber,
|
|
6014
6135
|
`\u{1F6D1} kody waitForCi: giving up after ${fixCiAttempts} fix-ci attempts. Failed: ${detail}`,
|
|
6015
6136
|
ctx.cwd
|
|
@@ -6021,7 +6142,7 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
6021
6142
|
maxAttempts: maxFixCiAttempts,
|
|
6022
6143
|
prUrl
|
|
6023
6144
|
});
|
|
6024
|
-
|
|
6145
|
+
tryPostPr7(
|
|
6025
6146
|
prNumber,
|
|
6026
6147
|
`\u274C kody waitForCi: CI failed (attempt ${fixCiAttempts + 1}/${maxFixCiAttempts}). Dispatching fix-ci. Failed: ${detail}`,
|
|
6027
6148
|
ctx.cwd
|
|
@@ -6031,7 +6152,7 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
6031
6152
|
}
|
|
6032
6153
|
if (pending.length === 0) {
|
|
6033
6154
|
ctx.data.action = mkAction("CI_PASSED", { checks: rows.length, prUrl });
|
|
6034
|
-
|
|
6155
|
+
tryPostPr7(prNumber, `\u2705 kody waitForCi: all ${rows.length} checks green on PR #${prNumber}`, ctx.cwd);
|
|
6035
6156
|
return;
|
|
6036
6157
|
}
|
|
6037
6158
|
await sleep(pollSeconds * 1e3);
|
|
@@ -6040,11 +6161,11 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
6040
6161
|
reason: `CI did not complete within ${timeoutMinutes} minutes`,
|
|
6041
6162
|
prUrl
|
|
6042
6163
|
});
|
|
6043
|
-
|
|
6164
|
+
tryPostPr7(prNumber, `\u231B kody waitForCi: timed out after ${timeoutMinutes} minutes`, ctx.cwd);
|
|
6044
6165
|
};
|
|
6045
6166
|
function fetchChecks(prNumber, cwd) {
|
|
6046
6167
|
try {
|
|
6047
|
-
const raw =
|
|
6168
|
+
const raw = execFileSync23("gh", ["pr", "checks", String(prNumber), "--json", "bucket,state,name,workflow,link"], {
|
|
6048
6169
|
encoding: "utf-8",
|
|
6049
6170
|
timeout: API_TIMEOUT_MS10,
|
|
6050
6171
|
cwd,
|
|
@@ -6080,7 +6201,7 @@ function numArg(args, key, fallback) {
|
|
|
6080
6201
|
}
|
|
6081
6202
|
return fallback;
|
|
6082
6203
|
}
|
|
6083
|
-
function
|
|
6204
|
+
function tryPostPr7(prNumber, body, cwd) {
|
|
6084
6205
|
try {
|
|
6085
6206
|
postPrReviewComment(prNumber, body, cwd);
|
|
6086
6207
|
} catch {
|
|
@@ -6253,6 +6374,7 @@ var preflightScripts = {
|
|
|
6253
6374
|
fixFlow,
|
|
6254
6375
|
fixCiFlow,
|
|
6255
6376
|
resolveFlow,
|
|
6377
|
+
revertFlow,
|
|
6256
6378
|
reviewFlow,
|
|
6257
6379
|
syncFlow,
|
|
6258
6380
|
initFlow,
|
|
@@ -6313,7 +6435,8 @@ var postflightScripts = {
|
|
|
6313
6435
|
notifyTerminal,
|
|
6314
6436
|
recordOutcome,
|
|
6315
6437
|
mergeReleasePr,
|
|
6316
|
-
waitForCi
|
|
6438
|
+
waitForCi,
|
|
6439
|
+
markFlowSuccess
|
|
6317
6440
|
};
|
|
6318
6441
|
var allScriptNames = /* @__PURE__ */ new Set([
|
|
6319
6442
|
...Object.keys(preflightScripts),
|
|
@@ -6321,7 +6444,7 @@ var allScriptNames = /* @__PURE__ */ new Set([
|
|
|
6321
6444
|
]);
|
|
6322
6445
|
|
|
6323
6446
|
// src/tools.ts
|
|
6324
|
-
import { execFileSync as
|
|
6447
|
+
import { execFileSync as execFileSync24 } from "child_process";
|
|
6325
6448
|
function verifyCliTools(tools, cwd) {
|
|
6326
6449
|
const out = [];
|
|
6327
6450
|
for (const t of tools) out.push(verifyOne(t, cwd));
|
|
@@ -6354,7 +6477,7 @@ function verifyOne(tool, cwd) {
|
|
|
6354
6477
|
}
|
|
6355
6478
|
function runShell(cmd, cwd, timeoutMs = 3e4) {
|
|
6356
6479
|
try {
|
|
6357
|
-
|
|
6480
|
+
execFileSync24("sh", ["-c", cmd], { cwd, stdio: "pipe", timeout: timeoutMs });
|
|
6358
6481
|
return true;
|
|
6359
6482
|
} catch {
|
|
6360
6483
|
return false;
|
|
@@ -6763,7 +6886,7 @@ function detectPackageManager2(cwd) {
|
|
|
6763
6886
|
}
|
|
6764
6887
|
function shellOut(cmd, args, cwd, stream = true) {
|
|
6765
6888
|
try {
|
|
6766
|
-
|
|
6889
|
+
execFileSync25(cmd, args, {
|
|
6767
6890
|
cwd,
|
|
6768
6891
|
stdio: stream ? "inherit" : "pipe",
|
|
6769
6892
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", CI: process.env.CI ?? "1" }
|
|
@@ -6776,7 +6899,7 @@ function shellOut(cmd, args, cwd, stream = true) {
|
|
|
6776
6899
|
}
|
|
6777
6900
|
function isOnPath(bin) {
|
|
6778
6901
|
try {
|
|
6779
|
-
|
|
6902
|
+
execFileSync25("which", [bin], { stdio: "pipe" });
|
|
6780
6903
|
return true;
|
|
6781
6904
|
} catch {
|
|
6782
6905
|
return false;
|
|
@@ -6810,7 +6933,7 @@ function installLitellmIfNeeded(cwd) {
|
|
|
6810
6933
|
} catch {
|
|
6811
6934
|
}
|
|
6812
6935
|
try {
|
|
6813
|
-
|
|
6936
|
+
execFileSync25("python3", ["-c", "import litellm"], { stdio: "pipe" });
|
|
6814
6937
|
process.stdout.write("\u2192 kody: litellm already installed\n");
|
|
6815
6938
|
return 0;
|
|
6816
6939
|
} catch {
|
|
@@ -6820,16 +6943,16 @@ function installLitellmIfNeeded(cwd) {
|
|
|
6820
6943
|
}
|
|
6821
6944
|
function configureGitIdentity(cwd) {
|
|
6822
6945
|
try {
|
|
6823
|
-
const name =
|
|
6946
|
+
const name = execFileSync25("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
|
|
6824
6947
|
if (name) return;
|
|
6825
6948
|
} catch {
|
|
6826
6949
|
}
|
|
6827
6950
|
try {
|
|
6828
|
-
|
|
6951
|
+
execFileSync25("git", ["config", "user.name", "github-actions[bot]"], { cwd, stdio: "pipe" });
|
|
6829
6952
|
} catch {
|
|
6830
6953
|
}
|
|
6831
6954
|
try {
|
|
6832
|
-
|
|
6955
|
+
execFileSync25("git", ["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"], {
|
|
6833
6956
|
cwd,
|
|
6834
6957
|
stdio: "pipe"
|
|
6835
6958
|
});
|
|
@@ -7100,9 +7223,9 @@ function commitChatFiles(cwd, sessionId, verbose) {
|
|
|
7100
7223
|
if (paths.length === 0) return;
|
|
7101
7224
|
const opts = { cwd, stdio: verbose ? "inherit" : "pipe" };
|
|
7102
7225
|
try {
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7226
|
+
execFileSync26("git", ["add", ...paths], opts);
|
|
7227
|
+
execFileSync26("git", ["commit", "--quiet", "-m", `chat: reply for ${sessionId}`], opts);
|
|
7228
|
+
execFileSync26("git", ["push", "--quiet", "origin", "HEAD"], opts);
|
|
7106
7229
|
} catch (err) {
|
|
7107
7230
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7108
7231
|
process.stderr.write(`[kody:chat] commit/push skipped: ${msg}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "revert",
|
|
3
|
+
"role": "primitive",
|
|
4
|
+
"describe": "Revert one or more commits on an existing PR branch via `git revert`. No agent — fully mechanical.",
|
|
5
|
+
"inputs": [
|
|
6
|
+
{
|
|
7
|
+
"name": "pr",
|
|
8
|
+
"flag": "--pr",
|
|
9
|
+
"type": "int",
|
|
10
|
+
"required": true,
|
|
11
|
+
"describe": "GitHub PR number whose branch to revert commits on."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "shas",
|
|
15
|
+
"flag": "--shas",
|
|
16
|
+
"type": "string",
|
|
17
|
+
"required": true,
|
|
18
|
+
"bindsCommentRest": true,
|
|
19
|
+
"describe": "One or more commit SHAs (whitespace-separated) to revert. Each must exist in the PR branch's history."
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"claudeCode": {
|
|
23
|
+
"model": "inherit",
|
|
24
|
+
"permissionMode": "acceptEdits",
|
|
25
|
+
"maxTurns": 0,
|
|
26
|
+
"maxThinkingTokens": null,
|
|
27
|
+
"systemPromptAppend": null,
|
|
28
|
+
"tools": [],
|
|
29
|
+
"hooks": [],
|
|
30
|
+
"skills": [],
|
|
31
|
+
"commands": [],
|
|
32
|
+
"subagents": [],
|
|
33
|
+
"plugins": [],
|
|
34
|
+
"mcpServers": []
|
|
35
|
+
},
|
|
36
|
+
"cliTools": [],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"preflight": [
|
|
39
|
+
{
|
|
40
|
+
"script": "setLifecycleLabel",
|
|
41
|
+
"with": {
|
|
42
|
+
"label": "kody:reverting",
|
|
43
|
+
"color": "cccccc",
|
|
44
|
+
"description": "kody: reverting commits"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{ "script": "revertFlow" },
|
|
48
|
+
{ "shell": "revert.sh" }
|
|
49
|
+
],
|
|
50
|
+
"postflight": [
|
|
51
|
+
{ "script": "markFlowSuccess" },
|
|
52
|
+
{ "script": "commitAndPush" },
|
|
53
|
+
{ "script": "ensurePr" },
|
|
54
|
+
{ "script": "postIssueComment" },
|
|
55
|
+
{ "script": "writeRunSummary" }
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
"output": {
|
|
59
|
+
"actionTypes": [
|
|
60
|
+
"REVERT_COMPLETED",
|
|
61
|
+
"REVERT_FAILED"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# revert: stage `git revert` of one or more commits on the PR branch.
|
|
4
|
+
#
|
|
5
|
+
# Runs as a preflight shell entry after revertFlow has validated inputs and
|
|
6
|
+
# checked out the branch. revertFlow:
|
|
7
|
+
# - Resolved every requested SHA to its full form and re-set
|
|
8
|
+
# ctx.args.shas to a whitespace-separated list (we read it via
|
|
9
|
+
# KODY_ARG_SHAS).
|
|
10
|
+
# - Set ctx.skipAgent=true and ctx.data.commitMessage already, so the
|
|
11
|
+
# agent never runs and commitAndPush will use that message.
|
|
12
|
+
#
|
|
13
|
+
# This script does only the staging — `--no-commit` so commitAndPush
|
|
14
|
+
# (postflight) makes the actual commit. That keeps kody's invariant
|
|
15
|
+
# intact (only commitAndPush commits) and means the message comes from
|
|
16
|
+
# revertFlow, not from git's auto-generated revert subject.
|
|
17
|
+
#
|
|
18
|
+
# Exits:
|
|
19
|
+
# 0 — staged successfully
|
|
20
|
+
# 1+ — git revert failed (executor surfaces stderr; postflight bails)
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
|
|
24
|
+
shas="${KODY_ARG_SHAS:-}"
|
|
25
|
+
if [[ -z "$shas" ]]; then
|
|
26
|
+
echo "revert.sh: KODY_ARG_SHAS is empty (revertFlow should have set it)" >&2
|
|
27
|
+
exit 64
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# shellcheck disable=SC2086 # Intentional word-splitting on whitespace-separated SHAs.
|
|
31
|
+
git revert --no-commit --no-edit $shas
|
|
32
|
+
|
|
33
|
+
echo "revert.sh: staged revert of: $shas"
|
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.51",
|
|
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",
|