@kody-ade/kody-engine 0.1.4 → 0.1.5

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/cli.mjs CHANGED
@@ -7965,10 +7965,16 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
7965
7965
  }
7966
7966
  if (!ctx.input.dryRun && !ctx.input.local) {
7967
7967
  try {
7968
- const currentBranch = execFileSync13("git", ["branch", "--show-current"], {
7969
- encoding: "utf-8"
7970
- }).trim();
7971
- const isFeatureBranch = !["dev", "main", "master"].includes(currentBranch);
7968
+ const currentBranch = execFileSync13(
7969
+ "git",
7970
+ ["branch", "--show-current"],
7971
+ {
7972
+ encoding: "utf-8"
7973
+ }
7974
+ ).trim();
7975
+ const isFeatureBranch = !["dev", "main", "master"].includes(
7976
+ currentBranch
7977
+ );
7972
7978
  if (isFeatureBranch) {
7973
7979
  commitPipelineFiles({
7974
7980
  taskDir: ctx.taskDir,
@@ -7981,7 +7987,10 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
7981
7987
  logger.info(" \u2713 Pushed fresh running status.json to branch");
7982
7988
  }
7983
7989
  } catch (earlyPushErr) {
7984
- logger.warn({ err: earlyPushErr }, "Early status push failed (non-fatal)");
7990
+ logger.warn(
7991
+ { err: earlyPushErr },
7992
+ "Early status push failed (non-fatal)"
7993
+ );
7985
7994
  }
7986
7995
  }
7987
7996
  } else {
@@ -8002,7 +8011,9 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
8002
8011
  }
8003
8012
  }
