@kody-ade/kody-engine 0.4.579 → 0.4.581
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 +54 -8
- 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.581",
|
|
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",
|
|
@@ -8620,6 +8620,7 @@ var init_pushWithRetry = __esm({
|
|
|
8620
8620
|
|
|
8621
8621
|
// src/commit.ts
|
|
8622
8622
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
8623
|
+
import { isDeepStrictEqual } from "util";
|
|
8623
8624
|
import * as fs29 from "fs";
|
|
8624
8625
|
import * as path28 from "path";
|
|
8625
8626
|
function isGitHubYamlPath(filePath) {
|
|
@@ -8694,13 +8695,46 @@ function isExplicitlyAllowed(p, allowlist) {
|
|
|
8694
8695
|
}
|
|
8695
8696
|
function isForbiddenPath(p, deliveryPathAllowlist = []) {
|
|
8696
8697
|
if (FORBIDDEN_PATH_EXACT.has(p)) return true;
|
|
8697
|
-
for (const pre of FORBIDDEN_PATH_PREFIXES) if (p.startsWith(pre)) return true;
|
|
8698
8698
|
for (const suf of FORBIDDEN_PATH_SUFFIXES) if (p.endsWith(suf)) return true;
|
|
8699
|
-
if (isExplicitlyAllowed(p, deliveryPathAllowlist))
|
|
8699
|
+
if (isExplicitlyAllowed(p, deliveryPathAllowlist) && (p.startsWith(".kody-engine/definitions/loops/") || isGitHubYamlPath(p))) {
|
|
8700
|
+
return false;
|
|
8701
|
+
}
|
|
8702
|
+
for (const pre of FORBIDDEN_PATH_PREFIXES) if (p.startsWith(pre)) return true;
|
|
8700
8703
|
if (isGitHubYamlPath(p)) return true;
|
|
8701
8704
|
for (const pre of ALLOWED_PATH_PREFIXES) if (p.startsWith(pre)) return false;
|
|
8702
8705
|
return false;
|
|
8703
8706
|
}
|
|
8707
|
+
function isRecord(value) {
|
|
8708
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8709
|
+
}
|
|
8710
|
+
function isSafeConfigActivationChange(before, after) {
|
|
8711
|
+
if (!isRecord(before) || !isRecord(after)) return false;
|
|
8712
|
+
const beforeRest = { ...before };
|
|
8713
|
+
const afterRest = { ...after };
|
|
8714
|
+
for (const field of ACTIVATION_FIELDS) {
|
|
8715
|
+
const previous = before[field];
|
|
8716
|
+
const next = after[field];
|
|
8717
|
+
delete beforeRest[field];
|
|
8718
|
+
delete afterRest[field];
|
|
8719
|
+
if (previous === void 0 && next === void 0) continue;
|
|
8720
|
+
if (!Array.isArray(previous ?? []) || !Array.isArray(next)) return false;
|
|
8721
|
+
if (!next.every((value) => typeof value === "string")) return false;
|
|
8722
|
+
if (!previous.every((value) => typeof value === "string")) return false;
|
|
8723
|
+
const nextValues = new Set(next);
|
|
8724
|
+
if (!previous.every((value) => nextValues.has(value))) return false;
|
|
8725
|
+
}
|
|
8726
|
+
return isDeepStrictEqual(beforeRest, afterRest);
|
|
8727
|
+
}
|
|
8728
|
+
function isTrustedConfigActivationChange(filePath, deliveryPathAllowlist, cwd) {
|
|
8729
|
+
if (filePath !== "kody.config.json" || !deliveryPathAllowlist.includes(filePath)) return false;
|
|
8730
|
+
try {
|
|
8731
|
+
const before = JSON.parse(git(["show", "HEAD:kody.config.json"], cwd));
|
|
8732
|
+
const after = JSON.parse(fs29.readFileSync(path28.join(cwd ?? process.cwd(), filePath), "utf-8"));
|
|
8733
|
+
return isSafeConfigActivationChange(before, after);
|
|
8734
|
+
} catch {
|
|
8735
|
+
return false;
|
|
8736
|
+
}
|
|
8737
|
+
}
|
|
8704
8738
|
function listChangedFiles(cwd) {
|
|
8705
8739
|
const raw = execFileSync6("git", ["status", "--porcelain=v1", "-z", "--untracked-files=all"], {
|
|
8706
8740
|
encoding: "utf-8",
|
|
@@ -8736,12 +8770,16 @@ function normalizeCommitMessage(raw) {
|
|
|
8736
8770
|
}
|
|
8737
8771
|
function commitAndPush(branch, agentMessage, cwd, deliveryPathAllowlist = []) {
|
|
8738
8772
|
const allChanged = listChangedFiles(cwd);
|
|
8739
|
-
const allowedFiles = allChanged.filter(
|
|
8773
|
+
const allowedFiles = allChanged.filter(
|
|
8774
|
+
(f) => !isForbiddenPath(f, deliveryPathAllowlist) || isTrustedConfigActivationChange(f, deliveryPathAllowlist, cwd)
|
|
8775
|
+
);
|
|
8740
8776
|
const mergeHeadExists = fs29.existsSync(path28.join(cwd ?? process.cwd(), ".git", "MERGE_HEAD"));
|
|
8741
8777
|
if (allowedFiles.length === 0 && !mergeHeadExists) {
|
|
8742
8778
|
return { committed: false, pushed: false, sha: "", message: "" };
|
|
8743
8779
|
}
|
|
8744
|
-
const forbiddenFiles = allChanged.filter(
|
|
8780
|
+
const forbiddenFiles = allChanged.filter(
|
|
8781
|
+
(f) => isForbiddenPath(f, deliveryPathAllowlist) && !isTrustedConfigActivationChange(f, deliveryPathAllowlist, cwd)
|
|
8782
|
+
);
|
|
8745
8783
|
for (const f of forbiddenFiles) {
|
|
8746
8784
|
try {
|
|
8747
8785
|
git(["reset", "-q", "--", f], cwd);
|
|
@@ -8785,7 +8823,7 @@ function hasCommitsAhead(branch, defaultBranch, cwd) {
|
|
|
8785
8823
|
}
|
|
8786
8824
|
}
|
|
8787
8825
|
}
|
|
8788
|
-
var FORBIDDEN_PATH_PREFIXES, ALLOWED_PATH_PREFIXES, FORBIDDEN_PATH_EXACT, FORBIDDEN_PATH_SUFFIXES, CONVENTIONAL_PREFIXES;
|
|
8826
|
+
var FORBIDDEN_PATH_PREFIXES, ALLOWED_PATH_PREFIXES, FORBIDDEN_PATH_EXACT, FORBIDDEN_PATH_SUFFIXES, ACTIVATION_FIELDS, CONVENTIONAL_PREFIXES;
|
|
8789
8827
|
var init_commit = __esm({
|
|
8790
8828
|
"src/commit.ts"() {
|
|
8791
8829
|
"use strict";
|
|
@@ -8808,6 +8846,14 @@ var init_commit = __esm({
|
|
|
8808
8846
|
ALLOWED_PATH_PREFIXES = [];
|
|
8809
8847
|
FORBIDDEN_PATH_EXACT = /* @__PURE__ */ new Set([".env", ".kody-pip-requirements.txt", "kody.config.json"]);
|
|
8810
8848
|
FORBIDDEN_PATH_SUFFIXES = [".log"];
|
|
8849
|
+
ACTIVATION_FIELDS = [
|
|
8850
|
+
"activeAgents",
|
|
8851
|
+
"activeCapabilities",
|
|
8852
|
+
"activeWorkflows",
|
|
8853
|
+
"activePipelines",
|
|
8854
|
+
"activeCommands",
|
|
8855
|
+
"activeFeatures"
|
|
8856
|
+
];
|
|
8811
8857
|
CONVENTIONAL_PREFIXES = [
|
|
8812
8858
|
"feat:",
|
|
8813
8859
|
"fix:",
|
|
@@ -8842,7 +8888,7 @@ var init_abortUnfinishedGitOps = __esm({
|
|
|
8842
8888
|
});
|
|
8843
8889
|
|
|
8844
8890
|
// src/scripts/deliveryOutcome.ts
|
|
8845
|
-
function
|
|
8891
|
+
function isRecord2(input) {
|
|
8846
8892
|
return !!input && typeof input === "object" && !Array.isArray(input);
|
|
8847
8893
|
}
|
|
8848
8894
|
function setDeliveryNotRequired(data, reason) {
|
|
@@ -8850,7 +8896,7 @@ function setDeliveryNotRequired(data, reason) {
|
|
|
8850
8896
|
}
|
|
8851
8897
|
function readDeliveryOutcome(data) {
|
|
8852
8898
|
const raw = data.deliveryOutcome;
|
|
8853
|
-
if (!
|
|
8899
|
+
if (!isRecord2(raw)) return null;
|
|
8854
8900
|
if (raw.kind !== "not_required" || typeof raw.reason !== "string" || raw.reason.length === 0) return null;
|
|
8855
8901
|
return { kind: "not_required", reason: raw.reason };
|
|
8856
8902
|
}
|
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.581",
|
|
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",
|