@kody-ade/kody-engine 0.4.485 → 0.4.487

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.485",
18
+ version: "0.4.487",
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",
@@ -15475,6 +15475,18 @@ async function resolveRuntimeSecret(name, ctx, opts = {}) {
15475
15475
  }
15476
15476
  return envSecret(name, env);
15477
15477
  }
15478
+ async function resolveRuntimeSecrets(names, ctx, opts = {}) {
15479
+ const declared = Array.isArray(names) ? [...new Set(names.filter((name) => typeof name === "string" && /^[A-Z][A-Z0-9_]*$/.test(name)))] : [];
15480
+ const resolved = await Promise.all(
15481
+ declared.map(async (name) => ({ name, result: await resolveRuntimeSecret(name, ctx, opts) }))
15482
+ );
15483
+ return {
15484
+ environment: Object.fromEntries(
15485
+ resolved.flatMap(({ name, result }) => result.value ? [[name, result.value]] : [])
15486
+ ),
15487
+ warnings: resolved.flatMap(({ result }) => result.warning ? [result.warning] : [])
15488
+ };
15489
+ }
15478
15490
  var init_runtimeSecrets = __esm({
15479
15491
  "src/scripts/runtimeSecrets.ts"() {
15480
15492
  "use strict";
@@ -19150,16 +19162,6 @@ import * as fs47 from "fs";
19150
19162
  function formatDuration2(timeoutMs) {
19151
19163
  return timeoutMs % 6e4 === 0 ? `${timeoutMs / 6e4} minutes` : `${timeoutMs}ms`;
19152
19164
  }
19153
- function declaredSecrets(names, parent) {
19154
- if (!Array.isArray(names)) return {};
19155
- const secrets = {};
19156
- for (const name of names) {
19157
- if (typeof name !== "string" || !/^[A-Z][A-Z0-9_]*$/.test(name)) continue;
19158
- const value = parent[name];
19159
- if (value !== void 0) secrets[name] = value;
19160
- }
19161
- return secrets;
19162
- }
19163
19165
  function isRegularFile2(filePath) {
19164
19166
  try {
19165
19167
  const stat = fs47.lstatSync(filePath);
@@ -19176,6 +19178,7 @@ var init_runSimpleCapabilityScript = __esm({
19176
19178
  "src/scripts/runSimpleCapabilityScript.ts"() {
19177
19179
  "use strict";
19178
19180
  init_capabilityResult();
19181
+ init_runtimeSecrets();
19179
19182
  init_tickShellRunner();
19180
19183
  DEFAULT_SCRIPT_TIMEOUT_MS = 5 * 60 * 1e3;
19181
19184
  SCRIPT_MAX_OUTPUT_BYTES = 1024 * 1024;
@@ -19188,13 +19191,17 @@ var init_runSimpleCapabilityScript = __esm({
19188
19191
  return;
19189
19192
  }
19190
19193
  const capabilityEnvironment = isStringRecord(ctx.data.capabilityEnvironment) ? ctx.data.capabilityEnvironment : {};
19191
- const capabilitySecrets = declaredSecrets(ctx.data.capabilitySecretNames, process.env);
19194
+ const capabilitySecrets = await resolveRuntimeSecrets(ctx.data.capabilitySecretNames, ctx);
19195
+ for (const warning of capabilitySecrets.warnings) {
19196
+ process.stderr.write(`\u2192 kody: WARNING ${warning}
19197
+ `);
19198
+ }
19192
19199
  const timeoutMs = typeof ctx.data.capabilityScriptTimeoutMs === "number" ? ctx.data.capabilityScriptTimeoutMs : DEFAULT_SCRIPT_TIMEOUT_MS;
19193
19200
  const result = spawnSync3("bash", [scriptPath], {
19194
19201
  cwd: ctx.cwd,
19195
19202
  env: {
19196
19203
  ...buildTickChildEnv(process.env, false),
19197
- ...capabilitySecrets,
19204
+ ...capabilitySecrets.environment,
19198
19205
  ...capabilityEnvironment
19199
19206
  },
19200
19207
  stdio: ["ignore", "pipe", "pipe"],
@@ -24233,14 +24240,14 @@ function primaryNumericInputName(implementation) {
24233
24240
  const intInput = inputs.find((i) => i.type === "int" && i.required);
24234
24241
  return intInput?.name ?? null;
24235
24242
  }
24236
- function resolveOperatorAction(action) {
24237
- return resolveCapabilityAction(action);
24243
+ function resolveOperatorAction(action, projectCapabilitiesRoot) {
24244
+ return resolveCapabilityAction(action, projectCapabilitiesRoot);
24238
24245
  }
24239
- function resolveConfiguredAction(action) {
24240
- return resolveCapabilityAction(action);
24246
+ function resolveConfiguredAction(action, projectCapabilitiesRoot) {
24247
+ return resolveCapabilityAction(action, projectCapabilitiesRoot);
24241
24248
  }
24242
- function requiredRoute(action) {
24243
- const route = resolveConfiguredAction(action);
24249
+ function requiredRoute(action, projectCapabilitiesRoot) {
24250
+ const route = resolveConfiguredAction(action, projectCapabilitiesRoot);
24244
24251
  if (!route) throw new Error(`required capability action not found: ${action}`);
24245
24252
  return route;
24246
24253
  }
@@ -24256,9 +24263,14 @@ function routeResult(route, cliArgs, target, why) {
24256
24263
  return result;
24257
24264
  }
24258
24265
  function autoDispatch(opts) {
24266
+ const projectCapabilitiesRoot = opts?.projectCapabilitiesRoot;
24259
24267
  const explicit = opts?.explicit;
24260
24268
  if (explicit?.issueNumber && explicit.issueNumber > 0) {
24261
- return routeResult(requiredRoute("run"), { issue: explicit.issueNumber }, explicit.issueNumber);
24269
+ return routeResult(
24270
+ requiredRoute("run", projectCapabilitiesRoot),
24271
+ { issue: explicit.issueNumber },
24272
+ explicit.issueNumber
24273
+ );
24262
24274
  }
24263
24275
  const eventName = process.env.GITHUB_EVENT_NAME;
24264
24276
  const eventPath = process.env.GITHUB_EVENT_PATH;
@@ -24274,7 +24286,7 @@ function autoDispatch(opts) {
24274
24286
  const n = parseInt(String(inputs2?.issue_number ?? ""), 10);
24275
24287
  if (!Number.isNaN(n) && n > 0) {
24276
24288
  const actionName = String(inputs2?.capability ?? "").trim() || "run";
24277
- const route2 = resolveConfiguredAction(actionName);
24289
+ const route2 = resolveConfiguredAction(actionName, projectCapabilitiesRoot);
24278
24290
  if (!route2) return null;
24279
24291
  const base = String(inputs2?.base ?? "").trim();
24280
24292
  const profileInputs = getProfileInputs(route2.implementation);
@@ -24296,7 +24308,7 @@ function autoDispatch(opts) {
24296
24308
  if (actionName && (action === "opened" || action === "synchronize" || action === "reopened")) {
24297
24309
  const pullRequest = objectValue(event.pull_request);
24298
24310
  if (isReleasePullRequest(pullRequest, opts?.config)) return null;
24299
- const route2 = resolveConfiguredAction(actionName);
24311
+ const route2 = resolveConfiguredAction(actionName, projectCapabilitiesRoot);
24300
24312
  if (!route2) return null;
24301
24313
  const prNum = Number(pullRequest?.number ?? event.number ?? 0);
24302
24314
  if (prNum > 0) {
@@ -24335,7 +24347,7 @@ function autoDispatch(opts) {
24335
24347
  let route = null;
24336
24348
  let consumedFirstToken = false;
24337
24349
  if (aliased) {
24338
- route = resolveOperatorAction(aliased);
24350
+ route = resolveOperatorAction(aliased, projectCapabilitiesRoot);
24339
24351
  if (route) {
24340
24352
  consumedFirstToken = true;
24341
24353
  } else if (firstToken && aliases[firstToken] && aliases[firstToken] === aliased) {
@@ -24347,7 +24359,7 @@ function autoDispatch(opts) {
24347
24359
  }
24348
24360
  if (!route && !firstToken) {
24349
24361
  const defaultAction = isPr ? opts?.config?.defaultPrImplementation ?? null : opts?.config?.defaultImplementation ?? null;
24350
- route = defaultAction ? resolveConfiguredAction(defaultAction) : null;
24362
+ route = defaultAction ? resolveConfiguredAction(defaultAction, projectCapabilitiesRoot) : null;
24351
24363
  }
24352
24364
  if (isBotAuthor && !consumedFirstToken) {
24353
24365
  process.stderr.write(
@@ -24358,14 +24370,14 @@ function autoDispatch(opts) {
24358
24370
  }
24359
24371
  if (!route) {
24360
24372
  if (!firstToken) return null;
24361
- const profileMissing = aliased ? resolveOperatorAction(aliased) === null : true;
24373
+ const profileMissing = aliased ? resolveOperatorAction(aliased, projectCapabilitiesRoot) === null : true;
24362
24374
  process.stderr.write(
24363
24375
  `[kody] dispatch: no capability action resolved for issue_comment (firstToken=${firstToken ?? "<none>"}, aliased=${aliased ?? "<none>"}, actionFound=${!profileMissing}, defaultImplementation=${opts?.config?.defaultImplementation ?? "<unset>"}, defaultPrImplementation=${opts?.config?.defaultPrImplementation ?? "<unset>"})
24364
24376
  `
24365
24377
  );
24366
24378
  return null;
24367
24379
  }
24368
- const inputs = getProfileInputs(route.implementation);
24380
+ const inputs = getCapabilityActionInputs(route.action, projectCapabilitiesRoot);
24369
24381
  const effectiveInputs = inputs ?? [];
24370
24382
  const unknownProfile = inputs === null;
24371
24383
  const rest = extractCommentRest(afterTag, consumedFirstToken ? firstToken : null);
@@ -24440,7 +24452,7 @@ function autoDispatchTyped(opts) {
24440
24452
  reason: tokenRaw ? `polite-word lead-in '${tokenRaw}', no default capability action configured` : "no subcommand token, no default capability action configured"
24441
24453
  };
24442
24454
  }
24443
- const available = listCapabilityActions().map((e) => e.action).filter((n) => !n.startsWith("goal-") && !n.startsWith("job-")).sort();
24455
+ const available = listCapabilityActions(opts?.projectCapabilitiesRoot).map((e) => e.action).filter((n) => !n.startsWith("goal-") && !n.startsWith("job-")).sort();
24444
24456
  return { kind: "unrecognized", token: tokenRaw, target: targetNum, isPr, available };
24445
24457
  }
24446
24458
  function dispatchScheduledWatches(opts) {
@@ -24651,7 +24663,7 @@ Options:
24651
24663
  --package-manager Override package-manager auto-detect
24652
24664
 
24653
24665
  Environment:
24654
- ALL_SECRETS JSON blob of all GitHub secrets (auto-populated in CI)
24666
+ ALL_SECRETS Legacy JSON secret blob (supported, never generated by current templates)
24655
24667
  KODY_TOKEN|GH_TOKEN|GITHUB_TOKEN|GH_PAT auth token for gh/git operations
24656
24668
 
24657
24669
  Exit codes (inherited from kody run):
@@ -24968,7 +24980,8 @@ async function runCi(argv) {
24968
24980
  } catch (err) {
24969
24981
  earlyConfigError = err instanceof Error ? err : new Error(String(err));
24970
24982
  }
24971
- const autoFallback = !args.issueNumber ? autoDispatch({ config: earlyConfig }) : null;
24983
+ const dispatchCapabilitiesRoot = capabilitiesRoot(cwd);
24984
+ const autoFallback = !args.issueNumber ? autoDispatch({ config: earlyConfig, projectCapabilitiesRoot: dispatchCapabilitiesRoot }) : null;
24972
24985
  const eventName = process.env.GITHUB_EVENT_NAME;
24973
24986
  const scheduledActionsWake = isScheduledActionsWake();
24974
24987
  const dispatchEventPath = process.env.GITHUB_EVENT_PATH;
@@ -25150,7 +25163,10 @@ async function runCi(argv) {
25150
25163
  return runScheduledFanOut(cwd, args, { force: manualWorkflowDispatch });
25151
25164
  }
25152
25165
  if (!args.issueNumber && !autoFallback && process.env.GITHUB_EVENT_NAME) {
25153
- const outcome = autoDispatchTyped({ config: earlyConfig });
25166
+ const outcome = autoDispatchTyped({
25167
+ config: earlyConfig,
25168
+ projectCapabilitiesRoot: dispatchCapabilitiesRoot
25169
+ });
25154
25170
  if (outcome.kind === "rejected") {
25155
25171
  try {
25156
25172
  unpackAllSecrets();
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.485",
3
+ "version": "0.4.487",
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
+ }
@@ -75,7 +75,10 @@ jobs:
75
75
  node-version: 22
76
76
 
77
77
  - env:
78
- ALL_SECRETS: ${{ toJSON(secrets) }}
78
+ GH_PAT: ${{ secrets.GH_PAT }}
79
+ KODY_TOKEN: ${{ secrets.KODY_TOKEN }}
80
+ KODY_APP_ID: ${{ secrets.KODY_APP_ID }}
81
+ KODY_APP_PRIVATE_KEY: ${{ secrets.KODY_APP_PRIVATE_KEY }}
79
82
  SESSION_ID: ${{ inputs.sessionId }}
80
83
  INIT_MESSAGE: ${{ inputs.message }}
81
84
  MODEL: ${{ inputs.model }}