@kody-ade/kody-engine 0.4.574 → 0.4.575
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
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.575",
|
|
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",
|
|
@@ -2188,6 +2188,7 @@ function readCapabilityFolder(root, slug) {
|
|
|
2188
2188
|
rawProfile: contract ? {
|
|
2189
2189
|
...contract.execution ? { execution: contract.execution } : {},
|
|
2190
2190
|
...contract.deliveryPolicy ? { deliveryPolicy: contract.deliveryPolicy } : {},
|
|
2191
|
+
...contract.deliveryPathAllowlist ? { deliveryPathAllowlist: contract.deliveryPathAllowlist } : {},
|
|
2191
2192
|
input: contract.input,
|
|
2192
2193
|
output: contract.output
|
|
2193
2194
|
} : {},
|
|
@@ -2227,8 +2228,12 @@ function parseCapabilityContract(raw) {
|
|
|
2227
2228
|
if (requiredSubagents && parsed.execution !== "agent") {
|
|
2228
2229
|
throw new Error('contract.json requiredSubagents are supported only when execution is "agent"');
|
|
2229
2230
|
}
|
|
2231
|
+
const deliveryPathAllowlist = parseDeliveryPathAllowlist(parsed.deliveryPathAllowlist);
|
|
2232
|
+
if (deliveryPathAllowlist && parsed.execution !== "agent") {
|
|
2233
|
+
throw new Error('contract.json deliveryPathAllowlist is supported only when execution is "agent"');
|
|
2234
|
+
}
|
|
2230
2235
|
const unsupported = Object.keys(parsed).filter(
|
|
2231
|
-
(key) => key !== "execution" && key !== "deliveryPolicy" && key !== "requirements" && key !== "secrets" && key !== "timeoutMs" && key !== "requiredSubagents" && key !== "input" && key !== "output"
|
|
2236
|
+
(key) => key !== "execution" && key !== "deliveryPolicy" && key !== "deliveryPathAllowlist" && key !== "requirements" && key !== "secrets" && key !== "timeoutMs" && key !== "requiredSubagents" && key !== "input" && key !== "output"
|
|
2232
2237
|
);
|
|
2233
2238
|
if (unsupported.length > 0) {
|
|
2234
2239
|
throw new Error(`contract.json contains unsupported fields: ${unsupported.join(", ")}`);
|
|
@@ -2242,6 +2247,7 @@ function parseCapabilityContract(raw) {
|
|
|
2242
2247
|
return {
|
|
2243
2248
|
...parsed.execution ? { execution: parsed.execution } : {},
|
|
2244
2249
|
...parsed.deliveryPolicy === "checkpoint" ? { deliveryPolicy: "checkpoint" } : {},
|
|
2250
|
+
...deliveryPathAllowlist ? { deliveryPathAllowlist } : {},
|
|
2245
2251
|
...requirements ? { requirements } : {},
|
|
2246
2252
|
...secrets ? { secrets } : {},
|
|
2247
2253
|
...timeoutMs !== void 0 ? { timeoutMs } : {},
|
|
@@ -2250,6 +2256,25 @@ function parseCapabilityContract(raw) {
|
|
|
2250
2256
|
output: parsed.output
|
|
2251
2257
|
};
|
|
2252
2258
|
}
|
|
2259
|
+
function parseDeliveryPathAllowlist(raw) {
|
|
2260
|
+
if (raw === void 0) return void 0;
|
|
2261
|
+
if (!Array.isArray(raw) || raw.length === 0 || raw.length > 64) {
|
|
2262
|
+
throw new Error("contract.json deliveryPathAllowlist must contain 1 to 64 paths");
|
|
2263
|
+
}
|
|
2264
|
+
if (!raw.every((value) => typeof value === "string")) {
|
|
2265
|
+
throw new Error("contract.json deliveryPathAllowlist must contain paths");
|
|
2266
|
+
}
|
|
2267
|
+
const paths = [...new Set(raw)];
|
|
2268
|
+
for (const value of paths) {
|
|
2269
|
+
const subtree = value.endsWith("/**");
|
|
2270
|
+
const base = subtree ? value.slice(0, -3) : value;
|
|
2271
|
+
const segments = base.split("/");
|
|
2272
|
+
if (!base || base.startsWith("/") || base.startsWith(".") && !base.startsWith(".github/") || base.includes("\\") || base.includes("..") || base.includes("*") || segments.some((segment) => !segment) || subtree && segments.length < 2 || value === ".github/**") {
|
|
2273
|
+
throw new Error(`contract.json deliveryPathAllowlist contains an unsafe path: ${value}`);
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
return paths;
|
|
2277
|
+
}
|
|
2253
2278
|
function parseCapabilityRequirements(raw) {
|
|
2254
2279
|
if (raw === void 0) return void 0;
|
|
2255
2280
|
if (!isPlainObject(raw)) throw new Error("contract.json requirements must be an object");
|
|
@@ -8655,12 +8680,18 @@ function abortUnfinishedGitOps(cwd) {
|
|
|
8655
8680
|
}
|
|
8656
8681
|
return aborted;
|
|
8657
8682
|
}
|
|
8658
|
-
function
|
|
8683
|
+
function isExplicitlyAllowed(p, allowlist) {
|
|
8684
|
+
return allowlist.some(
|
|
8685
|
+
(entry) => entry.endsWith("/**") ? p.startsWith(entry.slice(0, -2)) : p === entry
|
|
8686
|
+
);
|
|
8687
|
+
}
|
|
8688
|
+
function isForbiddenPath(p, deliveryPathAllowlist = []) {
|
|
8659
8689
|
if (FORBIDDEN_PATH_EXACT.has(p)) return true;
|
|
8660
|
-
if (isGitHubYamlPath(p)) return true;
|
|
8661
|
-
for (const pre of ALLOWED_PATH_PREFIXES) if (p.startsWith(pre)) return false;
|
|
8662
8690
|
for (const pre of FORBIDDEN_PATH_PREFIXES) if (p.startsWith(pre)) return true;
|
|
8663
8691
|
for (const suf of FORBIDDEN_PATH_SUFFIXES) if (p.endsWith(suf)) return true;
|
|
8692
|
+
if (isExplicitlyAllowed(p, deliveryPathAllowlist)) return false;
|
|
8693
|
+
if (isGitHubYamlPath(p)) return true;
|
|
8694
|
+
for (const pre of ALLOWED_PATH_PREFIXES) if (p.startsWith(pre)) return false;
|
|
8664
8695
|
return false;
|
|
8665
8696
|
}
|
|
8666
8697
|
function listChangedFiles(cwd) {
|
|
@@ -8696,14 +8727,14 @@ function normalizeCommitMessage(raw) {
|
|
|
8696
8727
|
}
|
|
8697
8728
|
return `chore: ${trimmed}`;
|
|
8698
8729
|
}
|
|
8699
|
-
function commitAndPush(branch, agentMessage, cwd) {
|
|
8730
|
+
function commitAndPush(branch, agentMessage, cwd, deliveryPathAllowlist = []) {
|
|
8700
8731
|
const allChanged = listChangedFiles(cwd);
|
|
8701
|
-
const allowedFiles = allChanged.filter((f) => !isForbiddenPath(f));
|
|
8732
|
+
const allowedFiles = allChanged.filter((f) => !isForbiddenPath(f, deliveryPathAllowlist));
|
|
8702
8733
|
const mergeHeadExists = fs29.existsSync(path28.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
|
|
8703
8734
|
if (allowedFiles.length === 0 && !mergeHeadExists) {
|
|
8704
8735
|
return { committed: false, pushed: false, sha: "", message: "" };
|
|
8705
8736
|
}
|
|
8706
|
-
const forbiddenFiles = allChanged.filter((f) => isForbiddenPath(f));
|
|
8737
|
+
const forbiddenFiles = allChanged.filter((f) => isForbiddenPath(f, deliveryPathAllowlist));
|
|
8707
8738
|
for (const f of forbiddenFiles) {
|
|
8708
8739
|
try {
|
|
8709
8740
|
git(["reset", "-q", "--", f], cwd);
|
|
@@ -12362,11 +12393,14 @@ var init_commitAndPush = __esm({
|
|
|
12362
12393
|
ctx.data.salvagedFromMissingMarker = true;
|
|
12363
12394
|
}
|
|
12364
12395
|
const message = ctx.data.commitMessage || DEFAULT_COMMIT_MESSAGE;
|
|
12396
|
+
const deliveryPathAllowlist = Array.isArray(ctx.data.deliveryPathAllowlist) ? ctx.data.deliveryPathAllowlist : [];
|
|
12365
12397
|
try {
|
|
12366
|
-
const result2 = commitAndPush(branch, message, ctx.cwd);
|
|
12398
|
+
const result2 = commitAndPush(branch, message, ctx.cwd, deliveryPathAllowlist);
|
|
12367
12399
|
ctx.data.commitResult = result2;
|
|
12368
12400
|
const postCommitFiles = result2.committed ? listFilesInCommit("HEAD", ctx.cwd) : listChangedFiles(ctx.cwd);
|
|
12369
|
-
ctx.data.changedFiles = postCommitFiles.filter(
|
|
12401
|
+
ctx.data.changedFiles = postCommitFiles.filter(
|
|
12402
|
+
(f) => !isForbiddenPath(f, deliveryPathAllowlist)
|
|
12403
|
+
);
|
|
12370
12404
|
if (result2.committed && !result2.pushed) {
|
|
12371
12405
|
const reason = result2.pushError ?? "push failed (no error detail)";
|
|
12372
12406
|
ctx.data.commitCrash = reason;
|
|
@@ -16326,6 +16360,9 @@ var init_loadSimpleCapability = __esm({
|
|
|
16326
16360
|
if (capability.contract?.deliveryPolicy) {
|
|
16327
16361
|
ctx.data.capabilityDeliveryPolicy = capability.contract.deliveryPolicy;
|
|
16328
16362
|
}
|
|
16363
|
+
if (capability.contract?.deliveryPathAllowlist) {
|
|
16364
|
+
ctx.data.deliveryPathAllowlist = capability.contract.deliveryPathAllowlist;
|
|
16365
|
+
}
|
|
16329
16366
|
if (capability.contract?.requirements) {
|
|
16330
16367
|
ctx.data.capabilityRequirements = capability.contract.requirements;
|
|
16331
16368
|
}
|
|
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.575",
|
|
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",
|
|
@@ -12,30 +12,6 @@
|
|
|
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
|
-
"clean:dist": "node scripts/clean-dist.cjs",
|
|
21
|
-
"build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
|
|
22
|
-
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
23
|
-
"pretest": "pnpm check:modularity",
|
|
24
|
-
"test": "vitest run tests/unit tests/int --coverage",
|
|
25
|
-
"posttest": "tsx scripts/check-coverage-floor.ts",
|
|
26
|
-
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
27
|
-
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
28
|
-
"verify:live-release": "tsx scripts/live-release-gate.ts",
|
|
29
|
-
"test:runtime-services": "node --test \"tests/runtime-services/*.test.mjs\"",
|
|
30
|
-
"test:all": "vitest run tests --no-coverage",
|
|
31
|
-
"typecheck": "tsc --noEmit",
|
|
32
|
-
"lint": "biome check",
|
|
33
|
-
"lint:fix": "biome check --write",
|
|
34
|
-
"format": "biome format --write",
|
|
35
|
-
"verify:package": "node scripts/verify-package-tarball.cjs",
|
|
36
|
-
"brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain --build-arg KODY_ENGINE_REF=$(git rev-parse HEAD) -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner",
|
|
37
|
-
"prepublishOnly": "pnpm typecheck && pnpm test:runtime-services && pnpm build && pnpm verify:package"
|
|
38
|
-
},
|
|
39
15
|
"dependencies": {
|
|
40
16
|
"@actions/cache": "^6.0.0",
|
|
41
17
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
@@ -62,5 +38,28 @@
|
|
|
62
38
|
"url": "git+https://github.com/aharonyaircohen/kody-engine.git"
|
|
63
39
|
},
|
|
64
40
|
"homepage": "https://github.com/aharonyaircohen/kody-engine",
|
|
65
|
-
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
66
|
-
|
|
41
|
+
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues",
|
|
42
|
+
"scripts": {
|
|
43
|
+
"kody:run": "tsx bin/kody.ts",
|
|
44
|
+
"serve": "tsx bin/kody.ts serve",
|
|
45
|
+
"serve:vscode": "tsx bin/kody.ts serve vscode",
|
|
46
|
+
"serve:claude": "tsx bin/kody.ts serve claude",
|
|
47
|
+
"clean:dist": "node scripts/clean-dist.cjs",
|
|
48
|
+
"build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
|
|
49
|
+
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
50
|
+
"pretest": "pnpm check:modularity",
|
|
51
|
+
"test": "vitest run tests/unit tests/int --coverage",
|
|
52
|
+
"posttest": "tsx scripts/check-coverage-floor.ts",
|
|
53
|
+
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
54
|
+
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
55
|
+
"verify:live-release": "tsx scripts/live-release-gate.ts",
|
|
56
|
+
"test:runtime-services": "node --test \"tests/runtime-services/*.test.mjs\"",
|
|
57
|
+
"test:all": "vitest run tests --no-coverage",
|
|
58
|
+
"typecheck": "tsc --noEmit",
|
|
59
|
+
"lint": "biome check",
|
|
60
|
+
"lint:fix": "biome check --write",
|
|
61
|
+
"format": "biome format --write",
|
|
62
|
+
"verify:package": "node scripts/verify-package-tarball.cjs",
|
|
63
|
+
"brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain --build-arg KODY_ENGINE_REF=$(git rev-parse HEAD) -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner"
|
|
64
|
+
}
|
|
65
|
+
}
|