@kody-ade/kody-engine 0.4.148 → 0.4.150
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 +113 -14
- 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.150",
|
|
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",
|
|
@@ -2703,6 +2703,76 @@ import { execFileSync as execFileSync29 } from "child_process";
|
|
|
2703
2703
|
import * as fs41 from "fs";
|
|
2704
2704
|
import * as path37 from "path";
|
|
2705
2705
|
|
|
2706
|
+
// src/app-auth.ts
|
|
2707
|
+
import { createSign } from "crypto";
|
|
2708
|
+
var GH_API = process.env.GITHUB_API_URL || "https://api.github.com";
|
|
2709
|
+
function b64url(input) {
|
|
2710
|
+
return Buffer.from(input).toString("base64url");
|
|
2711
|
+
}
|
|
2712
|
+
function normalizePem(key) {
|
|
2713
|
+
const trimmed = key.trim();
|
|
2714
|
+
if (trimmed.includes("BEGIN")) return trimmed;
|
|
2715
|
+
try {
|
|
2716
|
+
const decoded = Buffer.from(trimmed, "base64").toString("utf8");
|
|
2717
|
+
if (decoded.includes("BEGIN")) return decoded;
|
|
2718
|
+
} catch {
|
|
2719
|
+
}
|
|
2720
|
+
return trimmed;
|
|
2721
|
+
}
|
|
2722
|
+
function buildAppJwt(appId, privateKeyPem) {
|
|
2723
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
2724
|
+
const header = { alg: "RS256", typ: "JWT" };
|
|
2725
|
+
const payload = { iat: now - 60, exp: now + 9 * 60, iss: appId };
|
|
2726
|
+
const signingInput = `${b64url(JSON.stringify(header))}.${b64url(JSON.stringify(payload))}`;
|
|
2727
|
+
const signer = createSign("RSA-SHA256");
|
|
2728
|
+
signer.update(signingInput);
|
|
2729
|
+
signer.end();
|
|
2730
|
+
const signature = signer.sign(normalizePem(privateKeyPem)).toString("base64url");
|
|
2731
|
+
return `${signingInput}.${signature}`;
|
|
2732
|
+
}
|
|
2733
|
+
async function ghApp(jwt, apiPath, method = "GET") {
|
|
2734
|
+
const res = await fetch(`${GH_API}${apiPath}`, {
|
|
2735
|
+
method,
|
|
2736
|
+
headers: {
|
|
2737
|
+
Authorization: `Bearer ${jwt}`,
|
|
2738
|
+
Accept: "application/vnd.github+json",
|
|
2739
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
2740
|
+
"User-Agent": "kody-engine"
|
|
2741
|
+
}
|
|
2742
|
+
});
|
|
2743
|
+
if (!res.ok) {
|
|
2744
|
+
const body = await res.text().catch(() => "");
|
|
2745
|
+
throw new Error(
|
|
2746
|
+
`GitHub App API ${method} ${apiPath} \u2192 ${res.status} ${res.statusText}${body ? `: ${body.slice(0, 200)}` : ""}`
|
|
2747
|
+
);
|
|
2748
|
+
}
|
|
2749
|
+
return await res.json();
|
|
2750
|
+
}
|
|
2751
|
+
function readAppCreds(env = process.env) {
|
|
2752
|
+
const appId = env.KODY_APP_ID?.trim();
|
|
2753
|
+
const privateKey = env.KODY_APP_PRIVATE_KEY;
|
|
2754
|
+
if (!appId || !privateKey) return null;
|
|
2755
|
+
return {
|
|
2756
|
+
appId,
|
|
2757
|
+
privateKey,
|
|
2758
|
+
installationId: env.KODY_APP_INSTALLATION_ID?.trim() || void 0,
|
|
2759
|
+
repo: env.GITHUB_REPOSITORY?.trim() || void 0
|
|
2760
|
+
};
|
|
2761
|
+
}
|
|
2762
|
+
async function mintAppInstallationToken(creds) {
|
|
2763
|
+
const jwt = buildAppJwt(creds.appId, creds.privateKey);
|
|
2764
|
+
let installationId = creds.installationId;
|
|
2765
|
+
if (!installationId) {
|
|
2766
|
+
if (!creds.repo) {
|
|
2767
|
+
throw new Error("cannot resolve App installation: no KODY_APP_INSTALLATION_ID and no GITHUB_REPOSITORY");
|
|
2768
|
+
}
|
|
2769
|
+
const inst = await ghApp(jwt, `/repos/${creds.repo}/installation`);
|
|
2770
|
+
installationId = String(inst.id);
|
|
2771
|
+
}
|
|
2772
|
+
const tok = await ghApp(jwt, `/app/installations/${installationId}/access_tokens`, "POST");
|
|
2773
|
+
return tok.token;
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2706
2776
|
// src/dispatch.ts
|
|
2707
2777
|
import * as fs12 from "fs";
|
|
2708
2778
|
|
|
@@ -3029,9 +3099,6 @@ function coerceBare(spec, value) {
|
|
|
3029
3099
|
return value;
|
|
3030
3100
|
}
|
|
3031
3101
|
|
|
3032
|
-
// src/kody-cli.ts
|
|
3033
|
-
init_issue();
|
|
3034
|
-
|
|
3035
3102
|
// src/executor.ts
|
|
3036
3103
|
import { execFileSync as execFileSync28, spawn as spawn9 } from "child_process";
|
|
3037
3104
|
import * as fs40 from "fs";
|
|
@@ -10471,6 +10538,19 @@ var poolServe = async (ctx) => {
|
|
|
10471
10538
|
});
|
|
10472
10539
|
};
|
|
10473
10540
|
|
|
10541
|
+
// src/scripts/postAgentComment.ts
|
|
10542
|
+
init_issue();
|
|
10543
|
+
var postAgentComment = async (ctx) => {
|
|
10544
|
+
if (!ctx.data.agentDone) return;
|
|
10545
|
+
const targetNumber = Number(ctx.data.commentTargetNumber ?? 0);
|
|
10546
|
+
const answer = ctx.data.prSummary?.trim();
|
|
10547
|
+
if (!targetNumber || !answer) return;
|
|
10548
|
+
try {
|
|
10549
|
+
postIssueComment(targetNumber, answer, ctx.cwd);
|
|
10550
|
+
} catch {
|
|
10551
|
+
}
|
|
10552
|
+
};
|
|
10553
|
+
|
|
10474
10554
|
// src/scripts/postIssueComment.ts
|
|
10475
10555
|
init_issue();
|
|
10476
10556
|
|
|
@@ -12465,6 +12545,8 @@ var appendCompanyActivity = async (ctx, _profile, agentResult) => {
|
|
|
12465
12545
|
staffTitle,
|
|
12466
12546
|
trigger: resolveTrigger(force),
|
|
12467
12547
|
outcome: agentResult?.outcome ?? "unknown",
|
|
12548
|
+
outcomeKind: agentResult?.outcomeKind ?? null,
|
|
12549
|
+
reason: agentResult?.error ?? null,
|
|
12468
12550
|
durationMs: agentResult?.durationMs ?? null,
|
|
12469
12551
|
runUrl: getRunUrl() || null
|
|
12470
12552
|
};
|
|
@@ -12807,6 +12889,7 @@ var postflightScripts = {
|
|
|
12807
12889
|
stageMergeConflicts,
|
|
12808
12890
|
commitAndPush: commitAndPush2,
|
|
12809
12891
|
ensurePr: ensurePr2,
|
|
12892
|
+
postAgentComment,
|
|
12810
12893
|
postIssueComment: postIssueComment2,
|
|
12811
12894
|
postPlanComment,
|
|
12812
12895
|
postResearchComment,
|
|
@@ -13805,7 +13888,7 @@ function unpackAllSecrets(env = process.env) {
|
|
|
13805
13888
|
}
|
|
13806
13889
|
return count;
|
|
13807
13890
|
}
|
|
13808
|
-
function resolveAuthToken(env = process.env) {
|
|
13891
|
+
async function resolveAuthToken(env = process.env) {
|
|
13809
13892
|
const sources = [
|
|
13810
13893
|
["KODY_TOKEN", env.KODY_TOKEN],
|
|
13811
13894
|
["GH_TOKEN", env.GH_TOKEN],
|
|
@@ -13818,10 +13901,24 @@ function resolveAuthToken(env = process.env) {
|
|
|
13818
13901
|
if (token) {
|
|
13819
13902
|
process.stdout.write(`\u2192 kody: GH_TOKEN sourced from env.${picked[0]}
|
|
13820
13903
|
`);
|
|
13821
|
-
|
|
13822
|
-
|
|
13904
|
+
return token;
|
|
13905
|
+
}
|
|
13906
|
+
const creds = readAppCreds(env);
|
|
13907
|
+
if (creds) {
|
|
13908
|
+
try {
|
|
13909
|
+
const minted = await mintAppInstallationToken(creds);
|
|
13910
|
+
env.GH_TOKEN = minted;
|
|
13911
|
+
process.stdout.write("\u2192 kody: GH_TOKEN minted from GitHub App (KODY_APP_ID/KODY_APP_PRIVATE_KEY)\n");
|
|
13912
|
+
return minted;
|
|
13913
|
+
} catch (err) {
|
|
13914
|
+
process.stdout.write(`\u2192 kody: WARNING GitHub App token mint failed: ${err.message}
|
|
13915
|
+
`);
|
|
13916
|
+
}
|
|
13823
13917
|
}
|
|
13824
|
-
|
|
13918
|
+
process.stdout.write(
|
|
13919
|
+
"\u2192 kody: WARNING no auth token found (KODY_TOKEN/GH_TOKEN/GITHUB_TOKEN/GH_PAT/GitHub App all empty)\n"
|
|
13920
|
+
);
|
|
13921
|
+
return void 0;
|
|
13825
13922
|
}
|
|
13826
13923
|
function detectPackageManager2(cwd) {
|
|
13827
13924
|
if (fs41.existsSync(path37.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
@@ -13970,7 +14067,7 @@ async function runCi(argv) {
|
|
|
13970
14067
|
if (outcome.kind === "unrecognized") {
|
|
13971
14068
|
try {
|
|
13972
14069
|
unpackAllSecrets();
|
|
13973
|
-
resolveAuthToken();
|
|
14070
|
+
await resolveAuthToken();
|
|
13974
14071
|
} catch {
|
|
13975
14072
|
}
|
|
13976
14073
|
const tokenLabel = outcome.token ? `\`${outcome.token}\`` : "an empty subcommand";
|
|
@@ -13987,8 +14084,10 @@ async function runCi(argv) {
|
|
|
13987
14084
|
if (outcome.isPr) postPrReviewComment(outcome.target, body, cwd);
|
|
13988
14085
|
else postIssueComment(outcome.target, body, cwd);
|
|
13989
14086
|
} catch (err) {
|
|
13990
|
-
process.stderr.write(
|
|
13991
|
-
`)
|
|
14087
|
+
process.stderr.write(
|
|
14088
|
+
`[kody] dispatch: failed to post unrecognized-token feedback: ${err instanceof Error ? err.message : String(err)}
|
|
14089
|
+
`
|
|
14090
|
+
);
|
|
13992
14091
|
}
|
|
13993
14092
|
process.stdout.write(
|
|
13994
14093
|
`\u2192 kody: unrecognized subcommand "${outcome.token}" on #${outcome.target} \u2014 feedback comment attempt finished, exiting cleanly
|
|
@@ -14023,7 +14122,7 @@ ${CI_HELP}`);
|
|
|
14023
14122
|
const n = unpackAllSecrets();
|
|
14024
14123
|
if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
|
|
14025
14124
|
`);
|
|
14026
|
-
resolveAuthToken();
|
|
14125
|
+
await resolveAuthToken();
|
|
14027
14126
|
reactToTriggerComment(cwd);
|
|
14028
14127
|
const pm = args.packageManager ?? detectPackageManager2(cwd);
|
|
14029
14128
|
process.stdout.write(`\u2192 kody: package manager = ${pm}
|
|
@@ -14096,7 +14195,7 @@ async function runScheduledFanOut(cwd, args, opts) {
|
|
|
14096
14195
|
const n = unpackAllSecrets();
|
|
14097
14196
|
if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
|
|
14098
14197
|
`);
|
|
14099
|
-
resolveAuthToken();
|
|
14198
|
+
await resolveAuthToken();
|
|
14100
14199
|
const pm = args.packageManager ?? detectPackageManager2(cwd);
|
|
14101
14200
|
process.stdout.write(`\u2192 kody: package manager = ${pm}
|
|
14102
14201
|
`);
|
|
@@ -14269,7 +14368,7 @@ ${CHAT_HELP}`);
|
|
|
14269
14368
|
process.stdout.write(`\u2192 kody: unpacked ${unpackedSecrets} secret(s) from ALL_SECRETS
|
|
14270
14369
|
`);
|
|
14271
14370
|
}
|
|
14272
|
-
resolveAuthToken();
|
|
14371
|
+
await resolveAuthToken();
|
|
14273
14372
|
configureGitIdentity(cwd);
|
|
14274
14373
|
const config = tryLoadConfig(cwd);
|
|
14275
14374
|
const modelSpec = args.model ?? config?.agent.model ?? DEFAULT_MODEL;
|
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.150",
|
|
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",
|