@kody-ade/kody-engine 0.4.153 → 0.4.155
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 +135 -110
- package/dist/executables/release-publish/publish.sh +44 -17
- 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.155",
|
|
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 execFileSync31 } from "child_process";
|
|
1121
1121
|
import * as fs42 from "fs";
|
|
1122
1122
|
import * as path38 from "path";
|
|
1123
1123
|
|
|
@@ -1376,7 +1376,7 @@ function loadConfig(projectDir = process.cwd()) {
|
|
|
1376
1376
|
throw new Error(`kody.config.json is invalid JSON: ${msg}`);
|
|
1377
1377
|
}
|
|
1378
1378
|
const quality = raw.quality ?? {};
|
|
1379
|
-
const
|
|
1379
|
+
const git5 = raw.git ?? {};
|
|
1380
1380
|
const github = raw.github ?? {};
|
|
1381
1381
|
const agent = raw.agent ?? {};
|
|
1382
1382
|
if (!agent.model || typeof agent.model !== "string") {
|
|
@@ -1393,7 +1393,7 @@ function loadConfig(projectDir = process.cwd()) {
|
|
|
1393
1393
|
testUnit: typeof quality.testUnit === "string" ? quality.testUnit : ""
|
|
1394
1394
|
},
|
|
1395
1395
|
git: {
|
|
1396
|
-
defaultBranch: typeof
|
|
1396
|
+
defaultBranch: typeof git5.defaultBranch === "string" ? git5.defaultBranch : "main"
|
|
1397
1397
|
},
|
|
1398
1398
|
github: {
|
|
1399
1399
|
owner: String(github.owner),
|
|
@@ -2755,7 +2755,7 @@ async function emit2(sink, type, sessionId, suffix, payload) {
|
|
|
2755
2755
|
}
|
|
2756
2756
|
|
|
2757
2757
|
// src/kody-cli.ts
|
|
2758
|
-
import { execFileSync as
|
|
2758
|
+
import { execFileSync as execFileSync30 } from "child_process";
|
|
2759
2759
|
import * as fs41 from "fs";
|
|
2760
2760
|
import * as path37 from "path";
|
|
2761
2761
|
|
|
@@ -3156,7 +3156,7 @@ function coerceBare(spec, value) {
|
|
|
3156
3156
|
}
|
|
3157
3157
|
|
|
3158
3158
|
// src/executor.ts
|
|
3159
|
-
import { execFileSync as
|
|
3159
|
+
import { execFileSync as execFileSync29, spawn as spawn9 } from "child_process";
|
|
3160
3160
|
import * as fs40 from "fs";
|
|
3161
3161
|
import * as path36 from "path";
|
|
3162
3162
|
|
|
@@ -7529,6 +7529,7 @@ var dispatchNextTask = async (ctx) => {
|
|
|
7529
7529
|
|
|
7530
7530
|
// src/pr.ts
|
|
7531
7531
|
init_issue();
|
|
7532
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
7532
7533
|
function prMergeStatus(prNumber, cwd) {
|
|
7533
7534
|
try {
|
|
7534
7535
|
const out = gh(
|
|
@@ -7648,6 +7649,51 @@ function recoverSourceIssueNumber(existingBody, branch, prNumber) {
|
|
|
7648
7649
|
}
|
|
7649
7650
|
return null;
|
|
7650
7651
|
}
|
|
7652
|
+
var ALREADY_EXISTS_RE = /pull request .*already exists|already exists for/i;
|
|
7653
|
+
function isAlreadyExistsError(err) {
|
|
7654
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
7655
|
+
return ALREADY_EXISTS_RE.test(msg);
|
|
7656
|
+
}
|
|
7657
|
+
function git2(args, cwd) {
|
|
7658
|
+
return execFileSync13("git", args, {
|
|
7659
|
+
encoding: "utf-8",
|
|
7660
|
+
timeout: 3e4,
|
|
7661
|
+
cwd,
|
|
7662
|
+
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
7663
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
7664
|
+
}).trim();
|
|
7665
|
+
}
|
|
7666
|
+
function updateExistingPr(existing, body, draft, cwd) {
|
|
7667
|
+
const stripped = existing.url.replace(/^https:\/\/github\.com\//, "");
|
|
7668
|
+
const [owner, repo] = stripped.split("/");
|
|
7669
|
+
try {
|
|
7670
|
+
gh(["api", "--method", "PATCH", `repos/${owner}/${repo}/pulls/${existing.number}`, "-f", `body=${body}`], { cwd });
|
|
7671
|
+
} catch (err) {
|
|
7672
|
+
throw new Error(`gh api PATCH #${existing.number} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
7673
|
+
}
|
|
7674
|
+
return { url: existing.url, number: existing.number, draft, action: "updated" };
|
|
7675
|
+
}
|
|
7676
|
+
function createPr(branch, base, title, body, draft, cwd) {
|
|
7677
|
+
const args = ["pr", "create", "--head", branch, "--base", base, "--title", title, "--body-file", "-"];
|
|
7678
|
+
if (draft) args.push("--draft");
|
|
7679
|
+
const url = gh(args, { input: body, cwd }).trim();
|
|
7680
|
+
const match = url.match(/\/pull\/(\d+)$/);
|
|
7681
|
+
const number = match ? parseInt(match[1], 10) : 0;
|
|
7682
|
+
return { url, number, draft, action: "created" };
|
|
7683
|
+
}
|
|
7684
|
+
function recoverFromExistingPr(branch, base, title, body, draft, cwd) {
|
|
7685
|
+
const raced = findExistingPr(branch, cwd);
|
|
7686
|
+
if (raced) return updateExistingPr(raced, body, draft, cwd);
|
|
7687
|
+
try {
|
|
7688
|
+
git2(["push", "origin", "--delete", branch], cwd);
|
|
7689
|
+
} catch {
|
|
7690
|
+
}
|
|
7691
|
+
const push = pushWithRetry({ cwd, branch, setUpstream: true });
|
|
7692
|
+
if (!push.ok) {
|
|
7693
|
+
throw new Error(`re-push after deleting orphaned branch '${branch}' failed: ${push.reason}`);
|
|
7694
|
+
}
|
|
7695
|
+
return createPr(branch, base, title, body, draft, cwd);
|
|
7696
|
+
}
|
|
7651
7697
|
function ensurePr(opts) {
|
|
7652
7698
|
const existing = findExistingPr(opts.branch, opts.cwd);
|
|
7653
7699
|
const effectiveIssueNumber = existing ? recoverSourceIssueNumber(existing.body, opts.branch, existing.number) ?? opts.issueNumber : opts.issueNumber;
|
|
@@ -7655,36 +7701,15 @@ function ensurePr(opts) {
|
|
|
7655
7701
|
const title = buildPrTitle(effectiveOpts.issueNumber, effectiveOpts.issueTitle, effectiveOpts.draft);
|
|
7656
7702
|
const body = buildPrBody(effectiveOpts);
|
|
7657
7703
|
if (existing) {
|
|
7658
|
-
|
|
7659
|
-
const [owner, repo] = stripped.split("/");
|
|
7660
|
-
try {
|
|
7661
|
-
gh(["api", "--method", "PATCH", `repos/${owner}/${repo}/pulls/${existing.number}`, "-f", `body=${body}`], {
|
|
7662
|
-
cwd: opts.cwd
|
|
7663
|
-
});
|
|
7664
|
-
} catch (err) {
|
|
7665
|
-
throw new Error(`gh api PATCH #${existing.number} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
7666
|
-
}
|
|
7667
|
-
return { url: existing.url, number: existing.number, draft: opts.draft, action: "updated" };
|
|
7704
|
+
return updateExistingPr(existing, body, opts.draft, opts.cwd);
|
|
7668
7705
|
}
|
|
7669
7706
|
const base = opts.baseBranch && opts.baseBranch.length > 0 ? opts.baseBranch : opts.defaultBranch;
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
opts.branch,
|
|
7675
|
-
|
|
7676
|
-
base,
|
|
7677
|
-
"--title",
|
|
7678
|
-
title,
|
|
7679
|
-
"--body-file",
|
|
7680
|
-
"-"
|
|
7681
|
-
];
|
|
7682
|
-
if (opts.draft) args.push("--draft");
|
|
7683
|
-
const output = gh(args, { input: body, cwd: opts.cwd });
|
|
7684
|
-
const url = output.trim();
|
|
7685
|
-
const match = url.match(/\/pull\/(\d+)$/);
|
|
7686
|
-
const number = match ? parseInt(match[1], 10) : 0;
|
|
7687
|
-
return { url, number, draft: opts.draft, action: "created" };
|
|
7707
|
+
try {
|
|
7708
|
+
return createPr(opts.branch, base, title, body, opts.draft, opts.cwd);
|
|
7709
|
+
} catch (err) {
|
|
7710
|
+
if (!isAlreadyExistsError(err)) throw err;
|
|
7711
|
+
return recoverFromExistingPr(opts.branch, base, title, body, opts.draft, opts.cwd);
|
|
7712
|
+
}
|
|
7688
7713
|
}
|
|
7689
7714
|
|
|
7690
7715
|
// src/scripts/ensurePr.ts
|
|
@@ -7961,7 +7986,7 @@ var finalizeTerminal = async (ctx) => {
|
|
|
7961
7986
|
|
|
7962
7987
|
// src/scripts/finishFlow.ts
|
|
7963
7988
|
init_issue();
|
|
7964
|
-
import { execFileSync as
|
|
7989
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
7965
7990
|
var TERMINAL_PHASE = {
|
|
7966
7991
|
"review-passed": { phase: "shipped", status: "succeeded" },
|
|
7967
7992
|
"fix-applied": { phase: "shipped", status: "succeeded" },
|
|
@@ -8001,7 +8026,7 @@ var finishFlow = async (ctx, profile, _agentResult, args) => {
|
|
|
8001
8026
|
**PR:** ${state.core.prUrl}` : "";
|
|
8002
8027
|
const body = `${icon} kody flow \`${flowName}\` finished \u2014 \`${reason}\`${prSuffix}`;
|
|
8003
8028
|
try {
|
|
8004
|
-
|
|
8029
|
+
execFileSync14("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
8005
8030
|
timeout: API_TIMEOUT_MS6,
|
|
8006
8031
|
cwd: ctx.cwd,
|
|
8007
8032
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -8031,9 +8056,9 @@ var finishFlow = async (ctx, profile, _agentResult, args) => {
|
|
|
8031
8056
|
};
|
|
8032
8057
|
|
|
8033
8058
|
// src/branch.ts
|
|
8034
|
-
import { execFileSync as
|
|
8035
|
-
function
|
|
8036
|
-
return
|
|
8059
|
+
import { execFileSync as execFileSync15 } from "child_process";
|
|
8060
|
+
function git3(args, cwd) {
|
|
8061
|
+
return execFileSync15("git", args, {
|
|
8037
8062
|
encoding: "utf-8",
|
|
8038
8063
|
timeout: 3e4,
|
|
8039
8064
|
cwd,
|
|
@@ -8046,15 +8071,15 @@ function deriveBranchName(issueNumber, title) {
|
|
|
8046
8071
|
return slug ? `${issueNumber}-${slug}` : `${issueNumber}-task`;
|
|
8047
8072
|
}
|
|
8048
8073
|
function getCurrentBranch(cwd) {
|
|
8049
|
-
return
|
|
8074
|
+
return git3(["branch", "--show-current"], cwd);
|
|
8050
8075
|
}
|
|
8051
8076
|
function resetWorkingTree(cwd) {
|
|
8052
8077
|
try {
|
|
8053
|
-
|
|
8078
|
+
execFileSync15("git", ["reset", "--hard", "HEAD"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
8054
8079
|
} catch {
|
|
8055
8080
|
}
|
|
8056
8081
|
try {
|
|
8057
|
-
|
|
8082
|
+
execFileSync15("git", ["clean", "-fd"], { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
8058
8083
|
} catch {
|
|
8059
8084
|
}
|
|
8060
8085
|
}
|
|
@@ -8066,14 +8091,14 @@ function checkoutPrBranch(prNumber, cwd) {
|
|
|
8066
8091
|
GH_TOKEN: process.env.GH_PAT?.trim() || process.env.GH_TOKEN || ""
|
|
8067
8092
|
};
|
|
8068
8093
|
try {
|
|
8069
|
-
|
|
8094
|
+
execFileSync15("git", ["reset", "--hard", "HEAD"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
8070
8095
|
} catch {
|
|
8071
8096
|
}
|
|
8072
8097
|
try {
|
|
8073
|
-
|
|
8098
|
+
execFileSync15("git", ["clean", "-fd"], { cwd, env, stdio: ["ignore", "pipe", "pipe"], timeout: 3e4 });
|
|
8074
8099
|
} catch {
|
|
8075
8100
|
}
|
|
8076
|
-
|
|
8101
|
+
execFileSync15("gh", ["pr", "checkout", String(prNumber)], {
|
|
8077
8102
|
cwd,
|
|
8078
8103
|
env,
|
|
8079
8104
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -8083,21 +8108,21 @@ function checkoutPrBranch(prNumber, cwd) {
|
|
|
8083
8108
|
}
|
|
8084
8109
|
function mergeBase(baseBranch, cwd) {
|
|
8085
8110
|
try {
|
|
8086
|
-
|
|
8111
|
+
git3(["fetch", "origin", baseBranch], cwd);
|
|
8087
8112
|
} catch {
|
|
8088
8113
|
return "error";
|
|
8089
8114
|
}
|
|
8090
8115
|
try {
|
|
8091
|
-
|
|
8116
|
+
git3(["merge", `origin/${baseBranch}`, "--no-edit", "--no-ff"], cwd);
|
|
8092
8117
|
return "clean";
|
|
8093
8118
|
} catch {
|
|
8094
8119
|
try {
|
|
8095
|
-
const unmerged =
|
|
8120
|
+
const unmerged = git3(["diff", "--name-only", "--diff-filter=U"], cwd);
|
|
8096
8121
|
if (unmerged.length > 0) return "conflict";
|
|
8097
8122
|
} catch {
|
|
8098
8123
|
}
|
|
8099
8124
|
try {
|
|
8100
|
-
|
|
8125
|
+
git3(["merge", "--abort"], cwd);
|
|
8101
8126
|
} catch {
|
|
8102
8127
|
}
|
|
8103
8128
|
return "error";
|
|
@@ -8111,26 +8136,26 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
|
|
|
8111
8136
|
return { branch: branchName, created: false };
|
|
8112
8137
|
}
|
|
8113
8138
|
try {
|
|
8114
|
-
|
|
8139
|
+
git3(["fetch", "origin"], cwd);
|
|
8115
8140
|
} catch {
|
|
8116
8141
|
}
|
|
8117
8142
|
let originBranchExists = false;
|
|
8118
8143
|
try {
|
|
8119
|
-
|
|
8144
|
+
git3(["rev-parse", "--verify", "--quiet", `refs/remotes/origin/${branchName}`], cwd);
|
|
8120
8145
|
originBranchExists = true;
|
|
8121
8146
|
} catch {
|
|
8122
8147
|
}
|
|
8123
8148
|
if (originBranchExists && baseBranch && baseBranch !== defaultBranch2) {
|
|
8124
8149
|
let baseExists = false;
|
|
8125
8150
|
try {
|
|
8126
|
-
|
|
8151
|
+
git3(["rev-parse", "--verify", `origin/${baseBranch}`], cwd);
|
|
8127
8152
|
baseExists = true;
|
|
8128
8153
|
} catch {
|
|
8129
8154
|
}
|
|
8130
8155
|
if (baseExists) {
|
|
8131
8156
|
let descendsFromBase = false;
|
|
8132
8157
|
try {
|
|
8133
|
-
|
|
8158
|
+
git3(["merge-base", "--is-ancestor", `origin/${baseBranch}`, `origin/${branchName}`], cwd);
|
|
8134
8159
|
descendsFromBase = true;
|
|
8135
8160
|
} catch {
|
|
8136
8161
|
}
|
|
@@ -8140,15 +8165,15 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
|
|
|
8140
8165
|
`
|
|
8141
8166
|
);
|
|
8142
8167
|
try {
|
|
8143
|
-
|
|
8168
|
+
git3(["push", "origin", "--delete", branchName], cwd);
|
|
8144
8169
|
} catch {
|
|
8145
8170
|
}
|
|
8146
8171
|
try {
|
|
8147
|
-
|
|
8172
|
+
git3(["update-ref", "-d", `refs/remotes/origin/${branchName}`], cwd);
|
|
8148
8173
|
} catch {
|
|
8149
8174
|
}
|
|
8150
8175
|
try {
|
|
8151
|
-
|
|
8176
|
+
git3(["branch", "-D", branchName], cwd);
|
|
8152
8177
|
} catch {
|
|
8153
8178
|
}
|
|
8154
8179
|
originBranchExists = false;
|
|
@@ -8156,17 +8181,17 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
|
|
|
8156
8181
|
}
|
|
8157
8182
|
}
|
|
8158
8183
|
if (originBranchExists) {
|
|
8159
|
-
|
|
8184
|
+
git3(["checkout", branchName], cwd);
|
|
8160
8185
|
try {
|
|
8161
|
-
|
|
8186
|
+
git3(["pull", "origin", branchName], cwd);
|
|
8162
8187
|
} catch {
|
|
8163
8188
|
}
|
|
8164
8189
|
if (!baseBranch || baseBranch === defaultBranch2) {
|
|
8165
8190
|
try {
|
|
8166
|
-
|
|
8191
|
+
git3(["merge", "--no-edit", `origin/${defaultBranch2}`], cwd);
|
|
8167
8192
|
} catch {
|
|
8168
8193
|
try {
|
|
8169
|
-
|
|
8194
|
+
git3(["merge", "--abort"], cwd);
|
|
8170
8195
|
} catch {
|
|
8171
8196
|
}
|
|
8172
8197
|
throw new Error(
|
|
@@ -8177,29 +8202,29 @@ function ensureFeatureBranch(issueNumber, title, defaultBranch2, cwd, baseBranch
|
|
|
8177
8202
|
return { branch: branchName, created: false };
|
|
8178
8203
|
}
|
|
8179
8204
|
try {
|
|
8180
|
-
|
|
8181
|
-
|
|
8205
|
+
git3(["rev-parse", "--verify", "--quiet", `refs/heads/${branchName}`], cwd);
|
|
8206
|
+
git3(["checkout", branchName], cwd);
|
|
8182
8207
|
return { branch: branchName, created: false };
|
|
8183
8208
|
} catch {
|
|
8184
8209
|
}
|
|
8185
8210
|
let forkPoint = defaultBranch2;
|
|
8186
8211
|
if (baseBranch && baseBranch !== defaultBranch2) {
|
|
8187
8212
|
try {
|
|
8188
|
-
|
|
8213
|
+
git3(["rev-parse", "--verify", `origin/${baseBranch}`], cwd);
|
|
8189
8214
|
forkPoint = baseBranch;
|
|
8190
8215
|
} catch {
|
|
8191
8216
|
}
|
|
8192
8217
|
}
|
|
8193
8218
|
try {
|
|
8194
|
-
|
|
8219
|
+
git3(["checkout", "-b", branchName, `origin/${forkPoint}`], cwd);
|
|
8195
8220
|
} catch {
|
|
8196
|
-
|
|
8221
|
+
git3(["checkout", "-b", branchName], cwd);
|
|
8197
8222
|
}
|
|
8198
8223
|
return { branch: branchName, created: true };
|
|
8199
8224
|
}
|
|
8200
8225
|
|
|
8201
8226
|
// src/gha.ts
|
|
8202
|
-
import { execFileSync as
|
|
8227
|
+
import { execFileSync as execFileSync16 } from "child_process";
|
|
8203
8228
|
import * as fs29 from "fs";
|
|
8204
8229
|
function getRunUrl() {
|
|
8205
8230
|
const server = process.env.GITHUB_SERVER_URL;
|
|
@@ -8242,7 +8267,7 @@ function reactToTriggerComment(cwd) {
|
|
|
8242
8267
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
8243
8268
|
if (attempt > 0) sleepMs(attempt === 1 ? 500 : 1500);
|
|
8244
8269
|
try {
|
|
8245
|
-
|
|
8270
|
+
execFileSync16("gh", args, opts);
|
|
8246
8271
|
return;
|
|
8247
8272
|
} catch (err) {
|
|
8248
8273
|
lastErr = err;
|
|
@@ -8255,7 +8280,7 @@ function reactToTriggerComment(cwd) {
|
|
|
8255
8280
|
}
|
|
8256
8281
|
function sleepMs(ms) {
|
|
8257
8282
|
try {
|
|
8258
|
-
|
|
8283
|
+
execFileSync16("sleep", [(ms / 1e3).toString()], { stdio: "ignore", timeout: ms + 1e3 });
|
|
8259
8284
|
} catch {
|
|
8260
8285
|
}
|
|
8261
8286
|
}
|
|
@@ -8264,7 +8289,7 @@ function sleepMs(ms) {
|
|
|
8264
8289
|
init_issue();
|
|
8265
8290
|
|
|
8266
8291
|
// src/workflow.ts
|
|
8267
|
-
import { execFileSync as
|
|
8292
|
+
import { execFileSync as execFileSync17 } from "child_process";
|
|
8268
8293
|
var GH_TIMEOUT_MS = 3e4;
|
|
8269
8294
|
function ghToken3() {
|
|
8270
8295
|
return process.env.GH_PAT?.trim() || process.env.GH_TOKEN;
|
|
@@ -8272,7 +8297,7 @@ function ghToken3() {
|
|
|
8272
8297
|
function gh3(args, cwd) {
|
|
8273
8298
|
const token = ghToken3();
|
|
8274
8299
|
const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
|
|
8275
|
-
return
|
|
8300
|
+
return execFileSync17("gh", args, {
|
|
8276
8301
|
encoding: "utf-8",
|
|
8277
8302
|
timeout: GH_TIMEOUT_MS,
|
|
8278
8303
|
cwd,
|
|
@@ -8507,7 +8532,7 @@ var handleAbandonedGoal = async (ctx) => {
|
|
|
8507
8532
|
};
|
|
8508
8533
|
|
|
8509
8534
|
// src/scripts/initFlow.ts
|
|
8510
|
-
import { execFileSync as
|
|
8535
|
+
import { execFileSync as execFileSync18 } from "child_process";
|
|
8511
8536
|
import * as fs30 from "fs";
|
|
8512
8537
|
import * as path28 from "path";
|
|
8513
8538
|
function detectPackageManager(cwd) {
|
|
@@ -8533,7 +8558,7 @@ function schemaUrlFromPkg() {
|
|
|
8533
8558
|
function detectOwnerRepo(cwd) {
|
|
8534
8559
|
let url;
|
|
8535
8560
|
try {
|
|
8536
|
-
url =
|
|
8561
|
+
url = execFileSync18("git", ["remote", "get-url", "origin"], {
|
|
8537
8562
|
cwd,
|
|
8538
8563
|
encoding: "utf-8",
|
|
8539
8564
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -8618,7 +8643,7 @@ jobs:
|
|
|
8618
8643
|
`;
|
|
8619
8644
|
function defaultBranchFromGit(cwd) {
|
|
8620
8645
|
try {
|
|
8621
|
-
const ref =
|
|
8646
|
+
const ref = execFileSync18("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], {
|
|
8622
8647
|
cwd,
|
|
8623
8648
|
encoding: "utf-8",
|
|
8624
8649
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -8626,7 +8651,7 @@ function defaultBranchFromGit(cwd) {
|
|
|
8626
8651
|
return ref.replace("refs/remotes/origin/", "");
|
|
8627
8652
|
} catch {
|
|
8628
8653
|
try {
|
|
8629
|
-
return
|
|
8654
|
+
return execFileSync18("git", ["branch", "--show-current"], {
|
|
8630
8655
|
cwd,
|
|
8631
8656
|
encoding: "utf-8",
|
|
8632
8657
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -9316,7 +9341,7 @@ var mergeFlow = async (ctx) => {
|
|
|
9316
9341
|
};
|
|
9317
9342
|
|
|
9318
9343
|
// src/scripts/mergeReleasePr.ts
|
|
9319
|
-
import { execFileSync as
|
|
9344
|
+
import { execFileSync as execFileSync19 } from "child_process";
|
|
9320
9345
|
var API_TIMEOUT_MS7 = 6e4;
|
|
9321
9346
|
var mergeReleasePr = async (ctx) => {
|
|
9322
9347
|
const state = ctx.data.taskState;
|
|
@@ -9335,7 +9360,7 @@ var mergeReleasePr = async (ctx) => {
|
|
|
9335
9360
|
process.stderr.write(`[kody mergeReleasePr] merging PR #${prNumber} (${prUrl})
|
|
9336
9361
|
`);
|
|
9337
9362
|
try {
|
|
9338
|
-
const out =
|
|
9363
|
+
const out = execFileSync19("gh", ["pr", "merge", String(prNumber), "--merge"], {
|
|
9339
9364
|
timeout: API_TIMEOUT_MS7,
|
|
9340
9365
|
cwd: ctx.cwd,
|
|
9341
9366
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -10817,7 +10842,7 @@ ${body}`;
|
|
|
10817
10842
|
}
|
|
10818
10843
|
|
|
10819
10844
|
// src/scripts/recordClassification.ts
|
|
10820
|
-
import { execFileSync as
|
|
10845
|
+
import { execFileSync as execFileSync20 } from "child_process";
|
|
10821
10846
|
var API_TIMEOUT_MS8 = 3e4;
|
|
10822
10847
|
var VALID_CLASSES3 = /* @__PURE__ */ new Set(["feature", "bug", "spec", "chore"]);
|
|
10823
10848
|
var recordClassification = async (ctx) => {
|
|
@@ -10865,7 +10890,7 @@ function parseClassification(prSummary) {
|
|
|
10865
10890
|
}
|
|
10866
10891
|
function tryAuditComment(issueNumber, body, cwd) {
|
|
10867
10892
|
try {
|
|
10868
|
-
|
|
10893
|
+
execFileSync20("gh", ["issue", "comment", String(issueNumber), "--body", body], {
|
|
10869
10894
|
cwd,
|
|
10870
10895
|
timeout: API_TIMEOUT_MS8,
|
|
10871
10896
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -10979,7 +11004,7 @@ var resolveArtifacts = async (ctx, profile) => {
|
|
|
10979
11004
|
};
|
|
10980
11005
|
|
|
10981
11006
|
// src/scripts/resolveFlow.ts
|
|
10982
|
-
import { execFileSync as
|
|
11007
|
+
import { execFileSync as execFileSync21 } from "child_process";
|
|
10983
11008
|
init_issue();
|
|
10984
11009
|
var CONFLICT_DIFF_MAX_BYTES = 4e4;
|
|
10985
11010
|
var resolveFlow = async (ctx) => {
|
|
@@ -11073,7 +11098,7 @@ function buildPreferBlock(prefer, baseBranch) {
|
|
|
11073
11098
|
}
|
|
11074
11099
|
function getConflictedFiles(cwd) {
|
|
11075
11100
|
try {
|
|
11076
|
-
const out =
|
|
11101
|
+
const out = execFileSync21("git", ["diff", "--name-only", "--diff-filter=U"], {
|
|
11077
11102
|
encoding: "utf-8",
|
|
11078
11103
|
cwd,
|
|
11079
11104
|
env: { ...process.env, HUSKY: "0" }
|
|
@@ -11088,7 +11113,7 @@ function getConflictMarkersPreview(files, cwd, maxBytes = CONFLICT_DIFF_MAX_BYTE
|
|
|
11088
11113
|
let total = 0;
|
|
11089
11114
|
for (const f of files) {
|
|
11090
11115
|
try {
|
|
11091
|
-
const content =
|
|
11116
|
+
const content = execFileSync21("cat", [f], { encoding: "utf-8", cwd }).toString();
|
|
11092
11117
|
const snippet = `### ${f}
|
|
11093
11118
|
|
|
11094
11119
|
\`\`\`
|
|
@@ -11112,12 +11137,12 @@ function tryPostPr3(prNumber, body, cwd) {
|
|
|
11112
11137
|
function pushEmptyCommit(branch, cwd) {
|
|
11113
11138
|
const env = { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" };
|
|
11114
11139
|
try {
|
|
11115
|
-
|
|
11140
|
+
execFileSync21(
|
|
11116
11141
|
"git",
|
|
11117
11142
|
["commit", "--allow-empty", "-m", "chore: kody resolve refresh \u2014 empty commit to recompute mergeable status"],
|
|
11118
11143
|
{ cwd, env, stdio: ["ignore", "pipe", "pipe"] }
|
|
11119
11144
|
);
|
|
11120
|
-
|
|
11145
|
+
execFileSync21("git", ["push", "-u", "origin", branch], {
|
|
11121
11146
|
cwd,
|
|
11122
11147
|
env,
|
|
11123
11148
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -11248,10 +11273,10 @@ var resolvePreviewUrl = async (ctx) => {
|
|
|
11248
11273
|
};
|
|
11249
11274
|
|
|
11250
11275
|
// src/scripts/resolveQaUrl.ts
|
|
11251
|
-
import { execFileSync as
|
|
11276
|
+
import { execFileSync as execFileSync22 } from "child_process";
|
|
11252
11277
|
function ghQuery(args, cwd) {
|
|
11253
11278
|
try {
|
|
11254
|
-
const out =
|
|
11279
|
+
const out = execFileSync22("gh", args, {
|
|
11255
11280
|
cwd,
|
|
11256
11281
|
stdio: ["ignore", "pipe", "pipe"],
|
|
11257
11282
|
encoding: "utf-8",
|
|
@@ -11321,7 +11346,7 @@ var resolveQaUrl = async (ctx) => {
|
|
|
11321
11346
|
};
|
|
11322
11347
|
|
|
11323
11348
|
// src/scripts/revertFlow.ts
|
|
11324
|
-
import { execFileSync as
|
|
11349
|
+
import { execFileSync as execFileSync23 } from "child_process";
|
|
11325
11350
|
init_issue();
|
|
11326
11351
|
var SHA_RE = /^[0-9a-f]{4,40}$/i;
|
|
11327
11352
|
var revertFlow = async (ctx) => {
|
|
@@ -11360,7 +11385,7 @@ var revertFlow = async (ctx) => {
|
|
|
11360
11385
|
for (const s of requested) {
|
|
11361
11386
|
let full;
|
|
11362
11387
|
try {
|
|
11363
|
-
full =
|
|
11388
|
+
full = git4(["rev-parse", "--verify", `${s}^{commit}`], ctx.cwd);
|
|
11364
11389
|
} catch {
|
|
11365
11390
|
unreachable.push(s);
|
|
11366
11391
|
continue;
|
|
@@ -11371,7 +11396,7 @@ var revertFlow = async (ctx) => {
|
|
|
11371
11396
|
}
|
|
11372
11397
|
let subject = "";
|
|
11373
11398
|
try {
|
|
11374
|
-
subject =
|
|
11399
|
+
subject = git4(["log", "-1", "--format=%s", full], ctx.cwd);
|
|
11375
11400
|
} catch {
|
|
11376
11401
|
}
|
|
11377
11402
|
resolved.push({ input: s, full, subject });
|
|
@@ -11403,8 +11428,8 @@ function buildCommitMessage(resolved) {
|
|
|
11403
11428
|
function buildPrSummary(resolved) {
|
|
11404
11429
|
return resolved.map((r) => `- Reverted \`${r.full.slice(0, 7)}\`${r.subject ? ` \u2014 ${r.subject}` : ""}`).join("\n");
|
|
11405
11430
|
}
|
|
11406
|
-
function
|
|
11407
|
-
return
|
|
11431
|
+
function git4(args, cwd) {
|
|
11432
|
+
return execFileSync23("git", args, {
|
|
11408
11433
|
encoding: "utf-8",
|
|
11409
11434
|
timeout: 3e4,
|
|
11410
11435
|
cwd,
|
|
@@ -11414,7 +11439,7 @@ function git3(args, cwd) {
|
|
|
11414
11439
|
}
|
|
11415
11440
|
function isAncestorOfHead(sha, cwd) {
|
|
11416
11441
|
try {
|
|
11417
|
-
|
|
11442
|
+
execFileSync23("git", ["merge-base", "--is-ancestor", sha, "HEAD"], {
|
|
11418
11443
|
cwd,
|
|
11419
11444
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
11420
11445
|
stdio: ["ignore", "ignore", "ignore"]
|
|
@@ -12060,11 +12085,11 @@ var skipAgent = async (ctx) => {
|
|
|
12060
12085
|
};
|
|
12061
12086
|
|
|
12062
12087
|
// src/scripts/stageMergeConflicts.ts
|
|
12063
|
-
import { execFileSync as
|
|
12088
|
+
import { execFileSync as execFileSync24 } from "child_process";
|
|
12064
12089
|
var stageMergeConflicts = async (ctx) => {
|
|
12065
12090
|
if (ctx.data.agentDone === false) return;
|
|
12066
12091
|
try {
|
|
12067
|
-
|
|
12092
|
+
execFileSync24("git", ["add", "-A"], {
|
|
12068
12093
|
cwd: ctx.cwd,
|
|
12069
12094
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1" },
|
|
12070
12095
|
stdio: "pipe"
|
|
@@ -12075,7 +12100,7 @@ var stageMergeConflicts = async (ctx) => {
|
|
|
12075
12100
|
|
|
12076
12101
|
// src/scripts/startFlow.ts
|
|
12077
12102
|
init_issue();
|
|
12078
|
-
import { execFileSync as
|
|
12103
|
+
import { execFileSync as execFileSync25 } from "child_process";
|
|
12079
12104
|
var API_TIMEOUT_MS9 = 3e4;
|
|
12080
12105
|
var startFlow = async (ctx, profile, _agentResult, args) => {
|
|
12081
12106
|
const entry = args?.entry;
|
|
@@ -12109,7 +12134,7 @@ function postKodyComment(target, issueNumber, state, next, cwd) {
|
|
|
12109
12134
|
const sub = target === "pr" && state?.core.prUrl ? "pr" : "issue";
|
|
12110
12135
|
const body = `@kody ${next}`;
|
|
12111
12136
|
try {
|
|
12112
|
-
|
|
12137
|
+
execFileSync25("gh", [sub, "comment", String(targetNumber), "--body", body], {
|
|
12113
12138
|
timeout: API_TIMEOUT_MS9,
|
|
12114
12139
|
cwd,
|
|
12115
12140
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -12123,7 +12148,7 @@ function postKodyComment(target, issueNumber, state, next, cwd) {
|
|
|
12123
12148
|
}
|
|
12124
12149
|
|
|
12125
12150
|
// src/scripts/syncFlow.ts
|
|
12126
|
-
import { execFileSync as
|
|
12151
|
+
import { execFileSync as execFileSync26 } from "child_process";
|
|
12127
12152
|
init_issue();
|
|
12128
12153
|
var DONE2 = {
|
|
12129
12154
|
label: "kody:done",
|
|
@@ -12201,7 +12226,7 @@ function bail2(ctx, prNumber, reason) {
|
|
|
12201
12226
|
}
|
|
12202
12227
|
function revParseHead(cwd) {
|
|
12203
12228
|
try {
|
|
12204
|
-
return
|
|
12229
|
+
return execFileSync26("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }).toString().trim();
|
|
12205
12230
|
} catch {
|
|
12206
12231
|
return "";
|
|
12207
12232
|
}
|
|
@@ -12458,7 +12483,7 @@ var verifyWithRetry = async (ctx) => {
|
|
|
12458
12483
|
|
|
12459
12484
|
// src/scripts/waitForCi.ts
|
|
12460
12485
|
init_issue();
|
|
12461
|
-
import { execFileSync as
|
|
12486
|
+
import { execFileSync as execFileSync27 } from "child_process";
|
|
12462
12487
|
var API_TIMEOUT_MS10 = 3e4;
|
|
12463
12488
|
var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
12464
12489
|
const timeoutMinutes = numArg(args, "timeoutMinutes", 30);
|
|
@@ -12536,7 +12561,7 @@ var waitForCi = async (ctx, _profile, _agentResult, args) => {
|
|
|
12536
12561
|
};
|
|
12537
12562
|
function fetchChecks(prNumber, cwd) {
|
|
12538
12563
|
try {
|
|
12539
|
-
const raw =
|
|
12564
|
+
const raw = execFileSync27("gh", ["pr", "checks", String(prNumber), "--json", "bucket,state,name,workflow,link"], {
|
|
12540
12565
|
encoding: "utf-8",
|
|
12541
12566
|
timeout: API_TIMEOUT_MS10,
|
|
12542
12567
|
cwd,
|
|
@@ -13012,7 +13037,7 @@ var allScriptNames = /* @__PURE__ */ new Set([
|
|
|
13012
13037
|
]);
|
|
13013
13038
|
|
|
13014
13039
|
// src/tools.ts
|
|
13015
|
-
import { execFileSync as
|
|
13040
|
+
import { execFileSync as execFileSync28 } from "child_process";
|
|
13016
13041
|
function verifyCliTools(tools, cwd) {
|
|
13017
13042
|
const out = [];
|
|
13018
13043
|
for (const t of tools) out.push(verifyOne(t, cwd));
|
|
@@ -13049,7 +13074,7 @@ function verifyOne(tool4, cwd) {
|
|
|
13049
13074
|
}
|
|
13050
13075
|
function runShell(cmd, cwd, timeoutMs = 3e4) {
|
|
13051
13076
|
try {
|
|
13052
|
-
const stdout =
|
|
13077
|
+
const stdout = execFileSync28("sh", ["-c", cmd], {
|
|
13053
13078
|
cwd,
|
|
13054
13079
|
stdio: ["ignore", "pipe", "pipe"],
|
|
13055
13080
|
timeout: timeoutMs,
|
|
@@ -13838,7 +13863,7 @@ async function runContainerLoop(profile, ctx, input) {
|
|
|
13838
13863
|
}
|
|
13839
13864
|
function resetWorkingTree2(cwd) {
|
|
13840
13865
|
try {
|
|
13841
|
-
|
|
13866
|
+
execFileSync29("git", ["reset", "--hard", "HEAD"], {
|
|
13842
13867
|
cwd,
|
|
13843
13868
|
stdio: ["ignore", "pipe", "pipe"],
|
|
13844
13869
|
timeout: 3e4
|
|
@@ -14024,7 +14049,7 @@ function detectPackageManager2(cwd) {
|
|
|
14024
14049
|
}
|
|
14025
14050
|
function shellOut(cmd, args, cwd, stream = true) {
|
|
14026
14051
|
try {
|
|
14027
|
-
|
|
14052
|
+
execFileSync30(cmd, args, {
|
|
14028
14053
|
cwd,
|
|
14029
14054
|
stdio: stream ? "inherit" : "pipe",
|
|
14030
14055
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", CI: process.env.CI ?? "1" }
|
|
@@ -14037,7 +14062,7 @@ function shellOut(cmd, args, cwd, stream = true) {
|
|
|
14037
14062
|
}
|
|
14038
14063
|
function isOnPath(bin) {
|
|
14039
14064
|
try {
|
|
14040
|
-
|
|
14065
|
+
execFileSync30("which", [bin], { stdio: "pipe" });
|
|
14041
14066
|
return true;
|
|
14042
14067
|
} catch {
|
|
14043
14068
|
return false;
|
|
@@ -14078,7 +14103,7 @@ function installLitellmIfNeeded(cwd) {
|
|
|
14078
14103
|
} catch {
|
|
14079
14104
|
}
|
|
14080
14105
|
try {
|
|
14081
|
-
|
|
14106
|
+
execFileSync30("python3", ["-c", "import litellm"], { stdio: "pipe" });
|
|
14082
14107
|
process.stdout.write("\u2192 kody: litellm already installed\n");
|
|
14083
14108
|
return 0;
|
|
14084
14109
|
} catch {
|
|
@@ -14088,16 +14113,16 @@ function installLitellmIfNeeded(cwd) {
|
|
|
14088
14113
|
}
|
|
14089
14114
|
function configureGitIdentity(cwd) {
|
|
14090
14115
|
try {
|
|
14091
|
-
const name =
|
|
14116
|
+
const name = execFileSync30("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
|
|
14092
14117
|
if (name) return;
|
|
14093
14118
|
} catch {
|
|
14094
14119
|
}
|
|
14095
14120
|
try {
|
|
14096
|
-
|
|
14121
|
+
execFileSync30("git", ["config", "user.name", "github-actions[bot]"], { cwd, stdio: "pipe" });
|
|
14097
14122
|
} catch {
|
|
14098
14123
|
}
|
|
14099
14124
|
try {
|
|
14100
|
-
|
|
14125
|
+
execFileSync30("git", ["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"], {
|
|
14101
14126
|
cwd,
|
|
14102
14127
|
stdio: "pipe"
|
|
14103
14128
|
});
|
|
@@ -14417,8 +14442,8 @@ function commitChatFiles(cwd, sessionId, verbose) {
|
|
|
14417
14442
|
if (paths.length === 0) return;
|
|
14418
14443
|
const opts = { cwd, stdio: verbose ? "inherit" : "pipe" };
|
|
14419
14444
|
try {
|
|
14420
|
-
|
|
14421
|
-
|
|
14445
|
+
execFileSync31("git", ["add", "-f", ...paths], opts);
|
|
14446
|
+
execFileSync31("git", ["commit", "--quiet", "-m", `chat: reply for ${sessionId}`], opts);
|
|
14422
14447
|
} catch (err) {
|
|
14423
14448
|
const msg = err instanceof Error ? err.message : String(err);
|
|
14424
14449
|
process.stderr.write(`[kody:chat] commit skipped: ${msg}
|
|
@@ -56,44 +56,70 @@ tag="v${version}"
|
|
|
56
56
|
|
|
57
57
|
echo "→ release publish: ${tag}"
|
|
58
58
|
|
|
59
|
-
#
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
# Recovery is resume-not-overwrite: a release is three steps (push tag, run
|
|
60
|
+
# publishCommand, create GH release) and any of them may already be done from
|
|
61
|
+
# a prior partial run. We probe each step's state and perform only the missing
|
|
62
|
+
# parts. An already-fully-released version is therefore a no-op success, and we
|
|
63
|
+
# never re-point or force an existing tag (that would rewrite a shipped version).
|
|
64
|
+
tag_local=false
|
|
65
|
+
tag_remote=false
|
|
66
|
+
release_exists=false
|
|
67
|
+
if git rev-parse --verify "$tag" >/dev/null 2>&1; then tag_local=true; fi
|
|
68
|
+
if git ls-remote --exit-code --tags origin "refs/tags/$tag" >/dev/null 2>&1; then tag_remote=true; fi
|
|
69
|
+
if gh release view "$tag" >/dev/null 2>&1; then release_exists=true; fi
|
|
70
|
+
|
|
71
|
+
if [[ "$tag_local" == "true" || "$tag_remote" == "true" || "$release_exists" == "true" ]]; then
|
|
72
|
+
echo " resuming: tag exists (local=${tag_local} remote=${tag_remote}), gh-release=${release_exists}"
|
|
62
73
|
fi
|
|
63
74
|
|
|
64
75
|
if [[ "$dry_run" == "true" ]]; then
|
|
65
|
-
echo "KODY_REASON=dry-run — would tag + publish ${tag}"
|
|
76
|
+
echo "KODY_REASON=dry-run — would tag + publish ${tag} (tag_remote=${tag_remote}, gh-release=${release_exists})"
|
|
66
77
|
echo "KODY_SKIP_AGENT=true"
|
|
67
78
|
exit 0
|
|
68
79
|
fi
|
|
69
80
|
|
|
70
|
-
# Tag + push.
|
|
71
|
-
|
|
72
|
-
git
|
|
81
|
+
# Tag + push (skip whichever half already exists).
|
|
82
|
+
if [[ "$tag_local" == "false" && "$tag_remote" == "false" ]]; then
|
|
83
|
+
git tag -a "$tag" -m "Release ${tag}"
|
|
84
|
+
fi
|
|
85
|
+
if [[ "$tag_remote" == "false" ]]; then
|
|
86
|
+
git push origin "$tag"
|
|
87
|
+
fi
|
|
73
88
|
|
|
74
|
-
# publishCommand (optional).
|
|
75
|
-
#
|
|
89
|
+
# publishCommand (optional). A version that's already on the registry is the
|
|
90
|
+
# expected recovery case, not an error: treat "already published" as done.
|
|
91
|
+
# Any other non-zero is a real failure (recorded, but we still create the GH
|
|
92
|
+
# release so the tag is discoverable).
|
|
76
93
|
publish_status="skipped"
|
|
77
94
|
if [[ -n "$publish_cmd" ]]; then
|
|
78
95
|
cmd="${publish_cmd//\$VERSION/$version}"
|
|
79
96
|
echo " publish: ${cmd}"
|
|
80
|
-
|
|
97
|
+
publish_out=""
|
|
98
|
+
if publish_out=$(timeout "${timeout_s}" bash -c "$cmd" 2>&1); then
|
|
81
99
|
publish_status="ok"
|
|
100
|
+
elif echo "$publish_out" | grep -qiE "already exists|cannot publish over|previously published|403 Forbidden"; then
|
|
101
|
+
publish_status="already-published"
|
|
102
|
+
echo "[kody release-publish] version ${version} already on registry — treating as published"
|
|
82
103
|
else
|
|
83
104
|
publish_status="failed"
|
|
84
105
|
echo "[kody release-publish] publishCommand failed (continuing to create GH release)" >&2
|
|
85
106
|
fi
|
|
107
|
+
echo "$publish_out"
|
|
86
108
|
fi
|
|
87
109
|
|
|
88
|
-
# GitHub release.
|
|
110
|
+
# GitHub release (create only if missing).
|
|
89
111
|
release_url=""
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if release_url=$(gh release create "$tag" --title "$tag" --notes "Release ${tag} — automated by kody." $draft_flag 2>&1); then
|
|
93
|
-
:
|
|
112
|
+
if [[ "$release_exists" == "true" ]]; then
|
|
113
|
+
release_url=$(gh release view "$tag" --json url --jq .url 2>/dev/null || echo "")
|
|
94
114
|
else
|
|
95
|
-
|
|
96
|
-
|
|
115
|
+
draft_flag=""
|
|
116
|
+
[[ "$draft" == "true" ]] && draft_flag="--draft"
|
|
117
|
+
if release_url=$(gh release create "$tag" --title "$tag" --notes "Release ${tag} — automated by kody." $draft_flag 2>&1); then
|
|
118
|
+
:
|
|
119
|
+
else
|
|
120
|
+
echo "[kody release-publish] gh release create failed: $release_url" >&2
|
|
121
|
+
release_url=""
|
|
122
|
+
fi
|
|
97
123
|
fi
|
|
98
124
|
|
|
99
125
|
echo "RELEASE_TAG=${tag}"
|
|
@@ -108,3 +134,4 @@ fi
|
|
|
108
134
|
[[ -n "$release_url" ]] && echo "KODY_PR_URL=${release_url}"
|
|
109
135
|
echo "KODY_REASON=tagged ${tag}, published${publish_status:+ ($publish_status)}"
|
|
110
136
|
echo "KODY_SKIP_AGENT=true"
|
|
137
|
+
exit 0
|
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.155",
|
|
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",
|