@kody-ade/kody-engine 0.4.561 → 0.4.563
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.563",
|
|
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",
|
|
@@ -671,11 +671,22 @@ var init_format = __esm({
|
|
|
671
671
|
|
|
672
672
|
// src/agency/capability-contract-validation.ts
|
|
673
673
|
import Ajv from "ajv";
|
|
674
|
-
function
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
674
|
+
function createCapabilityContractValueValidator(compile) {
|
|
675
|
+
const compiled = /* @__PURE__ */ new WeakMap();
|
|
676
|
+
return (boundary, schema, value) => {
|
|
677
|
+
let validate = compiled.get(schema);
|
|
678
|
+
if (!validate) {
|
|
679
|
+
validate = compile(schema);
|
|
680
|
+
compiled.set(schema, validate);
|
|
681
|
+
}
|
|
682
|
+
if (!validate(value)) {
|
|
683
|
+
throw new CapabilityContractValidationError(boundary, validate.errors ?? []);
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
function validateCapabilityContractOutput(schema, value) {
|
|
688
|
+
if (value === void 0) throw new CapabilityContractMissingOutputError();
|
|
689
|
+
validateCapabilityContractValue("output", schema, value);
|
|
679
690
|
}
|
|
680
691
|
function capabilityContractInput(inputs, args, capabilityId, contractProperties = []) {
|
|
681
692
|
const isGenericRunnerInput = inputs.some((input) => input.name === "input") && Object.hasOwn(args, "input");
|
|
@@ -693,7 +704,7 @@ function capabilityContractInput(inputs, args, capabilityId, contractProperties
|
|
|
693
704
|
return value;
|
|
694
705
|
}
|
|
695
706
|
}
|
|
696
|
-
var validator, CapabilityContractValidationError;
|
|
707
|
+
var validator, CapabilityContractValidationError, CapabilityContractMissingOutputError, validateCapabilityContractValue;
|
|
697
708
|
var init_capability_contract_validation = __esm({
|
|
698
709
|
"src/agency/capability-contract-validation.ts"() {
|
|
699
710
|
"use strict";
|
|
@@ -717,6 +728,15 @@ var init_capability_contract_validation = __esm({
|
|
|
717
728
|
boundary;
|
|
718
729
|
errors;
|
|
719
730
|
};
|
|
731
|
+
CapabilityContractMissingOutputError = class extends Error {
|
|
732
|
+
constructor() {
|
|
733
|
+
super("Capability output is missing despite its declared contract");
|
|
734
|
+
this.name = "CapabilityContractMissingOutputError";
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
validateCapabilityContractValue = createCapabilityContractValueValidator(
|
|
738
|
+
(schema) => validator.compile(schema)
|
|
739
|
+
);
|
|
720
740
|
}
|
|
721
741
|
});
|
|
722
742
|
|
|
@@ -731,7 +751,7 @@ function outputContractError(contract) {
|
|
|
731
751
|
return `The required output file is missing or is not valid JSON: ${error instanceof Error ? error.message : String(error)}`;
|
|
732
752
|
}
|
|
733
753
|
try {
|
|
734
|
-
|
|
754
|
+
validateCapabilityContractOutput(contract.schema, value);
|
|
735
755
|
return null;
|
|
736
756
|
} catch (error) {
|
|
737
757
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -2012,20 +2032,52 @@ function listCapabilityFolderSlugs(absDir) {
|
|
|
2012
2032
|
return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).filter((e) => isCapabilityFolder(path8.join(absDir, e.name))).map((e) => e.name).sort();
|
|
2013
2033
|
}
|
|
2014
2034
|
function isCapabilityFolder(dir) {
|
|
2015
|
-
if (!fs7.existsSync(path8.join(dir, CAPABILITY_BODY_FILE))) return false;
|
|
2016
2035
|
const entries = fs7.readdirSync(dir, { withFileTypes: true });
|
|
2036
|
+
const legacyBody = path8.join(dir, CAPABILITY_BODY_FILE);
|
|
2037
|
+
if (fs7.existsSync(legacyBody)) {
|
|
2038
|
+
return entries.every(
|
|
2039
|
+
(entry) => entry.name === CAPABILITY_BODY_FILE || entry.name === CAPABILITY_CONTRACT_FILE || entry.isDirectory() && (entry.name === "skills" || entry.name === "tools")
|
|
2040
|
+
);
|
|
2041
|
+
}
|
|
2042
|
+
const canonicalBody = path8.join(dir, CANONICAL_CAPABILITY_BODY_FILE);
|
|
2043
|
+
const canonicalDefinition = path8.join(dir, CANONICAL_CAPABILITY_DEFINITION_FILE);
|
|
2044
|
+
if (!fs7.existsSync(canonicalBody) || !fs7.existsSync(canonicalDefinition)) return false;
|
|
2017
2045
|
return entries.every(
|
|
2018
|
-
(entry) => entry.name ===
|
|
2046
|
+
(entry) => entry.name === CANONICAL_CAPABILITY_BODY_FILE || entry.name === CANONICAL_CAPABILITY_DEFINITION_FILE
|
|
2019
2047
|
);
|
|
2020
2048
|
}
|
|
2021
2049
|
function readCapabilityFolder(root, slug) {
|
|
2022
2050
|
const dir = path8.join(root, slug);
|
|
2023
|
-
const
|
|
2051
|
+
const legacyBodyPath = path8.join(dir, CAPABILITY_BODY_FILE);
|
|
2052
|
+
const canonicalBodyPath = path8.join(dir, CANONICAL_CAPABILITY_BODY_FILE);
|
|
2053
|
+
const bodyPath = fs7.existsSync(legacyBodyPath) ? legacyBodyPath : canonicalBodyPath;
|
|
2024
2054
|
const contractPath = path8.join(dir, CAPABILITY_CONTRACT_FILE);
|
|
2025
2055
|
if (!fs7.existsSync(bodyPath) || !fs7.statSync(bodyPath).isFile()) return null;
|
|
2026
2056
|
if (!isCapabilityFolder(dir)) return null;
|
|
2027
2057
|
try {
|
|
2028
2058
|
const rawBody = fs7.readFileSync(bodyPath, "utf-8");
|
|
2059
|
+
if (bodyPath === canonicalBodyPath) {
|
|
2060
|
+
const definitionPath = path8.join(dir, CANONICAL_CAPABILITY_DEFINITION_FILE);
|
|
2061
|
+
const definition = JSON.parse(fs7.readFileSync(definitionPath, "utf-8"));
|
|
2062
|
+
if (definition.id !== slug || typeof definition.action !== "string") return null;
|
|
2063
|
+
const { title: title2, body: body2 } = parseCapabilityBody(rawBody, slug);
|
|
2064
|
+
return {
|
|
2065
|
+
slug,
|
|
2066
|
+
dir,
|
|
2067
|
+
profilePath: definitionPath,
|
|
2068
|
+
bodyPath,
|
|
2069
|
+
title: title2,
|
|
2070
|
+
body: body2,
|
|
2071
|
+
rawBody,
|
|
2072
|
+
config: {
|
|
2073
|
+
action: definition.action,
|
|
2074
|
+
describe: typeof definition.purpose === "string" ? definition.purpose : title2,
|
|
2075
|
+
...isPlainObject(definition.inputSchema) ? { inputSchema: definition.inputSchema } : {},
|
|
2076
|
+
...isPlainObject(definition.outputSchema) ? { outputSchema: definition.outputSchema } : {}
|
|
2077
|
+
},
|
|
2078
|
+
rawProfile: definition
|
|
2079
|
+
};
|
|
2080
|
+
}
|
|
2029
2081
|
const contract = fs7.existsSync(contractPath) ? parseCapabilityContract(fs7.readFileSync(contractPath, "utf-8")) : void 0;
|
|
2030
2082
|
if (contract?.execution === "script" && !isRegularFile(path8.join(dir, "tools", "run.sh"))) {
|
|
2031
2083
|
throw new Error('script-backed Capability requires a regular "tools/run.sh" file');
|
|
@@ -2301,13 +2353,15 @@ function isSafeSlug(value) {
|
|
|
2301
2353
|
function isSafeStepId(value) {
|
|
2302
2354
|
return /^[A-Za-z][A-Za-z0-9_-]*$/.test(value) && !value.includes("..");
|
|
2303
2355
|
}
|
|
2304
|
-
var CAPABILITY_BODY_FILE, CAPABILITY_CONTRACT_FILE, CAPABILITY_PROFILE_FILE;
|
|
2356
|
+
var CAPABILITY_BODY_FILE, CAPABILITY_CONTRACT_FILE, CAPABILITY_PROFILE_FILE, CANONICAL_CAPABILITY_BODY_FILE, CANONICAL_CAPABILITY_DEFINITION_FILE;
|
|
2305
2357
|
var init_capabilityFolders = __esm({
|
|
2306
2358
|
"src/capabilityFolders.ts"() {
|
|
2307
2359
|
"use strict";
|
|
2308
2360
|
CAPABILITY_BODY_FILE = "instructions.md";
|
|
2309
2361
|
CAPABILITY_CONTRACT_FILE = "contract.json";
|
|
2310
2362
|
CAPABILITY_PROFILE_FILE = CAPABILITY_BODY_FILE;
|
|
2363
|
+
CANONICAL_CAPABILITY_BODY_FILE = "capability.md";
|
|
2364
|
+
CANONICAL_CAPABILITY_DEFINITION_FILE = "definition.json";
|
|
2311
2365
|
}
|
|
2312
2366
|
});
|
|
2313
2367
|
|
|
@@ -2484,6 +2538,10 @@ function resolveCapabilityAction(action, projectCapabilitiesRoot = getProjectCap
|
|
|
2484
2538
|
if (!isSafeName(action)) return null;
|
|
2485
2539
|
return listCapabilityActions(projectCapabilitiesRoot).find((d) => d.action === action) ?? null;
|
|
2486
2540
|
}
|
|
2541
|
+
function resolveOperatorCapabilityAction(action, projectCapabilitiesRoot = getProjectCapabilitiesRoot()) {
|
|
2542
|
+
if (!isSafeName(action)) return null;
|
|
2543
|
+
return listBuiltinCapabilityActions(getBuiltinCapabilitiesRoot()).find((candidate) => candidate.action === action) ?? resolveCapabilityAction(action, projectCapabilitiesRoot);
|
|
2544
|
+
}
|
|
2487
2545
|
function hasCapabilityAction(action, projectCapabilitiesRoot = getProjectCapabilitiesRoot()) {
|
|
2488
2546
|
return resolveCapabilityAction(action, projectCapabilitiesRoot) !== null;
|
|
2489
2547
|
}
|
|
@@ -2498,6 +2556,7 @@ function resolveCapabilityFolder(slug, projectCapabilitiesRoot = getProjectCapab
|
|
|
2498
2556
|
function getCapabilityActionInputs(action, projectCapabilitiesRoot = getProjectCapabilitiesRoot()) {
|
|
2499
2557
|
const resolved = resolveCapabilityAction(action, projectCapabilitiesRoot);
|
|
2500
2558
|
if (!resolved) return null;
|
|
2559
|
+
if (resolved.source === "builtin") return getProfileInputs(resolved.implementation);
|
|
2501
2560
|
const capability = resolveCapabilityFolder(resolved.capability, projectCapabilitiesRoot);
|
|
2502
2561
|
if (capability && !capability.config.workflow) {
|
|
2503
2562
|
return [
|
|
@@ -17251,7 +17310,7 @@ var init_parseSimpleCapabilityOutput = __esm({
|
|
|
17251
17310
|
const outputSchema = isObject2(ctx.data.capabilityOutputSchema) ? ctx.data.capabilityOutputSchema : void 0;
|
|
17252
17311
|
if (outputSchema) {
|
|
17253
17312
|
try {
|
|
17254
|
-
|
|
17313
|
+
validateCapabilityContractOutput(outputSchema, output);
|
|
17255
17314
|
} catch (error) {
|
|
17256
17315
|
const reason2 = error instanceof Error ? error.message : String(error);
|
|
17257
17316
|
ctx.output.exitCode = 64;
|
|
@@ -22221,8 +22280,7 @@ async function runImplementation(profileName, input) {
|
|
|
22221
22280
|
const capabilityResults = Array.isArray(ctx.data.capabilityResults) ? ctx.data.capabilityResults : void 0;
|
|
22222
22281
|
if (profile.canonicalContract) {
|
|
22223
22282
|
try {
|
|
22224
|
-
|
|
22225
|
-
"output",
|
|
22283
|
+
validateCapabilityContractOutput(
|
|
22226
22284
|
profile.canonicalContract.outputSchema,
|
|
22227
22285
|
capabilityResults?.at(-1) ?? {
|
|
22228
22286
|
exitCode: ctx.output.exitCode ?? 0,
|
|
@@ -23197,11 +23255,11 @@ async function runCapabilityImplementationStep(valid, profileName, capabilityIde
|
|
|
23197
23255
|
}
|
|
23198
23256
|
function enforceCapabilityOutputContract(capability, result) {
|
|
23199
23257
|
const schema = capability?.config.outputSchema;
|
|
23200
|
-
if (result.exitCode !== 0 || !schema
|
|
23258
|
+
if (result.exitCode !== 0 || !schema) {
|
|
23201
23259
|
return result;
|
|
23202
23260
|
}
|
|
23203
23261
|
try {
|
|
23204
|
-
|
|
23262
|
+
validateCapabilityContractOutput(schema, result.capabilityOutput);
|
|
23205
23263
|
return result;
|
|
23206
23264
|
} catch (error) {
|
|
23207
23265
|
const reason = error instanceof Error ? error.message : String(error);
|
|
@@ -23937,8 +23995,8 @@ var DEFAULT_INSTANT_AGENT, localJobSeq, InvalidJobError;
|
|
|
23937
23995
|
var init_job = __esm({
|
|
23938
23996
|
"src/job.ts"() {
|
|
23939
23997
|
"use strict";
|
|
23940
|
-
init_agencyBoundaryEval();
|
|
23941
23998
|
init_capability_contract_validation();
|
|
23999
|
+
init_agencyBoundaryEval();
|
|
23942
24000
|
init_capabilityFolders();
|
|
23943
24001
|
init_config();
|
|
23944
24002
|
init_definition_paths();
|
|
@@ -25519,10 +25577,10 @@ function primaryNumericInputName(implementation) {
|
|
|
25519
25577
|
return intInput?.name ?? null;
|
|
25520
25578
|
}
|
|
25521
25579
|
function resolveOperatorAction(action, projectCapabilitiesRoot) {
|
|
25522
|
-
return
|
|
25580
|
+
return resolveOperatorCapabilityAction(action, projectCapabilitiesRoot);
|
|
25523
25581
|
}
|
|
25524
25582
|
function resolveConfiguredAction(action, projectCapabilitiesRoot) {
|
|
25525
|
-
return
|
|
25583
|
+
return resolveOperatorCapabilityAction(action, projectCapabilitiesRoot);
|
|
25526
25584
|
}
|
|
25527
25585
|
function requiredRoute(action, projectCapabilitiesRoot) {
|
|
25528
25586
|
const route = resolveConfiguredAction(action, projectCapabilitiesRoot);
|
|
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.563",
|
|
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
|
+
}
|