@nathapp/nax 0.57.0 → 0.57.1-canary.1
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/nax.js +101 -33
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -18048,31 +18048,36 @@ var init_defaults = __esm(() => {
|
|
|
18048
18048
|
enabled: true,
|
|
18049
18049
|
resolver: { type: "synthesis" },
|
|
18050
18050
|
sessionMode: "stateful",
|
|
18051
|
-
rounds: 3
|
|
18051
|
+
rounds: 3,
|
|
18052
|
+
timeoutSeconds: 600
|
|
18052
18053
|
},
|
|
18053
18054
|
review: {
|
|
18054
18055
|
enabled: true,
|
|
18055
18056
|
resolver: { type: "majority-fail-closed" },
|
|
18056
18057
|
sessionMode: "one-shot",
|
|
18057
|
-
rounds: 2
|
|
18058
|
+
rounds: 2,
|
|
18059
|
+
timeoutSeconds: 600
|
|
18058
18060
|
},
|
|
18059
18061
|
acceptance: {
|
|
18060
18062
|
enabled: false,
|
|
18061
18063
|
resolver: { type: "majority-fail-closed" },
|
|
18062
18064
|
sessionMode: "one-shot",
|
|
18063
|
-
rounds: 1
|
|
18065
|
+
rounds: 1,
|
|
18066
|
+
timeoutSeconds: 600
|
|
18064
18067
|
},
|
|
18065
18068
|
rectification: {
|
|
18066
18069
|
enabled: false,
|
|
18067
18070
|
resolver: { type: "synthesis" },
|
|
18068
18071
|
sessionMode: "one-shot",
|
|
18069
|
-
rounds: 1
|
|
18072
|
+
rounds: 1,
|
|
18073
|
+
timeoutSeconds: 600
|
|
18070
18074
|
},
|
|
18071
18075
|
escalation: {
|
|
18072
18076
|
enabled: false,
|
|
18073
18077
|
resolver: { type: "majority-fail-closed" },
|
|
18074
18078
|
sessionMode: "one-shot",
|
|
18075
|
-
rounds: 1
|
|
18079
|
+
rounds: 1,
|
|
18080
|
+
timeoutSeconds: 600
|
|
18076
18081
|
}
|
|
18077
18082
|
}
|
|
18078
18083
|
}
|
|
@@ -18102,7 +18107,8 @@ var TokenPricingSchema, ModelDefSchema, ModelEntrySchema, PerAgentModelMapSchema
|
|
|
18102
18107
|
resolver: makeResolverSchema(defaults.resolverType),
|
|
18103
18108
|
sessionMode: exports_external.enum(["one-shot", "stateful"]).default(defaults.sessionMode),
|
|
18104
18109
|
rounds: exports_external.number().int().min(1).default(defaults.rounds),
|
|
18105
|
-
debaters: exports_external.array(DebaterSchema).min(2, "debaters must have at least 2 entries").optional()
|
|
18110
|
+
debaters: exports_external.array(DebaterSchema).min(2, "debaters must have at least 2 entries").optional(),
|
|
18111
|
+
timeoutSeconds: exports_external.number().int().positive().default(600)
|
|
18106
18112
|
})), DebateConfigSchema, NaxConfigSchema;
|
|
18107
18113
|
var init_schemas3 = __esm(() => {
|
|
18108
18114
|
init_zod();
|
|
@@ -18303,7 +18309,8 @@ var init_schemas3 = __esm(() => {
|
|
|
18303
18309
|
});
|
|
18304
18310
|
PlanConfigSchema = exports_external.object({
|
|
18305
18311
|
model: ModelTierSchema,
|
|
18306
|
-
outputPath: exports_external.string().min(1, "plan.outputPath must be non-empty")
|
|
18312
|
+
outputPath: exports_external.string().min(1, "plan.outputPath must be non-empty"),
|
|
18313
|
+
timeoutSeconds: exports_external.number().int().positive().default(600)
|
|
18307
18314
|
});
|
|
18308
18315
|
AcceptanceFixConfigSchema = exports_external.object({
|
|
18309
18316
|
diagnoseModel: exports_external.string().min(1, "acceptance.fix.diagnoseModel must be non-empty"),
|
|
@@ -19846,9 +19853,9 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
|
|
|
19846
19853
|
modelDef,
|
|
19847
19854
|
prompt: "",
|
|
19848
19855
|
modelTier: options.modelTier || "balanced",
|
|
19849
|
-
timeoutSeconds: 600
|
|
19856
|
+
timeoutSeconds: options.timeoutSeconds ?? 600
|
|
19850
19857
|
};
|
|
19851
|
-
const
|
|
19858
|
+
const planTimeoutMs = (options.timeoutSeconds ?? 600) * 1000;
|
|
19852
19859
|
if (options.interactive) {
|
|
19853
19860
|
const proc = Bun.spawn(cmd, {
|
|
19854
19861
|
cwd: options.workdir,
|
|
@@ -19860,7 +19867,7 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
|
|
|
19860
19867
|
await pidRegistry.register(proc.pid);
|
|
19861
19868
|
let exitCode;
|
|
19862
19869
|
try {
|
|
19863
|
-
const timeoutResult = await withProcessTimeout(proc,
|
|
19870
|
+
const timeoutResult = await withProcessTimeout(proc, planTimeoutMs, {
|
|
19864
19871
|
graceMs: 5000
|
|
19865
19872
|
});
|
|
19866
19873
|
exitCode = timeoutResult.exitCode;
|
|
@@ -19886,7 +19893,7 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
|
|
|
19886
19893
|
await pidRegistry.register(proc.pid);
|
|
19887
19894
|
let exitCode;
|
|
19888
19895
|
try {
|
|
19889
|
-
const timeoutResult = await withProcessTimeout(proc,
|
|
19896
|
+
const timeoutResult = await withProcessTimeout(proc, planTimeoutMs, {
|
|
19890
19897
|
graceMs: 5000
|
|
19891
19898
|
});
|
|
19892
19899
|
exitCode = timeoutResult.exitCode;
|
|
@@ -22156,7 +22163,7 @@ var package_default;
|
|
|
22156
22163
|
var init_package = __esm(() => {
|
|
22157
22164
|
package_default = {
|
|
22158
22165
|
name: "@nathapp/nax",
|
|
22159
|
-
version: "0.57.
|
|
22166
|
+
version: "0.57.1-canary.1",
|
|
22160
22167
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
22161
22168
|
type: "module",
|
|
22162
22169
|
bin: {
|
|
@@ -22235,8 +22242,8 @@ var init_version = __esm(() => {
|
|
|
22235
22242
|
NAX_VERSION = package_default.version;
|
|
22236
22243
|
NAX_COMMIT = (() => {
|
|
22237
22244
|
try {
|
|
22238
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
22239
|
-
return "
|
|
22245
|
+
if (/^[0-9a-f]{6,10}$/.test("814ed29f"))
|
|
22246
|
+
return "814ed29f";
|
|
22240
22247
|
} catch {}
|
|
22241
22248
|
try {
|
|
22242
22249
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -22523,10 +22530,11 @@ function modelTierFromDebater(debater) {
|
|
|
22523
22530
|
function isTierLabel(value) {
|
|
22524
22531
|
return value === "fast" || value === "balanced" || value === "powerful";
|
|
22525
22532
|
}
|
|
22526
|
-
async function runComplete(adapter, prompt, options, modelTier) {
|
|
22533
|
+
async function runComplete(adapter, prompt, options, modelTier, timeoutMs) {
|
|
22527
22534
|
return adapter.complete(prompt, {
|
|
22528
22535
|
...options,
|
|
22529
|
-
modelTier
|
|
22536
|
+
modelTier,
|
|
22537
|
+
...timeoutMs !== undefined && { timeoutMs }
|
|
22530
22538
|
});
|
|
22531
22539
|
}
|
|
22532
22540
|
|
|
@@ -22538,6 +22546,9 @@ class DebateSession {
|
|
|
22538
22546
|
workdir;
|
|
22539
22547
|
featureName;
|
|
22540
22548
|
timeoutSeconds;
|
|
22549
|
+
get timeoutMs() {
|
|
22550
|
+
return this.timeoutSeconds * 1000;
|
|
22551
|
+
}
|
|
22541
22552
|
constructor(opts) {
|
|
22542
22553
|
this.storyId = opts.storyId;
|
|
22543
22554
|
this.stage = opts.stage;
|
|
@@ -22545,7 +22556,7 @@ class DebateSession {
|
|
|
22545
22556
|
this.config = opts.config;
|
|
22546
22557
|
this.workdir = opts.workdir ?? process.cwd();
|
|
22547
22558
|
this.featureName = opts.featureName ?? opts.stage;
|
|
22548
|
-
this.timeoutSeconds = opts.timeoutSeconds ?? opts.
|
|
22559
|
+
this.timeoutSeconds = opts.timeoutSeconds ?? opts.stageConfig.timeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS;
|
|
22549
22560
|
}
|
|
22550
22561
|
pipelineStageForDebate() {
|
|
22551
22562
|
switch (this.stage) {
|
|
@@ -22785,7 +22796,8 @@ class DebateSession {
|
|
|
22785
22796
|
featureName: this.stage,
|
|
22786
22797
|
config: this.config,
|
|
22787
22798
|
storyId: this.storyId,
|
|
22788
|
-
sessionRole: "debate-proposal"
|
|
22799
|
+
sessionRole: "debate-proposal",
|
|
22800
|
+
timeoutMs: this.timeoutMs
|
|
22789
22801
|
}, modelTierFromDebater(debater)).then((result) => ({ debater, adapter, output: result.output, cost: result.costUsd }))));
|
|
22790
22802
|
const successful = proposalSettled.filter((r) => r.status === "fulfilled").map((r) => r.value);
|
|
22791
22803
|
for (const r of proposalSettled) {
|
|
@@ -22839,7 +22851,8 @@ class DebateSession {
|
|
|
22839
22851
|
featureName: this.stage,
|
|
22840
22852
|
config: this.config,
|
|
22841
22853
|
storyId: this.storyId,
|
|
22842
|
-
sessionRole: "debate-fallback"
|
|
22854
|
+
sessionRole: "debate-fallback",
|
|
22855
|
+
timeoutMs: this.timeoutMs
|
|
22843
22856
|
}, modelTierFromDebater(fallbackDebater));
|
|
22844
22857
|
totalCostUsd += fallbackResult.costUsd;
|
|
22845
22858
|
logger?.info("debate", "debate:result", {
|
|
@@ -22869,7 +22882,8 @@ class DebateSession {
|
|
|
22869
22882
|
featureName: this.stage,
|
|
22870
22883
|
config: this.config,
|
|
22871
22884
|
storyId: this.storyId,
|
|
22872
|
-
sessionRole: "debate-critique"
|
|
22885
|
+
sessionRole: "debate-critique",
|
|
22886
|
+
timeoutMs: this.timeoutMs
|
|
22873
22887
|
}, modelTierFromDebater(debater))));
|
|
22874
22888
|
for (const r of critiqueSettled) {
|
|
22875
22889
|
if (r.status === "fulfilled") {
|
|
@@ -23012,7 +23026,8 @@ Do NOT output the JSON to the conversation. Write the file, then reply with a br
|
|
|
23012
23026
|
model: resolveDebaterModel({ agent: agentName }, this.config),
|
|
23013
23027
|
config: this.config,
|
|
23014
23028
|
storyId: this.storyId,
|
|
23015
|
-
sessionRole: "synthesis"
|
|
23029
|
+
sessionRole: "synthesis",
|
|
23030
|
+
timeoutMs: this.timeoutMs
|
|
23016
23031
|
}
|
|
23017
23032
|
});
|
|
23018
23033
|
return {
|
|
@@ -23034,7 +23049,8 @@ Do NOT output the JSON to the conversation. Write the file, then reply with a br
|
|
|
23034
23049
|
model: resolveDebaterModel({ agent: agentName }, this.config),
|
|
23035
23050
|
config: this.config,
|
|
23036
23051
|
storyId: this.storyId,
|
|
23037
|
-
sessionRole: "judge"
|
|
23052
|
+
sessionRole: "judge",
|
|
23053
|
+
timeoutMs: this.timeoutMs
|
|
23038
23054
|
}
|
|
23039
23055
|
});
|
|
23040
23056
|
return {
|
|
@@ -23048,7 +23064,7 @@ Do NOT output the JSON to the conversation. Write the file, then reply with a br
|
|
|
23048
23064
|
};
|
|
23049
23065
|
}
|
|
23050
23066
|
}
|
|
23051
|
-
var RESOLVER_FALLBACK_AGENT = "synthesis", _debateSessionDeps;
|
|
23067
|
+
var RESOLVER_FALLBACK_AGENT = "synthesis", _debateSessionDeps, DEFAULT_TIMEOUT_SECONDS = 600;
|
|
23052
23068
|
var init_session = __esm(() => {
|
|
23053
23069
|
init_registry();
|
|
23054
23070
|
init_config();
|
|
@@ -23252,13 +23268,15 @@ class AutoInteractionPlugin {
|
|
|
23252
23268
|
const modelDef = resolveModelForAgent(naxConfig.models, naxConfig.autoMode.defaultAgent, modelTier, naxConfig.autoMode.defaultAgent);
|
|
23253
23269
|
modelArg = modelDef.model;
|
|
23254
23270
|
}
|
|
23271
|
+
const timeoutMs = this.config.naxConfig ? (this.config.naxConfig.execution?.sessionTimeoutSeconds ?? 600) * 1000 : undefined;
|
|
23255
23272
|
const result = await adapter.complete(prompt, {
|
|
23256
23273
|
...modelArg && { model: modelArg },
|
|
23257
23274
|
jsonMode: true,
|
|
23258
23275
|
...this.config.naxConfig && { config: this.config.naxConfig },
|
|
23259
23276
|
featureName: request.featureName,
|
|
23260
23277
|
storyId: request.storyId,
|
|
23261
|
-
sessionRole: "auto"
|
|
23278
|
+
sessionRole: "auto",
|
|
23279
|
+
...timeoutMs !== undefined && { timeoutMs }
|
|
23262
23280
|
});
|
|
23263
23281
|
const output = typeof result === "string" ? result : result.output;
|
|
23264
23282
|
return this.parseResponse(output);
|
|
@@ -31556,8 +31574,15 @@ async function _defaultRunDebate(storyId, stageConfig, prompt, config2) {
|
|
|
31556
31574
|
if (resolved.length === 0) {
|
|
31557
31575
|
return { output: null, totalCostUsd: 0 };
|
|
31558
31576
|
}
|
|
31577
|
+
const timeoutMs = (config2?.execution?.sessionTimeoutSeconds ?? 600) * 1000;
|
|
31559
31578
|
const startMs = Date.now();
|
|
31560
|
-
const proposalSettled = await Promise.allSettled(resolved.map(({ debater, adapter }) => adapter.complete(prompt, {
|
|
31579
|
+
const proposalSettled = await Promise.allSettled(resolved.map(({ debater, adapter }) => adapter.complete(prompt, {
|
|
31580
|
+
model: debater.model,
|
|
31581
|
+
config: config2,
|
|
31582
|
+
storyId,
|
|
31583
|
+
sessionRole: "debate-proposal",
|
|
31584
|
+
timeoutMs
|
|
31585
|
+
}).then((out) => typeof out === "string" ? out : out.output)));
|
|
31561
31586
|
const durationMs = Date.now() - startMs;
|
|
31562
31587
|
const successful = proposalSettled.filter((r) => r.status === "fulfilled").map((r) => r.value);
|
|
31563
31588
|
if (successful.length === 0) {
|
|
@@ -34882,6 +34907,16 @@ async function runDeferredRegression(options) {
|
|
|
34882
34907
|
};
|
|
34883
34908
|
}
|
|
34884
34909
|
const testSummary = _regressionDeps.parseBunTestOutput(fullSuiteResult.output);
|
|
34910
|
+
if (testSummary.failed === 0 && testSummary.passed === 0) {
|
|
34911
|
+
logger?.warn("regression", "No test results parsed from output \u2014 test runner likely crashed or errored (not a regression, accepting as pass)", { output: fullSuiteResult.output.slice(0, 500) });
|
|
34912
|
+
return {
|
|
34913
|
+
success: true,
|
|
34914
|
+
failedTests: 0,
|
|
34915
|
+
passedTests: 0,
|
|
34916
|
+
rectificationAttempts: 0,
|
|
34917
|
+
affectedStories: []
|
|
34918
|
+
};
|
|
34919
|
+
}
|
|
34885
34920
|
const affectedStories = new Set;
|
|
34886
34921
|
const affectedStoriesObjs = new Map;
|
|
34887
34922
|
logger?.warn("regression", "Regression detected", {
|
|
@@ -37063,13 +37098,25 @@ async function executeUnified(ctx, initialPrd) {
|
|
|
37063
37098
|
prd = await loadPRD(ctx.prdPath);
|
|
37064
37099
|
prdDirty = false;
|
|
37065
37100
|
}
|
|
37101
|
+
const storyCounts = countStories(prd);
|
|
37102
|
+
logger?.debug("execution", "Loop iteration", {
|
|
37103
|
+
iteration: iterations,
|
|
37104
|
+
isComplete: isComplete(prd),
|
|
37105
|
+
passed: storyCounts.passed,
|
|
37106
|
+
pending: storyCounts.pending,
|
|
37107
|
+
failed: storyCounts.failed,
|
|
37108
|
+
total: storyCounts.total
|
|
37109
|
+
});
|
|
37066
37110
|
if (isComplete(prd)) {
|
|
37111
|
+
logger?.debug("execution", "All stories complete \u2014 entering completion path");
|
|
37067
37112
|
if (ctx.interactionChain && isTriggerEnabled("pre-merge", ctx.config)) {
|
|
37068
37113
|
const shouldProceed = await checkPreMerge({ featureName: ctx.feature, totalStories: prd.userStories.length, cost: totalCost }, ctx.config, ctx.interactionChain);
|
|
37069
37114
|
if (!shouldProceed)
|
|
37070
37115
|
return buildResult2("pre-merge-aborted");
|
|
37071
37116
|
}
|
|
37117
|
+
logger?.debug("execution", "Running deferred review");
|
|
37072
37118
|
deferredReview = await runDeferredReview(ctx.workdir, ctx.config.review, ctx.pluginRegistry, runStartRef);
|
|
37119
|
+
logger?.debug("execution", "Deferred review done \u2014 returning completed");
|
|
37073
37120
|
return buildResult2("completed");
|
|
37074
37121
|
}
|
|
37075
37122
|
const costLimit = ctx.config.execution.costLimit;
|
|
@@ -37322,9 +37369,7 @@ async function executeUnified(ctx, initialPrd) {
|
|
|
37322
37369
|
}, ctx.eventEmitter);
|
|
37323
37370
|
}
|
|
37324
37371
|
return buildResult2("max-iterations");
|
|
37325
|
-
} finally {
|
|
37326
|
-
stopHeartbeat();
|
|
37327
|
-
}
|
|
37372
|
+
} finally {}
|
|
37328
37373
|
}
|
|
37329
37374
|
var _unifiedExecutorDeps;
|
|
37330
37375
|
var init_unified_executor = __esm(() => {
|
|
@@ -70249,6 +70294,7 @@ function validatePlanOutput(raw, feature, branch) {
|
|
|
70249
70294
|
}
|
|
70250
70295
|
|
|
70251
70296
|
// src/cli/plan.ts
|
|
70297
|
+
var DEFAULT_TIMEOUT_SECONDS2 = 600;
|
|
70252
70298
|
var _planDeps = {
|
|
70253
70299
|
readFile: (path) => Bun.file(path).text(),
|
|
70254
70300
|
writeFile: (path, content) => Bun.write(path, content).then(() => {}),
|
|
@@ -70299,7 +70345,7 @@ async function planCommand(workdir, config2, options) {
|
|
|
70299
70345
|
const outputPath = join12(outputDir, "prd.json");
|
|
70300
70346
|
await _planDeps.mkdirp(outputDir);
|
|
70301
70347
|
const agentName = config2?.autoMode?.defaultAgent ?? "claude";
|
|
70302
|
-
const timeoutSeconds = config2?.
|
|
70348
|
+
const timeoutSeconds = config2?.plan?.timeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS2;
|
|
70303
70349
|
let rawResponse;
|
|
70304
70350
|
const debateEnabled = config2?.debate?.enabled && config2?.debate?.stages?.plan?.enabled;
|
|
70305
70351
|
if (debateEnabled) {
|
|
@@ -70383,6 +70429,7 @@ async function planCommand(workdir, config2, options) {
|
|
|
70383
70429
|
}
|
|
70384
70430
|
rawResponse = await _planDeps.readFile(outputPath);
|
|
70385
70431
|
} else {
|
|
70432
|
+
const timeoutMs = (config2?.plan?.timeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS2) * 1000;
|
|
70386
70433
|
const completeResult = await adapter.complete(prompt, {
|
|
70387
70434
|
model: autoModel,
|
|
70388
70435
|
jsonMode: true,
|
|
@@ -70390,7 +70437,7 @@ async function planCommand(workdir, config2, options) {
|
|
|
70390
70437
|
config: config2,
|
|
70391
70438
|
featureName: options.feature,
|
|
70392
70439
|
sessionRole: "plan",
|
|
70393
|
-
timeoutMs
|
|
70440
|
+
timeoutMs
|
|
70394
70441
|
});
|
|
70395
70442
|
let result = typeof completeResult === "string" ? completeResult : completeResult.output;
|
|
70396
70443
|
try {
|
|
@@ -70763,6 +70810,8 @@ async function planDecomposeCommand(workdir, config2, options) {
|
|
|
70763
70810
|
const stages = config2?.debate?.stages;
|
|
70764
70811
|
const debateEnabled = config2?.debate?.enabled && stages?.decompose?.enabled;
|
|
70765
70812
|
let rawResponse;
|
|
70813
|
+
const timeoutSeconds = config2?.plan?.timeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS2;
|
|
70814
|
+
const timeoutMs = timeoutSeconds * 1000;
|
|
70766
70815
|
if (debateEnabled) {
|
|
70767
70816
|
const stageConfig = stages?.decompose;
|
|
70768
70817
|
const debateSession = _planDeps.createDebateSession({
|
|
@@ -70772,7 +70821,7 @@ async function planDecomposeCommand(workdir, config2, options) {
|
|
|
70772
70821
|
config: config2,
|
|
70773
70822
|
workdir,
|
|
70774
70823
|
featureName: options.feature,
|
|
70775
|
-
timeoutSeconds
|
|
70824
|
+
timeoutSeconds
|
|
70776
70825
|
});
|
|
70777
70826
|
const debateResult = await debateSession.run(prompt);
|
|
70778
70827
|
if (debateResult.outcome !== "failed" && debateResult.output) {
|
|
@@ -70784,7 +70833,7 @@ async function planDecomposeCommand(workdir, config2, options) {
|
|
|
70784
70833
|
sessionRole: "decompose",
|
|
70785
70834
|
featureName: options.feature,
|
|
70786
70835
|
storyId: options.storyId,
|
|
70787
|
-
timeoutMs
|
|
70836
|
+
timeoutMs
|
|
70788
70837
|
});
|
|
70789
70838
|
rawResponse = typeof completeResult === "string" ? completeResult : completeResult.output;
|
|
70790
70839
|
}
|
|
@@ -70795,7 +70844,7 @@ async function planDecomposeCommand(workdir, config2, options) {
|
|
|
70795
70844
|
sessionRole: "decompose",
|
|
70796
70845
|
featureName: options.feature,
|
|
70797
70846
|
storyId: options.storyId,
|
|
70798
|
-
timeoutMs
|
|
70847
|
+
timeoutMs
|
|
70799
70848
|
});
|
|
70800
70849
|
rawResponse = typeof completeResult === "string" ? completeResult : completeResult.output;
|
|
70801
70850
|
}
|
|
@@ -73438,6 +73487,10 @@ init_crash_recovery();
|
|
|
73438
73487
|
init_story_context();
|
|
73439
73488
|
async function runCompletionPhase(options) {
|
|
73440
73489
|
const logger = getSafeLogger();
|
|
73490
|
+
logger?.debug("execution", "Completion phase started", {
|
|
73491
|
+
acceptanceEnabled: options.config.acceptance?.enabled,
|
|
73492
|
+
isComplete: isComplete(options.prd)
|
|
73493
|
+
});
|
|
73441
73494
|
if (options.config.acceptance.enabled && isComplete(options.prd)) {
|
|
73442
73495
|
const { runAcceptanceLoop: runAcceptanceLoop2 } = await Promise.resolve().then(() => (init_acceptance_loop(), exports_acceptance_loop));
|
|
73443
73496
|
const acceptanceResult = await runAcceptanceLoop2({
|
|
@@ -73505,9 +73558,12 @@ async function runCompletionPhase(options) {
|
|
|
73505
73558
|
formatterMode: options.formatterMode
|
|
73506
73559
|
});
|
|
73507
73560
|
}
|
|
73561
|
+
logger?.debug("execution", "Completion phase \u2014 stopping heartbeat and writing exit summary");
|
|
73508
73562
|
stopHeartbeat();
|
|
73509
73563
|
await writeExitSummary(options.logFilePath, options.totalCost, options.iterations, options.storiesCompleted, durationMs);
|
|
73564
|
+
logger?.debug("execution", "Completion phase \u2014 auto-committing dirty files");
|
|
73510
73565
|
await autoCommitIfDirty(options.workdir, "run.complete", "run-summary", options.feature);
|
|
73566
|
+
logger?.debug("execution", "Completion phase done \u2014 returning to runner");
|
|
73511
73567
|
return {
|
|
73512
73568
|
durationMs,
|
|
73513
73569
|
runCompletedAt
|
|
@@ -73645,6 +73701,12 @@ async function runExecutionPhase(options, prd, pluginRegistry) {
|
|
|
73645
73701
|
storiesCompleted = unifiedResult.storiesCompleted;
|
|
73646
73702
|
totalCost = unifiedResult.totalCost;
|
|
73647
73703
|
allStoryMetrics.push(...unifiedResult.allStoryMetrics);
|
|
73704
|
+
logger?.debug("execution", "Execution phase complete \u2014 handing off to completion phase", {
|
|
73705
|
+
exitReason: unifiedResult.exitReason,
|
|
73706
|
+
iterations,
|
|
73707
|
+
storiesCompleted,
|
|
73708
|
+
totalCost
|
|
73709
|
+
});
|
|
73648
73710
|
return { prd, iterations, storiesCompleted, totalCost, allStoryMetrics };
|
|
73649
73711
|
}
|
|
73650
73712
|
|
|
@@ -73803,15 +73865,20 @@ async function run(options) {
|
|
|
73803
73865
|
durationMs
|
|
73804
73866
|
};
|
|
73805
73867
|
} finally {
|
|
73868
|
+
const logger2 = getSafeLogger();
|
|
73869
|
+
logger2?.debug("execution", "Runner finally block \u2014 starting cleanup");
|
|
73806
73870
|
stopHeartbeat();
|
|
73807
73871
|
cleanupCrashHandlers();
|
|
73872
|
+
logger2?.debug("execution", "Runner finally \u2014 sweeping ACP sessions");
|
|
73808
73873
|
await sweepFeatureSessions(workdir, feature).catch(() => {});
|
|
73874
|
+
logger2?.debug("execution", "Runner finally \u2014 ACP sweep done");
|
|
73809
73875
|
let branch = "";
|
|
73810
73876
|
try {
|
|
73811
73877
|
const { stdout, exitCode } = await gitWithTimeout(["branch", "--show-current"], workdir);
|
|
73812
73878
|
if (exitCode === 0)
|
|
73813
73879
|
branch = stdout.trim();
|
|
73814
73880
|
} catch {}
|
|
73881
|
+
logger2?.debug("execution", "Runner finally \u2014 running cleanupRun");
|
|
73815
73882
|
const { cleanupRun: cleanupRun2 } = await Promise.resolve().then(() => (init_run_cleanup(), exports_run_cleanup));
|
|
73816
73883
|
await cleanupRun2({
|
|
73817
73884
|
runId,
|
|
@@ -73827,6 +73894,7 @@ async function run(options) {
|
|
|
73827
73894
|
branch,
|
|
73828
73895
|
version: NAX_VERSION
|
|
73829
73896
|
});
|
|
73897
|
+
logger2?.debug("execution", "Runner finally \u2014 cleanupRun done, run() returning");
|
|
73830
73898
|
}
|
|
73831
73899
|
}
|
|
73832
73900
|
|