@kody-ade/kody-engine 0.4.159 → 0.4.161
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 +121 -132
- package/dist/executables/types.ts +8 -0
- package/package.json +1 -1
package/dist/bin/kody.js
CHANGED
|
@@ -1061,7 +1061,7 @@ var init_loadPriorArt = __esm({
|
|
|
1061
1061
|
// package.json
|
|
1062
1062
|
var package_default = {
|
|
1063
1063
|
name: "@kody-ade/kody-engine",
|
|
1064
|
-
version: "0.4.
|
|
1064
|
+
version: "0.4.161",
|
|
1065
1065
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
1066
1066
|
license: "MIT",
|
|
1067
1067
|
type: "module",
|
|
@@ -1117,7 +1117,7 @@ var package_default = {
|
|
|
1117
1117
|
};
|
|
1118
1118
|
|
|
1119
1119
|
// src/chat-cli.ts
|
|
1120
|
-
import { execFileSync as
|
|
1120
|
+
import { execFileSync as execFileSync29 } from "child_process";
|
|
1121
1121
|
import * as fs43 from "fs";
|
|
1122
1122
|
import * as path39 from "path";
|
|
1123
1123
|
|
|
@@ -2819,7 +2819,7 @@ async function emit2(sink, type, sessionId, suffix, payload) {
|
|
|
2819
2819
|
}
|
|
2820
2820
|
|
|
2821
2821
|
// src/kody-cli.ts
|
|
2822
|
-
import { execFileSync as
|
|
2822
|
+
import { execFileSync as execFileSync28 } from "child_process";
|
|
2823
2823
|
import * as fs42 from "fs";
|
|
2824
2824
|
import * as path38 from "path";
|
|
2825
2825
|
|
|
@@ -3227,7 +3227,7 @@ function coerceBare(spec, value) {
|
|
|
3227
3227
|
}
|
|
3228
3228
|
|
|
3229
3229
|
// src/executor.ts
|
|
3230
|
-
import { execFileSync as
|
|
3230
|
+
import { execFileSync as execFileSync27, spawn as spawn9 } from "child_process";
|
|
3231
3231
|
import * as fs41 from "fs";
|
|
3232
3232
|
import * as path37 from "path";
|
|
3233
3233
|
|
|
@@ -4699,7 +4699,7 @@ var advanceFlow = async (ctx, profile) => {
|
|
|
4699
4699
|
`
|
|
4700
4700
|
);
|
|
4701
4701
|
}
|
|
4702
|
-
|
|
4702
|
+
ctx.output.nextDispatch = { executable: flow.name, cliArgs: { issue: flow.issueNumber } };
|
|
4703
4703
|
};
|
|
4704
4704
|
|
|
4705
4705
|
// src/scripts/brainServe.ts
|
|
@@ -6865,8 +6865,6 @@ var discoverQaContext = async (ctx) => {
|
|
|
6865
6865
|
};
|
|
6866
6866
|
|
|
6867
6867
|
// src/scripts/dispatch.ts
|
|
6868
|
-
import { execFileSync as execFileSync11 } from "child_process";
|
|
6869
|
-
var API_TIMEOUT_MS4 = 3e4;
|
|
6870
6868
|
var dispatch = async (ctx, _profile, _agentResult, args) => {
|
|
6871
6869
|
const next = args?.next;
|
|
6872
6870
|
if (!next) {
|
|
@@ -6898,20 +6896,10 @@ var dispatch = async (ctx, _profile, _agentResult, args) => {
|
|
|
6898
6896
|
}
|
|
6899
6897
|
const usePr = target === "pr" && state?.core.prUrl;
|
|
6900
6898
|
const targetNumber = usePr ? parsePr(state.core.prUrl) ?? issueNumber : issueNumber;
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
timeout: API_TIMEOUT_MS4,
|
|
6906
|
-
cwd: ctx.cwd,
|
|
6907
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
6908
|
-
});
|
|
6909
|
-
} catch (err) {
|
|
6910
|
-
process.stderr.write(
|
|
6911
|
-
`[kody dispatch] failed to post @kody ${next} on ${sub} #${targetNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
6912
|
-
`
|
|
6913
|
-
);
|
|
6914
|
-
}
|
|
6899
|
+
ctx.output.nextDispatch = {
|
|
6900
|
+
executable: next,
|
|
6901
|
+
cliArgs: usePr ? { pr: targetNumber } : { issue: targetNumber }
|
|
6902
|
+
};
|
|
6915
6903
|
};
|
|
6916
6904
|
function parsePr(url) {
|
|
6917
6905
|
const m = url.match(/\/pull\/(\d+)(?:[/?#]|$)/);
|
|
@@ -6921,8 +6909,8 @@ function parsePr(url) {
|
|
|
6921
6909
|
}
|
|
6922
6910
|
|
|
6923
6911
|
// src/scripts/dispatchClassified.ts
|
|
6924
|
-
import { execFileSync as
|
|
6925
|
-
var
|
|
6912
|
+
import { execFileSync as execFileSync11 } from "child_process";
|
|
6913
|
+
var API_TIMEOUT_MS4 = 3e4;
|
|
6926
6914
|
var VALID_CLASSES2 = /* @__PURE__ */ new Set(["feature", "bug", "spec", "chore"]);
|
|
6927
6915
|
var dispatchClassified = async (ctx) => {
|
|
6928
6916
|
const issueNumber = ctx.args.issue;
|
|
@@ -6931,38 +6919,34 @@ var dispatchClassified = async (ctx) => {
|
|
|
6931
6919
|
if (!classification || !VALID_CLASSES2.has(classification)) return;
|
|
6932
6920
|
const action = ctx.data.action;
|
|
6933
6921
|
if (!action) return;
|
|
6934
|
-
const
|
|
6935
|
-
const dispatchLine = `@kody ${classification}${baseArg}`;
|
|
6922
|
+
const base = typeof ctx.args.base === "string" && ctx.args.base.length > 0 ? ctx.args.base : void 0;
|
|
6936
6923
|
const auditLine = ctx.data.classificationAudit ?? `\u{1F50E} kody classified as \`${classification}\``;
|
|
6937
6924
|
const state = ctx.data.taskState ?? emptyState();
|
|
6938
6925
|
const nextState = reduce(state, "classify", action, void 0);
|
|
6939
6926
|
const stateBody = renderStateComment(nextState);
|
|
6940
6927
|
ctx.data.taskState = nextState;
|
|
6941
6928
|
ctx.data.taskStateRendered = stateBody;
|
|
6942
|
-
const body = `${
|
|
6943
|
-
|
|
6944
|
-
${auditLine}
|
|
6929
|
+
const body = `${auditLine}
|
|
6945
6930
|
|
|
6946
6931
|
${stateBody}`;
|
|
6947
6932
|
try {
|
|
6948
|
-
|
|
6933
|
+
execFileSync11("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
6949
6934
|
cwd: ctx.cwd,
|
|
6950
|
-
timeout:
|
|
6935
|
+
timeout: API_TIMEOUT_MS4,
|
|
6951
6936
|
stdio: ["ignore", "pipe", "pipe"]
|
|
6952
6937
|
});
|
|
6953
6938
|
} catch (err) {
|
|
6954
6939
|
process.stderr.write(
|
|
6955
|
-
`[kody dispatchClassified] failed to
|
|
6940
|
+
`[kody dispatchClassified] failed to post state comment for #${issueNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
6956
6941
|
`
|
|
6957
6942
|
);
|
|
6958
|
-
ctx.data.action = failedAction3("dispatch post failed");
|
|
6959
|
-
ctx.output.exitCode = 1;
|
|
6960
|
-
ctx.output.reason = "classify: dispatch failed";
|
|
6961
6943
|
}
|
|
6944
|
+
const cliArgs = { issue: issueNumber };
|
|
6945
|
+
if (base && getProfileInputs(classification)?.some((i) => i.name === "base")) {
|
|
6946
|
+
cliArgs.base = base;
|
|
6947
|
+
}
|
|
6948
|
+
ctx.output.nextDispatch = { executable: classification, cliArgs };
|
|
6962
6949
|
};
|
|
6963
|
-
function failedAction3(reason) {
|
|
6964
|
-
return { type: "CLASSIFY_FAILED", payload: { reason }, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
6965
|
-
}
|
|
6966
6950
|
|
|
6967
6951
|
// src/scripts/dispatchJobFileTicks.ts
|
|
6968
6952
|
import * as fs29 from "fs";
|
|
@@ -7620,20 +7604,18 @@ var dispatchNextTask = async (ctx) => {
|
|
|
7620
7604
|
return;
|
|
7621
7605
|
}
|
|
7622
7606
|
const base = goal.leafPr?.headRefName ?? goal.defaultBranch;
|
|
7623
|
-
process.stdout.write(`[goal-tick] dispatching
|
|
7624
|
-
`);
|
|
7625
|
-
const comment = commentOnIssue(next.number, `@kody --base ${base}`, ctx.cwd);
|
|
7626
|
-
if (!comment.ok) {
|
|
7627
|
-
process.stderr.write(`[goal-tick] dispatchNextTask: comment failed on #${next.number}: ${comment.error}
|
|
7607
|
+
process.stdout.write(`[goal-tick] dispatching #${next.number} in-process via classify (--base ${base})
|
|
7628
7608
|
`);
|
|
7629
|
-
|
|
7630
|
-
|
|
7609
|
+
ctx.output.nextDispatch = {
|
|
7610
|
+
executable: "classify",
|
|
7611
|
+
cliArgs: { issue: next.number, base }
|
|
7612
|
+
};
|
|
7631
7613
|
goal.lastDispatchedIssue = next.number;
|
|
7632
7614
|
};
|
|
7633
7615
|
|
|
7634
7616
|
// src/pr.ts
|
|
7635
7617
|
init_issue();
|
|
7636
|
-
import { execFileSync as
|
|
7618
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
7637
7619
|
function prMergeStatus(prNumber, cwd) {
|
|
7638
7620
|
try {
|
|
7639
7621
|
const out = gh(
|
|
@@ -7759,7 +7741,7 @@ function isAlreadyExistsError(err) {
|
|
|
7759
7741
|
return ALREADY_EXISTS_RE.test(msg);
|
|
7760
7742
|
}
|
|
7761
7743
|
function git2(args, cwd) {
|
|
7762
|
-
return
|
|
7744
|
+
return execFileSync12("git", args, {
|
|
7763
7745
|
encoding: "utf-8",
|
|
7764
7746
|
timeout: 3e4,
|
|
7765
7747
|
cwd,
|
|
@@ -8090,14 +8072,14 @@ var finalizeTerminal = async (ctx) => {
|
|
|
8090
8072
|
|
|
8091
8073
|
// src/scripts/finishFlow.ts
|
|
8092
8074
|
init_issue();
|
|
8093
|
-
import { execFileSync as
|
|
8075
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
8094
8076
|
var TERMINAL_PHASE = {
|
|
8095
8077
|
"review-passed": { phase: "shipped", status: "succeeded" },
|
|
8096
8078
|
"fix-applied": { phase: "shipped", status: "succeeded" },
|
|
8097
8079
|
"review-failed": { phase: "failed", status: "failed" },
|
|
8098
8080
|
aborted: { phase: "failed", status: "failed" }
|
|
8099
8081
|
};
|
|
8100
|
-
var
|
|
8082
|
+
var API_TIMEOUT_MS5 = 3e4;
|
|
8101
8083
|
var STATUS_ICON = {
|
|
8102
8084
|
"review-passed": "\u2705",
|
|
8103
8085
|
"fix-applied": "\u2705",
|
|
@@ -8130,8 +8112,8 @@ var finishFlow = async (ctx, profile, _agentResult, args) => {
|
|
|
8130
8112
|
**PR:** ${state.core.prUrl}` : "";
|
|
8131
8113
|
const body = `${icon} kody flow \`${flowName}\` finished \u2014 \`${reason}\`${prSuffix}`;
|
|
8132
8114
|
try {
|
|
8133
|
-
|
|
8134
|
-
timeout:
|
|
8115
|
+
execFileSync13("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
8116
|
+
timeout: API_TIMEOUT_MS5,
|
|
8135
8117
|
cwd: ctx.cwd,
|
|
8136
8118
|
stdio: ["ignore", "pipe", "pipe"]
|
|
8137
8119
|
});
|
|
@@ -8160,9 +8142,9 @@ var finishFlow = async (ctx, profile, _agentResult, args) => {
|
|
|
8160
8142
|
};
|
|
8161
8143
|
|
|
8162
8144
|
// src/branch.ts
|
|
8163
|
-
import { execFileSync as
|
|
8145
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
8164
8146
|
function git3(args, cwd) {
|
|
8165
|
-
return
|
|
8147
|
+
return execFileSync14("git", args, {
|
|
8166
8148
|
encoding: "utf-8",
|
|
8167
8149
|
timeout: 3e4,
|
|
8168
8150
|
cwd,
|
|
@@ -8179,11 +8161,11 @@ function getCurrentBranch(cwd) {
|
|
|
8179
8161
|
}
|
|
8180
8162
|
function resetWorkingTree(cwd) {
|
|
8181
8163
|
try {
|
|
8182
|
-
|
|
8164
|
+
execFileSync14("git", ["reset", "--hard", "HEAD"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
8183
8165
|
} catch {
|
|
8184
8166
|
}
|
|
8185
8167
|
try {
|
|
8186
|
-
|
|
8168
|
+
execFileSync14("git", ["clean", "-fd"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
8187
8169
|
} catch {
|
|
8188
8170
|
}
|
|
8189
8171
|
}
|
|
@@ -8195,14 +8177,14 @@ function checkoutPrBranch(prNumber, cwd) {
|
|
|
8195
8177
|
GH_TOKEN: process.env.GH_PAT?.trim() || process.env.GH_TOKEN || ""
|
|
8196
8178
|
};
|
|
8197
8179
|
try {
|
|
8198
|
-
|
|
8180
|
+
execFileSync14("git", ["reset", "--hard", "HEAD"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
8199
8181
|
} catch {
|
|
8200
8182
|
}
|
|
8201
8183
|
try {
|
|
8202
|
-
|
|
8184
|
+
execFileSync14("git", ["clean", "-fd"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
8203
8185
|
} catch {
|
|
8204
8186
|
}
|
|
8205
|
-
|
|
8187
|
+
execFileSync14("gh", ["pr", "checkout", String(prNumber)], {
|
|
8206
8188
|
cwd,
|
|
8207
8189
|
env,
|
|
8208
8190
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -8328,7 +8310,7 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
|
|
|
8328
8310
|
}
|
|
8329
8311
|
|
|
8330
8312
|
// src/gha.ts
|
|
8331
|
-
import { execFileSync as
|
|
8313
|
+
import { execFileSync as execFileSync15 } from "child_process";
|
|
8332
8314
|
import * as fs30 from "fs";
|
|
8333
8315
|
function getRunUrl() {
|
|
8334
8316
|
const server = process.env.GITHUB_SERVER_URL;
|
|
@@ -8371,7 +8353,7 @@ function reactToTriggerComment(cwd) {
|
|
|
8371
8353
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
8372
8354
|
if (attempt > 0) sleepMs(attempt === 1 ? 500 : 1500);
|
|
8373
8355
|
try {
|
|
8374
|
-
|
|
8356
|
+
execFileSync15("gh", args, opts);
|
|
8375
8357
|
return;
|
|
8376
8358
|
} catch (err) {
|
|
8377
8359
|
lastErr = err;
|
|
@@ -8384,7 +8366,7 @@ function reactToTriggerComment(cwd) {
|
|
|
8384
8366
|
}
|
|
8385
8367
|
function sleepMs(ms) {
|
|
8386
8368
|
try {
|
|
8387
|
-
|
|
8369
|
+
execFileSync15("sleep", [(ms / 1e3).toString()], { stdio: "ignore", timeout: ms + 1e3 });
|
|
8388
8370
|
} catch {
|
|
8389
8371
|
}
|
|
8390
8372
|
}
|
|
@@ -8393,7 +8375,7 @@ function sleepMs(ms) {
|
|
|
8393
8375
|
init_issue();
|
|
8394
8376
|
|
|
8395
8377
|
// src/workflow.ts
|
|
8396
|
-
import { execFileSync as
|
|
8378
|
+
import { execFileSync as execFileSync16 } from "child_process";
|
|
8397
8379
|
var GH_TIMEOUT_MS = 3e4;
|
|
8398
8380
|
function ghToken3() {
|
|
8399
8381
|
return process.env.GH_PAT?.trim() || process.env.GH_TOKEN;
|
|
@@ -8401,7 +8383,7 @@ function ghToken3() {
|
|
|
8401
8383
|
function gh3(args, cwd) {
|
|
8402
8384
|
const token = ghToken3();
|
|
8403
8385
|
const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
|
|
8404
|
-
return
|
|
8386
|
+
return execFileSync16("gh", args, {
|
|
8405
8387
|
encoding: "utf-8",
|
|
8406
8388
|
timeout: GH_TIMEOUT_MS,
|
|
8407
8389
|
cwd,
|
|
@@ -8636,7 +8618,7 @@ var handleAbandonedGoal = async (ctx) => {
|
|
|
8636
8618
|
};
|
|
8637
8619
|
|
|
8638
8620
|
// src/scripts/initFlow.ts
|
|
8639
|
-
import { execFileSync as
|
|
8621
|
+
import { execFileSync as execFileSync17 } from "child_process";
|
|
8640
8622
|
import * as fs31 from "fs";
|
|
8641
8623
|
import * as path29 from "path";
|
|
8642
8624
|
function detectPackageManager(cwd) {
|
|
@@ -8662,7 +8644,7 @@ function schemaUrlFromPkg() {
|
|
|
8662
8644
|
function detectOwnerRepo(cwd) {
|
|
8663
8645
|
let url;
|
|
8664
8646
|
try {
|
|
8665
|
-
url =
|
|
8647
|
+
url = execFileSync17("git", ["remote", "get-url", "origin"], {
|
|
8666
8648
|
cwd,
|
|
8667
8649
|
encoding: "utf-8",
|
|
8668
8650
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -8747,7 +8729,7 @@ jobs:
|
|
|
8747
8729
|
`;
|
|
8748
8730
|
function defaultBranchFromGit(cwd) {
|
|
8749
8731
|
try {
|
|
8750
|
-
const ref =
|
|
8732
|
+
const ref = execFileSync17("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], {
|
|
8751
8733
|
cwd,
|
|
8752
8734
|
encoding: "utf-8",
|
|
8753
8735
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -8755,7 +8737,7 @@ function defaultBranchFromGit(cwd) {
|
|
|
8755
8737
|
return ref.replace("refs/remotes/origin/", "");
|
|
8756
8738
|
} catch {
|
|
8757
8739
|
try {
|
|
8758
|
-
return
|
|
8740
|
+
return execFileSync17("git", ["branch", "--show-current"], {
|
|
8759
8741
|
cwd,
|
|
8760
8742
|
encoding: "utf-8",
|
|
8761
8743
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -9445,8 +9427,8 @@ var mergeFlow = async (ctx) => {
|
|
|
9445
9427
|
};
|
|
9446
9428
|
|
|
9447
9429
|
// src/scripts/mergeReleasePr.ts
|
|
9448
|
-
import { execFileSync as
|
|
9449
|
-
var
|
|
9430
|
+
import { execFileSync as execFileSync18 } from "child_process";
|
|
9431
|
+
var API_TIMEOUT_MS6 = 6e4;
|
|
9450
9432
|
var mergeReleasePr = async (ctx) => {
|
|
9451
9433
|
const state = ctx.data.taskState;
|
|
9452
9434
|
const prUrl = state?.core.prUrl;
|
|
@@ -9464,8 +9446,8 @@ var mergeReleasePr = async (ctx) => {
|
|
|
9464
9446
|
process.stderr.write(`[kody mergeReleasePr] merging PR #${prNumber} (${prUrl})
|
|
9465
9447
|
`);
|
|
9466
9448
|
try {
|
|
9467
|
-
const out =
|
|
9468
|
-
timeout:
|
|
9449
|
+
const out = execFileSync18("gh", ["pr", "merge", String(prNumber), "--merge"], {
|
|
9450
|
+
timeout: API_TIMEOUT_MS6,
|
|
9469
9451
|
cwd: ctx.cwd,
|
|
9470
9452
|
stdio: ["ignore", "pipe", "pipe"]
|
|
9471
9453
|
});
|
|
@@ -9572,7 +9554,7 @@ function qaAction2(verdict, payload) {
|
|
|
9572
9554
|
const type = verdict === "PASS" ? "QA_PASS" : verdict === "CONCERNS" ? "QA_CONCERNS" : verdict === "FAIL" ? "QA_FAIL" : "QA_COMPLETED";
|
|
9573
9555
|
return { type, payload: { verdict, ...payload }, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
9574
9556
|
}
|
|
9575
|
-
function
|
|
9557
|
+
function failedAction3(reason) {
|
|
9576
9558
|
return { type: "QA_FAILED", payload: { reason }, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
9577
9559
|
}
|
|
9578
9560
|
function slugifyScope(scope) {
|
|
@@ -9608,7 +9590,7 @@ var openQaIssue = async (ctx, _profile, agentResult) => {
|
|
|
9608
9590
|
`);
|
|
9609
9591
|
ctx.output.exitCode = 1;
|
|
9610
9592
|
ctx.output.reason = reason;
|
|
9611
|
-
ctx.data.action =
|
|
9593
|
+
ctx.data.action = failedAction3(reason);
|
|
9612
9594
|
return;
|
|
9613
9595
|
}
|
|
9614
9596
|
const reportBody = agentResult.finalText.trim();
|
|
@@ -9616,7 +9598,7 @@ var openQaIssue = async (ctx, _profile, agentResult) => {
|
|
|
9616
9598
|
process.stderr.write("qa-engineer: agent produced no report body\n");
|
|
9617
9599
|
ctx.output.exitCode = 1;
|
|
9618
9600
|
ctx.output.reason = "empty report body";
|
|
9619
|
-
ctx.data.action =
|
|
9601
|
+
ctx.data.action = failedAction3("empty report body");
|
|
9620
9602
|
return;
|
|
9621
9603
|
}
|
|
9622
9604
|
const verdict = detectVerdict(reportBody);
|
|
@@ -9630,7 +9612,7 @@ var openQaIssue = async (ctx, _profile, agentResult) => {
|
|
|
9630
9612
|
const msg = err instanceof Error ? err.message : String(err);
|
|
9631
9613
|
ctx.output.exitCode = 4;
|
|
9632
9614
|
ctx.output.reason = `failed to comment on issue #${existingIssue}: ${msg}`;
|
|
9633
|
-
ctx.data.action =
|
|
9615
|
+
ctx.data.action = failedAction3(ctx.output.reason);
|
|
9634
9616
|
return;
|
|
9635
9617
|
}
|
|
9636
9618
|
process.stdout.write(
|
|
@@ -9652,7 +9634,7 @@ QA_REPORT_POSTED=https://github.com/${ctx.config.github.owner}/${ctx.config.gith
|
|
|
9652
9634
|
const msg = err instanceof Error ? err.message : String(err);
|
|
9653
9635
|
ctx.output.exitCode = 4;
|
|
9654
9636
|
ctx.output.reason = `failed to open QA issue: ${truncate2(msg, 1e3)}`;
|
|
9655
|
-
ctx.data.action =
|
|
9637
|
+
ctx.data.action = failedAction3(ctx.output.reason);
|
|
9656
9638
|
return;
|
|
9657
9639
|
}
|
|
9658
9640
|
process.stdout.write(`
|
|
@@ -10946,8 +10928,8 @@ ${body}`;
|
|
|
10946
10928
|
}
|
|
10947
10929
|
|
|
10948
10930
|
// src/scripts/recordClassification.ts
|
|
10949
|
-
import { execFileSync as
|
|
10950
|
-
var
|
|
10931
|
+
import { execFileSync as execFileSync19 } from "child_process";
|
|
10932
|
+
var API_TIMEOUT_MS7 = 3e4;
|
|
10951
10933
|
var VALID_CLASSES3 = /* @__PURE__ */ new Set(["feature", "bug", "spec", "chore"]);
|
|
10952
10934
|
var recordClassification = async (ctx) => {
|
|
10953
10935
|
const issueNumber = ctx.args.issue;
|
|
@@ -10964,7 +10946,7 @@ var recordClassification = async (ctx) => {
|
|
|
10964
10946
|
reason = parsed?.reason ?? null;
|
|
10965
10947
|
}
|
|
10966
10948
|
if (!classification) {
|
|
10967
|
-
ctx.data.action =
|
|
10949
|
+
ctx.data.action = failedAction4("classification missing or invalid");
|
|
10968
10950
|
tryAuditComment(
|
|
10969
10951
|
issueNumber,
|
|
10970
10952
|
"\u26A0\uFE0F kody classifier could not decide \u2014 please re-run with an explicit `@kody <type>`.",
|
|
@@ -10994,9 +10976,9 @@ function parseClassification(prSummary) {
|
|
|
10994
10976
|
}
|
|
10995
10977
|
function tryAuditComment(issueNumber, body, cwd) {
|
|
10996
10978
|
try {
|
|
10997
|
-
|
|
10979
|
+
execFileSync19("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
10998
10980
|
cwd,
|
|
10999
|
-
timeout:
|
|
10981
|
+
timeout: API_TIMEOUT_MS7,
|
|
11000
10982
|
stdio: ["ignore", "pipe", "pipe"]
|
|
11001
10983
|
});
|
|
11002
10984
|
} catch {
|
|
@@ -11005,7 +10987,7 @@ function tryAuditComment(issueNumber, body, cwd) {
|
|
|
11005
10987
|
function makeAction3(type, payload) {
|
|
11006
10988
|
return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
11007
10989
|
}
|
|
11008
|
-
function
|
|
10990
|
+
function failedAction4(reason) {
|
|
11009
10991
|
return { type: "CLASSIFY_FAILED", payload: { reason }, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
11010
10992
|
}
|
|
11011
10993
|
|
|
@@ -11108,7 +11090,7 @@ var resolveArtifacts = async (ctx, profile) => {
|
|
|
11108
11090
|
};
|
|
11109
11091
|
|
|
11110
11092
|
// src/scripts/resolveFlow.ts
|
|
11111
|
-
import { execFileSync as
|
|
11093
|
+
import { execFileSync as execFileSync20 } from "child_process";
|
|
11112
11094
|
init_issue();
|
|
11113
11095
|
var CONFLICT_DIFF_MAX_BYTES = 4e4;
|
|
11114
11096
|
var resolveFlow = async (ctx) => {
|
|
@@ -11202,7 +11184,7 @@ function buildPreferBlock(prefer, baseBranch) {
|
|
|
11202
11184
|
}
|
|
11203
11185
|
function getConflictedFiles(cwd) {
|
|
11204
11186
|
try {
|
|
11205
|
-
const out =
|
|
11187
|
+
const out = execFileSync20("git", ["diff", "--name-only", "--diff-filter=U"], {
|
|
11206
11188
|
encoding: "utf-8",
|
|
11207
11189
|
cwd,
|
|
11208
11190
|
env: { ...process.env, HUSKY: "0" }
|
|
@@ -11217,7 +11199,7 @@ function getConflictMarkersPreview(files, cwd, maxBytes = CONFLICT_DIFF_MAX_BYTE
|
|
|
11217
11199
|
let total = 0;
|
|
11218
11200
|
for (const f of files) {
|
|
11219
11201
|
try {
|
|
11220
|
-
const content =
|
|
11202
|
+
const content = execFileSync20("cat", [f], { encoding: "utf-8", cwd }).toString();
|
|
11221
11203
|
const snippet = `### ${f}
|
|
11222
11204
|
|
|
11223
11205
|
\`\`\`
|
|
@@ -11241,12 +11223,12 @@ function tryPostPr3(prNumber, body, cwd) {
|
|
|
11241
11223
|
function pushEmptyCommit(branch, cwd) {
|
|
11242
11224
|
const env = { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" };
|
|
11243
11225
|
try {
|
|
11244
|
-
|
|
11226
|
+
execFileSync20(
|
|
11245
11227
|
"git",
|
|
11246
11228
|
["commit", "--allow-empty", "-m", "chore: kody resolve refresh \u2014 empty commit to recompute mergeable status"],
|
|
11247
11229
|
{ cwd, env, stdio: ["ignore", "pipe", "pipe"] }
|
|
11248
11230
|
);
|
|
11249
|
-
|
|
11231
|
+
execFileSync20("git", ["push", "-u", "origin", branch], {
|
|
11250
11232
|
cwd,
|
|
11251
11233
|
env,
|
|
11252
11234
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -11377,10 +11359,10 @@ var resolvePreviewUrl = async (ctx) => {
|
|
|
11377
11359
|
};
|
|
11378
11360
|
|
|
11379
11361
|
// src/scripts/resolveQaUrl.ts
|
|
11380
|
-
import { execFileSync as
|
|
11362
|
+
import { execFileSync as execFileSync21 } from "child_process";
|
|
11381
11363
|
function ghQuery(args, cwd) {
|
|
11382
11364
|
try {
|
|
11383
|
-
const out =
|
|
11365
|
+
const out = execFileSync21("gh", args, {
|
|
11384
11366
|
cwd,
|
|
11385
11367
|
stdio: ["ignore", "pipe", "pipe"],
|
|
11386
11368
|
encoding: "utf-8",
|
|
@@ -11450,7 +11432,7 @@ var resolveQaUrl = async (ctx) => {
|
|
|
11450
11432
|
};
|
|
11451
11433
|
|
|
11452
11434
|
// src/scripts/revertFlow.ts
|
|
11453
|
-
import { execFileSync as
|
|
11435
|
+
import { execFileSync as execFileSync22 } from "child_process";
|
|
11454
11436
|
init_issue();
|
|
11455
11437
|
var SHA_RE = /^[0-9a-f]{4,40}$/i;
|
|
11456
11438
|
var revertFlow = async (ctx) => {
|
|
@@ -11533,7 +11515,7 @@ function buildPrSummary(resolved) {
|
|
|
11533
11515
|
return resolved.map((r) => `- Reverted \`${r.full.slice(0, 7)}\`${r.subject ? ` \u2014 ${r.subject}` : ""}`).join("\n");
|
|
11534
11516
|
}
|
|
11535
11517
|
function git4(args, cwd) {
|
|
11536
|
-
return
|
|
11518
|
+
return execFileSync22("git", args, {
|
|
11537
11519
|
encoding: "utf-8",
|
|
11538
11520
|
timeout: 3e4,
|
|
11539
11521
|
cwd,
|
|
@@ -11543,7 +11525,7 @@ function git4(args, cwd) {
|
|
|
11543
11525
|
}
|
|
11544
11526
|
function isAncestorOfHead(sha, cwd) {
|
|
11545
11527
|
try {
|
|
11546
|
-
|
|
11528
|
+
execFileSync22("git", ["merge-base", "--is-ancestor", sha, "HEAD"], {
|
|
11547
11529
|
cwd,
|
|
11548
11530
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
11549
11531
|
stdio: ["ignore", "ignore", "ignore"]
|
|
@@ -12189,11 +12171,11 @@ var skipAgent = async (ctx) => {
|
|
|
12189
12171
|
};
|
|
12190
12172
|
|
|
12191
12173
|
// src/scripts/stageMergeConflicts.ts
|
|
12192
|
-
import { execFileSync as
|
|
12174
|
+
import { execFileSync as execFileSync23 } from "child_process";
|
|
12193
12175
|
var stageMergeConflicts = async (ctx) => {
|
|
12194
12176
|
if (ctx.data.agentDone === false) return;
|
|
12195
12177
|
try {
|
|
12196
|
-
|
|
12178
|
+
execFileSync23("git", ["add", "-A"], {
|
|
12197
12179
|
cwd: ctx.cwd,
|
|
12198
12180
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
12199
12181
|
stdio: "pipe"
|
|
@@ -12204,8 +12186,6 @@ var stageMergeConflicts = async (ctx) => {
|
|
|
12204
12186
|
|
|
12205
12187
|
// src/scripts/startFlow.ts
|
|
12206
12188
|
init_issue();
|
|
12207
|
-
import { execFileSync as execFileSync25 } from "child_process";
|
|
12208
|
-
var API_TIMEOUT_MS9 = 3e4;
|
|
12209
12189
|
var startFlow = async (ctx, profile, _agentResult, args) => {
|
|
12210
12190
|
const entry = args?.entry;
|
|
12211
12191
|
if (!entry) {
|
|
@@ -12232,28 +12212,16 @@ var startFlow = async (ctx, profile, _agentResult, args) => {
|
|
|
12232
12212
|
hops: 0
|
|
12233
12213
|
};
|
|
12234
12214
|
}
|
|
12235
|
-
|
|
12215
|
+
const usePr = target === "pr" && !!state?.core.prUrl;
|
|
12216
|
+
const targetNumber = usePr ? parsePrNumber(state.core.prUrl) ?? issueNumber : issueNumber;
|
|
12217
|
+
ctx.output.nextDispatch = {
|
|
12218
|
+
executable: entry,
|
|
12219
|
+
cliArgs: usePr ? { pr: targetNumber } : { issue: targetNumber }
|
|
12220
|
+
};
|
|
12236
12221
|
};
|
|
12237
|
-
function postKodyComment(target, issueNumber, state, next, cwd) {
|
|
12238
|
-
const targetNumber = target === "pr" && state?.core.prUrl ? parsePrNumber(state.core.prUrl) ?? issueNumber : issueNumber;
|
|
12239
|
-
const sub = target === "pr" && state?.core.prUrl ? "pr" : "issue";
|
|
12240
|
-
const body = `@kody ${next}`;
|
|
12241
|
-
try {
|
|
12242
|
-
execFileSync25("gh", [sub, "comment", String(targetNumber), "--body", body], {
|
|
12243
|
-
timeout: API_TIMEOUT_MS9,
|
|
12244
|
-
cwd,
|
|
12245
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
12246
|
-
});
|
|
12247
|
-
} catch (err) {
|
|
12248
|
-
process.stderr.write(
|
|
12249
|
-
`[kody startFlow] failed to post @kody ${next} on ${sub} #${targetNumber}: ${err instanceof Error ? err.message : String(err)}
|
|
12250
|
-
`
|
|
12251
|
-
);
|
|
12252
|
-
}
|
|
12253
|
-
}
|
|
12254
12222
|
|
|
12255
12223
|
// src/scripts/syncFlow.ts
|
|
12256
|
-
import { execFileSync as
|
|
12224
|
+
import { execFileSync as execFileSync24 } from "child_process";
|
|
12257
12225
|
init_issue();
|
|
12258
12226
|
var DONE2 = {
|
|
12259
12227
|
label: "kody:done",
|
|
@@ -12331,7 +12299,7 @@ function bail2(ctx, prNumber, reason) {
|
|
|
12331
12299
|
}
|
|
12332
12300
|
function revParseHead(cwd) {
|
|
12333
12301
|
try {
|
|
12334
|
-
return
|
|
12302
|
+
return execFileSync24("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
|
|
12335
12303
|
} catch {
|
|
12336
12304
|
return "";
|
|
12337
12305
|
}
|
|
@@ -12588,8 +12556,8 @@ var verifyWithRetry = async (ctx) => {
|
|
|
12588
12556
|
|
|
12589
12557
|
// src/scripts/waitForCi.ts
|
|
12590
12558
|
init_issue();
|
|
12591
|
-
import { execFileSync as
|
|
12592
|
-
var
|
|
12559
|
+
import { execFileSync as execFileSync25 } from "child_process";
|
|
12560
|
+
var API_TIMEOUT_MS8 = 3e4;
|
|
12593
12561
|
var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
12594
12562
|
const timeoutMinutes = numArg(args, "timeoutMinutes", 30);
|
|
12595
12563
|
const pollSeconds = numArg(args, "pollSeconds", 30);
|
|
@@ -12666,9 +12634,9 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
12666
12634
|
};
|
|
12667
12635
|
function fetchChecks(prNumber, cwd) {
|
|
12668
12636
|
try {
|
|
12669
|
-
const raw =
|
|
12637
|
+
const raw = execFileSync25("gh", ["pr", "checks", String(prNumber), "--json", "bucket,state,name,workflow,link"], {
|
|
12670
12638
|
encoding: "utf-8",
|
|
12671
|
-
timeout:
|
|
12639
|
+
timeout: API_TIMEOUT_MS8,
|
|
12672
12640
|
cwd,
|
|
12673
12641
|
stdio: ["ignore", "pipe", "pipe"]
|
|
12674
12642
|
});
|
|
@@ -13142,7 +13110,7 @@ var allScriptNames = /* @__PURE__ */ new Set([
|
|
|
13142
13110
|
]);
|
|
13143
13111
|
|
|
13144
13112
|
// src/tools.ts
|
|
13145
|
-
import { execFileSync as
|
|
13113
|
+
import { execFileSync as execFileSync26 } from "child_process";
|
|
13146
13114
|
function verifyCliTools(tools, cwd) {
|
|
13147
13115
|
const out = [];
|
|
13148
13116
|
for (const t of tools) out.push(verifyOne(t, cwd));
|
|
@@ -13179,7 +13147,7 @@ function verifyOne(tool4, cwd) {
|
|
|
13179
13147
|
}
|
|
13180
13148
|
function runShell(cmd, cwd, timeoutMs = 3e4) {
|
|
13181
13149
|
try {
|
|
13182
|
-
const stdout =
|
|
13150
|
+
const stdout = execFileSync26("sh", ["-c", cmd], {
|
|
13183
13151
|
cwd,
|
|
13184
13152
|
stdio: ["ignore", "pipe", "pipe"],
|
|
13185
13153
|
timeout: timeoutMs,
|
|
@@ -13485,7 +13453,8 @@ async function runExecutable(profileName, input) {
|
|
|
13485
13453
|
return finishAndEnd({
|
|
13486
13454
|
exitCode: ctx.output.exitCode ?? 0,
|
|
13487
13455
|
prUrl: ctx.output.prUrl,
|
|
13488
|
-
reason: ctx.output.reason
|
|
13456
|
+
reason: ctx.output.reason,
|
|
13457
|
+
nextDispatch: ctx.output.nextDispatch
|
|
13489
13458
|
});
|
|
13490
13459
|
} finally {
|
|
13491
13460
|
clearStampedLifecycleLabels(profile, ctx);
|
|
@@ -13968,7 +13937,7 @@ async function runContainerLoop(profile, ctx, input) {
|
|
|
13968
13937
|
}
|
|
13969
13938
|
function resetWorkingTree2(cwd) {
|
|
13970
13939
|
try {
|
|
13971
|
-
|
|
13940
|
+
execFileSync27("git", ["reset", "--hard", "HEAD"], {
|
|
13972
13941
|
cwd,
|
|
13973
13942
|
stdio: ["ignore", "pipe", "pipe"],
|
|
13974
13943
|
timeout: 3e4
|
|
@@ -14154,7 +14123,7 @@ function detectPackageManager2(cwd) {
|
|
|
14154
14123
|
}
|
|
14155
14124
|
function shellOut(cmd, args, cwd, stream = true) {
|
|
14156
14125
|
try {
|
|
14157
|
-
|
|
14126
|
+
execFileSync28(cmd, args, {
|
|
14158
14127
|
cwd,
|
|
14159
14128
|
stdio: stream ? "inherit" : "pipe",
|
|
14160
14129
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", CI: process.env.CI ?? "1" }
|
|
@@ -14167,7 +14136,7 @@ function shellOut(cmd, args, cwd, stream = true) {
|
|
|
14167
14136
|
}
|
|
14168
14137
|
function isOnPath(bin) {
|
|
14169
14138
|
try {
|
|
14170
|
-
|
|
14139
|
+
execFileSync28("which", [bin], { stdio: "pipe" });
|
|
14171
14140
|
return true;
|
|
14172
14141
|
} catch {
|
|
14173
14142
|
return false;
|
|
@@ -14208,7 +14177,7 @@ function installLitellmIfNeeded(cwd) {
|
|
|
14208
14177
|
} catch {
|
|
14209
14178
|
}
|
|
14210
14179
|
try {
|
|
14211
|
-
|
|
14180
|
+
execFileSync28("python3", ["-c", "import litellm"], { stdio: "pipe" });
|
|
14212
14181
|
process.stdout.write("\u2192 kody: litellm already installed\n");
|
|
14213
14182
|
return 0;
|
|
14214
14183
|
} catch {
|
|
@@ -14218,16 +14187,16 @@ function installLitellmIfNeeded(cwd) {
|
|
|
14218
14187
|
}
|
|
14219
14188
|
function configureGitIdentity(cwd) {
|
|
14220
14189
|
try {
|
|
14221
|
-
const name =
|
|
14190
|
+
const name = execFileSync28("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
|
|
14222
14191
|
if (name) return;
|
|
14223
14192
|
} catch {
|
|
14224
14193
|
}
|
|
14225
14194
|
try {
|
|
14226
|
-
|
|
14195
|
+
execFileSync28("git", ["config", "user.name", "github-actions[bot]"], { cwd, stdio: "pipe" });
|
|
14227
14196
|
} catch {
|
|
14228
14197
|
}
|
|
14229
14198
|
try {
|
|
14230
|
-
|
|
14199
|
+
execFileSync28("git", ["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"], {
|
|
14231
14200
|
cwd,
|
|
14232
14201
|
stdio: "pipe"
|
|
14233
14202
|
});
|
|
@@ -14384,13 +14353,33 @@ ${CI_HELP}`);
|
|
|
14384
14353
|
`);
|
|
14385
14354
|
try {
|
|
14386
14355
|
const config = earlyConfig ?? loadConfig(cwd);
|
|
14387
|
-
|
|
14356
|
+
let result = await runExecutable(dispatch2.executable, {
|
|
14388
14357
|
cliArgs: dispatch2.cliArgs,
|
|
14389
14358
|
cwd,
|
|
14390
14359
|
config,
|
|
14391
14360
|
verbose: args.verbose,
|
|
14392
14361
|
quiet: args.quiet
|
|
14393
14362
|
});
|
|
14363
|
+
const MAX_CHAIN_HOPS = 60;
|
|
14364
|
+
for (let hops = 1; result.nextDispatch && hops <= MAX_CHAIN_HOPS; hops++) {
|
|
14365
|
+
const next = result.nextDispatch;
|
|
14366
|
+
process.stdout.write(`\u2192 kody: in-process hand-off \u2192 ${next.executable} (hop ${hops}/${MAX_CHAIN_HOPS})
|
|
14367
|
+
|
|
14368
|
+
`);
|
|
14369
|
+
result = await runExecutable(next.executable, {
|
|
14370
|
+
cliArgs: next.cliArgs,
|
|
14371
|
+
cwd,
|
|
14372
|
+
config,
|
|
14373
|
+
verbose: args.verbose,
|
|
14374
|
+
quiet: args.quiet
|
|
14375
|
+
});
|
|
14376
|
+
}
|
|
14377
|
+
if (result.nextDispatch) {
|
|
14378
|
+
process.stderr.write(
|
|
14379
|
+
`[kody] in-process hand-off cap (${MAX_CHAIN_HOPS}) reached; not running ${result.nextDispatch.executable}
|
|
14380
|
+
`
|
|
14381
|
+
);
|
|
14382
|
+
}
|
|
14394
14383
|
if (result.exitCode !== 0 && result.exitCode !== 1 && result.exitCode !== 2) {
|
|
14395
14384
|
postFailureTail(issueNumber, cwd, result.reason || `exit ${result.exitCode}`);
|
|
14396
14385
|
}
|
|
@@ -14547,8 +14536,8 @@ function commitChatFiles(cwd, sessionId, verbose) {
|
|
|
14547
14536
|
if (paths.length === 0) return;
|
|
14548
14537
|
const opts = { cwd, stdio: verbose ? "inherit" : "pipe" };
|
|
14549
14538
|
try {
|
|
14550
|
-
|
|
14551
|
-
|
|
14539
|
+
execFileSync29("git", ["add", "-f", ...paths], opts);
|
|
14540
|
+
execFileSync29("git", ["commit", "--quiet", "-m", `chat: reply for ${sessionId}`], opts);
|
|
14552
14541
|
} catch (err) {
|
|
14553
14542
|
const msg = err instanceof Error ? err.message : String(err);
|
|
14554
14543
|
process.stderr.write(`[kody:chat] commit skipped: ${msg}
|
|
@@ -347,6 +347,14 @@ export interface Context {
|
|
|
347
347
|
exitCode: number
|
|
348
348
|
prUrl?: string
|
|
349
349
|
reason?: string
|
|
350
|
+
/**
|
|
351
|
+
* In-process hand-off to the next stage. A stage (e.g. `classify`) sets
|
|
352
|
+
* this so the orchestrator runs the chosen sub-orchestrator
|
|
353
|
+
* (feature/bug/spec/chore) in the same process — instead of posting an
|
|
354
|
+
* `@kody <next>` comment, which is silently ignored when Kody comments as
|
|
355
|
+
* a GitHub App (bot author), stalling the pipeline at classify.
|
|
356
|
+
*/
|
|
357
|
+
nextDispatch?: { executable: string; cliArgs: Record<string, unknown> }
|
|
350
358
|
}
|
|
351
359
|
/**
|
|
352
360
|
* If a preflight script sets this to true, the executor skips the agent
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.161",
|
|
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",
|