@kody-ade/kody-engine 0.4.409 → 0.4.410
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 +155 -97
- package/package.json +1 -1
package/dist/bin/kody.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "@kody-ade/kody-engine",
|
|
18
|
-
version: "0.4.
|
|
18
|
+
version: "0.4.410",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -2219,6 +2219,108 @@ var init_convex_client = __esm({
|
|
|
2219
2219
|
}
|
|
2220
2220
|
});
|
|
2221
2221
|
|
|
2222
|
+
// src/kody-api-client.ts
|
|
2223
|
+
import { getFunctionName } from "convex/server";
|
|
2224
|
+
function apiUrl(env) {
|
|
2225
|
+
return (env.KODY_API_URL?.trim() || DEFAULT_KODY_API_URL).replace(/\/$/, "");
|
|
2226
|
+
}
|
|
2227
|
+
function oidcRequestUrl(env) {
|
|
2228
|
+
const raw = env.ACTIONS_ID_TOKEN_REQUEST_URL?.trim();
|
|
2229
|
+
if (!raw) throw new Error("GitHub Actions OIDC request URL is unavailable");
|
|
2230
|
+
const url = new URL(raw);
|
|
2231
|
+
if (url.protocol !== "https:") throw new Error("GitHub Actions OIDC request URL must use HTTPS");
|
|
2232
|
+
url.searchParams.set("audience", OIDC_AUDIENCE);
|
|
2233
|
+
return url;
|
|
2234
|
+
}
|
|
2235
|
+
function tokenExpiry(token) {
|
|
2236
|
+
try {
|
|
2237
|
+
const payload = JSON.parse(Buffer.from(token.split(".")[1] ?? "", "base64url").toString("utf8"));
|
|
2238
|
+
return typeof payload.exp === "number" ? payload.exp * 1e3 : Date.now() + 4 * 6e4;
|
|
2239
|
+
} catch {
|
|
2240
|
+
return Date.now() + 4 * 6e4;
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
async function githubOidcToken(env, force = false) {
|
|
2244
|
+
if (!force && cachedToken && cachedToken.expiresAt - 6e4 > Date.now()) return cachedToken.value;
|
|
2245
|
+
const requestToken = env.ACTIONS_ID_TOKEN_REQUEST_TOKEN?.trim();
|
|
2246
|
+
if (!requestToken) throw new Error("GitHub Actions OIDC request token is unavailable");
|
|
2247
|
+
const response = await fetch(oidcRequestUrl(env), {
|
|
2248
|
+
headers: { Authorization: `Bearer ${requestToken}` },
|
|
2249
|
+
signal: AbortSignal.timeout(15e3)
|
|
2250
|
+
});
|
|
2251
|
+
if (!response.ok) throw new Error(`GitHub Actions identity request failed (${response.status})`);
|
|
2252
|
+
const body = await response.json();
|
|
2253
|
+
if (typeof body.value !== "string" || !body.value) throw new Error("GitHub Actions identity response was invalid");
|
|
2254
|
+
cachedToken = { value: body.value, expiresAt: tokenExpiry(body.value) };
|
|
2255
|
+
return body.value;
|
|
2256
|
+
}
|
|
2257
|
+
function operationName(fn) {
|
|
2258
|
+
return getFunctionName(fn).replace(":", ".");
|
|
2259
|
+
}
|
|
2260
|
+
async function callKodyApi(kind, fn, args, env) {
|
|
2261
|
+
const call = async (forceToken) => {
|
|
2262
|
+
const token = await githubOidcToken(env, forceToken);
|
|
2263
|
+
return fetch(`${apiUrl(env)}/api/kody/engine/backend`, {
|
|
2264
|
+
method: "POST",
|
|
2265
|
+
headers: {
|
|
2266
|
+
Authorization: `Bearer ${token}`,
|
|
2267
|
+
"Content-Type": "application/json"
|
|
2268
|
+
},
|
|
2269
|
+
body: JSON.stringify({ kind, operation: operationName(fn), args }),
|
|
2270
|
+
signal: AbortSignal.timeout(3e4)
|
|
2271
|
+
});
|
|
2272
|
+
};
|
|
2273
|
+
let response = await call(false);
|
|
2274
|
+
if (response.status === 401) response = await call(true);
|
|
2275
|
+
if (!response.ok) throw new Error(`Kody backend request failed (${response.status})`);
|
|
2276
|
+
const body = await response.json();
|
|
2277
|
+
return body.result;
|
|
2278
|
+
}
|
|
2279
|
+
function hasGitHubActionsIdentity(env = process.env) {
|
|
2280
|
+
return Boolean(
|
|
2281
|
+
env.GITHUB_ACTIONS === "true" && env.ACTIONS_ID_TOKEN_REQUEST_URL?.trim() && env.ACTIONS_ID_TOKEN_REQUEST_TOKEN?.trim()
|
|
2282
|
+
);
|
|
2283
|
+
}
|
|
2284
|
+
function createKodyApiBackendClient(env = process.env) {
|
|
2285
|
+
if (!hasGitHubActionsIdentity(env)) throw new Error("GitHub Actions workflow identity is unavailable");
|
|
2286
|
+
return {
|
|
2287
|
+
query: (fn, args) => callKodyApi("query", fn, args, env),
|
|
2288
|
+
mutation: (fn, args) => callKodyApi("mutation", fn, args, env)
|
|
2289
|
+
};
|
|
2290
|
+
}
|
|
2291
|
+
async function readRuntimeSecretFromKody(name, env = process.env) {
|
|
2292
|
+
const token = await githubOidcToken(env);
|
|
2293
|
+
const response = await fetch(`${apiUrl(env)}/api/kody/engine/secret`, {
|
|
2294
|
+
method: "POST",
|
|
2295
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
2296
|
+
body: JSON.stringify({ name }),
|
|
2297
|
+
signal: AbortSignal.timeout(3e4)
|
|
2298
|
+
});
|
|
2299
|
+
if (response.status === 404) return null;
|
|
2300
|
+
if (!response.ok) throw new Error(`Kody secret request failed (${response.status})`);
|
|
2301
|
+
const body = await response.json();
|
|
2302
|
+
return typeof body.value === "string" ? body.value : null;
|
|
2303
|
+
}
|
|
2304
|
+
async function readPreviewContextFromKody(env = process.env) {
|
|
2305
|
+
const token = await githubOidcToken(env);
|
|
2306
|
+
const response = await fetch(`${apiUrl(env)}/api/kody/engine/preview-context`, {
|
|
2307
|
+
method: "POST",
|
|
2308
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
2309
|
+
signal: AbortSignal.timeout(3e4)
|
|
2310
|
+
});
|
|
2311
|
+
if (!response.ok) throw new Error(`Kody preview context request failed (${response.status})`);
|
|
2312
|
+
return await response.json();
|
|
2313
|
+
}
|
|
2314
|
+
var DEFAULT_KODY_API_URL, OIDC_AUDIENCE, cachedToken;
|
|
2315
|
+
var init_kody_api_client = __esm({
|
|
2316
|
+
"src/kody-api-client.ts"() {
|
|
2317
|
+
"use strict";
|
|
2318
|
+
DEFAULT_KODY_API_URL = "https://kody-dashboard-khaki.vercel.app";
|
|
2319
|
+
OIDC_AUDIENCE = "kody-api";
|
|
2320
|
+
cachedToken = null;
|
|
2321
|
+
}
|
|
2322
|
+
});
|
|
2323
|
+
|
|
2222
2324
|
// src/state-backend.ts
|
|
2223
2325
|
import { anyApi } from "convex/server";
|
|
2224
2326
|
function requireTenant(tenantId2) {
|
|
@@ -2236,10 +2338,16 @@ function requireNonEmpty(value, name) {
|
|
|
2236
2338
|
return normalized;
|
|
2237
2339
|
}
|
|
2238
2340
|
function createStateBackendFromEnv(env = process.env, client) {
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
if (!
|
|
2242
|
-
|
|
2341
|
+
let transport = client;
|
|
2342
|
+
if (!transport && hasGitHubActionsIdentity(env)) transport = createKodyApiBackendClient(env);
|
|
2343
|
+
if (!transport) {
|
|
2344
|
+
const url = env.CONVEX_URL?.trim();
|
|
2345
|
+
const serviceKey = env.KODY_SERVICE_KEY?.trim();
|
|
2346
|
+
if (!url || !serviceKey) {
|
|
2347
|
+
throw new Error("GitHub Actions identity or direct Kody backend credentials are required");
|
|
2348
|
+
}
|
|
2349
|
+
transport = createConvexClientFromEnv(env);
|
|
2350
|
+
}
|
|
2243
2351
|
return {
|
|
2244
2352
|
async get(tenantId2, taskKey, kind) {
|
|
2245
2353
|
const result = await transport.query(anyApi.taskState.get, {
|
|
@@ -2412,10 +2520,14 @@ function createStateBackendFromEnv(env = process.env, client) {
|
|
|
2412
2520
|
}
|
|
2413
2521
|
};
|
|
2414
2522
|
}
|
|
2523
|
+
function hasStateBackendConfig(env = process.env) {
|
|
2524
|
+
return hasGitHubActionsIdentity(env) || Boolean(env.CONVEX_URL?.trim() && env.KODY_SERVICE_KEY?.trim());
|
|
2525
|
+
}
|
|
2415
2526
|
var init_state_backend = __esm({
|
|
2416
2527
|
"src/state-backend.ts"() {
|
|
2417
2528
|
"use strict";
|
|
2418
2529
|
init_convex_client();
|
|
2530
|
+
init_kody_api_client();
|
|
2419
2531
|
}
|
|
2420
2532
|
});
|
|
2421
2533
|
|
|
@@ -3699,12 +3811,10 @@ function verifyTaskArtifacts(absDir) {
|
|
|
3699
3811
|
}
|
|
3700
3812
|
async function persistTaskArtifactsToState(config, _cwd, artifacts) {
|
|
3701
3813
|
const tenantId2 = config.github?.owner && config.github.repo ? `${config.github.owner}/${config.github.repo}` : process.env.GITHUB_REPOSITORY?.trim();
|
|
3702
|
-
if (process.env.GITHUB_ACTIONS === "true" && (!
|
|
3703
|
-
throw new Error(
|
|
3704
|
-
"Convex artifact backend is required in GitHub Actions (CONVEX_URL, KODY_SERVICE_KEY, and repository identity)"
|
|
3705
|
-
);
|
|
3814
|
+
if (process.env.GITHUB_ACTIONS === "true" && (!hasStateBackendConfig() || !tenantId2)) {
|
|
3815
|
+
throw new Error("Kody backend access and repository identity are required in GitHub Actions");
|
|
3706
3816
|
}
|
|
3707
|
-
if (
|
|
3817
|
+
if (hasStateBackendConfig() && tenantId2) {
|
|
3708
3818
|
const backend = createStateBackendFromEnv();
|
|
3709
3819
|
for (const file of TASK_ARTIFACT_FILES) {
|
|
3710
3820
|
const full = path11.join(artifacts.absDir, file);
|
|
@@ -5834,7 +5944,7 @@ var init_loadMemoryContext = __esm({
|
|
|
5834
5944
|
loadMemoryContext = async (ctx) => {
|
|
5835
5945
|
if (typeof ctx.data.memoryContext === "string") return;
|
|
5836
5946
|
const tenantId2 = ctx.config.github?.owner && ctx.config.github.repo ? `${ctx.config.github.owner}/${ctx.config.github.repo}` : process.env.GITHUB_REPOSITORY?.trim();
|
|
5837
|
-
if (
|
|
5947
|
+
if (hasStateBackendConfig() && tenantId2) {
|
|
5838
5948
|
try {
|
|
5839
5949
|
const backend = createStateBackendFromEnv();
|
|
5840
5950
|
const docs = await backend.listRepoDocs(tenantId2, "memory:");
|
|
@@ -9535,7 +9645,7 @@ function subjectCandidates(kind, id, state) {
|
|
|
9535
9645
|
return [...ids].map((candidate) => ({ kind, id: candidate }));
|
|
9536
9646
|
}
|
|
9537
9647
|
async function firstTrustOverride(ctx, subjects) {
|
|
9538
|
-
const backendConfigured =
|
|
9648
|
+
const backendConfigured = hasStateBackendConfig();
|
|
9539
9649
|
if (!backendConfigured) return null;
|
|
9540
9650
|
const repoSlug = ctx.config.github?.owner && ctx.config.github?.repo ? `${ctx.config.github.owner}/${ctx.config.github.repo}` : "";
|
|
9541
9651
|
for (const subject of subjects) {
|
|
@@ -9751,6 +9861,7 @@ var init_advanceManagedGoal = __esm({
|
|
|
9751
9861
|
init_typeDefinitions();
|
|
9752
9862
|
init_issue();
|
|
9753
9863
|
init_registry();
|
|
9864
|
+
init_state_backend();
|
|
9754
9865
|
init_trustPolicy();
|
|
9755
9866
|
init_workflowDefinitions();
|
|
9756
9867
|
init_goalCapabilityScheduling();
|
|
@@ -10048,12 +10159,12 @@ function resolveTrigger(force) {
|
|
|
10048
10159
|
}
|
|
10049
10160
|
async function appendActivity(ctx, record2) {
|
|
10050
10161
|
const tenantId2 = ctx.config.github?.owner && ctx.config.github.repo ? `${ctx.config.github.owner}/${ctx.config.github.repo}` : process.env.GITHUB_REPOSITORY;
|
|
10051
|
-
if (
|
|
10162
|
+
if (hasStateBackendConfig() && tenantId2) {
|
|
10052
10163
|
await createStateBackendFromEnv().appendDailyLog(tenantId2, "activity", record2.ts.slice(0, 10), record2);
|
|
10053
10164
|
return;
|
|
10054
10165
|
}
|
|
10055
10166
|
if (process.env.GITHUB_ACTIONS === "true") {
|
|
10056
|
-
throw new Error("
|
|
10167
|
+
throw new Error("Kody backend access is required for company activity in GitHub Actions");
|
|
10057
10168
|
}
|
|
10058
10169
|
}
|
|
10059
10170
|
var appendCompanyActivity;
|
|
@@ -14773,6 +14884,18 @@ function envSecret(name, env) {
|
|
|
14773
14884
|
}
|
|
14774
14885
|
async function resolveRuntimeSecret(name, ctx, opts = {}) {
|
|
14775
14886
|
const env = opts.env ?? process.env;
|
|
14887
|
+
if (hasGitHubActionsIdentity(env)) {
|
|
14888
|
+
try {
|
|
14889
|
+
const value = await readRuntimeSecretFromKody(name, env);
|
|
14890
|
+
return value ? { value, source: "vault" } : envSecret(name, env);
|
|
14891
|
+
} catch (err) {
|
|
14892
|
+
const fallback = envSecret(name, env);
|
|
14893
|
+
return {
|
|
14894
|
+
...fallback,
|
|
14895
|
+
warning: `Kody secret read failed for ${name}: ${err instanceof Error ? err.message : String(err)}`
|
|
14896
|
+
};
|
|
14897
|
+
}
|
|
14898
|
+
}
|
|
14776
14899
|
const masterRaw = env.KODY_MASTER_KEY?.trim() ?? "";
|
|
14777
14900
|
if (!masterRaw || !env.CONVEX_URL?.trim() || !env.KODY_SERVICE_KEY?.trim()) return envSecret(name, env);
|
|
14778
14901
|
try {
|
|
@@ -14800,6 +14923,7 @@ var init_runtimeSecrets = __esm({
|
|
|
14800
14923
|
"src/scripts/runtimeSecrets.ts"() {
|
|
14801
14924
|
"use strict";
|
|
14802
14925
|
init_backendVault();
|
|
14926
|
+
init_kody_api_client();
|
|
14803
14927
|
init_keys();
|
|
14804
14928
|
}
|
|
14805
14929
|
});
|
|
@@ -16618,7 +16742,7 @@ var init_publishReport = __esm({
|
|
|
16618
16742
|
});
|
|
16619
16743
|
const runId = generatedAt.replace(/\.\d{3}Z$/, "Z").replace(/:/g, "-");
|
|
16620
16744
|
const tenantId2 = ctx.config.github?.owner && ctx.config.github.repo ? `${ctx.config.github.owner}/${ctx.config.github.repo}` : process.env.GITHUB_REPOSITORY;
|
|
16621
|
-
if (
|
|
16745
|
+
if (hasStateBackendConfig() && tenantId2) {
|
|
16622
16746
|
await createStateBackendFromEnv().saveReport(
|
|
16623
16747
|
tenantId2,
|
|
16624
16748
|
slug,
|
|
@@ -16634,7 +16758,7 @@ var init_publishReport = __esm({
|
|
|
16634
16758
|
generatedAt
|
|
16635
16759
|
);
|
|
16636
16760
|
} else if (process.env.GITHUB_ACTIONS === "true") {
|
|
16637
|
-
throw new Error("
|
|
16761
|
+
throw new Error("Kody backend access is required for reports in GitHub Actions");
|
|
16638
16762
|
}
|
|
16639
16763
|
};
|
|
16640
16764
|
}
|
|
@@ -17447,53 +17571,14 @@ function basePreviewAppName(repo) {
|
|
|
17447
17571
|
}
|
|
17448
17572
|
return `kp-${shortHash(owner)}-${shortHash(name)}-base`;
|
|
17449
17573
|
}
|
|
17450
|
-
function decryptVaultPayload(payload, keyRaw) {
|
|
17451
|
-
const parts = payload.split(":");
|
|
17452
|
-
if (parts.length !== 4 || parts[0] !== "v1") {
|
|
17453
|
-
throw new Error("invalid vault payload format");
|
|
17454
|
-
}
|
|
17455
|
-
const [, ivB64, ctB64, tagB64] = parts;
|
|
17456
|
-
const key = decodeMasterKey(keyRaw);
|
|
17457
|
-
if (key.length !== 32) {
|
|
17458
|
-
throw new Error("KODY_MASTER_KEY must decode to 32 bytes");
|
|
17459
|
-
}
|
|
17460
|
-
const iv = Buffer.from(ivB64, "base64");
|
|
17461
|
-
const ct = Buffer.from(ctB64, "base64");
|
|
17462
|
-
const tag = Buffer.from(tagB64, "base64");
|
|
17463
|
-
const decipher = createDecipheriv2("aes-256-gcm", key, iv);
|
|
17464
|
-
decipher.setAuthTag(tag);
|
|
17465
|
-
return Buffer.concat([decipher.update(ct), decipher.final()]).toString("utf8");
|
|
17466
|
-
}
|
|
17467
|
-
function decodeMasterKey(keyRaw) {
|
|
17468
|
-
if (/^[0-9a-fA-F]{64}$/.test(keyRaw)) return Buffer.from(keyRaw, "hex");
|
|
17469
|
-
return Buffer.from(keyRaw.replace(/-/g, "+").replace(/_/g, "/"), "base64");
|
|
17470
|
-
}
|
|
17471
|
-
function derivePreviewVerifyKey(masterKeyRaw) {
|
|
17472
|
-
const masterKey = decodeMasterKey(masterKeyRaw);
|
|
17473
|
-
if (masterKey.length !== 32) {
|
|
17474
|
-
throw new Error("KODY_MASTER_KEY must decode to 32 bytes");
|
|
17475
|
-
}
|
|
17476
|
-
return Buffer.from(hkdfSync2("sha256", masterKey, Buffer.alloc(0), PREVIEW_KEY_INFO, 32)).toString("hex");
|
|
17477
|
-
}
|
|
17478
17574
|
function previewRuntimeEnv(args) {
|
|
17479
17575
|
return {
|
|
17480
17576
|
...args.buildEnv,
|
|
17481
|
-
KODY_PREVIEW_VERIFY_KEY:
|
|
17577
|
+
KODY_PREVIEW_VERIFY_KEY: args.previewVerifyKey,
|
|
17482
17578
|
KODY_REPO_CONTEXT: args.repo,
|
|
17483
17579
|
KODY_PR: String(args.pr)
|
|
17484
17580
|
};
|
|
17485
17581
|
}
|
|
17486
|
-
function buildEnvFromVault(doc) {
|
|
17487
|
-
const buildEnv = {};
|
|
17488
|
-
for (const [name, entry] of Object.entries(doc.secrets ?? {})) {
|
|
17489
|
-
if (!entry?.value) continue;
|
|
17490
|
-
if (NEVER_PASS_TO_BUILD.has(name)) continue;
|
|
17491
|
-
buildEnv[name] = entry.value;
|
|
17492
|
-
}
|
|
17493
|
-
const raw = doc.secrets?.KODY_PREVIEW_BUILD_MODE?.value;
|
|
17494
|
-
const buildMode = raw?.toLowerCase().trim() === "dev" ? "dev" : "prod";
|
|
17495
|
-
return { buildEnv, buildMode };
|
|
17496
|
-
}
|
|
17497
17582
|
function formatPreviewComment(args) {
|
|
17498
17583
|
return [
|
|
17499
17584
|
"<!-- kody-fly-preview -->",
|
|
@@ -17505,23 +17590,9 @@ function formatPreviewComment(args) {
|
|
|
17505
17590
|
function defaultImageTag(repo, ref) {
|
|
17506
17591
|
return createHash4("sha256").update(`${repo}@${ref}`).digest("hex").slice(0, 12);
|
|
17507
17592
|
}
|
|
17508
|
-
var NEVER_PASS_TO_BUILD, PREVIEW_KEY_INFO;
|
|
17509
17593
|
var init_previewBuildHelpers = __esm({
|
|
17510
17594
|
"src/scripts/previewBuildHelpers.ts"() {
|
|
17511
17595
|
"use strict";
|
|
17512
|
-
NEVER_PASS_TO_BUILD = /* @__PURE__ */ new Set([
|
|
17513
|
-
"FLY_API_TOKEN",
|
|
17514
|
-
"FLY_ORG_SLUG",
|
|
17515
|
-
"FLY_DEFAULT_REGION",
|
|
17516
|
-
"KODY_MASTER_KEY",
|
|
17517
|
-
// Preview-config knob; consumed by the dispatcher before spawn.
|
|
17518
|
-
"KODY_PREVIEW_BUILD_MODE",
|
|
17519
|
-
"KODY_PREVIEW_VERIFY_KEY",
|
|
17520
|
-
"KODY_REPO_CONTEXT",
|
|
17521
|
-
"KODY_PR",
|
|
17522
|
-
"KODY_BRANCH"
|
|
17523
|
-
]);
|
|
17524
|
-
PREVIEW_KEY_INFO = "kody-preview:v1";
|
|
17525
17596
|
}
|
|
17526
17597
|
});
|
|
17527
17598
|
|
|
@@ -17630,16 +17701,6 @@ function flyHeaders(token) {
|
|
|
17630
17701
|
"Content-Type": "application/json"
|
|
17631
17702
|
};
|
|
17632
17703
|
}
|
|
17633
|
-
async function fetchVaultDoc(repo, masterKey) {
|
|
17634
|
-
const [owner, name] = repo.split("/", 2);
|
|
17635
|
-
if (!owner || !name) throw new Error(`invalid GITHUB_REPOSITORY "${repo}"`);
|
|
17636
|
-
const record2 = await createStateBackendFromEnv().getRepoDoc(`${owner}/${name}`, "secrets.enc");
|
|
17637
|
-
const raw = record2?.doc;
|
|
17638
|
-
const payload = raw && typeof raw === "object" && !Array.isArray(raw) && typeof raw.ciphertext === "string" ? raw.ciphertext : "";
|
|
17639
|
-
if (!payload) throw new Error("backend vault is empty \u2014 save secrets from the dashboard first");
|
|
17640
|
-
const plaintext = decryptVaultPayload(payload, masterKey);
|
|
17641
|
-
return JSON.parse(plaintext);
|
|
17642
|
-
}
|
|
17643
17704
|
async function flyAppExists(name, token) {
|
|
17644
17705
|
const res = await fetch(`${FLY_MACHINES}/apps/${encodeURIComponent(name)}`, {
|
|
17645
17706
|
headers: flyHeaders(token),
|
|
@@ -17814,7 +17875,7 @@ var FLY_MACHINES, FLY_GRAPHQL, REQ_TIMEOUT_MS2, runPreviewBuild;
|
|
|
17814
17875
|
var init_runPreviewBuild = __esm({
|
|
17815
17876
|
"src/scripts/runPreviewBuild.ts"() {
|
|
17816
17877
|
"use strict";
|
|
17817
|
-
|
|
17878
|
+
init_kody_api_client();
|
|
17818
17879
|
init_previewBuildHelpers();
|
|
17819
17880
|
init_previewBuildNamespace();
|
|
17820
17881
|
init_previewBuildRun();
|
|
@@ -17831,12 +17892,10 @@ var init_runPreviewBuild = __esm({
|
|
|
17831
17892
|
}
|
|
17832
17893
|
let repo;
|
|
17833
17894
|
let ref;
|
|
17834
|
-
let masterKey;
|
|
17835
17895
|
let ghToken3;
|
|
17836
17896
|
try {
|
|
17837
17897
|
repo = required("GITHUB_REPOSITORY");
|
|
17838
17898
|
ref = required("GITHUB_SHA");
|
|
17839
|
-
masterKey = required("KODY_MASTER_KEY");
|
|
17840
17899
|
ghToken3 = (process.env.KODY_TOKEN ?? process.env.GH_TOKEN ?? process.env.GITHUB_TOKEN ?? process.env.GH_PAT ?? "").trim();
|
|
17841
17900
|
if (!ghToken3) {
|
|
17842
17901
|
throw new Error("GitHub auth token missing (KODY_TOKEN / GH_TOKEN / GITHUB_TOKEN / GH_PAT all empty)");
|
|
@@ -17850,17 +17909,17 @@ var init_runPreviewBuild = __esm({
|
|
|
17850
17909
|
const appName = previewAppName(repo, pr);
|
|
17851
17910
|
const tag = defaultImageTag(repo, ref);
|
|
17852
17911
|
try {
|
|
17853
|
-
const
|
|
17854
|
-
const { buildEnv, buildMode } =
|
|
17855
|
-
const flyToken =
|
|
17912
|
+
const previewContext = await readPreviewContextFromKody();
|
|
17913
|
+
const { buildEnv, buildMode } = previewContext;
|
|
17914
|
+
const flyToken = previewContext.flyApiToken?.trim();
|
|
17856
17915
|
if (!flyToken) {
|
|
17857
17916
|
ctx.output.exitCode = 99;
|
|
17858
17917
|
ctx.output.reason = "runPreviewBuild: vault has no FLY_API_TOKEN \u2014 add it via the dashboard's /secrets page";
|
|
17859
17918
|
return;
|
|
17860
17919
|
}
|
|
17861
|
-
const orgSlug =
|
|
17862
|
-
const region =
|
|
17863
|
-
const nscTenantId =
|
|
17920
|
+
const orgSlug = previewContext.flyOrgSlug?.trim() || (process.env.FLY_ORG_SLUG ?? "personal").trim();
|
|
17921
|
+
const region = previewContext.flyRegion?.trim() || (process.env.FLY_REGION ?? "fra").trim();
|
|
17922
|
+
const nscTenantId = previewContext.namespaceTenantId?.trim() || "";
|
|
17864
17923
|
console.log(`[preview-build] vault: ${Object.keys(buildEnv).length} secrets, mode=${buildMode}`);
|
|
17865
17924
|
if (Object.keys(buildEnv).length > 0) {
|
|
17866
17925
|
const lines = Object.entries(buildEnv).map(([k, v]) => `${k}=${JSON.stringify(v)}`);
|
|
@@ -17942,7 +18001,7 @@ var init_runPreviewBuild = __esm({
|
|
|
17942
18001
|
appName,
|
|
17943
18002
|
region,
|
|
17944
18003
|
image: `registry.fly.io/${appName}:${tag}`,
|
|
17945
|
-
env: previewRuntimeEnv({ buildEnv,
|
|
18004
|
+
env: previewRuntimeEnv({ buildEnv, previewVerifyKey: previewContext.previewVerifyKey, pr, repo })
|
|
17946
18005
|
},
|
|
17947
18006
|
flyToken
|
|
17948
18007
|
);
|
|
@@ -19725,10 +19784,10 @@ async function hydrateWorkflows(backend, tenant, cwd) {
|
|
|
19725
19784
|
}
|
|
19726
19785
|
async function hydrateStateWorkspace(config, cwd, backendOverride) {
|
|
19727
19786
|
const tenant = tenantId(config);
|
|
19728
|
-
const configured =
|
|
19787
|
+
const configured = hasStateBackendConfig();
|
|
19729
19788
|
if (!tenant || !configured) {
|
|
19730
19789
|
if (process.env.GITHUB_ACTIONS === "true")
|
|
19731
|
-
throw new Error("
|
|
19790
|
+
throw new Error("Kody backend access is required for runtime workspace documents");
|
|
19732
19791
|
return;
|
|
19733
19792
|
}
|
|
19734
19793
|
const key = `${path43.resolve(cwd)}|${tenant}`;
|
|
@@ -24353,12 +24412,12 @@ var BrokerSink = class {
|
|
|
24353
24412
|
const be = translateChatEvent(event, this.chatId);
|
|
24354
24413
|
if (!be) return;
|
|
24355
24414
|
this.emitToLog(be);
|
|
24356
|
-
if (this.tenantId &&
|
|
24415
|
+
if (this.tenantId && hasStateBackendConfig2()) {
|
|
24357
24416
|
await createStateBackendFromEnv().appendChatEvent(this.tenantId, this.chatId, be);
|
|
24358
24417
|
}
|
|
24359
24418
|
}
|
|
24360
24419
|
};
|
|
24361
|
-
function
|
|
24420
|
+
function hasStateBackendConfig2(env = process.env) {
|
|
24362
24421
|
return Boolean(env.CONVEX_URL?.trim() && env.KODY_SERVICE_KEY?.trim());
|
|
24363
24422
|
}
|
|
24364
24423
|
var chatQueues = /* @__PURE__ */ new Map();
|
|
@@ -25623,10 +25682,9 @@ async function hydrateDefinitions(options) {
|
|
|
25623
25682
|
}
|
|
25624
25683
|
async function hydrateDefinitionsFromEnv(cwd = process.cwd(), env = process.env) {
|
|
25625
25684
|
const tenantId2 = env.GITHUB_REPOSITORY?.trim();
|
|
25626
|
-
|
|
25627
|
-
if (!hasCredentials) {
|
|
25685
|
+
if (!hasStateBackendConfig(env)) {
|
|
25628
25686
|
if (env.GITHUB_ACTIONS === "true") {
|
|
25629
|
-
throw new Error("
|
|
25687
|
+
throw new Error("GitHub Actions workflow identity is required for backend definitions");
|
|
25630
25688
|
}
|
|
25631
25689
|
return null;
|
|
25632
25690
|
}
|
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.410",
|
|
4
4
|
"description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|