@kody-ade/kody-engine 0.1.3 → 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 +106 -23
- package/dist/bin/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bin/cli.mjs
CHANGED
|
@@ -214,14 +214,14 @@ var init_registry = __esm({
|
|
|
214
214
|
},
|
|
215
215
|
test: {
|
|
216
216
|
outputFile: "test.md",
|
|
217
|
-
timeout: ms("
|
|
217
|
+
timeout: ms("40m"),
|
|
218
218
|
complexityThreshold: 0,
|
|
219
219
|
contextFiles: ["spec.md", "clarified.md", "plan.md", "task.json"],
|
|
220
220
|
type: "agent"
|
|
221
221
|
},
|
|
222
222
|
build: {
|
|
223
223
|
outputFile: "build.md",
|
|
224
|
-
timeout: ms("
|
|
224
|
+
timeout: ms("60m"),
|
|
225
225
|
complexityThreshold: 0,
|
|
226
226
|
contextFiles: [
|
|
227
227
|
"spec.md",
|
|
@@ -248,7 +248,14 @@ var init_registry = __esm({
|
|
|
248
248
|
outputFile: "review.md",
|
|
249
249
|
timeout: ms("15m"),
|
|
250
250
|
complexityThreshold: 30,
|
|
251
|
-
contextFiles: [
|
|
251
|
+
contextFiles: [
|
|
252
|
+
"review.md",
|
|
253
|
+
"build.md",
|
|
254
|
+
"plan.md",
|
|
255
|
+
"context.md",
|
|
256
|
+
"spec.md",
|
|
257
|
+
"clarified.md"
|
|
258
|
+
],
|
|
252
259
|
type: "agent"
|
|
253
260
|
},
|
|
254
261
|
fix: {
|
|
@@ -317,7 +324,12 @@ var init_registry = __esm({
|
|
|
317
324
|
"pr"
|
|
318
325
|
];
|
|
319
326
|
SPEC_ORDER_TURBO = ["taskify"];
|
|
320
|
-
IMPL_ORDER_TURBO = [
|
|
327
|
+
IMPL_ORDER_TURBO = [
|
|
328
|
+
"build",
|
|
329
|
+
"commit",
|
|
330
|
+
"verify",
|
|
331
|
+
"pr"
|
|
332
|
+
];
|
|
321
333
|
FIX_FULL_ORDER = [
|
|
322
334
|
"taskify",
|
|
323
335
|
"architect",
|
|
@@ -7953,10 +7965,16 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
|
|
|
7953
7965
|
}
|
|
7954
7966
|
if (!ctx.input.dryRun && !ctx.input.local) {
|
|
7955
7967
|
try {
|
|
7956
|
-
const currentBranch = execFileSync13(
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
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
|
+
);
|
|
7960
7978
|
if (isFeatureBranch) {
|
|
7961
7979
|
commitPipelineFiles({
|
|
7962
7980
|
taskDir: ctx.taskDir,
|
|
@@ -7969,7 +7987,10 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
|
|
|
7969
7987
|
logger.info(" \u2713 Pushed fresh running status.json to branch");
|
|
7970
7988
|
}
|
|
7971
7989
|
} catch (earlyPushErr) {
|
|
7972
|
-
logger.warn(
|
|
7990
|
+
logger.warn(
|
|
7991
|
+
{ err: earlyPushErr },
|
|
7992
|
+
"Early status push failed (non-fatal)"
|
|
7993
|
+
);
|
|
7973
7994
|
}
|
|
7974
7995
|
}
|
|
7975
7996
|
} else {
|
|
@@ -7990,7 +8011,9 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
|
|
|
7990
8011
|
}
|
|
7991
8012
|
}
|
|
7992
8013
|
if (state.state === "paused") {
|
|
7993
|
-
const anyPausedStage = Object.values(state.stages).some(
|
|
8014
|
+
const anyPausedStage = Object.values(state.stages).some(
|
|
8015
|
+
(s) => s.state === "paused"
|
|
8016
|
+
);
|
|
7994
8017
|
if (!anyPausedStage) {
|
|
7995
8018
|
state = {
|
|
7996
8019
|
...state,
|
|
@@ -8023,7 +8046,11 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
|
|
|
8023
8046
|
const recoveredState = recoverStaleStages(currentState);
|
|
8024
8047
|
if (recoveredState !== currentState) {
|
|
8025
8048
|
logger.info("\u26A0\uFE0F Periodic recovery: reset stale running stages");
|
|
8026
|
-
logRecovery(
|
|
8049
|
+
logRecovery(
|
|
8050
|
+
"stale-stage-recovery",
|
|
8051
|
+
ctx.taskId,
|
|
8052
|
+
"Reset stale running stages"
|
|
8053
|
+
);
|
|
8027
8054
|
state = recoveredState;
|
|
8028
8055
|
writeState(ctx.taskId, state);
|
|
8029
8056
|
}
|
|
@@ -8035,7 +8062,10 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
|
|
|
8035
8062
|
const newOrder = flattenPipelineOrder(pipeline.order);
|
|
8036
8063
|
for (const stageName of newOrder) {
|
|
8037
8064
|
if (!state.stages[stageName]) {
|
|
8038
|
-
state = updateStage(state, stageName, {
|
|
8065
|
+
state = updateStage(state, stageName, {
|
|
8066
|
+
state: "pending",
|
|
8067
|
+
retries: 0
|
|
8068
|
+
});
|
|
8039
8069
|
}
|
|
8040
8070
|
}
|
|
8041
8071
|
writeState(ctx.taskId, state);
|
|
@@ -8076,7 +8106,9 @@ async function runPipeline(ctx, pipeline, hooks, rebuildPipeline) {
|
|
|
8076
8106
|
const stageState = failedStage?.[1];
|
|
8077
8107
|
const stageOutcome = stageState?.state || "unknown";
|
|
8078
8108
|
const stageError = stageState?.error ? `: ${stageState.error}` : "";
|
|
8079
|
-
throw new Error(
|
|
8109
|
+
throw new Error(
|
|
8110
|
+
`Pipeline failed at stage: ${stageName} (${stageOutcome})${stageError}`
|
|
8111
|
+
);
|
|
8080
8112
|
}
|
|
8081
8113
|
return state;
|
|
8082
8114
|
}
|
|
@@ -8122,7 +8154,10 @@ async function executeSingleStep(ctx, pipeline, state, stageName) {
|
|
|
8122
8154
|
logger.info(` ${stageName} already completed, skipping`);
|
|
8123
8155
|
return state;
|
|
8124
8156
|
}
|
|
8125
|
-
state = updateStage(state, stageName, {
|
|
8157
|
+
state = updateStage(state, stageName, {
|
|
8158
|
+
state: "running",
|
|
8159
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8160
|
+
});
|
|
8126
8161
|
writeState(ctx.taskId, state);
|
|
8127
8162
|
logStageStart(stageName, ctx.taskId);
|
|
8128
8163
|
if (ctx.input.dryRun) {
|
|
@@ -8144,7 +8179,30 @@ async function executeSingleStep(ctx, pipeline, state, stageName) {
|
|
|
8144
8179
|
const handler = getHandler(def.name, def.type);
|
|
8145
8180
|
const result = await handler.execute(ctx, def);
|
|
8146
8181
|
ciGroupEnd();
|
|
8147
|
-
|
|
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
|
+
);
|
|
8148
8206
|
} catch (error) {
|
|
8149
8207
|
ciGroupEnd();
|
|
8150
8208
|
if (error instanceof PipelinePausedError) {
|
|
@@ -8202,7 +8260,10 @@ async function executeSingleStep(ctx, pipeline, state, stageName) {
|
|
|
8202
8260
|
return completeState(state, "failed");
|
|
8203
8261
|
}
|
|
8204
8262
|
} catch (observerError) {
|
|
8205
|
-
logger.error(
|
|
8263
|
+
logger.error(
|
|
8264
|
+
{ err: observerError },
|
|
8265
|
+
`[StateMachine] Observer error, falling back`
|
|
8266
|
+
);
|
|
8206
8267
|
state = updateStage(state, stageName, {
|
|
8207
8268
|
state: "failed",
|
|
8208
8269
|
error: errorMessage
|
|
@@ -8249,7 +8310,10 @@ async function executeParallelStep(ctx, pipeline, state, stageNames) {
|
|
|
8249
8310
|
stagesToRun.map(async (stageName) => {
|
|
8250
8311
|
const def = pipeline.stages.get(stageName);
|
|
8251
8312
|
if (!def) {
|
|
8252
|
-
throw new StageError(
|
|
8313
|
+
throw new StageError(
|
|
8314
|
+
`Stage '${stageName}' not found in pipeline definitions`,
|
|
8315
|
+
stageName
|
|
8316
|
+
);
|
|
8253
8317
|
}
|
|
8254
8318
|
if (def.shouldSkip) {
|
|
8255
8319
|
const skipResult = def.shouldSkip(ctx);
|
|
@@ -8348,7 +8412,10 @@ async function executeParallelStep(ctx, pipeline, state, stageNames) {
|
|
|
8348
8412
|
pausedStage = stageName;
|
|
8349
8413
|
continue;
|
|
8350
8414
|
}
|
|
8351
|
-
logger.error(
|
|
8415
|
+
logger.error(
|
|
8416
|
+
{ err: postError },
|
|
8417
|
+
` Post-action failed for parallel stage ${stageName}:`
|
|
8418
|
+
);
|
|
8352
8419
|
const postErrorMsg = postError instanceof Error ? postError.message : String(postError);
|
|
8353
8420
|
state = updateStage(state, stageName, {
|
|
8354
8421
|
state: "failed",
|
|
@@ -8374,7 +8441,10 @@ async function executeParallelStep(ctx, pipeline, state, stageNames) {
|
|
|
8374
8441
|
error: stageResult.reason || "timed out"
|
|
8375
8442
|
});
|
|
8376
8443
|
if (!isAdvisory) {
|
|
8377
|
-
criticalFailures.push({
|
|
8444
|
+
criticalFailures.push({
|
|
8445
|
+
name: stageName,
|
|
8446
|
+
reason: stageResult.reason || "timed out"
|
|
8447
|
+
});
|
|
8378
8448
|
}
|
|
8379
8449
|
} else if (stageResult.outcome === "failed") {
|
|
8380
8450
|
const isAdvisory = pipeline.stages.get(stageName)?.advisory === true;
|
|
@@ -8383,20 +8453,28 @@ async function executeParallelStep(ctx, pipeline, state, stageNames) {
|
|
|
8383
8453
|
state: "failed",
|
|
8384
8454
|
error: stageResult.reason || "failed"
|
|
8385
8455
|
});
|
|
8386
|
-
advisoryFailures.push({
|
|
8456
|
+
advisoryFailures.push({
|
|
8457
|
+
name: stageName,
|
|
8458
|
+
reason: stageResult.reason || "failed"
|
|
8459
|
+
});
|
|
8387
8460
|
} else {
|
|
8388
8461
|
state = updateStage(state, stageName, {
|
|
8389
8462
|
state: "failed",
|
|
8390
8463
|
error: stageResult.reason || "failed"
|
|
8391
8464
|
});
|
|
8392
|
-
criticalFailures.push({
|
|
8465
|
+
criticalFailures.push({
|
|
8466
|
+
name: stageName,
|
|
8467
|
+
reason: stageResult.reason || "failed"
|
|
8468
|
+
});
|
|
8393
8469
|
}
|
|
8394
8470
|
}
|
|
8395
8471
|
}
|
|
8396
8472
|
if (criticalFailures.length > 0) {
|
|
8397
8473
|
const errors = criticalFailures.map((f) => f.reason).join("; ");
|
|
8398
8474
|
const names = criticalFailures.map((f) => f.name);
|
|
8399
|
-
logger.error(
|
|
8475
|
+
logger.error(
|
|
8476
|
+
` \u274C Parallel stages [${names.join(", ")}] failed: ${errors}`
|
|
8477
|
+
);
|
|
8400
8478
|
if (ctx.input.issueNumber) {
|
|
8401
8479
|
setLifecycleLabel(ctx.input.issueNumber, "kody:failed");
|
|
8402
8480
|
}
|
|
@@ -8422,7 +8500,12 @@ async function handleStageResult(ctx, pipeline, state, stageName, result, def) {
|
|
|
8422
8500
|
cost: result.cost,
|
|
8423
8501
|
sessionId: result.sessionId
|
|
8424
8502
|
});
|
|
8425
|
-
logStageComplete(
|
|
8503
|
+
logStageComplete(
|
|
8504
|
+
stageName,
|
|
8505
|
+
ctx.taskId,
|
|
8506
|
+
"completed",
|
|
8507
|
+
elapsed ? elapsed * 1e3 : void 0
|
|
8508
|
+
);
|
|
8426
8509
|
if (result.sessionId) {
|
|
8427
8510
|
ctx.lastSessionId = result.sessionId;
|
|
8428
8511
|
}
|