@kody-ade/kody-engine 0.4.280 → 0.4.281

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.
Files changed (2) hide show
  1. package/dist/bin/kody.js +50 -19
  2. package/package.json +23 -24
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.280",
18
+ version: "0.4.281",
19
19
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
20
20
  license: "MIT",
21
21
  type: "module",
@@ -6305,6 +6305,28 @@ var init_abortUnfinishedGitOps = __esm({
6305
6305
  }
6306
6306
  });
6307
6307
 
6308
+ // src/scripts/deliveryOutcome.ts
6309
+ function isRecord(input) {
6310
+ return !!input && typeof input === "object" && !Array.isArray(input);
6311
+ }
6312
+ function setDeliveryNotRequired(data, reason) {
6313
+ data.deliveryOutcome = { kind: "not_required", reason };
6314
+ }
6315
+ function readDeliveryOutcome(data) {
6316
+ const raw = data.deliveryOutcome;
6317
+ if (!isRecord(raw)) return null;
6318
+ if (raw.kind !== "not_required" || typeof raw.reason !== "string" || raw.reason.length === 0) return null;
6319
+ return { kind: "not_required", reason: raw.reason };
6320
+ }
6321
+ function isDeliveryNotRequired(data) {
6322
+ return readDeliveryOutcome(data)?.kind === "not_required";
6323
+ }
6324
+ var init_deliveryOutcome = __esm({
6325
+ "src/scripts/deliveryOutcome.ts"() {
6326
+ "use strict";
6327
+ }
6328
+ });
6329
+
6308
6330
  // src/scripts/saveTaskState.ts
