@kody-ade/kody-engine 0.4.31 → 0.4.32

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
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@kody-ade/kody-engine",
6
- version: "0.4.31",
6
+ version: "0.4.32",
7
7
  description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
8
8
  license: "MIT",
9
9
  type: "module",
@@ -5304,20 +5304,37 @@ function ensurePr(opts) {
5304
5304
  }
5305
5305
 
5306
5306
  // src/scripts/ensurePr.ts
5307
+ function setOutcome(ctx, outcome) {
5308
+ ctx.data.prResult = outcome;
5309
+ if (outcome.kind === "created" || outcome.kind === "updated") {
5310
+ ctx.output.prUrl = outcome.url;
5311
+ }
5312
+ }
5307
5313
  var ensurePr2 = async (ctx) => {
5308
5314
  if (ctx.skipAgent && ctx.output.exitCode !== void 0) {
5315
+ setOutcome(ctx, { kind: "skipped", reason: "preflight short-circuited (skipAgent)" });
5309
5316
  return;
5310
5317
  }
5311
5318
  const commitResult = ctx.data.commitResult;
5312
5319
  const hasCommits = Boolean(ctx.data.hasCommitsAhead);
5313
5320
  if (!commitResult?.committed && !hasCommits) {
5321
+ setOutcome(ctx, { kind: "skipped", reason: "no commits to ship" });
5314
5322
  return;
5315
5323
  }
5316
5324
  if (commitResult?.committed && commitResult.pushed === false) {
5325
+ setOutcome(ctx, { kind: "skipped", reason: "local commit succeeded but push failed" });
5326
+ return;
5327
+ }
5328
+ if (ctx.data.verifyOk === false) {
5329
+ const reason = `verify failed: ${ctx.data.verifyReason ?? "unknown"}`;
5330
+ setOutcome(ctx, { kind: "skipped", reason });
5317
5331
  return;
5318
5332
  }
5319
5333
  const branch = ctx.data.branch;
5320
- if (!branch) return;
5334
+ if (!branch) {
5335
+ setOutcome(ctx, { kind: "skipped", reason: "no branch context (ctx.data.branch missing)" });
5336
+ return;
5337
+ }
5321
5338
  const failureReason = computeFailureReason(ctx);
5322
5339
  const isFailure = failureReason.length > 0;
5323
5340
  const changedFiles = ctx.data.changedFiles ?? [];
@@ -5339,13 +5356,26 @@ var ensurePr2 = async (ctx) => {
5339
5356
  baseBranch,
5340
5357
  cwd: ctx.cwd
5341
5358
  });
5342
- ctx.output.prUrl = result.url;
5343
- ctx.data.prResult = result;
5359
+ if (!result.url || result.url.trim().length === 0) {
5360
+ const reason = `gh pr create returned empty URL (action=${result.action}); refusing to claim success`;
5361
+ ctx.data.prCrashReason = reason;
5362
+ ctx.output.exitCode = 4;
5363
+ ctx.output.reason = reason;
5364
+ setOutcome(ctx, { kind: "crashed", reason });
5365
+ return;
5366
+ }
5367
+ setOutcome(ctx, {
5368
+ kind: result.action === "created" ? "created" : "updated",
5369
+ url: result.url,
5370
+ number: result.number,
5371
+ draft: result.draft
5372
+ });
5344
5373
  } catch (err) {
5345
5374
  const reason = `PR creation failed: ${err instanceof Error ? err.message : String(err)}`;
5346
5375
  ctx.data.prCrashReason = reason;
5347
5376
  ctx.output.exitCode = 4;
5348
5377
  ctx.output.reason = reason;
5378
+ setOutcome(ctx, { kind: "crashed", reason });
5349
5379
  }
5350
5380
  };
5351
5381
  function computeFailureReason(ctx) {
@@ -7235,6 +7265,22 @@ var persistFlowState = async (ctx) => {
7235
7265
  }
7236
7266
  };
7237
7267
 
7268
+ // src/scripts/prOutcome.ts
7269
+ function readPrOutcome(data) {
7270
+ const raw = data.prResult;
7271
+ if (!raw || typeof raw !== "object") return null;
7272
+ const r = raw;
7273
+ switch (r.kind) {
7274
+ case "created":
7275
+ case "updated":
7276
+ case "skipped":
7277
+ case "crashed":
7278
+ return raw;
7279
+ default:
7280
+ return null;
7281
+ }
7282
+ }
7283
+
7238
7284
  // src/scripts/postIssueComment.ts
