@kody-ade/kody-engine 0.4.477 → 0.4.479
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 +103 -57
- package/dist/runtime-services/goal-scheduler/scheduler.sh +0 -0
- package/kody.config.schema.json +38 -0
- package/package.json +25 -26
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.479",
|
|
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",
|
|
@@ -447,6 +447,20 @@ function parseReleaseConfig(raw) {
|
|
|
447
447
|
if (!raw || typeof raw !== "object") return void 0;
|
|
448
448
|
const r = raw;
|
|
449
449
|
const out = {};
|
|
450
|
+
if (r.version !== void 0) {
|
|
451
|
+
const version = recordValue(r.version);
|
|
452
|
+
const readCommand = typeof version?.readCommand === "string" ? version.readCommand.trim() : "";
|
|
453
|
+
const writeCommand = typeof version?.writeCommand === "string" ? version.writeCommand.trim() : "";
|
|
454
|
+
const files = Array.isArray(version?.files) ? version.files.filter(
|
|
455
|
+
(file) => typeof file === "string" && file.trim().length > 0
|
|
456
|
+
).map((file) => file.trim()) : [];
|
|
457
|
+
if (!readCommand || !writeCommand || files.length === 0) {
|
|
458
|
+
throw new Error(
|
|
459
|
+
"kody.config.json: release.version requires readCommand, writeCommand, and files"
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
out.version = { readCommand, writeCommand, files: [...new Set(files)] };
|
|
463
|
+
}
|
|
450
464
|
if (Array.isArray(r.versionFiles)) out.versionFiles = r.versionFiles.filter((f) => typeof f === "string");
|
|
451
465
|
if (typeof r.publishCommand === "string") out.publishCommand = r.publishCommand;
|
|
452
466
|
if (typeof r.notifyCommand === "string") out.notifyCommand = r.notifyCommand;
|
|
@@ -457,24 +471,36 @@ function parseReleaseConfig(raw) {
|
|
|
457
471
|
if (typeof r.allowAdminMerge === "boolean") out.allowAdminMerge = r.allowAdminMerge;
|
|
458
472
|
if (typeof r.releaseBranch === "string") out.releaseBranch = r.releaseBranch;
|
|
459
473
|
if (typeof r.timeoutMs === "number" && r.timeoutMs > 0) out.timeoutMs = Math.floor(r.timeoutMs);
|
|
460
|
-
if (
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
474
|
+
if (typeof r.productionDeployRequired === "boolean")
|
|
475
|
+
out.productionDeployRequired = r.productionDeployRequired;
|
|
476
|
+
out.validation = parseReleaseWorkflowRequest(r.validation, "validation");
|
|
477
|
+
out.deployment = parseReleaseWorkflowRequest(
|
|
478
|
+
r.deployment,
|
|
479
|
+
"deployment",
|
|
480
|
+
true
|
|
481
|
+
);
|
|
482
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
483
|
+
}
|
|
484
|
+
function parseReleaseWorkflowRequest(raw, field, requiredWhenConfigured = false) {
|
|
485
|
+
if (raw === void 0) return void 0;
|
|
486
|
+
const request = recordValue(raw);
|
|
487
|
+
const workflow = typeof request?.workflow === "string" ? request.workflow.trim() : "";
|
|
488
|
+
if (!workflow) {
|
|
489
|
+
if (requiredWhenConfigured) {
|
|
490
|
+
throw new Error(`kody.config.json: release.${field}.workflow is required`);
|
|
475
491
|
}
|
|
492
|
+
return void 0;
|
|
476
493
|
}
|
|
477
|
-
|
|
494
|
+
const rawInputs = recordValue(request?.inputs);
|
|
495
|
+
const inputs = rawInputs ? Object.fromEntries(
|
|
496
|
+
Object.entries(rawInputs).filter(
|
|
497
|
+
(entry) => /^[a-z][a-z0-9_]*$/.test(entry[0]) && (typeof entry[1] === "string" || typeof entry[1] === "number" || typeof entry[1] === "boolean")
|
|
498
|
+
)
|
|
499
|
+
) : void 0;
|
|
500
|
+
return {
|
|
501
|
+
workflow,
|
|
502
|
+
...inputs && Object.keys(inputs).length > 0 ? { inputs } : {}
|
|
503
|
+
};
|
|
478
504
|
}
|
|
479
505
|
function parseIssueContext(raw) {
|
|
480
506
|
if (!raw || typeof raw !== "object") return void 0;
|
|
@@ -4241,6 +4267,56 @@ var init_agencyBoundaryEval = __esm({
|
|
|
4241
4267
|
}
|
|
4242
4268
|
});
|
|
4243
4269
|
|
|
4270
|
+
// src/scripts/capabilityExecutionEnvironment.ts
|
|
4271
|
+
function capabilityInputEnvironment(input) {
|
|
4272
|
+
const environment = {
|
|
4273
|
+
KODY_CAPABILITY_INPUT: JSON.stringify(input ?? null)
|
|
4274
|
+
};
|
|
4275
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
4276
|
+
return environment;
|
|
4277
|
+
}
|
|
4278
|
+
for (const [name, value] of Object.entries(input)) {
|
|
4279
|
+
if (value === void 0 || value === null) continue;
|
|
4280
|
+
const key = environmentKey(name);
|
|
4281
|
+
environment[`KODY_ARG_${key}`] = typeof value === "string" ? value : JSON.stringify(value);
|
|
4282
|
+
}
|
|
4283
|
+
return environment;
|
|
4284
|
+
}
|
|
4285
|
+
function capabilityConfigEnvironment(config) {
|
|
4286
|
+
if (!config || typeof config !== "object" || Array.isArray(config)) return {};
|
|
4287
|
+
return Object.fromEntries(
|
|
4288
|
+
flattenConfig(config).map(([key, value]) => [
|
|
4289
|
+
`KODY_CFG_${key}`,
|
|
4290
|
+
value
|
|
4291
|
+
])
|
|
4292
|
+
);
|
|
4293
|
+
}
|
|
4294
|
+
function flattenConfig(config, prefix = "") {
|
|
4295
|
+
const entries = [];
|
|
4296
|
+
for (const [name, value] of Object.entries(config)) {
|
|
4297
|
+
if (value === null || value === void 0) continue;
|
|
4298
|
+
const key = prefix ? `${prefix}_${environmentKey(name)}` : environmentKey(name);
|
|
4299
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
4300
|
+
entries.push([key, String(value)]);
|
|
4301
|
+
} else if (Array.isArray(value)) {
|
|
4302
|
+
entries.push([key, JSON.stringify(value)]);
|
|
4303
|
+
} else if (typeof value === "object") {
|
|
4304
|
+
entries.push(
|
|
4305
|
+
...flattenConfig(value, key)
|
|
4306
|
+
);
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
return entries;
|
|
4310
|
+
}
|
|
4311
|
+
function environmentKey(name) {
|
|
4312
|
+
return name.toUpperCase().replace(/[^A-Z0-9]+/g, "_");
|
|
4313
|
+
}
|
|
4314
|
+
var init_capabilityExecutionEnvironment = __esm({
|
|
4315
|
+
"src/scripts/capabilityExecutionEnvironment.ts"() {
|
|
4316
|
+
"use strict";
|
|
4317
|
+
}
|
|
4318
|
+
});
|
|
4319
|
+
|
|
4244
4320
|
// src/agency/capability-contract-validation.ts
|
|
4245
4321
|
import Ajv from "ajv";
|
|
4246
4322
|
function validateCapabilityContractValue(boundary, schema, value) {
|
|
@@ -15533,18 +15609,6 @@ function scalar(value) {
|
|
|
15533
15609
|
if (/^-?\d+$/.test(value)) return Number(value);
|
|
15534
15610
|
return value;
|
|
15535
15611
|
}
|
|
15536
|
-
function capabilityEnvironment(input) {
|
|
15537
|
-
const environment = {
|
|
15538
|
-
KODY_CAPABILITY_INPUT: JSON.stringify(input ?? null)
|
|
15539
|
-
};
|
|
15540
|
-
if (!input || typeof input !== "object" || Array.isArray(input)) return environment;
|
|
15541
|
-
for (const [name, value] of Object.entries(input)) {
|
|
15542
|
-
if (value === void 0 || value === null) continue;
|
|
15543
|
-
const key = name.toUpperCase().replace(/[^A-Z0-9]+/g, "_");
|
|
15544
|
-
environment[`KODY_ARG_${key}`] = typeof value === "string" ? value : JSON.stringify(value);
|
|
15545
|
-
}
|
|
15546
|
-
return environment;
|
|
15547
|
-
}
|
|
15548
15612
|
function listFiles(root) {
|
|
15549
15613
|
if (!fs43.existsSync(root)) return [];
|
|
15550
15614
|
const files = [];
|
|
@@ -15566,6 +15630,7 @@ var init_loadSimpleCapability = __esm({
|
|
|
15566
15630
|
init_capability_contract_validation();
|
|
15567
15631
|
init_capabilityFolders();
|
|
15568
15632
|
init_definition_paths();
|
|
15633
|
+
init_capabilityExecutionEnvironment();
|
|
15569
15634
|
loadSimpleCapability = async (ctx) => {
|
|
15570
15635
|
const slug = typeof ctx.args.capability === "string" ? ctx.args.capability.trim() : "";
|
|
15571
15636
|
if (!/^[a-z][a-z0-9-]*$/.test(slug)) {
|
|
@@ -15594,7 +15659,10 @@ var init_loadSimpleCapability = __esm({
|
|
|
15594
15659
|
if (capability.config.outputSchema) {
|
|
15595
15660
|
ctx.data.capabilityOutputSchema = capability.config.outputSchema;
|
|
15596
15661
|
}
|
|
15597
|
-
ctx.data.capabilityEnvironment =
|
|
15662
|
+
ctx.data.capabilityEnvironment = {
|
|
15663
|
+
...capabilityInputEnvironment(input),
|
|
15664
|
+
...capabilityConfigEnvironment(ctx.config)
|
|
15665
|
+
};
|
|
15598
15666
|
ctx.data.prompt = [
|
|
15599
15667
|
capability.rawBody.trim(),
|
|
15600
15668
|
"",
|
|
@@ -19096,7 +19164,7 @@ var init_runSimpleCapabilityScript = __esm({
|
|
|
19096
19164
|
ctx.output.reason = 'Script-backed Capability requires a regular "tools/run.sh" entrypoint';
|
|
19097
19165
|
return;
|
|
19098
19166
|
}
|
|
19099
|
-
const
|
|
19167
|
+
const capabilityEnvironment = isStringRecord(ctx.data.capabilityEnvironment) ? ctx.data.capabilityEnvironment : {};
|
|
19100
19168
|
const capabilitySecrets = declaredSecrets(ctx.data.capabilitySecretNames, process.env);
|
|
19101
19169
|
const timeoutMs = typeof ctx.data.capabilityScriptTimeoutMs === "number" ? ctx.data.capabilityScriptTimeoutMs : DEFAULT_SCRIPT_TIMEOUT_MS;
|
|
19102
19170
|
const result = spawnSync3("bash", [scriptPath], {
|
|
@@ -19104,7 +19172,7 @@ var init_runSimpleCapabilityScript = __esm({
|
|
|
19104
19172
|
env: {
|
|
19105
19173
|
...buildTickChildEnv(process.env, false),
|
|
19106
19174
|
...capabilitySecrets,
|
|
19107
|
-
...
|
|
19175
|
+
...capabilityEnvironment
|
|
19108
19176
|
},
|
|
19109
19177
|
stdio: ["ignore", "pipe", "pipe"],
|
|
19110
19178
|
encoding: "utf-8",
|
|
@@ -21597,13 +21665,8 @@ async function runShellEntry(entry, ctx, profile) {
|
|
|
21597
21665
|
`kody-shell-output-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
|
|
21598
21666
|
);
|
|
21599
21667
|
const env = { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", KODY_OUTPUT: outputFile };
|
|
21600
|
-
|
|
21601
|
-
|
|
21602
|
-
env[`KODY_ARG_${envKey(k)}`] = String(v);
|
|
21603
|
-
}
|
|
21604
|
-
for (const [k, v] of flattenConfig(ctx.config)) {
|
|
21605
|
-
env[`KODY_CFG_${k}`] = v;
|
|
21606
|
-
}
|
|
21668
|
+
Object.assign(env, capabilityInputEnvironment(ctx.args));
|
|
21669
|
+
Object.assign(env, capabilityConfigEnvironment(ctx.config));
|
|
21607
21670
|
const timeoutMs = resolveShellTimeoutMs(entry);
|
|
21608
21671
|
const child = spawn8("bash", [shellPath, ...positional], {
|
|
21609
21672
|
cwd: ctx.cwd,
|
|
@@ -21704,28 +21767,11 @@ async function runShellEntry(entry, ctx, profile) {
|
|
|
21704
21767
|
}
|
|
21705
21768
|
}
|
|
21706
21769
|
}
|
|
21707
|
-
function envKey(name) {
|
|
21708
|
-
return name.toUpperCase().replace(/-/g, "_");
|
|
21709
|
-
}
|
|
21710
|
-
function flattenConfig(obj, prefix = "") {
|
|
21711
|
-
const out = [];
|
|
21712
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
21713
|
-
if (v === null || v === void 0) continue;
|
|
21714
|
-
const key = prefix ? `${prefix}_${envKey(k)}` : envKey(k);
|
|
21715
|
-
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
|
|
21716
|
-
out.push([key, String(v)]);
|
|
21717
|
-
} else if (Array.isArray(v)) {
|
|
21718
|
-
out.push([key, JSON.stringify(v)]);
|
|
21719
|
-
} else if (typeof v === "object") {
|
|
21720
|
-
out.push(...flattenConfig(v, key));
|
|
21721
|
-
}
|
|
21722
|
-
}
|
|
21723
|
-
return out;
|
|
21724
|
-
}
|
|
21725
21770
|
var MUTATING_POSTFLIGHTS, SHELL_MARKER_RE, TASK_ARTIFACT_WRITE_TOOLS, MAX_CHAIN_HOPS, DEFAULT_SHELL_TIMEOUT_MS, SIGKILL_GRACE_MS;
|
|
21726
21771
|
var init_executor = __esm({
|
|
21727
21772
|
"src/executor.ts"() {
|
|
21728
21773
|
"use strict";
|
|
21774
|
+
init_capabilityExecutionEnvironment();
|
|
21729
21775
|
init_capability_contract_validation();
|
|
21730
21776
|
init_agent();
|
|
21731
21777
|
init_agents();
|
|
File without changes
|
package/kody.config.schema.json
CHANGED
|
@@ -140,6 +140,21 @@
|
|
|
140
140
|
"type": "object",
|
|
141
141
|
"additionalProperties": false,
|
|
142
142
|
"properties": {
|
|
143
|
+
"version": {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"additionalProperties": false,
|
|
146
|
+
"required": ["readCommand", "writeCommand", "files"],
|
|
147
|
+
"properties": {
|
|
148
|
+
"readCommand": { "type": "string", "minLength": 1 },
|
|
149
|
+
"writeCommand": { "type": "string", "minLength": 1 },
|
|
150
|
+
"files": {
|
|
151
|
+
"type": "array",
|
|
152
|
+
"minItems": 1,
|
|
153
|
+
"uniqueItems": true,
|
|
154
|
+
"items": { "type": "string", "minLength": 1 }
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
},
|
|
143
158
|
"versionFiles": {
|
|
144
159
|
"type": "array",
|
|
145
160
|
"items": { "type": "string" }
|
|
@@ -147,6 +162,9 @@
|
|
|
147
162
|
"publishCommand": { "type": "string" },
|
|
148
163
|
"notifyCommand": { "type": "string" },
|
|
149
164
|
"e2eCommand": { "type": "string" },
|
|
165
|
+
"productionUrl": { "type": "string" },
|
|
166
|
+
"smokeCommand": { "type": "string" },
|
|
167
|
+
"productionDeployRequired": { "type": "boolean" },
|
|
150
168
|
"draftRelease": { "type": "boolean" },
|
|
151
169
|
"releaseBranch": { "type": "string" },
|
|
152
170
|
"allowAdminMerge": { "type": "boolean" },
|
|
@@ -170,6 +188,26 @@
|
|
|
170
188
|
}
|
|
171
189
|
}
|
|
172
190
|
},
|
|
191
|
+
"deployment": {
|
|
192
|
+
"type": "object",
|
|
193
|
+
"additionalProperties": false,
|
|
194
|
+
"required": ["workflow"],
|
|
195
|
+
"properties": {
|
|
196
|
+
"workflow": {
|
|
197
|
+
"type": "string",
|
|
198
|
+
"minLength": 1
|
|
199
|
+
},
|
|
200
|
+
"inputs": {
|
|
201
|
+
"type": "object",
|
|
202
|
+
"propertyNames": {
|
|
203
|
+
"pattern": "^[a-z][a-z0-9_]*$"
|
|
204
|
+
},
|
|
205
|
+
"additionalProperties": {
|
|
206
|
+
"type": ["string", "number", "boolean"]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
173
211
|
"timeoutMs": {
|
|
174
212
|
"type": "integer",
|
|
175
213
|
"minimum": 1
|
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.479",
|
|
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,29 +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
|
-
"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
|
-
},
|
|
38
15
|
"dependencies": {
|
|
39
16
|
"@actions/cache": "^6.0.0",
|
|
40
17
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
@@ -61,5 +38,27 @@
|
|
|
61
38
|
"url": "git+https://github.com/aharonyaircohen/kody-engine.git"
|
|
62
39
|
},
|
|
63
40
|
"homepage": "https://github.com/aharonyaircohen/kody-engine",
|
|
64
|
-
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
65
|
-
|
|
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
|
+
"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
|
+
}
|