8004
8013
  if (state.state === "paused") {
8005
- const anyPausedStage = Object.values(state.stages).some((s) => s.state === "paused");
8014
+ const anyPausedStage = Object.values(state.stages).some(
8015
+ (s) => s.state === "paused"
8016
+ );
8006
8017
  if (!anyPausedStage) {
8007
8018
  state = {
8008
8019
  ...state,
@@ -8035,7 +8046,11 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
8035
8046
  const recoveredState = recoverStaleStages(currentState);
8036
8047
  if (recoveredState !== currentState) {
8037
8048
  logger.info("\u26A0\uFE0F Periodic recovery: reset stale running stages");
8038
- logRecovery("stale-stage-recovery", ctx.taskId, "Reset stale running stages");
8049
+ logRecovery(
8050
+ "stale-stage-recovery",
8051
+ ctx.taskId,
8052
+ "Reset stale running stages"
8053
+ );
8039
8054
  state = recoveredState;
8040
8055
  writeState(ctx.taskId, state);
8041
8056
  }
@@ -8047,7 +8062,10 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
8047
8062
  const newOrder = flattenPipelineOrder(pipeline.order);
8048
8063
  for (const stageName of newOrder) {
8049
8064
  if (!state.stages[stageName]) {
8050
- state = updateStage(state, stageName, { state: "pending", retries: 0 });
8065
+ state = updateStage(state, stageName, {
8066
+ state: "pending",
8067
+ retries: 0
8068
+ });
8051
8069
  }
8052
8070
  }
8053
8071
  writeState(ctx.taskId, state);
@@ -8088,7 +8106,9 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
8088
8106
  const stageState = failedStage?.[1];
8089
8107
  const stageOutcome = stageState?.state || "unknown";
8090
8108
  const stageError = stageState?.error ? `: ${stageState.error}` : "";
8091
- throw new Error(`Pipeline failed at stage: ${stageName} (${stageOutcome})${stageError}`);
8109
+ throw new Error(
8110
+ `Pipeline failed at stage: ${stageName} (${stageOutcome})${stageError}`
8111
+ );
8092
8112
  }
8093
8113
  return state;
8094
8114
  }
@@ -8134,7 +8154,10 @@ async function executeSingleStep(ctx, pipeline, state, stageName) {
8134
8154
  logger.info(` ${stageName} already completed, skipping`);
8135
8155
  return state;
8136
8156
  }
8137
- state = updateStage(state, stageName, { state: "running", startedAt: (/* @__PURE__ */ new Date()).toISOString() });
8157
+ state = updateStage(state, stageName, {
8158
+ state: "running",
8159
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
8160
+ });
8138
8161
  writeState(ctx.taskId, state);
8139
8162
  logStageStart(stageName, ctx.taskId);
8140
8163
  if (ctx.input.dryRun) {
@@ -8156,7 +8179,30 @@ async function executeSingleStep(ctx, pipeline, state, stageName) {
8156
8179
  const handler = getHandler(def.name, def.type);
8157
8180
  const result = await handler.execute(ctx, def);
8158
8181
  ciGroupEnd();
8159
- return await handleStageResult(ctx, pipeline, state, stageName, result, def);
8182
+ if (result.outcome === "failed" || result.outcome === "timed_out") {
8183
+ if (def.postActions && !ctx.input.dryRun) {
8184
+ try {
8185
+ for (const action of def.postActions) {
8186
+ await executePostAction(ctx, action, state);
8187
+ }
8188
+ } catch (postError) {
8189
+ logger.error(
8190
+ { err: postError },
8191
+ ` Post-action failed for ${stageName}:`
8192
+ );
8193
+ }
8194
+ }
8195
+ const errorMessage = `${stageName} ${result.outcome === "timed_out" ? "timed out" : "failed"}: ${result.reason || "unknown"}`;
8196
+ throw new Error(errorMessage);
8197
+ }
8198
+ return await handleStageResult(
8199
+ ctx,
8200
+ pipeline,
8201
+ state,
8202
+ stageName,
8203
+ result,
8204
+ def
8205
+ );
8160
8206
  } catch (error) {
8161
8207
  ciGroupEnd();
8162
8208
  if (error instanceof PipelinePausedError) {
@@ -8214,7 +8260,10 @@ async function executeSingleStep(ctx, pipeline, state, stageName) {
8214
8260
  return completeState(state, "failed");
8215
8261
  }
8216
8262
  } catch (observerError) {
8217
- logger.error({ err: observerError }, `[StateMachine] Observer error, falling back`);
8263
+ logger.error(
8264
+ { err: observerError },
8265
+ `[StateMachine] Observer error, falling back`
8266
+ );
8218
8267
  state = updateStage(state, stageName, {
8219
8268
  state: "failed",
8220
8269
  error: errorMessage
@@ -8261,7 +8310,10 @@ async function executeParallelStep(ctx, pipeline, state, stageNames) {
8261
8310
  stagesToRun.map(async (stageName) => {
8262
8311
  const def = pipeline.stages.get(stageName);
8263
8312
  if (!def) {
8264
- throw new StageError(`Stage '${stageName}' not found in pipeline definitions`, stageName);
8313
+ throw new StageError(
8314
+ `Stage '${stageName}' not found in pipeline definitions`,
8315
+ stageName
8316
+ );
8265
8317
  }
8266
8318
  if (def.shouldSkip) {
8267
8319
  const skipResult = def.shouldSkip(ctx);
@@ -8360,7 +8412,10 @@ async function executeParallelStep(ctx, pipeline, state, stageNames) {
8360
8412
  pausedStage = stageName;
8361
8413
  continue;
8362
8414
  }
8363
- logger.error({ err: postError }, ` Post-action failed for parallel stage ${stageName}:`);
8415
+ logger.error(
8416
+ { err: postError },
8417
+ ` Post-action failed for parallel stage ${stageName}:`
8418
+ );
8364
8419
  const postErrorMsg = postError instanceof Error ? postError.message : String(postError);
8365
8420
  state = updateStage(state, stageName, {
8366
8421
  state: "failed",
@@ -8386,7 +8441,10 @@ async function executeParallelStep(ctx, pipeline, state, stageNames) {
8386
8441
  error: stageResult.reason || "timed out"
8387
8442
  });
8388
8443
  if (!isAdvisory) {
8389
- criticalFailures.push({ name: stageName, reason: stageResult.reason || "timed out" });
8444
+ criticalFailures.push({
8445
+ name: stageName,
8446
+ reason: stageResult.reason || "timed out"
8447
+ });
8390
8448
  }
8391
8449
  } else if (stageResult.outcome === "failed") {
8392
8450
  const isAdvisory = pipeline.stages.get(stageName)?.advisory === true;
@@ -8395,20 +8453,28 @@ async function executeParallelStep(ctx, pipeline, state, stageNames) {
8395
8453
  state: "failed",
8396
8454
  error: stageResult.reason || "failed"
8397
8455
  });
8398
- advisoryFailures.push({ name: stageName, reason: stageResult.reason || "failed" });
8456
+ advisoryFailures.push({
8457
+ name: stageName,
8458
+ reason: stageResult.reason || "failed"
8459
+ });
8399
8460
  } else {
8400
8461
  state = updateStage(state, stageName, {
8401
8462
  state: "failed",
8402
8463
  error: stageResult.reason || "failed"
8403
8464
  });
8404
- criticalFailures.push({ name: stageName, reason: stageResult.reason || "failed" });
8465
+ criticalFailures.push({
8466
+ name: stageName,
8467
+ reason: stageResult.reason || "failed"
8468
+ });
8405
8469
  }
8406
8470
  }
8407
8471
  }
8408
8472
  if (criticalFailures.length > 0) {
8409
8473
  const errors = criticalFailures.map((f) => f.reason).join("; ");
8410
8474
  const names = criticalFailures.map((f) => f.name);
8411
- logger.error(` \u274C Parallel stages [${names.join(", ")}] failed: ${errors}`);
8475
+ logger.error(
8476
+ ` \u274C Parallel stages [${names.join(", ")}] failed: ${errors}`
8477
+ );
8412
8478
  if (ctx.input.issueNumber) {
8413
8479
  setLifecycleLabel(ctx.input.issueNumber, "kody:failed");
8414
8480
  }
@@ -8434,7 +8500,12 @@ async function handleStageResult(ctx, pipeline, state, stageName, result, def) {
8434
8500
  cost: result.cost,
8435
8501
  sessionId: result.sessionId
8436
8502
  });
8437
- logStageComplete(stageName, ctx.taskId, "completed", elapsed ? elapsed * 1e3 : void 0);
8503
+ logStageComplete(
8504
+ stageName,
8505
+ ctx.taskId,
8506
+ "completed",
8507
+ elapsed ? elapsed * 1e3 : void 0
8508
+ );
8438
8509
  if (result.sessionId) {
8439
8510
  ctx.lastSessionId = result.sessionId;
8440
8511
  }