@kody-ade/kody-engine 0.4.473 → 0.4.474

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.473",
18
+ version: "0.4.474",
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 unsupported = Object.keys(parsed).filter((key) => key !== "execution" && key !== "input" && key !== "output");
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);
@@ -19038,10 +19067,12 @@ var init_runSimpleCapabilityScript = __esm({
19038
19067
  return;
19039
19068
  }
19040
19069
  const capabilityEnvironment2 = isStringRecord(ctx.data.capabilityEnvironment) ? ctx.data.capabilityEnvironment : {};
19070
+ const capabilitySecrets = declaredSecrets(ctx.data.capabilitySecretNames, process.env);
19041
19071
  const result = spawnSync3("bash", [scriptPath], {
19042
19072
  cwd: ctx.cwd,
19043
19073
  env: {
19044
19074
  ...buildTickChildEnv(process.env, false),
19075
+ ...capabilitySecrets,
19045
19076
  ...capabilityEnvironment2
19046
19077
  },
19047
19078
  stdio: ["ignore", "pipe", "pipe"],
@@ -22259,11 +22290,7 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
22259
22290
  return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
22260
22291
  }
22261
22292
  if (!step.next || step.next.length === 0) {
22262
- state.status = "done";
22263
- delete state.currentStepId;
22264
- delete state.blocker;
22265
- await checkpoint?.(state);
22266
- return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
22293
+ return completeWorkflowAtTerminal(capability, state, result, checkpoint);
22267
22294
  }
22268
22295
  const resultConditionPaths = workflowResultConditionPaths(step.next);
22269
22296
  if (resultConditionPaths.length > 0 && !result.capabilityResults?.at(-1)) {
@@ -22286,11 +22313,7 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
22286
22313
  state.transitionCounts[key] = (state.transitionCounts[key] ?? 0) + 1;
22287
22314
  }
22288
22315
  if (transition.to === "$end") {
22289
- state.status = "done";
22290
- delete state.currentStepId;
22291
- delete state.blocker;
22292
- await checkpoint?.(state);
22293
- return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
22316
+ return completeWorkflowAtTerminal(capability, state, result, checkpoint);
22294
22317
  }
22295
22318
  state.currentStepId = transition.to;
22296
22319
  state.status = "running";
@@ -22301,6 +22324,25 @@ async function runGraphCapabilityWorkflow(parent, workflow, capability, base, ch
22301
22324
  await checkpoint?.(state);
22302
22325
  return withWorkflowBoundaryEval(capability, { ...result, workflowState: state });
22303
22326
  }
22327
+ async function completeWorkflowAtTerminal(capability, state, output, checkpoint) {
22328
+ const result = output.capabilityResults?.at(-1);
22329
+ if (result?.status === "fail" || result?.status === "blocked") {
22330
+ state.status = result.status === "fail" ? "failed" : "blocked";
22331
+ state.blocker = result.summary;
22332
+ await checkpoint?.(state);
22333
+ return withWorkflowBoundaryEval(capability, {
22334
+ ...output,
22335
+ exitCode: result.status === "fail" ? 1 : 64,
22336
+ reason: result.summary,
22337
+ workflowState: state
22338
+ });
22339
+ }
22340
+ state.status = "done";
22341
+ delete state.currentStepId;
22342
+ delete state.blocker;
22343
+ await checkpoint?.(state);
22344
+ return withWorkflowBoundaryEval(capability, { ...output, workflowState: state });
22345
+ }
22304
22346
  function graphWorkflowExecutionKey(parentExecutionKey, workflowSlug, stepId, transitionCounts) {
22305
22347
  const transitionHistory = Object.entries(transitionCounts).filter(([, count]) => count > 0).sort(([left], [right]) => left.localeCompare(right)).map(([transition, count]) => `${transition}=${count}`).join(",");
22306
22348
  return [
File without changes
@@ -149,6 +149,7 @@
149
149
  "e2eCommand": { "type": "string" },
150
150
  "draftRelease": { "type": "boolean" },
151
151
  "releaseBranch": { "type": "string" },
152
+ "allowAdminMerge": { "type": "boolean" },
152
153
  "timeoutMs": {
153
154
  "type": "integer",
154
155
  "minimum": 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.473",
3
+ "version": "0.4.474",
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
- "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
- }
64
+ "bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
65
+ }