@kody-ade/kody-engine 0.4.473 → 0.4.475
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.475",
|
|
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",
|
|
@@ -454,6 +454,7 @@ function parseReleaseConfig(raw) {
|
|
|
454
454
|
if (typeof r.productionUrl === "string") out.productionUrl = r.productionUrl;
|
|
455
455
|
if (typeof r.smokeCommand === "string") out.smokeCommand = r.smokeCommand;
|
|
456
456
|
if (typeof r.draftRelease === "boolean") out.draftRelease = r.draftRelease;
|
|
457
|
+
if (typeof r.allowAdminMerge === "boolean") out.allowAdminMerge = r.allowAdminMerge;
|
|
457
458
|
if (typeof r.releaseBranch === "string") out.releaseBranch = r.releaseBranch;
|
|
458
459
|
if (typeof r.timeoutMs === "number" && r.timeoutMs > 0) out.timeoutMs = Math.floor(r.timeoutMs);
|
|
459
460
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
@@ -1729,12 +1730,22 @@ function parseCapabilityContract(raw) {
|
|
|
1729
1730
|
if (parsed.execution !== void 0 && parsed.execution !== "agent" && parsed.execution !== "script") {
|
|
1730
1731
|
throw new Error('contract.json execution must be "agent" or "script"');
|
|
1731
1732
|
}
|
|
1732
|
-
const
|
|
1733
|
+
const secrets = parsed.secrets === void 0 ? void 0 : Array.isArray(parsed.secrets) && parsed.secrets.every((name) => typeof name === "string" && /^[A-Z][A-Z0-9_]*$/.test(name)) ? [...new Set(parsed.secrets)] : null;
|
|
1734
|
+
if (secrets === null) {
|
|
1735
|
+
throw new Error("contract.json secrets must contain valid environment variable names");
|
|
1736
|
+
}
|
|
1737
|
+
if (secrets && parsed.execution !== "script") {
|
|
1738
|
+
throw new Error('contract.json secrets are supported only when execution is "script"');
|
|
1739
|
+
}
|
|
1740
|
+
const unsupported = Object.keys(parsed).filter(
|
|
1741
|
+
(key) => key !== "execution" && key !== "secrets" && key !== "input" && key !== "output"
|
|
1742
|
+
);
|
|
1733
1743
|
if (unsupported.length > 0) {
|
|
1734
1744
|
throw new Error(`contract.json contains unsupported fields: ${unsupported.join(", ")}`);
|
|
1735
1745
|
}
|
|
1736
1746
|
return {
|
|
1737
1747
|
...parsed.execution ? { execution: parsed.execution } : {},
|
|
1748
|
+
...secrets ? { secrets } : {},
|
|
1738
1749
|
input: parsed.input,
|
|
1739
1750
|
output: parsed.output
|
|
1740
1751
|
};
|
|
@@ -15552,6 +15563,7 @@ var init_loadSimpleCapability = __esm({
|
|
|
15552
15563
|
ctx.data.capabilityExecution = capability.contract?.execution ?? "agent";
|
|
15553
15564
|
if (capability.contract?.execution === "script") {
|
|
15554
15565
|
ctx.data.capabilityScriptPath = path40.join(capability.dir, "tools", "run.sh");
|
|
15566
|
+
ctx.data.capabilitySecretNames = capability.contract.secrets ?? [];
|
|
15555
15567
|
}
|
|
15556
15568
|
if (capability.config.outputSchema) {
|
|
15557
15569
|
ctx.data.capabilityOutputSchema = capability.config.outputSchema;
|
|
@@ -16577,6 +16589,7 @@ var init_parseSimpleCapabilityOutput = __esm({
|
|
|
16577
16589
|
"src/scripts/parseSimpleCapabilityOutput.ts"() {
|
|
16578
16590
|
"use strict";
|
|
16579
16591
|
init_capability_contract_validation();
|
|
16592
|
+
init_capabilityResult();
|
|
16580
16593
|
parseSimpleCapabilityOutput = async (ctx, _profile, agentResult) => {
|
|
16581
16594
|
const output = Object.hasOwn(ctx.data, "capabilityScriptOutput") ? ctx.data.capabilityScriptOutput : parseOutput(agentResult?.finalText);
|
|
16582
16595
|
if (output === void 0) {
|
|
@@ -16625,6 +16638,12 @@ var init_parseSimpleCapabilityOutput = __esm({
|
|
|
16625
16638
|
}
|
|
16626
16639
|
}
|
|
16627
16640
|
ctx.data.capabilityOutput = output;
|
|
16641
|
+
const structuredResult = parseCapabilityResult(output);
|
|
16642
|
+
if (structuredResult) {
|
|
16643
|
+
ctx.output.reason = structuredResult.summary;
|
|
16644
|
+
ctx.data.capabilityResults = [structuredResult];
|
|
16645
|
+
return;
|
|
16646
|
+
}
|
|
16628
16647
|
const result = isObject2(output) ? output : {};
|
|
16629
16648
|
const data = isObject2(result.data) ? result.data : isObject2(output) ? output : { output };
|
|
16630
16649
|
const summary = typeof result.summary === "string" ? result.summary : "Capability completed";
|
|
@@ -19011,6 +19030,16 @@ var init_runScheduledImplementationTick = __esm({
|
|
|
19011
19030
|
// src/scripts/runSimpleCapabilityScript.ts
|
|
19012
19031
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
19013
19032
|
import * as fs47 from "fs";
|
|
19033
|
+
function declaredSecrets(names, parent) {
|
|
19034
|
+
if (!Array.isArray(names)) return {};
|
|
19035
|
+
const secrets = {};
|
|
19036
|
+
for (const name of names) {
|
|
19037
|
+
if (typeof name !== "string" || !/^[A-Z][A-Z0-9_]*$/.test(name)) continue;
|
|
19038
|
+
const value = parent[name];
|
|
19039
|
+
if (value !== void 0) secrets[name] = value;
|
|
19040
|
+
}
|
|
19041
|
+
return secrets;
|
|
19042
|
+
}
|
|
19014
19043
|
function isRegularFile2(filePath) {
|
|
19015
19044
|
try {
|
|
19016
19045
|
const stat = fs47.lstatSync(filePath);
|
|
@@ -19026,6 +19055,7 @@ var SCRIPT_TIMEOUT_MS, SCRIPT_MAX_OUTPUT_BYTES, runSimpleCapabilityScript;
|
|
|
19026
19055
|
var init_runSimpleCapabilityScript = __esm({
|
|
19027
19056
|
"src/scripts/runSimpleCapabilityScript.ts"() {
|
|
19028
19057
|
"use strict";
|
|
19058
|
+
init_capabilityResult();
|
|
19029
19059
|
init_tickShellRunner();
|
|
19030
19060
|
SCRIPT_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
19031
19061
|
SCRIPT_MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
@@ -19038,10 +19068,12 @@ var init_runSimpleCapabilityScript = __esm({
|
|
|
19038
19068
|
return;
|
|
19039
19069
|
}
|
|
19040
19070
|
const capabilityEnvironment2 = isStringRecord(ctx.data.capabilityEnvironment) ? ctx.data.capabilityEnvironment : {};
|
|
19071
|
+
const capabilitySecrets = declaredSecrets(ctx.data.capabilitySecretNames, process.env);
|
|
19041
19072
|
const result = spawnSync3("bash", [scriptPath], {
|
|
19042
19073
|
cwd: ctx.cwd,
|
|
19043
19074
|
env: {
|
|
19044
19075
|
...buildTickChildEnv(process.env, false),
|
|
19076
|
+
...capabilitySecrets,
|
|
19045
19077
|
...capabilityEnvironment2
|
|
19046
19078
|
},
|
|
19047
19079
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -19066,11 +19098,17 @@ var init_runSimpleCapabilityScript = __esm({
|
|
|
19066
19098
|
ctx.output.reason = `Capability script exited ${result.status ?? 99}`;
|
|
19067
19099
|
return;
|
|
19068
19100
|
}
|
|
19101
|
+
const stdout = result.stdout ?? "";
|
|
19069
19102
|
try {
|
|
19070
|
-
ctx.data.capabilityScriptOutput = JSON.parse(
|
|
19103
|
+
ctx.data.capabilityScriptOutput = JSON.parse(stdout);
|
|
19071
19104
|
} catch {
|
|
19105
|
+
const structuredResult = parseCapabilityResultsFromText(stdout).at(-1);
|
|
19106
|
+
if (structuredResult) {
|
|
19107
|
+
ctx.data.capabilityScriptOutput = structuredResult;
|
|
19108
|
+
return;
|
|
19109
|
+
}
|
|
19072
19110
|
ctx.output.exitCode = 64;
|
|
19073
|
-
ctx.output.reason = "Capability script must return exactly one valid JSON value
|
|
19111
|
+
ctx.output.reason = "Capability script must return exactly one valid JSON value or emit a valid KODY_CAPABILITY_RESULT marker";
|
|
19074
19112
|
}
|
|
19075
19113
|
};
|
|
19076
19114
|
}
|
|
@@ -22259,11 +22297,7 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
|
|
|
22259
22297
|
return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
|
|
22260
22298
|
}
|
|
22261
22299
|
if (!step.next || step.next.length === 0) {
|
|
22262
|
-
state
|
|
22263
|
-
delete state.currentStepId;
|
|
22264
|
-
delete state.blocker;
|
|
22265
|
-
await checkpoint?.(state);
|
|
22266
|
-
return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
|
|
22300
|
+
return completeWorkflowAtTerminal(capability, state, result, checkpoint);
|
|
22267
22301
|
}
|
|
22268
22302
|
const resultConditionPaths = workflowResultConditionPaths(step.next);
|
|
22269
22303
|
if (resultConditionPaths.length > 0 && !result.capabilityResults?.at(-1)) {
|
|
@@ -22286,11 +22320,7 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
|
|
|
22286
22320
|
state.transitionCounts[key] = (state.transitionCounts[key] ?? 0) + 1;
|
|
22287
22321
|
}
|
|
22288
22322
|
if (transition.to === "$end") {
|
|
22289
|
-
state
|
|
22290
|
-
delete state.currentStepId;
|
|
22291
|
-
delete state.blocker;
|
|
22292
|
-
await checkpoint?.(state);
|
|
22293
|
-
return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
|
|
22323
|
+
return completeWorkflowAtTerminal(capability, state, result, checkpoint);
|
|
22294
22324
|
}
|
|
22295
22325
|
state.currentStepId = transition.to;
|
|
22296
22326
|
state.status = "running";
|
|
@@ -22301,6 +22331,25 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
|
|
|
22301
22331
|
await checkpoint?.(state);
|
|
22302
22332
|
return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
|
|
22303
22333
|
}
|
|
22334
|
+
async function completeWorkflowAtTerminal(capability, state, output, checkpoint) {
|
|
22335
|
+
const result = output.capabilityResults?.at(-1);
|
|
22336
|
+
if (result?.status === "fail" || result?.status === "blocked") {
|
|
22337
|
+
state.status = result.status === "fail" ? "failed" : "blocked";
|
|
22338
|
+
state.blocker = result.summary;
|
|
22339
|
+
await checkpoint?.(state);
|
|
22340
|
+
return withWorkflowBoundaryEval(capability, {
|
|
22341
|
+
...output,
|
|
22342
|
+
exitCode: result.status === "fail" ? 1 : 64,
|
|
22343
|
+
reason: result.summary,
|
|
22344
|
+
workflowState: state
|
|
22345
|
+
});
|
|
22346
|
+
}
|
|
22347
|
+
state.status = "done";
|
|
22348
|
+
delete state.currentStepId;
|
|
22349
|
+
delete state.blocker;
|
|
22350
|
+
await checkpoint?.(state);
|
|
22351
|
+
return withWorkflowBoundaryEval(capability, { ...output, workflowState: state });
|
|
22352
|
+
}
|
|
22304
22353
|
function graphWorkflowExecutionKey(parentExecutionKey, workflowSlug, stepId, transitionCounts) {
|
|
22305
22354
|
const transitionHistory = Object.entries(transitionCounts).filter(([, count]) => count > 0).sort(([left], [right]) => left.localeCompare(right)).map(([transition, count]) => `${transition}=${count}`).join(",");
|
|
22306
22355
|
return [
|
|
@@ -22476,7 +22525,7 @@ function valueMatches(actual, expected) {
|
|
|
22476
22525
|
return actual === expected;
|
|
22477
22526
|
}
|
|
22478
22527
|
function workflowStepTargetNumber(step, parent, chainData) {
|
|
22479
|
-
if (step.target === "pr") return
|
|
22528
|
+
if (step.target === "pr") return workflowTargetFactNumber(step, chainData) ?? workflowPrNumber(chainData);
|
|
22480
22529
|
if (step.target === "issue") return workflowIssueNumber(parent) ?? workflowTargetFactNumber(step, chainData);
|
|
22481
22530
|
return typeof parent.target === "number" ? parent.target : targetFromCliArgs(parent.cliArgs);
|
|
22482
22531
|
}
|
|
File without changes
|
package/kody.config.schema.json
CHANGED
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.475",
|
|
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,6 +12,29 @@
|
|
|
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
|
+
"test:runtime-services": "node --test \"tests/runtime-services/*.test.mjs\"",
|
|
29
|
+
"test:all": "vitest run tests --no-coverage",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"lint": "biome check",
|
|
32
|
+
"lint:fix": "biome check --write",
|
|
33
|
+
"format": "biome format --write",
|
|
34
|
+
"verify:package": "node scripts/verify-package-tarball.cjs",
|
|
35
|
+
"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",
|
|
36
|
+
"prepublishOnly": "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm test:runtime-services && pnpm build && pnpm verify:package"
|
|
37
|
+
},
|
|
15
38
|
"dependencies": {
|
|
16
39
|
"@actions/cache": "^6.0.0",
|
|
17
40
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
@@ -38,27 +61,5 @@
|
|
|
38
61
|
"url": "git+https://github.com/aharonyaircohen/kody-engine.git"
|
|
39
62
|
},
|
|
40
63
|
"homepage": "https://github.com/aharonyaircohen/kody-engine",
|
|
41
|
-
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
42
|
-
|
|
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
|
-
"test:runtime-services": "node --test \"tests/runtime-services/*.test.mjs\"",
|
|
56
|
-
"test:all": "vitest run tests --no-coverage",
|
|
57
|
-
"typecheck": "tsc --noEmit",
|
|
58
|
-
"lint": "biome check",
|
|
59
|
-
"lint:fix": "biome check --write",
|
|
60
|
-
"format": "biome format --write",
|
|
61
|
-
"verify:package": "node scripts/verify-package-tarball.cjs",
|
|
62
|
-
"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"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
64
|
+
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
65
|
+
}
|