6309
6331
  function jobMetaFromData(data) {
6310
6332
  return {
@@ -6322,7 +6344,7 @@ function jobMetaFromData(data) {
6322
6344
  }
6323
6345
  function applyStandaloneTerminalState(state, ctx, profile) {
6324
6346
  if (profile.lifecycleConfig?.finalize !== true || state.flow?.issueNumber) return;
6325
- const delivered = ctx.output.exitCode === 0 && !!state.core.prUrl;
6347
+ const delivered = ctx.output.exitCode === 0 && (!!state.core.prUrl || isDeliveryNotRequired(ctx.data));
6326
6348
  state.core.phase = delivered ? "shipped" : "failed";
6327
6349
  state.core.status = delivered ? "succeeded" : "failed";
6328
6350
  state.core.currentExecutable = null;
@@ -6344,6 +6366,7 @@ var init_saveTaskState = __esm({
6344
6366
  "src/scripts/saveTaskState.ts"() {
6345
6367
  "use strict";
6346
6368
  init_state();
6369
+ init_deliveryOutcome();
6347
6370
  saveTaskState = async (ctx, profile) => {
6348
6371
  const target = ctx.data.commentTargetType;
6349
6372
  const number = ctx.data.commentTargetNumber;
@@ -11670,6 +11693,7 @@ var init_finalizeTerminal = __esm({
11670
11693
  init_issue();
11671
11694
  init_lifecycleLabels();
11672
11695
  init_state();
11696
+ init_deliveryOutcome();
11673
11697
  DONE = {
11674
11698
  label: "kody:done",
11675
11699
  color: "0e8a16",
@@ -11690,7 +11714,7 @@ var init_finalizeTerminal = __esm({
11690
11714
  const cachedState = ctx.data.taskState;
11691
11715
  let state = cachedState;
11692
11716
  const prUrl = cachedState?.core.prUrl ?? ctx.output.prUrl ?? ctx.data.prResult?.url;
11693
- const delivered = ctx.output.exitCode === 0 && !!prUrl;
11717
+ const delivered = ctx.output.exitCode === 0 && (!!prUrl || isDeliveryNotRequired(ctx.data));
11694
11718
  const spec = delivered ? DONE : FAILED;
11695
11719
  const phase = delivered ? "shipped" : "failed";
11696
11720
  const status = delivered ? "succeeded" : "failed";
@@ -14331,6 +14355,7 @@ var init_postIssueComment = __esm({
14331
14355
  "use strict";
14332
14356
  init_issue();
14333
14357
  init_lifecycleLabels();
14358
+ init_deliveryOutcome();
14334
14359
  init_prOutcome();
14335
14360
  FAILED_LABEL_SPEC = {
14336
14361
  label: "kody:failed",
@@ -14347,7 +14372,14 @@ var init_postIssueComment = __esm({
14347
14372
  const prResult = readPrOutcome(ctx.data);
14348
14373
  if (!commitResult?.committed && !hasCommits) {
14349
14374
  const specific = computeFailureReason2(ctx);
14350
- const reason = specific.length > 0 ? specific : "no changes to commit";
14375
+ if (specific.length === 0) {
14376
+ const reason2 = "work already satisfied; no PR needed";
14377
+ setDeliveryNotRequired(ctx.data, reason2);
14378
+ postWith(targetType, targetNumber, `\u2139\uFE0F kody made no changes \u2014 ${reason2}`, ctx.cwd);
14379
+ ctx.output.exitCode = 0;
14380
+ return;
14381
+ }
14382
+ const reason = specific;
14351
14383
  const containerParent = process.env.KODY_CONTAINER_PARENT;
14352
14384
  if (containerParent) {
14353
14385
  postWith(
@@ -19932,22 +19964,20 @@ init_gha();
19932
19964
  init_issue();
19933
19965
  init_job();
19934
19966
  init_registry();
19935
- init_runtimePaths();
19936
- init_stateWorkspace();
19937
19967
 
19938
19968
  // src/run-request.ts
19939
19969
  var RUN_REQUEST_ENV = "KODY_RUN_REQUEST_JSON";
19940
19970
  var INTENTS = /* @__PURE__ */ new Set(["continue", "manage", "run", "tick"]);
19941
19971
  var SOURCES = /* @__PURE__ */ new Set(["dashboard", "github", "schedule"]);
19942
19972
  var TARGET_TYPES = /* @__PURE__ */ new Set(["chat", "goal", "issue", "workflow"]);
19943
- function isRecord(value) {
19973
+ function isRecord2(value) {
19944
19974
  return typeof value === "object" && value !== null && !Array.isArray(value);
19945
19975
  }
19946
19976
  function readString(value) {
19947
19977
  return typeof value === "string" ? value.trim() : "";
19948
19978
  }
19949
19979
  function parseTarget(input) {
19950
- if (!isRecord(input)) return { error: "runRequest.target must be an object" };
19980
+ if (!isRecord2(input)) return { error: "runRequest.target must be an object" };
19951
19981
  const type = readString(input.type);
19952
19982
  if (!TARGET_TYPES.has(type)) return { error: "runRequest.target.type is invalid" };
19953
19983
  if (type === "issue") {
@@ -19970,14 +20000,14 @@ function parseRunRequest(input) {
19970
20000
  return { error: `${RUN_REQUEST_ENV} must be valid JSON` };
19971
20001
  }
19972
20002
  }
19973
- if (!isRecord(body)) return { error: "runRequest must be an object" };
20003
+ if (!isRecord2(body)) return { error: "runRequest must be an object" };
19974
20004
  const parsedTarget = parseTarget(body.target);
19975
20005
  if ("error" in parsedTarget) return parsedTarget;
19976
20006
  const intent = readString(body.intent);
19977
20007
  if (!INTENTS.has(intent)) return { error: "runRequest.intent is invalid" };
19978
20008
  const source = readString(body.source);
19979
20009
  if (!SOURCES.has(source)) return { error: "runRequest.source is invalid" };
19980
- if (body.input !== void 0 && !isRecord(body.input)) {
20010
+ if (body.input !== void 0 && !isRecord2(body.input)) {
19981
20011
  return { error: "runRequest.input must be an object when provided" };
19982
20012
  }
19983
20013
  return {
@@ -19996,6 +20026,8 @@ function readRunRequestFromEnv(env = process.env) {
19996
20026
  }
19997
20027
 
19998
20028
  // src/kody-cli.ts
20029
+ init_runtimePaths();
20030
+ init_stateWorkspace();
19999
20031
  var CI_HELP = `kody ci \u2014 minimal-YAML autonomous engineer (CI preflight + run)
20000
20032
 
20001
20033
  Usage:
@@ -20268,6 +20300,9 @@ ${tail}
20268
20300
  } catch {
20269
20301
  }
20270
20302
  }
20303
+ function shouldPostRunFailureTail(exitCode) {
20304
+ return exitCode !== 0 && exitCode !== 1 && exitCode !== 2 && exitCode !== 3;
20305
+ }
20271
20306
  async function runCi(argv) {
20272
20307
  if (argv.includes("--help") || argv.includes("-h")) {
20273
20308
  process.stdout.write(CI_HELP);
@@ -20497,10 +20532,8 @@ ${CI_HELP}`);
20497
20532
  `);
20498
20533
  const buildOnly = dispatch2.executable === "preview-build";
20499
20534
  if (args.skipInstall || buildOnly) {
20500
- process.stdout.write(
20501
- `\u2192 kody: skipping dep install (${buildOnly ? "build-only executable" : "--skip-install"})
20502
- `
20503
- );
20535
+ process.stdout.write(`\u2192 kody: skipping dep install (${buildOnly ? "build-only executable" : "--skip-install"})
20536
+ `);
20504
20537
  } else {
20505
20538
  const code = installDeps(pm, cwd);
20506
20539
  if (code !== 0) {
@@ -20539,7 +20572,7 @@ ${CI_HELP}`);
20539
20572
  verbose: args.verbose,
20540
20573
  quiet: args.quiet
20541
20574
  });
20542
- if (result.exitCode !== 0 && result.exitCode !== 1 && result.exitCode !== 2) {
20575
+ if (shouldPostRunFailureTail(result.exitCode)) {
20543
20576
  postFailureTail(issueNumber, cwd, result.reason || `exit ${result.exitCode}`);
20544
20577
  }
20545
20578
  return result.exitCode;
@@ -20599,11 +20632,9 @@ async function runScheduledFanOut(cwd, args, opts) {
20599
20632
  const config = loadConfig(cwd);
20600
20633
  const serial = process.env.KODY_SERIAL_WATCHES === "1";
20601
20634
  const runWatch = async (match) => {
20602
- process.stdout.write(
20603
- `
20635
+ process.stdout.write(`
20604
20636
  \u2192 kody: running watch capability \`${match.capability}\` (${match.executable})
20605
- `
20606
- );
20637
+ `);
20607
20638
  try {
20608
20639
  const result = await runJob(
20609
20640
  mintScheduledJob({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.280",
3
+ "version": "0.4.281",
4
4
  "description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,27 +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:all": "vitest run tests --no-coverage",
29
- "typecheck": "tsc --noEmit",
30
- "lint": "biome check",
31
- "lint:fix": "biome check --write",
32
- "format": "biome format --write",
33
- "brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner",
34
- "prepublishOnly": "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm build"
35
- },
36
15
  "dependencies": {
37
16
  "@actions/cache": "^6.0.0",
38
17
  "@anthropic-ai/claude-agent-sdk": "0.2.119",
@@ -56,5 +35,25 @@
56
35
  "url": "git+https://github.com/aharonyaircohen/kody-engine.git"
57
36
  },
58
37
  "homepage": "https://github.com/aharonyaircohen/kody-engine",
59
- "bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
60
- }
38
+ "bugs": "https://github.com/aharonyaircohen/kody-engine/issues",
39
+ "scripts": {
40
+ "kody:run": "tsx bin/kody.ts",
41
+ "serve": "tsx bin/kody.ts serve",
42
+ "serve:vscode": "tsx bin/kody.ts serve vscode",
43
+ "serve:claude": "tsx bin/kody.ts serve claude",
44
+ "clean:dist": "node scripts/clean-dist.cjs",
45
+ "build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
46
+ "check:modularity": "tsx scripts/check-script-modularity.ts",
47
+ "pretest": "pnpm check:modularity",
48
+ "test": "vitest run tests/unit tests/int --coverage",
49
+ "posttest": "tsx scripts/check-coverage-floor.ts",
50
+ "test:smoke": "vitest run tests/smoke --no-coverage",
51
+ "test:e2e": "vitest run tests/e2e --no-coverage",
52
+ "test:all": "vitest run tests --no-coverage",
53
+ "typecheck": "tsc --noEmit",
54
+ "lint": "biome check",
55
+ "lint:fix": "biome check --write",
56
+ "format": "biome format --write",
57
+ "brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner"
58
+ }
59
+ }