@nathapp/nax 0.61.2-canary.1 → 0.61.2
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 +57 -103
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -2634,17 +2634,6 @@ function formatDuration(durationMs) {
|
|
|
2634
2634
|
function formatCost(cost) {
|
|
2635
2635
|
return `$${cost.toFixed(4)}`;
|
|
2636
2636
|
}
|
|
2637
|
-
function getStageEmoji(stage) {
|
|
2638
|
-
if (stage.includes("routing"))
|
|
2639
|
-
return EMOJI.routing;
|
|
2640
|
-
if (stage.includes("execution") || stage.includes("agent"))
|
|
2641
|
-
return EMOJI.execution;
|
|
2642
|
-
if (stage.includes("review"))
|
|
2643
|
-
return EMOJI.review;
|
|
2644
|
-
if (stage.includes("tdd"))
|
|
2645
|
-
return EMOJI.tdd;
|
|
2646
|
-
return EMOJI.info;
|
|
2647
|
-
}
|
|
2648
2637
|
function shouldDisplay(entry, mode) {
|
|
2649
2638
|
if (mode === "json")
|
|
2650
2639
|
return true;
|
|
@@ -2685,7 +2674,7 @@ function formatLogEntry(entry, options) {
|
|
|
2685
2674
|
}
|
|
2686
2675
|
return formatDefault(entry, colorize, timestamp, mode);
|
|
2687
2676
|
}
|
|
2688
|
-
function formatRunStart(entry, c, timestamp,
|
|
2677
|
+
function formatRunStart(entry, c, timestamp, _mode) {
|
|
2689
2678
|
const data = entry.data;
|
|
2690
2679
|
const lines = [];
|
|
2691
2680
|
lines.push("");
|
|
@@ -2704,7 +2693,7 @@ function formatRunStart(entry, c, timestamp, mode) {
|
|
|
2704
2693
|
shouldDisplay: true
|
|
2705
2694
|
};
|
|
2706
2695
|
}
|
|
2707
|
-
function formatStoryStart(entry, c,
|
|
2696
|
+
function formatStoryStart(entry, c, _timestamp, mode) {
|
|
2708
2697
|
const data = entry.data;
|
|
2709
2698
|
const storyId = String(data.storyId || entry.storyId || "unknown");
|
|
2710
2699
|
const title = String(data.storyTitle || data.title || "Untitled story");
|
|
@@ -2734,7 +2723,7 @@ function formatStoryStart(entry, c, timestamp, mode) {
|
|
|
2734
2723
|
shouldDisplay: true
|
|
2735
2724
|
};
|
|
2736
2725
|
}
|
|
2737
|
-
function formatStoryComplete(entry, c,
|
|
2726
|
+
function formatStoryComplete(entry, c, _timestamp, mode) {
|
|
2738
2727
|
const data = entry.data;
|
|
2739
2728
|
const storyId = String(data.storyId || entry.storyId || "unknown");
|
|
2740
2729
|
const success = data.success ?? true;
|
|
@@ -2766,7 +2755,7 @@ function formatStoryComplete(entry, c, timestamp, mode) {
|
|
|
2766
2755
|
shouldDisplay: true
|
|
2767
2756
|
};
|
|
2768
2757
|
}
|
|
2769
|
-
function formatTDDSession(entry, c,
|
|
2758
|
+
function formatTDDSession(entry, c, _timestamp, mode) {
|
|
2770
2759
|
if (mode === "quiet") {
|
|
2771
2760
|
return { output: "", shouldDisplay: false };
|
|
2772
2761
|
}
|
|
@@ -2781,7 +2770,6 @@ function formatTDDSession(entry, c, timestamp, mode) {
|
|
|
2781
2770
|
function formatDefault(entry, c, timestamp, mode) {
|
|
2782
2771
|
const levelEmoji = entry.level === "error" ? EMOJI.failure : entry.level === "warn" ? EMOJI.warning : EMOJI.info;
|
|
2783
2772
|
const levelColor = entry.level === "error" ? c.red : entry.level === "warn" ? c.yellow : c.gray;
|
|
2784
|
-
const stageEmoji = getStageEmoji(entry.stage);
|
|
2785
2773
|
const parts = [c.gray(`[${timestamp}]`), levelColor(`${levelEmoji} ${entry.stage}`)];
|
|
2786
2774
|
if (entry.storyId) {
|
|
2787
2775
|
parts.push(c.dim(`[${entry.storyId}]`));
|
|
@@ -3626,7 +3614,14 @@ var init_env = __esm(() => {
|
|
|
3626
3614
|
|
|
3627
3615
|
// src/agents/acp/parser.ts
|
|
3628
3616
|
function createParseState() {
|
|
3629
|
-
return {
|
|
3617
|
+
return {
|
|
3618
|
+
text: "",
|
|
3619
|
+
tokenUsage: undefined,
|
|
3620
|
+
exactCostUsd: undefined,
|
|
3621
|
+
stopReason: undefined,
|
|
3622
|
+
error: undefined,
|
|
3623
|
+
retryable: false
|
|
3624
|
+
};
|
|
3630
3625
|
}
|
|
3631
3626
|
function parseAcpxJsonLine(line, state) {
|
|
3632
3627
|
try {
|
|
@@ -3665,6 +3660,8 @@ function parseAcpxJsonLine(line, state) {
|
|
|
3665
3660
|
const suffix = [data.acpxCode, data.detailCode].filter(Boolean).join("/");
|
|
3666
3661
|
if (suffix)
|
|
3667
3662
|
errorMsg = `${errorMsg} [${suffix}]`;
|
|
3663
|
+
if (!state.error && data.retryable === true)
|
|
3664
|
+
state.retryable = true;
|
|
3668
3665
|
}
|
|
3669
3666
|
if (!state.error)
|
|
3670
3667
|
state.error = errorMsg;
|
|
@@ -3703,7 +3700,8 @@ function finalizeParseState(state) {
|
|
|
3703
3700
|
tokenUsage: state.tokenUsage,
|
|
3704
3701
|
exactCostUsd: state.exactCostUsd,
|
|
3705
3702
|
stopReason: state.stopReason,
|
|
3706
|
-
error: state.error
|
|
3703
|
+
error: state.error,
|
|
3704
|
+
retryable: state.retryable
|
|
3707
3705
|
};
|
|
3708
3706
|
}
|
|
3709
3707
|
|
|
@@ -3828,7 +3826,8 @@ class SpawnAcpSession {
|
|
|
3828
3826
|
});
|
|
3829
3827
|
return {
|
|
3830
3828
|
messages: [{ role: "assistant", content: errorContent }],
|
|
3831
|
-
stopReason: "error"
|
|
3829
|
+
stopReason: "error",
|
|
3830
|
+
retryable: parsedOnError.retryable
|
|
3832
3831
|
};
|
|
3833
3832
|
}
|
|
3834
3833
|
try {
|
|
@@ -3904,7 +3903,6 @@ class SpawnAcpSession {
|
|
|
3904
3903
|
}
|
|
3905
3904
|
|
|
3906
3905
|
class SpawnAcpClient {
|
|
3907
|
-
agentName;
|
|
3908
3906
|
model;
|
|
3909
3907
|
cwd;
|
|
3910
3908
|
timeoutSeconds;
|
|
@@ -3918,7 +3916,6 @@ class SpawnAcpClient {
|
|
|
3918
3916
|
if (!lastToken || lastToken.startsWith("-")) {
|
|
3919
3917
|
throw new Error(`[acp-adapter] Could not parse agentName from cmdStr: "${cmdStr}"`);
|
|
3920
3918
|
}
|
|
3921
|
-
this.agentName = lastToken;
|
|
3922
3919
|
this.cwd = cwd || process.cwd();
|
|
3923
3920
|
this.timeoutSeconds = timeoutSeconds || 1800;
|
|
3924
3921
|
this.env = buildAllowedEnv();
|
|
@@ -4132,17 +4129,6 @@ function estimateCostByDuration(modelTier, durationMs) {
|
|
|
4132
4129
|
confidence: "fallback"
|
|
4133
4130
|
};
|
|
4134
4131
|
}
|
|
4135
|
-
function formatCostWithConfidence(estimate) {
|
|
4136
|
-
const formattedCost = `$${estimate.cost.toFixed(2)}`;
|
|
4137
|
-
switch (estimate.confidence) {
|
|
4138
|
-
case "exact":
|
|
4139
|
-
return formattedCost;
|
|
4140
|
-
case "estimated":
|
|
4141
|
-
return `~${formattedCost}`;
|
|
4142
|
-
case "fallback":
|
|
4143
|
-
return `~${formattedCost} (duration-based)`;
|
|
4144
|
-
}
|
|
4145
|
-
}
|
|
4146
4132
|
function estimateCostFromTokenUsage(usage, model) {
|
|
4147
4133
|
const pricing = MODEL_PRICING[model];
|
|
4148
4134
|
if (!pricing) {
|
|
@@ -18177,6 +18163,8 @@ var init_schemas3 = __esm(() => {
|
|
|
18177
18163
|
iterationDelayMs: exports_external.number().int().nonnegative(),
|
|
18178
18164
|
costLimit: exports_external.number().positive({ message: "costLimit must be > 0" }),
|
|
18179
18165
|
sessionTimeoutSeconds: exports_external.number().int().positive({ message: "sessionTimeoutSeconds must be > 0" }).default(3600),
|
|
18166
|
+
sessionErrorMaxRetries: exports_external.number().int().min(0).max(5).default(1),
|
|
18167
|
+
sessionErrorRetryableMaxRetries: exports_external.number().int().min(0).max(10).default(3),
|
|
18180
18168
|
verificationTimeoutSeconds: exports_external.number().int().min(1).max(3600).default(300),
|
|
18181
18169
|
maxStoriesPerFeature: exports_external.number().int().positive(),
|
|
18182
18170
|
rectification: RectificationConfigSchema,
|
|
@@ -19095,7 +19083,9 @@ class AcpAgentAdapter {
|
|
|
19095
19083
|
});
|
|
19096
19084
|
let currentAgent = this.resolveCurrentAgent(config2);
|
|
19097
19085
|
const rateLimitedRetryAfter = new Map;
|
|
19098
|
-
let
|
|
19086
|
+
let sessionErrorRetries = 0;
|
|
19087
|
+
const SESSION_ERROR_MAX_RETRIES = config2?.execution?.sessionErrorMaxRetries ?? 1;
|
|
19088
|
+
const SESSION_ERROR_RETRYABLE_MAX_RETRIES = config2?.execution?.sessionErrorRetryableMaxRetries ?? 3;
|
|
19099
19089
|
let legacyAttempt = 0;
|
|
19100
19090
|
let retryCount = 0;
|
|
19101
19091
|
while (true) {
|
|
@@ -19106,11 +19096,15 @@ class AcpAgentAdapter {
|
|
|
19106
19096
|
exitCode: result.exitCode,
|
|
19107
19097
|
...result.output ? { output: result.output.slice(0, 500) } : {}
|
|
19108
19098
|
});
|
|
19109
|
-
|
|
19110
|
-
|
|
19099
|
+
const maxSessionRetries = result.sessionErrorRetryable ? SESSION_ERROR_RETRYABLE_MAX_RETRIES : SESSION_ERROR_MAX_RETRIES;
|
|
19100
|
+
if (result.sessionError && _acpAdapterDeps.shouldRetrySessionError && sessionErrorRetries < maxSessionRetries) {
|
|
19101
|
+
sessionErrorRetries += 1;
|
|
19111
19102
|
getSafeLogger()?.warn("acp-adapter", "Session error \u2014 retrying with fresh session", {
|
|
19112
19103
|
storyId: options.storyId,
|
|
19113
|
-
featureName: options.featureName
|
|
19104
|
+
featureName: options.featureName,
|
|
19105
|
+
retryable: result.sessionErrorRetryable,
|
|
19106
|
+
attempt: sessionErrorRetries,
|
|
19107
|
+
maxAttempts: maxSessionRetries
|
|
19114
19108
|
});
|
|
19115
19109
|
if (options.featureName && options.storyId) {
|
|
19116
19110
|
await clearAcpSession(options.workdir, options.featureName, options.storyId, options.sessionRole);
|
|
@@ -19329,6 +19323,7 @@ class AcpAgentAdapter {
|
|
|
19329
19323
|
}
|
|
19330
19324
|
const success2 = lastResponse?.stopReason === "end_turn";
|
|
19331
19325
|
const isSessionError = lastResponse?.stopReason === "error";
|
|
19326
|
+
const isSessionErrorRetryable = isSessionError && lastResponse?.retryable === true;
|
|
19332
19327
|
const output = extractOutput(lastResponse);
|
|
19333
19328
|
const estimatedCost = totalExactCostUsd ?? (totalTokenUsage.input_tokens > 0 || totalTokenUsage.output_tokens > 0 ? estimateCostFromTokenUsage(totalTokenUsage, options.modelDef.model) : 0);
|
|
19334
19329
|
const tokenUsage = totalTokenUsage.input_tokens > 0 || totalTokenUsage.output_tokens > 0 ? {
|
|
@@ -19347,6 +19342,7 @@ class AcpAgentAdapter {
|
|
|
19347
19342
|
output: output.slice(-MAX_AGENT_OUTPUT_CHARS),
|
|
19348
19343
|
rateLimited: false,
|
|
19349
19344
|
sessionError: isSessionError,
|
|
19345
|
+
sessionErrorRetryable: isSessionErrorRetryable,
|
|
19350
19346
|
durationMs,
|
|
19351
19347
|
estimatedCost,
|
|
19352
19348
|
tokenUsage
|
|
@@ -23020,7 +23016,7 @@ class AutoInteractionPlugin {
|
|
|
23020
23016
|
};
|
|
23021
23017
|
}
|
|
23022
23018
|
async destroy() {}
|
|
23023
|
-
async send(
|
|
23019
|
+
async send(_request) {}
|
|
23024
23020
|
async receive(_requestId, _timeout = 60000) {
|
|
23025
23021
|
throw new Error("Auto plugin requires full request context (not just requestId)");
|
|
23026
23022
|
}
|
|
@@ -24518,7 +24514,7 @@ async function checkHomeEnvValid() {
|
|
|
24518
24514
|
message: passed ? `HOME env is valid: ${home}` : home === "" ? "HOME env is not set \u2014 agent may write files to unexpected locations" : `HOME env is not an absolute path ("${home}") \u2014 may cause literal "~" directories in repo`
|
|
24519
24515
|
};
|
|
24520
24516
|
}
|
|
24521
|
-
async function checkLanguageTools(profile,
|
|
24517
|
+
async function checkLanguageTools(profile, _workdir) {
|
|
24522
24518
|
if (!profile || !profile.language) {
|
|
24523
24519
|
return {
|
|
24524
24520
|
name: "language-tools-available",
|
|
@@ -25247,7 +25243,7 @@ function countStories(prd) {
|
|
|
25247
25243
|
decomposed: prd.userStories.filter((s) => s.status === "decomposed").length
|
|
25248
25244
|
};
|
|
25249
25245
|
}
|
|
25250
|
-
function markStoryPassed(prd, storyId,
|
|
25246
|
+
function markStoryPassed(prd, storyId, _statusWriter) {
|
|
25251
25247
|
const story = prd.userStories.find((s) => s.id === storyId);
|
|
25252
25248
|
if (story) {
|
|
25253
25249
|
story.passes = true;
|
|
@@ -26180,7 +26176,7 @@ function parseAcceptanceCriteria(specContent) {
|
|
|
26180
26176
|
}
|
|
26181
26177
|
return criteria;
|
|
26182
26178
|
}
|
|
26183
|
-
function buildAcceptanceTestPrompt(criteria, featureName,
|
|
26179
|
+
function buildAcceptanceTestPrompt(criteria, featureName, _codebaseContext, testPathConfig, language) {
|
|
26184
26180
|
const criteriaList = criteria.map((ac) => `${ac.id}: ${ac.text}`).join(`
|
|
26185
26181
|
`);
|
|
26186
26182
|
const resolvedTestPath = resolveAcceptanceTestFile2(language, testPathConfig);
|
|
@@ -26329,7 +26325,7 @@ ${tests || " // No acceptance criteria found"}
|
|
|
26329
26325
|
});
|
|
26330
26326
|
`;
|
|
26331
26327
|
}
|
|
26332
|
-
function generateGoSkeletonTests(
|
|
26328
|
+
function generateGoSkeletonTests(_featureName, criteria) {
|
|
26333
26329
|
const sanitize = (text) => text.replace(/[^a-zA-Z0-9 ]/g, "").split(" ").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
26334
26330
|
const tests = criteria.map((ac) => {
|
|
26335
26331
|
const funcName = `Test${sanitize(ac.text) || ac.id.replace("-", "")}`;
|
|
@@ -27514,40 +27510,8 @@ var init_claude = __esm(() => {
|
|
|
27514
27510
|
function validateAgentForTier(agent, tier) {
|
|
27515
27511
|
return agent.capabilities.supportedTiers.includes(tier);
|
|
27516
27512
|
}
|
|
27517
|
-
function validateAgentFeature(agent, feature) {
|
|
27518
|
-
return agent.capabilities.features.has(feature);
|
|
27519
|
-
}
|
|
27520
|
-
function describeAgentCapabilities(agent) {
|
|
27521
|
-
const tiers = agent.capabilities.supportedTiers.join(",");
|
|
27522
|
-
const features = Array.from(agent.capabilities.features).join(",");
|
|
27523
|
-
const maxTokens = agent.capabilities.maxContextTokens;
|
|
27524
|
-
return `${agent.name}: tiers=[${tiers}], maxTokens=${maxTokens}, features=[${features}]`;
|
|
27525
|
-
}
|
|
27526
27513
|
|
|
27527
27514
|
// src/agents/index.ts
|
|
27528
|
-
var exports_agents = {};
|
|
27529
|
-
__export(exports_agents, {
|
|
27530
|
-
validateAgentForTier: () => validateAgentForTier,
|
|
27531
|
-
validateAgentFeature: () => validateAgentFeature,
|
|
27532
|
-
parseTokenUsage: () => parseTokenUsage,
|
|
27533
|
-
getInstalledAgents: () => getInstalledAgents,
|
|
27534
|
-
getAllAgentNames: () => getAllAgentNames,
|
|
27535
|
-
getAgentVersions: () => getAgentVersions,
|
|
27536
|
-
getAgentVersion: () => getAgentVersion,
|
|
27537
|
-
getAgent: () => getAgent,
|
|
27538
|
-
formatCostWithConfidence: () => formatCostWithConfidence,
|
|
27539
|
-
estimateCostFromTokenUsage: () => estimateCostFromTokenUsage,
|
|
27540
|
-
estimateCostFromOutput: () => estimateCostFromOutput,
|
|
27541
|
-
estimateCostByDuration: () => estimateCostByDuration,
|
|
27542
|
-
estimateCost: () => estimateCost,
|
|
27543
|
-
describeAgentCapabilities: () => describeAgentCapabilities,
|
|
27544
|
-
checkAgentHealth: () => checkAgentHealth,
|
|
27545
|
-
MODEL_PRICING: () => MODEL_PRICING,
|
|
27546
|
-
CompleteError: () => CompleteError,
|
|
27547
|
-
ClaudeCodeAdapter: () => ClaudeCodeAdapter,
|
|
27548
|
-
COST_RATES: () => COST_RATES,
|
|
27549
|
-
AllAgentsUnavailableError: () => AllAgentsUnavailableError
|
|
27550
|
-
});
|
|
27551
27515
|
var init_agents = __esm(() => {
|
|
27552
27516
|
init_types2();
|
|
27553
27517
|
init_claude();
|
|
@@ -28114,7 +28078,7 @@ ${stat}
|
|
|
28114
28078
|
return `${statPreamble}${truncated}
|
|
28115
28079
|
... (truncated at ${DIFF_CAP_BYTES} bytes, showing ${visibleFiles}/${totalFiles} files)`;
|
|
28116
28080
|
}
|
|
28117
|
-
function buildPrompt(story, semanticConfig, diff,
|
|
28081
|
+
function buildPrompt(story, semanticConfig, diff, _stat) {
|
|
28118
28082
|
const acList = story.acceptanceCriteria.map((ac, i) => `${i + 1}. ${ac}`).join(`
|
|
28119
28083
|
`);
|
|
28120
28084
|
const customRulesSection = semanticConfig.rules.length > 0 ? `
|
|
@@ -30002,9 +29966,7 @@ function deriveTestPatterns(contextFiles) {
|
|
|
30002
29966
|
async function detectTestDir(workdir) {
|
|
30003
29967
|
for (const dir of COMMON_TEST_DIRS) {
|
|
30004
29968
|
const fullPath = path7.join(workdir, dir);
|
|
30005
|
-
const file3 = Bun.file(path7.join(fullPath, "."));
|
|
30006
29969
|
try {
|
|
30007
|
-
const dirStat = await Bun.file(fullPath).exists();
|
|
30008
29970
|
const proc = Bun.spawn(["test", "-d", fullPath], { stdout: "pipe", stderr: "pipe" });
|
|
30009
29971
|
const exitCode = await proc.exited;
|
|
30010
29972
|
if (exitCode === 0)
|
|
@@ -30805,7 +30767,7 @@ function globToRegex(pattern) {
|
|
|
30805
30767
|
const regexStr = filePattern.replace(/\./g, "\\.").replace(/\*/g, "[^/]*").replace(/\{([^}]+)\}/g, (_, group) => `(${group.replace(/,/g, "|")})`).replace(/\\\.\\\*/g, "\\.[^/]*");
|
|
30806
30768
|
return new RegExp(`${regexStr}$`);
|
|
30807
30769
|
}
|
|
30808
|
-
async function isGreenfieldStory(
|
|
30770
|
+
async function isGreenfieldStory(_story, workdir, testPattern = "**/*.{test,spec}.{ts,js,tsx,jsx}") {
|
|
30809
30771
|
try {
|
|
30810
30772
|
const regex = globToRegex(testPattern);
|
|
30811
30773
|
const testFiles = await scanForTestFiles(workdir, regex);
|
|
@@ -33423,7 +33385,7 @@ var init_optimizer2 = __esm(() => {
|
|
|
33423
33385
|
init_optimizer();
|
|
33424
33386
|
optimizerStage = {
|
|
33425
33387
|
name: "optimizer",
|
|
33426
|
-
enabled: (
|
|
33388
|
+
enabled: (_ctx) => {
|
|
33427
33389
|
return true;
|
|
33428
33390
|
},
|
|
33429
33391
|
async execute(ctx) {
|
|
@@ -34773,7 +34735,7 @@ var init_classify = __esm(() => {
|
|
|
34773
34735
|
});
|
|
34774
34736
|
|
|
34775
34737
|
// src/routing/strategies/llm-prompts.ts
|
|
34776
|
-
function buildRoutingPrompt(story,
|
|
34738
|
+
function buildRoutingPrompt(story, _config) {
|
|
34777
34739
|
const { title, description, acceptanceCriteria, tags } = story;
|
|
34778
34740
|
const criteria = acceptanceCriteria.map((c, i) => `${i + 1}. ${c}`).join(`
|
|
34779
34741
|
`);
|
|
@@ -34807,7 +34769,7 @@ Respond with:
|
|
|
34807
34769
|
{"complexity":"simple|medium|complex|expert","modelTier":"fast|balanced|powerful","reasoning":"<one line>"}`;
|
|
34808
34770
|
return wrapJsonPrompt(core2);
|
|
34809
34771
|
}
|
|
34810
|
-
function buildBatchRoutingPrompt(stories,
|
|
34772
|
+
function buildBatchRoutingPrompt(stories, _config) {
|
|
34811
34773
|
const storyBlocks = stories.map((story, idx) => {
|
|
34812
34774
|
const criteria = story.acceptanceCriteria.map((c, i) => ` ${i + 1}. ${c}`).join(`
|
|
34813
34775
|
`);
|
|
@@ -36676,7 +36638,7 @@ var package_default;
|
|
|
36676
36638
|
var init_package = __esm(() => {
|
|
36677
36639
|
package_default = {
|
|
36678
36640
|
name: "@nathapp/nax",
|
|
36679
|
-
version: "0.61.2
|
|
36641
|
+
version: "0.61.2",
|
|
36680
36642
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
36681
36643
|
type: "module",
|
|
36682
36644
|
bin: {
|
|
@@ -36756,8 +36718,8 @@ var init_version = __esm(() => {
|
|
|
36756
36718
|
NAX_VERSION = package_default.version;
|
|
36757
36719
|
NAX_COMMIT = (() => {
|
|
36758
36720
|
try {
|
|
36759
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
36760
|
-
return "
|
|
36721
|
+
if (/^[0-9a-f]{6,10}$/.test("16490524"))
|
|
36722
|
+
return "16490524";
|
|
36761
36723
|
} catch {}
|
|
36762
36724
|
try {
|
|
36763
36725
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -37104,7 +37066,7 @@ function parseImportStatements(content) {
|
|
|
37104
37066
|
}
|
|
37105
37067
|
return imports;
|
|
37106
37068
|
}
|
|
37107
|
-
function resolveImportPaths(imports,
|
|
37069
|
+
function resolveImportPaths(imports, _workdir) {
|
|
37108
37070
|
const resolved = [];
|
|
37109
37071
|
for (const imp of imports) {
|
|
37110
37072
|
if (imp.startsWith(".")) {
|
|
@@ -38357,7 +38319,7 @@ function wireHooks(bus, hooks, workdir, feature) {
|
|
|
38357
38319
|
return fn().catch((err) => logger?.warn("hooks-subscriber", `Hook "${name}" failed`, { error: String(err) })).catch(() => {});
|
|
38358
38320
|
};
|
|
38359
38321
|
const unsubs = [];
|
|
38360
|
-
unsubs.push(bus.on("run:started", (
|
|
38322
|
+
unsubs.push(bus.on("run:started", (_ev) => {
|
|
38361
38323
|
return safe("on-start", () => fireHook(hooks, "on-start", hookCtx(feature, { status: "running" }), workdir));
|
|
38362
38324
|
}));
|
|
38363
38325
|
unsubs.push(bus.on("story:started", (ev) => {
|
|
@@ -38378,7 +38340,7 @@ function wireHooks(bus, hooks, workdir, feature) {
|
|
|
38378
38340
|
unsubs.push(bus.on("run:completed", (ev) => {
|
|
38379
38341
|
return safe("on-complete", () => fireHook(hooks, "on-complete", hookCtx(feature, { status: "complete", cost: ev.totalCost ?? 0 }), workdir));
|
|
38380
38342
|
}));
|
|
38381
|
-
unsubs.push(bus.on("run:resumed", (
|
|
38343
|
+
unsubs.push(bus.on("run:resumed", (_ev) => {
|
|
38382
38344
|
return safe("on-resume", () => fireHook(hooks, "on-resume", hookCtx(feature, { status: "running" }), workdir));
|
|
38383
38345
|
}));
|
|
38384
38346
|
unsubs.push(bus.on("story:completed", (ev) => {
|
|
@@ -39131,7 +39093,6 @@ var init_pipeline_result_handler = __esm(() => {
|
|
|
39131
39093
|
// src/execution/iteration-runner.ts
|
|
39132
39094
|
import { join as join45 } from "path";
|
|
39133
39095
|
async function runIteration(ctx, prd, selection, iterations, totalCost, allStoryMetrics) {
|
|
39134
|
-
const logger = getSafeLogger();
|
|
39135
39096
|
const { story, storiesToExecute, routing, isBatchExecution } = selection;
|
|
39136
39097
|
if (ctx.dryRun) {
|
|
39137
39098
|
const dryRunResult = await handleDryRun({
|
|
@@ -39255,7 +39216,6 @@ async function runIteration(ctx, prd, selection, iterations, totalCost, allStory
|
|
|
39255
39216
|
var _iterationRunnerDeps;
|
|
39256
39217
|
var init_iteration_runner = __esm(() => {
|
|
39257
39218
|
init_loader();
|
|
39258
|
-
init_logger2();
|
|
39259
39219
|
init_runner();
|
|
39260
39220
|
init_stages();
|
|
39261
39221
|
init_prd();
|
|
@@ -39373,7 +39333,7 @@ async function executeStoryInWorktree(story, worktreePath, context, routing, eve
|
|
|
39373
39333
|
};
|
|
39374
39334
|
}
|
|
39375
39335
|
}
|
|
39376
|
-
async function executeParallelBatch(stories,
|
|
39336
|
+
async function executeParallelBatch(stories, _projectRoot, config2, context, worktreePaths, maxConcurrency, eventEmitter, storyEffectiveConfigs) {
|
|
39377
39337
|
const logger = getSafeLogger();
|
|
39378
39338
|
const results = {
|
|
39379
39339
|
pipelinePassed: [],
|
|
@@ -40524,7 +40484,7 @@ function detectType(pkg) {
|
|
|
40524
40484
|
return "cli";
|
|
40525
40485
|
return;
|
|
40526
40486
|
}
|
|
40527
|
-
async function detectTestFramework(
|
|
40487
|
+
async function detectTestFramework(_workdir, language, pkg) {
|
|
40528
40488
|
if (language === "go")
|
|
40529
40489
|
return "go-test";
|
|
40530
40490
|
if (language === "rust")
|
|
@@ -40984,7 +40944,6 @@ import { join as join50 } from "path";
|
|
|
40984
40944
|
async function reconcileState(prd, prdPath, workdir, config2) {
|
|
40985
40945
|
const logger = getSafeLogger();
|
|
40986
40946
|
let reconciledCount = 0;
|
|
40987
|
-
let modified = false;
|
|
40988
40947
|
for (const story of prd.userStories) {
|
|
40989
40948
|
if (story.status !== "failed")
|
|
40990
40949
|
continue;
|
|
@@ -41019,7 +40978,6 @@ async function reconcileState(prd, prdPath, workdir, config2) {
|
|
|
41019
40978
|
});
|
|
41020
40979
|
markStoryPassed(prd, story.id);
|
|
41021
40980
|
reconciledCount++;
|
|
41022
|
-
modified = true;
|
|
41023
40981
|
}
|
|
41024
40982
|
if (reconciledCount > 0) {
|
|
41025
40983
|
logger?.info("reconciliation", `Reconciled ${reconciledCount} failed stories from git history`);
|
|
@@ -41031,7 +40989,6 @@ async function checkAgentInstalled(config2, dryRun, agentGetFn) {
|
|
|
41031
40989
|
if (dryRun)
|
|
41032
40990
|
return;
|
|
41033
40991
|
const logger = getSafeLogger();
|
|
41034
|
-
const { getAgent: getAgent2 } = await Promise.resolve().then(() => (init_agents(), exports_agents));
|
|
41035
40992
|
const agent = (agentGetFn ?? _reconcileDeps.getAgent)(config2.autoMode.defaultAgent);
|
|
41036
40993
|
if (!agent) {
|
|
41037
40994
|
logger?.error("execution", "Agent not found", {
|
|
@@ -74892,7 +74849,7 @@ import { existsSync as existsSync22, readdirSync as readdirSync6 } from "fs";
|
|
|
74892
74849
|
import { join as join30 } from "path";
|
|
74893
74850
|
|
|
74894
74851
|
// src/cli/diagnose-analysis.ts
|
|
74895
|
-
function detectFailurePattern(story,
|
|
74852
|
+
function detectFailurePattern(story, _prd, status) {
|
|
74896
74853
|
if (story.status === "passed" && story.priorErrors?.some((err) => err.toLowerCase().includes("greenfield-no-tests"))) {
|
|
74897
74854
|
return "AUTO_RECOVERED";
|
|
74898
74855
|
}
|
|
@@ -76838,7 +76795,6 @@ async function run(options) {
|
|
|
76838
76795
|
let totalCost = 0;
|
|
76839
76796
|
let runCompleted = false;
|
|
76840
76797
|
const allStoryMetrics = [];
|
|
76841
|
-
const logger = getSafeLogger();
|
|
76842
76798
|
const registry2 = createAgentRegistry(config2);
|
|
76843
76799
|
const agentGetFn = registry2.getAgent.bind(registry2);
|
|
76844
76800
|
let prd;
|
|
@@ -76939,20 +76895,20 @@ async function run(options) {
|
|
|
76939
76895
|
durationMs
|
|
76940
76896
|
};
|
|
76941
76897
|
} finally {
|
|
76942
|
-
const
|
|
76943
|
-
|
|
76898
|
+
const logger = getSafeLogger();
|
|
76899
|
+
logger?.debug("execution", "Runner finally block \u2014 starting cleanup");
|
|
76944
76900
|
stopHeartbeat();
|
|
76945
76901
|
cleanupCrashHandlers();
|
|
76946
|
-
|
|
76902
|
+
logger?.debug("execution", "Runner finally \u2014 sweeping ACP sessions");
|
|
76947
76903
|
await sweepFeatureSessions(workdir, feature).catch(() => {});
|
|
76948
|
-
|
|
76904
|
+
logger?.debug("execution", "Runner finally \u2014 ACP sweep done");
|
|
76949
76905
|
let branch = "";
|
|
76950
76906
|
try {
|
|
76951
76907
|
const { stdout, exitCode } = await gitWithTimeout(["branch", "--show-current"], workdir);
|
|
76952
76908
|
if (exitCode === 0)
|
|
76953
76909
|
branch = stdout.trim();
|
|
76954
76910
|
} catch {}
|
|
76955
|
-
|
|
76911
|
+
logger?.debug("execution", "Runner finally \u2014 running cleanupRun");
|
|
76956
76912
|
const { cleanupRun: cleanupRun2 } = await Promise.resolve().then(() => (init_run_cleanup(), exports_run_cleanup));
|
|
76957
76913
|
await cleanupRun2({
|
|
76958
76914
|
runId,
|
|
@@ -76969,7 +76925,7 @@ async function run(options) {
|
|
|
76969
76925
|
version: NAX_VERSION,
|
|
76970
76926
|
runCompleted
|
|
76971
76927
|
});
|
|
76972
|
-
|
|
76928
|
+
logger?.debug("execution", "Runner finally \u2014 cleanupRun done, run() returning");
|
|
76973
76929
|
}
|
|
76974
76930
|
}
|
|
76975
76931
|
|
|
@@ -83955,7 +83911,6 @@ function usePty(options) {
|
|
|
83955
83911
|
isRunning: false
|
|
83956
83912
|
}));
|
|
83957
83913
|
const [handle, setHandle] = import_react33.useState(null);
|
|
83958
|
-
const [ptyProcess, setPtyProcess] = import_react33.useState(null);
|
|
83959
83914
|
const command = options?.command;
|
|
83960
83915
|
const argsJson = JSON.stringify(options?.args);
|
|
83961
83916
|
const cwd2 = options?.cwd;
|
|
@@ -83971,7 +83926,6 @@ function usePty(options) {
|
|
|
83971
83926
|
stdout: "pipe",
|
|
83972
83927
|
stderr: "inherit"
|
|
83973
83928
|
});
|
|
83974
|
-
setPtyProcess(proc);
|
|
83975
83929
|
setState((prev) => ({ ...prev, isRunning: true }));
|
|
83976
83930
|
(async () => {
|
|
83977
83931
|
let currentLine = "";
|