7239
7285
  var FAILED_LABEL_SPEC = {
7240
7286
  label: "kody:failed",
@@ -7248,8 +7294,7 @@ var postIssueComment2 = async (ctx) => {
7248
7294
  if (!targetType || !targetNumber) return;
7249
7295
  const commitResult = ctx.data.commitResult;
7250
7296
  const hasCommits = Boolean(ctx.data.hasCommitsAhead);
7251
- const prUrl = ctx.output.prUrl;
7252
- const prAction = ctx.data.prResult?.action;
7297
+ const prResult = readPrOutcome(ctx.data);
7253
7298
  if (!commitResult?.committed && !hasCommits) {
7254
7299
  const specific = computeFailureReason2(ctx);
7255
7300
  const reason = specific.length > 0 ? specific : "no changes to commit";
@@ -7267,18 +7312,17 @@ var postIssueComment2 = async (ctx) => {
7267
7312
  }
7268
7313
  const failureReason = computeFailureReason2(ctx);
7269
7314
  const isFailure = failureReason.length > 0;
7270
- const justPushedToExistingPr = prAction === "updated" && commitResult?.committed === true;
7271
- const successMsg = justPushedToExistingPr ? `\u2705 kody pushed to ${prUrl}` : prAction === "updated" ? `\u2139\uFE0F kody made no changes \u2014 PR: ${prUrl}` : `\u2705 kody PR opened: ${prUrl}`;
7272
7315
  const branch = ctx.data.branch;
7273
- const failurePrSuffix = computeFailureSuffix({
7274
- prUrl,
7275
- prAction,
7316
+ const msg = renderMessage({
7317
+ prResult,
7318
+ isFailure,
7319
+ failureReason,
7320
+ justPushedToExistingPr: prResult?.kind === "updated" && commitResult?.committed === true,
7276
7321
  branch,
7277
7322
  branchPushed: commitResult?.committed === true,
7278
7323
  githubOwner: ctx.config.github?.owner,
7279
7324
  githubRepo: ctx.config.github?.repo
7280
7325
  });
7281
- const msg = isFailure ? `\u26A0\uFE0F kody FAILED: ${truncate2(failureReason, 1500)}${failurePrSuffix}` : successMsg;
7282
7326
  postWith(targetType, targetNumber, msg, ctx.cwd);
7283
7327
  let exitCode = 0;
7284
7328
  const agentDone = Boolean(ctx.data.agentDone);
@@ -7302,12 +7346,29 @@ function markRunFailed(ctx) {
7302
7346
  }
7303
7347
  }
7304
7348
  function computeFailureSuffix(input) {
7305
- if (input.prUrl) {
7306
- return input.prAction === "updated" ? ` \u2014 PR: ${input.prUrl}` : ` \u2014 draft PR: ${input.prUrl}`;
7307
- }
7349
+ if (input.prResult?.kind === "created") return ` \u2014 draft PR: ${input.prResult.url}`;
7350
+ if (input.prResult?.kind === "updated") return ` \u2014 PR: ${input.prResult.url}`;
7308
7351
  if (!input.branchPushed || !input.branch || !input.githubOwner || !input.githubRepo) return "";
7309
7352
  return ` \u2014 branch: https://github.com/${input.githubOwner}/${input.githubRepo}/tree/${input.branch}`;
7310
7353
  }
7354
+ function renderMessage(input) {
7355
+ const suffix = computeFailureSuffix(input);
7356
+ if (input.isFailure) {
7357
+ return `\u26A0\uFE0F kody FAILED: ${truncate2(input.failureReason, 1500)}${suffix}`;
7358
+ }
7359
+ switch (input.prResult?.kind) {
7360
+ case "created":
7361
+ return `\u2705 kody PR opened: ${input.prResult.url}`;
7362
+ case "updated":
7363
+ return input.justPushedToExistingPr ? `\u2705 kody pushed to ${input.prResult.url}` : `\u2139\uFE0F kody made no changes \u2014 PR: ${input.prResult.url}`;
7364
+ case "skipped":
7365
+ return `\u26A0\uFE0F kody finished but did not open a PR \u2014 ${input.prResult.reason}${suffix}`;
7366
+ case "crashed":
7367
+ return `\u26A0\uFE0F kody PR step crashed: ${truncate2(input.prResult.reason, 1500)}${suffix}`;
7368
+ case void 0:
7369
+ return `\u26A0\uFE0F kody finished but PR step did not run${suffix}`;
7370
+ }
7371
+ }
7311
7372
  function computeFailureReason2(ctx) {
7312
7373
  const misses = ctx.data.coverageMisses ?? [];
7313
7374
  if (misses.length > 0) return `missing tests: ${misses.map((m) => m.expectedTest).join(", ")}`;
@@ -65,7 +65,7 @@
65
65
  { "script": "checkCoverageWithRetry" },
66
66
  { "script": "abortUnfinishedGitOps" },
67
67
  { "script": "commitAndPush" },
68
- { "script": "ensurePr", "runWhen": { "data.verifyOk": true } },
68
+ { "script": "ensurePr" },
69
69
  { "script": "postIssueComment" },
70
70
  { "script": "writeRunSummary" },
71
71
  { "script": "saveTaskState" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kody-ade/kody-engine",
3
- "version": "0.4.31",
3
+ "version": "0.4.32",
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",