@kody-ade/kody-engine 0.4.188 → 0.4.190
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 +119 -29
- package/dist/bin/preview-build-templates/default-Dockerfile.preview.dev +6 -1
- package/dist/bin/preview-build-templates/default-Dockerfile.preview.prod +6 -1
- package/dist/executables/goal-scheduler/scheduler.sh +0 -0
- package/dist/executables/release-deploy/deploy.sh +0 -0
- package/dist/executables/release-prepare/prepare.sh +0 -0
- package/dist/executables/release-publish/publish.sh +0 -0
- package/dist/executables/resolve/apply-prefer.sh +0 -0
- package/dist/executables/revert/revert.sh +0 -0
- package/package.json +21 -20
- package/templates/kody.yml +1 -0
package/dist/bin/kody.js
CHANGED
|
@@ -1309,7 +1309,7 @@ var init_loadPriorArt = __esm({
|
|
|
1309
1309
|
// package.json
|
|
1310
1310
|
var package_default = {
|
|
1311
1311
|
name: "@kody-ade/kody-engine",
|
|
1312
|
-
version: "0.4.
|
|
1312
|
+
version: "0.4.190",
|
|
1313
1313
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
1314
1314
|
license: "MIT",
|
|
1315
1315
|
type: "module",
|
|
@@ -12365,10 +12365,79 @@ async function runCmd(cmd, args, opts = {}) {
|
|
|
12365
12365
|
});
|
|
12366
12366
|
}
|
|
12367
12367
|
|
|
12368
|
+
// src/scripts/previewBuildNamespace.ts
|
|
12369
|
+
var NSC_OIDC_AUDIENCE = "https://namespace.so";
|
|
12370
|
+
var REQ_TIMEOUT_MS = 15e3;
|
|
12371
|
+
var NSC_INSTALL = `
|
|
12372
|
+
set -euo pipefail
|
|
12373
|
+
if [ ! -x /usr/local/bin/nsc ]; then
|
|
12374
|
+
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
|
|
12375
|
+
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
12376
|
+
curl -fsSL "https://get.namespace.so/packages/nsc/latest?arch=\${ARCH}&os=\${OS}" -o /tmp/nsc.tar.gz
|
|
12377
|
+
mkdir -p /tmp/nsc-extract
|
|
12378
|
+
tar -xzf /tmp/nsc.tar.gz -C /tmp/nsc-extract
|
|
12379
|
+
NSC_BIN=$(find /tmp/nsc-extract -type f -name nsc | head -1)
|
|
12380
|
+
sudo install -m 0755 "$NSC_BIN" /usr/local/bin/nsc
|
|
12381
|
+
fi
|
|
12382
|
+
/usr/local/bin/nsc version
|
|
12383
|
+
`;
|
|
12384
|
+
async function fetchGithubOidcToken(audience) {
|
|
12385
|
+
const url = process.env.ACTIONS_ID_TOKEN_REQUEST_URL?.trim();
|
|
12386
|
+
const requestToken = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN?.trim();
|
|
12387
|
+
if (!url || !requestToken) return null;
|
|
12388
|
+
const res = await fetch(`${url}&audience=${encodeURIComponent(audience)}`, {
|
|
12389
|
+
headers: { Authorization: `Bearer ${requestToken}` },
|
|
12390
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS)
|
|
12391
|
+
});
|
|
12392
|
+
if (!res.ok) {
|
|
12393
|
+
throw new Error(`OIDC token request failed: ${res.status} ${res.statusText}`);
|
|
12394
|
+
}
|
|
12395
|
+
const data = await res.json();
|
|
12396
|
+
if (!data.value) throw new Error("OIDC token response missing `value`");
|
|
12397
|
+
return data.value;
|
|
12398
|
+
}
|
|
12399
|
+
async function setupNamespaceBuilder(opts) {
|
|
12400
|
+
try {
|
|
12401
|
+
await runCmd("bash", ["-c", NSC_INSTALL]);
|
|
12402
|
+
const jwt = await fetchGithubOidcToken(NSC_OIDC_AUDIENCE);
|
|
12403
|
+
if (!jwt) {
|
|
12404
|
+
console.warn(
|
|
12405
|
+
"[preview-build] no GitHub OIDC token (id-token: write missing?) \u2014 local docker build"
|
|
12406
|
+
);
|
|
12407
|
+
return null;
|
|
12408
|
+
}
|
|
12409
|
+
await runCmd("nsc", [
|
|
12410
|
+
"auth",
|
|
12411
|
+
"exchange-oidc-token",
|
|
12412
|
+
"--tenant_id",
|
|
12413
|
+
opts.tenantId,
|
|
12414
|
+
"--token",
|
|
12415
|
+
jwt
|
|
12416
|
+
]);
|
|
12417
|
+
await runCmd("nsc", [
|
|
12418
|
+
"docker",
|
|
12419
|
+
"buildx",
|
|
12420
|
+
"setup",
|
|
12421
|
+
"--name",
|
|
12422
|
+
opts.builderName
|
|
12423
|
+
]);
|
|
12424
|
+
console.log(
|
|
12425
|
+
`[preview-build] Namespace remote builder ready (${opts.builderName})`
|
|
12426
|
+
);
|
|
12427
|
+
return opts.builderName;
|
|
12428
|
+
} catch (err) {
|
|
12429
|
+
console.warn(
|
|
12430
|
+
"[preview-build] Namespace setup failed \u2014 falling back to local docker:",
|
|
12431
|
+
err instanceof Error ? err.message : String(err)
|
|
12432
|
+
);
|
|
12433
|
+
return null;
|
|
12434
|
+
}
|
|
12435
|
+
}
|
|
12436
|
+
|
|
12368
12437
|
// src/scripts/runPreviewBuild.ts
|
|
12369
12438
|
var FLY_MACHINES = "https://api.machines.dev/v1";
|
|
12370
12439
|
var FLY_GRAPHQL = "https://api.fly.io/graphql";
|
|
12371
|
-
var
|
|
12440
|
+
var REQ_TIMEOUT_MS2 = 3e4;
|
|
12372
12441
|
function bundledDockerfilePath(mode) {
|
|
12373
12442
|
const here = path36.dirname(fileURLToPath(import.meta.url));
|
|
12374
12443
|
const file = mode === "dev" ? "default-Dockerfile.preview.dev" : "default-Dockerfile.preview.prod";
|
|
@@ -12392,7 +12461,7 @@ async function ghJSON(url, token) {
|
|
|
12392
12461
|
Accept: "application/vnd.github+json",
|
|
12393
12462
|
"X-GitHub-Api-Version": "2022-11-28"
|
|
12394
12463
|
},
|
|
12395
|
-
signal: AbortSignal.timeout(
|
|
12464
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12396
12465
|
});
|
|
12397
12466
|
if (!res.ok) {
|
|
12398
12467
|
throw new Error(`GitHub ${url}: ${res.status} ${res.statusText}`);
|
|
@@ -12411,7 +12480,7 @@ async function fetchVaultDoc(repo, ghToken4, masterKey) {
|
|
|
12411
12480
|
async function flyAppExists(name, token) {
|
|
12412
12481
|
const res = await fetch(`${FLY_MACHINES}/apps/${encodeURIComponent(name)}`, {
|
|
12413
12482
|
headers: flyHeaders(token),
|
|
12414
|
-
signal: AbortSignal.timeout(
|
|
12483
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12415
12484
|
});
|
|
12416
12485
|
if (res.status === 404) return false;
|
|
12417
12486
|
if (!res.ok) {
|
|
@@ -12424,7 +12493,7 @@ async function flyCreateApp(name, orgSlug, token) {
|
|
|
12424
12493
|
method: "POST",
|
|
12425
12494
|
headers: flyHeaders(token),
|
|
12426
12495
|
body: JSON.stringify({ app_name: name, org_slug: orgSlug }),
|
|
12427
|
-
signal: AbortSignal.timeout(
|
|
12496
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12428
12497
|
});
|
|
12429
12498
|
if (res.status === 422) return;
|
|
12430
12499
|
if (!res.ok) {
|
|
@@ -12443,7 +12512,7 @@ async function flyAllocateSharedIps(appName, token) {
|
|
|
12443
12512
|
method: "POST",
|
|
12444
12513
|
headers: flyHeaders(token),
|
|
12445
12514
|
body: JSON.stringify({ query: mutation, variables: { appId: appName } }),
|
|
12446
|
-
signal: AbortSignal.timeout(
|
|
12515
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12447
12516
|
});
|
|
12448
12517
|
if (!res.ok) {
|
|
12449
12518
|
throw new Error(`allocateSharedIps ${appName}: ${res.status}`);
|
|
@@ -12461,7 +12530,7 @@ async function flyListMachines(appName, token) {
|
|
|
12461
12530
|
`${FLY_MACHINES}/apps/${encodeURIComponent(appName)}/machines`,
|
|
12462
12531
|
{
|
|
12463
12532
|
headers: flyHeaders(token),
|
|
12464
|
-
signal: AbortSignal.timeout(
|
|
12533
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12465
12534
|
}
|
|
12466
12535
|
);
|
|
12467
12536
|
if (res.status === 404) return [];
|
|
@@ -12477,7 +12546,7 @@ async function flyDestroyMachine(appName, machineId, token) {
|
|
|
12477
12546
|
{
|
|
12478
12547
|
method: "POST",
|
|
12479
12548
|
headers: flyHeaders(token),
|
|
12480
|
-
signal: AbortSignal.timeout(
|
|
12549
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12481
12550
|
}
|
|
12482
12551
|
).catch(() => void 0);
|
|
12483
12552
|
const res = await fetch(
|
|
@@ -12485,7 +12554,7 @@ async function flyDestroyMachine(appName, machineId, token) {
|
|
|
12485
12554
|
{
|
|
12486
12555
|
method: "DELETE",
|
|
12487
12556
|
headers: flyHeaders(token),
|
|
12488
|
-
signal: AbortSignal.timeout(
|
|
12557
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12489
12558
|
}
|
|
12490
12559
|
);
|
|
12491
12560
|
if (res.status === 404) return;
|
|
@@ -12538,7 +12607,7 @@ async function flyCreatePreviewMachine(args, token) {
|
|
|
12538
12607
|
method: "POST",
|
|
12539
12608
|
headers: flyHeaders(token),
|
|
12540
12609
|
body: JSON.stringify(body),
|
|
12541
|
-
signal: AbortSignal.timeout(
|
|
12610
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12542
12611
|
}
|
|
12543
12612
|
);
|
|
12544
12613
|
if (res.ok) {
|
|
@@ -12565,7 +12634,7 @@ async function postOrUpdatePreviewComment(args) {
|
|
|
12565
12634
|
};
|
|
12566
12635
|
const listRes = await fetch(`${base}?per_page=100`, {
|
|
12567
12636
|
headers,
|
|
12568
|
-
signal: AbortSignal.timeout(
|
|
12637
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12569
12638
|
}).catch(() => null);
|
|
12570
12639
|
let existingId = null;
|
|
12571
12640
|
if (listRes && listRes.ok) {
|
|
@@ -12580,7 +12649,7 @@ async function postOrUpdatePreviewComment(args) {
|
|
|
12580
12649
|
method: "PATCH",
|
|
12581
12650
|
headers,
|
|
12582
12651
|
body: JSON.stringify({ body: args.body }),
|
|
12583
|
-
signal: AbortSignal.timeout(
|
|
12652
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12584
12653
|
}
|
|
12585
12654
|
);
|
|
12586
12655
|
return;
|
|
@@ -12589,7 +12658,7 @@ async function postOrUpdatePreviewComment(args) {
|
|
|
12589
12658
|
method: "POST",
|
|
12590
12659
|
headers,
|
|
12591
12660
|
body: JSON.stringify({ body: args.body }),
|
|
12592
|
-
signal: AbortSignal.timeout(
|
|
12661
|
+
signal: AbortSignal.timeout(REQ_TIMEOUT_MS2)
|
|
12593
12662
|
});
|
|
12594
12663
|
}
|
|
12595
12664
|
var runPreviewBuild = async (ctx, _profile, _args) => {
|
|
@@ -12633,6 +12702,7 @@ var runPreviewBuild = async (ctx, _profile, _args) => {
|
|
|
12633
12702
|
}
|
|
12634
12703
|
const orgSlug = doc.secrets?.FLY_ORG_SLUG?.value?.trim() || (process.env.FLY_ORG_SLUG ?? "personal").trim();
|
|
12635
12704
|
const region = doc.secrets?.FLY_DEFAULT_REGION?.value?.trim() || (process.env.FLY_REGION ?? "fra").trim();
|
|
12705
|
+
const nscTenantId = doc.secrets?.NSC_TENANT_ID?.value?.trim() || "";
|
|
12636
12706
|
console.log(
|
|
12637
12707
|
`[preview-build] vault: ${Object.keys(buildEnv).length} secrets, mode=${buildMode}`
|
|
12638
12708
|
);
|
|
@@ -12696,22 +12766,42 @@ var runPreviewBuild = async (ctx, _profile, _args) => {
|
|
|
12696
12766
|
["login", "registry.fly.io", "-u", "x", "--password-stdin"],
|
|
12697
12767
|
{ input: flyToken, cwd: ctx.cwd }
|
|
12698
12768
|
);
|
|
12699
|
-
const
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
|
|
12705
|
-
|
|
12706
|
-
|
|
12707
|
-
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12769
|
+
const imageRef = `registry.fly.io/${appName}:${tag}`;
|
|
12770
|
+
const nsBuilder = nscTenantId ? await setupNamespaceBuilder({
|
|
12771
|
+
tenantId: nscTenantId,
|
|
12772
|
+
builderName: `kody-preview-${pr}`
|
|
12773
|
+
}) : null;
|
|
12774
|
+
if (nsBuilder) {
|
|
12775
|
+
const a = [
|
|
12776
|
+
"buildx",
|
|
12777
|
+
"build",
|
|
12778
|
+
"--builder",
|
|
12779
|
+
nsBuilder,
|
|
12780
|
+
"-f",
|
|
12781
|
+
"Dockerfile.preview",
|
|
12782
|
+
"-t",
|
|
12783
|
+
imageRef,
|
|
12784
|
+
"--push"
|
|
12785
|
+
];
|
|
12786
|
+
if (baseImage) a.push("--build-arg", `BASE_IMAGE=${baseImage}`);
|
|
12787
|
+
a.push(".");
|
|
12788
|
+
await runCmd("docker", a, { cwd: ctx.cwd });
|
|
12789
|
+
} else {
|
|
12790
|
+
const buildArgs = [
|
|
12791
|
+
"build",
|
|
12792
|
+
"-f",
|
|
12793
|
+
"Dockerfile.preview",
|
|
12794
|
+
"-t",
|
|
12795
|
+
imageRef
|
|
12796
|
+
];
|
|
12797
|
+
if (baseImage) buildArgs.push("--build-arg", `BASE_IMAGE=${baseImage}`);
|
|
12798
|
+
buildArgs.push(".");
|
|
12799
|
+
await runCmd("docker", buildArgs, {
|
|
12800
|
+
cwd: ctx.cwd,
|
|
12801
|
+
env: { DOCKER_BUILDKIT: "1" }
|
|
12802
|
+
});
|
|
12803
|
+
await runCmd("docker", ["push", imageRef], { cwd: ctx.cwd });
|
|
12804
|
+
}
|
|
12715
12805
|
const stale = await flyListMachines(appName, flyToken);
|
|
12716
12806
|
for (const m of stale) {
|
|
12717
12807
|
await flyDestroyMachine(appName, m.id, flyToken).catch(() => void 0);
|
|
@@ -18,7 +18,12 @@ ARG BASE_IMAGE=node:22-alpine
|
|
|
18
18
|
FROM ${BASE_IMAGE}
|
|
19
19
|
WORKDIR /app
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
# corepack's default pnpm on the base image can fall outside the app's
|
|
22
|
+
# engines.pnpm range → ERR_PNPM_UNSUPPORTED_ENGINE. Pin a current pnpm
|
|
23
|
+
# for repos that don't set packageManager (corepack still honors one
|
|
24
|
+
# when present, so this only affects the unpinned case).
|
|
25
|
+
RUN corepack enable 2>/dev/null || true; \
|
|
26
|
+
corepack prepare pnpm@10.17.0 --activate 2>/dev/null || npm i -g pnpm@10 2>/dev/null || true
|
|
22
27
|
|
|
23
28
|
COPY package.json pnpm-lock.yaml* package-lock.json* yarn.lock* ./
|
|
24
29
|
RUN --mount=type=cache,id=kp-pnpm-store,target=/root/.local/share/pnpm/store \
|
|
@@ -12,7 +12,12 @@ ARG BASE_IMAGE=node:22-alpine
|
|
|
12
12
|
FROM ${BASE_IMAGE}
|
|
13
13
|
WORKDIR /app
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
# corepack's default pnpm on the base image can fall outside the app's
|
|
16
|
+
# engines.pnpm range → ERR_PNPM_UNSUPPORTED_ENGINE. Pin a current pnpm
|
|
17
|
+
# for repos that don't set packageManager (corepack still honors one
|
|
18
|
+
# when present, so this only affects the unpinned case).
|
|
19
|
+
RUN corepack enable 2>/dev/null || true; \
|
|
20
|
+
corepack prepare pnpm@10.17.0 --activate 2>/dev/null || npm i -g pnpm@10 2>/dev/null || true
|
|
16
21
|
|
|
17
22
|
COPY package.json pnpm-lock.yaml* package-lock.json* yarn.lock* ./
|
|
18
23
|
RUN --mount=type=cache,id=kp-pnpm-store,target=/root/.local/share/pnpm/store \
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
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.190",
|
|
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",
|
|
@@ -12,6 +12,24 @@
|
|
|
12
12
|
"templates",
|
|
13
13
|
"kody.config.schema.json"
|
|
14
14
|
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"kody:run": "tsx bin/kody.ts",
|
|
17
|
+
"serve": "tsx bin/kody.ts serve",
|
|
18
|
+
"serve:vscode": "tsx bin/kody.ts serve vscode",
|
|
19
|
+
"serve:claude": "tsx bin/kody.ts serve claude",
|
|
20
|
+
"build": "tsup && node scripts/copy-assets.cjs",
|
|
21
|
+
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
22
|
+
"pretest": "pnpm check:modularity",
|
|
23
|
+
"test": "vitest run tests/unit tests/int --coverage",
|
|
24
|
+
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
25
|
+
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
26
|
+
"test:all": "vitest run tests --no-coverage",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"lint": "biome check",
|
|
29
|
+
"lint:fix": "biome check --write",
|
|
30
|
+
"format": "biome format --write",
|
|
31
|
+
"prepublishOnly": "pnpm build"
|
|
32
|
+
},
|
|
15
33
|
"dependencies": {
|
|
16
34
|
"@actions/cache": "^6.0.0",
|
|
17
35
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
@@ -34,22 +52,5 @@
|
|
|
34
52
|
"url": "git+https://github.com/aharonyaircohen/kody-engine.git"
|
|
35
53
|
},
|
|
36
54
|
"homepage": "https://github.com/aharonyaircohen/kody-engine",
|
|
37
|
-
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
38
|
-
|
|
39
|
-
"kody:run": "tsx bin/kody.ts",
|
|
40
|
-
"serve": "tsx bin/kody.ts serve",
|
|
41
|
-
"serve:vscode": "tsx bin/kody.ts serve vscode",
|
|
42
|
-
"serve:claude": "tsx bin/kody.ts serve claude",
|
|
43
|
-
"build": "tsup && node scripts/copy-assets.cjs",
|
|
44
|
-
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
45
|
-
"pretest": "pnpm check:modularity",
|
|
46
|
-
"test": "vitest run tests/unit tests/int --coverage",
|
|
47
|
-
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
48
|
-
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
49
|
-
"test:all": "vitest run tests --no-coverage",
|
|
50
|
-
"typecheck": "tsc --noEmit",
|
|
51
|
-
"lint": "biome check",
|
|
52
|
-
"lint:fix": "biome check --write",
|
|
53
|
-
"format": "biome format --write"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
55
|
+
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
56
|
+
}
|