@nathapp/nax 0.73.2 → 0.73.3
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 +398 -94
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -24524,16 +24524,24 @@ function buildTestFrameworkHint(testCommand) {
|
|
|
24524
24524
|
return "Use Jest (describe/test/expect)";
|
|
24525
24525
|
return "Use your project's test framework";
|
|
24526
24526
|
}
|
|
24527
|
+
function stripAnsi(output) {
|
|
24528
|
+
return output.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "");
|
|
24529
|
+
}
|
|
24527
24530
|
function detectFramework(output) {
|
|
24528
|
-
|
|
24531
|
+
const clean = stripAnsi(output);
|
|
24532
|
+
if (/^\s*Test Files\s+\d+/m.test(clean))
|
|
24529
24533
|
return "vitest";
|
|
24530
|
-
if (/^\s*Tests:\s+\d+/m.test(
|
|
24534
|
+
if (/^\s*Tests:\s+\d+/m.test(clean))
|
|
24531
24535
|
return "jest";
|
|
24532
|
-
if (/={3,}\s+\d+\s+(?:failed|passed).*in\s+[\d.]+s\s*={3,}/m.test(
|
|
24536
|
+
if (/={3,}\s+\d+\s+(?:failed|passed).*in\s+[\d.]+s\s*={3,}/m.test(clean))
|
|
24533
24537
|
return "pytest";
|
|
24534
|
-
if (/^--- (?:FAIL|PASS):/m.test(
|
|
24538
|
+
if (/^--- (?:FAIL|PASS):/m.test(clean) || /^(?:ok|FAIL)\s+\t/m.test(clean))
|
|
24535
24539
|
return "go";
|
|
24536
|
-
if (
|
|
24540
|
+
if (/^test result:\s+(?:ok|FAILED)\./m.test(clean) || /panicked at /.test(clean))
|
|
24541
|
+
return "rust";
|
|
24542
|
+
if (/^\s*\d+\s+passing\b/m.test(clean))
|
|
24543
|
+
return "mocha";
|
|
24544
|
+
if (/^\(fail\)\s/m.test(clean) || /^bun test/m.test(clean) || /[\u2713\u2714\u2717\u2718]/m.test(clean))
|
|
24537
24545
|
return "bun";
|
|
24538
24546
|
return "unknown";
|
|
24539
24547
|
}
|
|
@@ -24670,21 +24678,125 @@ var init_resolver = __esm(() => {
|
|
|
24670
24678
|
};
|
|
24671
24679
|
});
|
|
24672
24680
|
|
|
24681
|
+
// src/test-runners/parse-mocha.ts
|
|
24682
|
+
function parseMochaOutput(output) {
|
|
24683
|
+
return {
|
|
24684
|
+
passed: matchCount(output, /(\d+)\s+passing\b/),
|
|
24685
|
+
failed: matchCount(output, /(\d+)\s+failing\b/),
|
|
24686
|
+
failures: extractMochaFailures(output)
|
|
24687
|
+
};
|
|
24688
|
+
}
|
|
24689
|
+
function matchCount(output, re) {
|
|
24690
|
+
const m = output.match(re);
|
|
24691
|
+
return m ? Number.parseInt(m[1], 10) : 0;
|
|
24692
|
+
}
|
|
24693
|
+
function extractMochaFailures(output) {
|
|
24694
|
+
const failingIdx = output.search(/^\s*\d+\s+failing\b/m);
|
|
24695
|
+
if (failingIdx === -1)
|
|
24696
|
+
return [];
|
|
24697
|
+
const lines = output.slice(failingIdx).split(`
|
|
24698
|
+
`);
|
|
24699
|
+
const failures = [];
|
|
24700
|
+
for (let i = 1;i < lines.length; i++) {
|
|
24701
|
+
const header = lines[i].match(/^\s*(\d+)\)\s+(.+)$/);
|
|
24702
|
+
if (!header)
|
|
24703
|
+
continue;
|
|
24704
|
+
const testName = header[2].replace(/:\s*$/, "").trim();
|
|
24705
|
+
let file3 = "unknown";
|
|
24706
|
+
let error48 = "";
|
|
24707
|
+
const stackTrace = [];
|
|
24708
|
+
for (let j = i + 1;j < lines.length; j++) {
|
|
24709
|
+
const line = lines[j];
|
|
24710
|
+
if (/^\s*\d+\)\s+/.test(line))
|
|
24711
|
+
break;
|
|
24712
|
+
const at = line.match(/at\s+.*\(([^)]+):(\d+):(\d+)\)/);
|
|
24713
|
+
if (at) {
|
|
24714
|
+
if (file3 === "unknown")
|
|
24715
|
+
file3 = at[1];
|
|
24716
|
+
if (stackTrace.length < MAX_STACK_LINES)
|
|
24717
|
+
stackTrace.push(`${at[1]}:${at[2]}`);
|
|
24718
|
+
continue;
|
|
24719
|
+
}
|
|
24720
|
+
if (!error48 && line.trim())
|
|
24721
|
+
error48 = line.trim();
|
|
24722
|
+
}
|
|
24723
|
+
failures.push({ file: file3, testName, error: error48 || "Unknown error", stackTrace });
|
|
24724
|
+
}
|
|
24725
|
+
return failures;
|
|
24726
|
+
}
|
|
24727
|
+
var MAX_STACK_LINES = 5;
|
|
24728
|
+
|
|
24729
|
+
// src/test-runners/parse-rust.ts
|
|
24730
|
+
function parseRustTestOutput(output) {
|
|
24731
|
+
let passed = 0;
|
|
24732
|
+
let failed = 0;
|
|
24733
|
+
for (const m of output.matchAll(RESULT_LINE_RE)) {
|
|
24734
|
+
passed += Number.parseInt(m[1], 10);
|
|
24735
|
+
failed += Number.parseInt(m[2], 10);
|
|
24736
|
+
}
|
|
24737
|
+
return { passed, failed, failures: extractRustFailures(output) };
|
|
24738
|
+
}
|
|
24739
|
+
function extractRustFailures(output) {
|
|
24740
|
+
const lines = output.split(`
|
|
24741
|
+
`);
|
|
24742
|
+
const failures = [];
|
|
24743
|
+
for (let i = 0;i < lines.length; i++) {
|
|
24744
|
+
const header = lines[i].match(/^---- (\S+) stdout ----$/);
|
|
24745
|
+
if (!header)
|
|
24746
|
+
continue;
|
|
24747
|
+
const testName = header[1];
|
|
24748
|
+
let file3 = "unknown";
|
|
24749
|
+
let error48 = "";
|
|
24750
|
+
const stackTrace = [];
|
|
24751
|
+
for (let j = i + 1;j < lines.length; j++) {
|
|
24752
|
+
const line = lines[j];
|
|
24753
|
+
if (/^---- \S+ stdout ----$/.test(line) || /^test result:/.test(line))
|
|
24754
|
+
break;
|
|
24755
|
+
const panic = line.match(/panicked at ([^:\n]+):(\d+):(?:\d+):/);
|
|
24756
|
+
if (panic) {
|
|
24757
|
+
file3 = panic[1];
|
|
24758
|
+
if (stackTrace.length < MAX_STACK_LINES2)
|
|
24759
|
+
stackTrace.push(`${panic[1]}:${panic[2]}`);
|
|
24760
|
+
continue;
|
|
24761
|
+
}
|
|
24762
|
+
if (!error48 && line.trim() && !line.startsWith("note:"))
|
|
24763
|
+
error48 = line.trim();
|
|
24764
|
+
}
|
|
24765
|
+
failures.push({ file: file3, testName, error: error48 || "Unknown error", stackTrace });
|
|
24766
|
+
}
|
|
24767
|
+
if (failures.length > 0)
|
|
24768
|
+
return failures;
|
|
24769
|
+
for (const m of output.matchAll(FAILED_TEST_LINE_RE)) {
|
|
24770
|
+
failures.push({ file: "unknown", testName: m[1], error: "Unknown error", stackTrace: [] });
|
|
24771
|
+
}
|
|
24772
|
+
return failures;
|
|
24773
|
+
}
|
|
24774
|
+
var RESULT_LINE_RE, FAILED_TEST_LINE_RE, MAX_STACK_LINES2 = 5;
|
|
24775
|
+
var init_parse_rust = __esm(() => {
|
|
24776
|
+
RESULT_LINE_RE = /^test result:\s+(?:ok|FAILED)\.\s+(\d+)\s+passed;\s+(\d+)\s+failed;/gm;
|
|
24777
|
+
FAILED_TEST_LINE_RE = /^test (\S+) \.\.\. FAILED$/gm;
|
|
24778
|
+
});
|
|
24779
|
+
|
|
24673
24780
|
// src/test-runners/parser.ts
|
|
24674
24781
|
function parseTestOutput(output) {
|
|
24675
|
-
const
|
|
24782
|
+
const clean = stripAnsi(output);
|
|
24783
|
+
const framework = detectFramework(clean);
|
|
24676
24784
|
switch (framework) {
|
|
24677
24785
|
case "bun":
|
|
24678
|
-
return parseBunOutput(
|
|
24786
|
+
return parseBunOutput(clean);
|
|
24679
24787
|
case "jest":
|
|
24680
24788
|
case "vitest":
|
|
24681
|
-
return parseJestOutput(
|
|
24789
|
+
return parseJestOutput(clean);
|
|
24682
24790
|
case "pytest":
|
|
24683
|
-
return parsePytestOutput(
|
|
24791
|
+
return parsePytestOutput(clean);
|
|
24684
24792
|
case "go":
|
|
24685
|
-
return parseGoTestOutput(
|
|
24793
|
+
return parseGoTestOutput(clean);
|
|
24794
|
+
case "rust":
|
|
24795
|
+
return parseRustTestOutput(clean);
|
|
24796
|
+
case "mocha":
|
|
24797
|
+
return parseMochaOutput(clean);
|
|
24686
24798
|
default:
|
|
24687
|
-
return parseCommonOutput(
|
|
24799
|
+
return parseCommonOutput(clean);
|
|
24688
24800
|
}
|
|
24689
24801
|
}
|
|
24690
24802
|
function parseBunTestOutput(output) {
|
|
@@ -25014,11 +25126,12 @@ function analyzeTestExitCode(output, exitCode) {
|
|
|
25014
25126
|
}
|
|
25015
25127
|
var init_parser = __esm(() => {
|
|
25016
25128
|
init_detector2();
|
|
25129
|
+
init_parse_rust();
|
|
25017
25130
|
});
|
|
25018
25131
|
|
|
25019
25132
|
// src/test-runners/ac-parser.ts
|
|
25020
25133
|
function parseTestFailures(output) {
|
|
25021
|
-
const clean = output
|
|
25134
|
+
const clean = stripAnsi(output);
|
|
25022
25135
|
const framework = detectFramework(clean);
|
|
25023
25136
|
const failedACs = [];
|
|
25024
25137
|
const lines = clean.split(`
|
|
@@ -25072,10 +25185,8 @@ function parseTestFailures(output) {
|
|
|
25072
25185
|
}
|
|
25073
25186
|
return failedACs;
|
|
25074
25187
|
}
|
|
25075
|
-
var ANSI_ESCAPE_PATTERN;
|
|
25076
25188
|
var init_ac_parser = __esm(() => {
|
|
25077
25189
|
init_detector2();
|
|
25078
|
-
ANSI_ESCAPE_PATTERN = new RegExp(`${String.fromCharCode(27)}\\[[0-9;?]*[A-Za-z]`, "g");
|
|
25079
25190
|
});
|
|
25080
25191
|
|
|
25081
25192
|
// src/utils/git.ts
|
|
@@ -25756,6 +25867,8 @@ __export(exports_test_runners, {
|
|
|
25756
25867
|
resolveReviewExcludePatterns: () => resolveReviewExcludePatterns,
|
|
25757
25868
|
parseTestOutput: () => parseTestOutput,
|
|
25758
25869
|
parseTestFailures: () => parseTestFailures,
|
|
25870
|
+
parseRustTestOutput: () => parseRustTestOutput,
|
|
25871
|
+
parseMochaOutput: () => parseMochaOutput,
|
|
25759
25872
|
parseBunTestOutput: () => parseBunTestOutput,
|
|
25760
25873
|
isTestFileByPatterns: () => isTestFileByPatterns,
|
|
25761
25874
|
isTestFile: () => isTestFile,
|
|
@@ -25787,6 +25900,7 @@ var init_test_runners = __esm(() => {
|
|
|
25787
25900
|
init_detector2();
|
|
25788
25901
|
init_resolver();
|
|
25789
25902
|
init_parser();
|
|
25903
|
+
init_parse_rust();
|
|
25790
25904
|
init_workspace();
|
|
25791
25905
|
init_ac_parser();
|
|
25792
25906
|
init_scoped_selection();
|
|
@@ -35651,7 +35765,7 @@ var init_semantic_review = __esm(() => {
|
|
|
35651
35765
|
const substantiated = await substantiateSemanticEvidence(sanitized, input.mode, input.workdir, input.story.id, threshold, input.repoRoot);
|
|
35652
35766
|
const { accepted, dropped } = filterByAcGroundingMinimal(substantiated, input.story.acceptanceCriteria);
|
|
35653
35767
|
const blocking = accepted.filter((f) => isBlockingSeverity(f.severity, threshold));
|
|
35654
|
-
const passed = parsed.passed
|
|
35768
|
+
const passed = blocking.length === 0 && (parsed.passed || accepted.length > 0);
|
|
35655
35769
|
return {
|
|
35656
35770
|
...parsed,
|
|
35657
35771
|
passed,
|
|
@@ -40454,27 +40568,37 @@ function flipWithPairs(pairs, snippet) {
|
|
|
40454
40568
|
}
|
|
40455
40569
|
return results;
|
|
40456
40570
|
}
|
|
40457
|
-
function
|
|
40458
|
-
|
|
40459
|
-
|
|
40460
|
-
|
|
40461
|
-
|
|
40462
|
-
|
|
40463
|
-
|
|
40464
|
-
}
|
|
40465
|
-
if (/\bfalse\b/.test(snippet)) {
|
|
40466
|
-
const produced = snippet.replace(/\bfalse\b/g, "true");
|
|
40467
|
-
if (!seen.has(produced))
|
|
40571
|
+
function makeBooleanFlip(trueLit, falseLit) {
|
|
40572
|
+
return (snippet) => {
|
|
40573
|
+
const seen = new Set;
|
|
40574
|
+
const results = [];
|
|
40575
|
+
if (new RegExp(`\\b${trueLit}\\b`).test(snippet)) {
|
|
40576
|
+
const produced = snippet.replace(new RegExp(`\\b${trueLit}\\b`, "g"), falseLit);
|
|
40577
|
+
seen.add(produced);
|
|
40468
40578
|
results.push(produced);
|
|
40469
|
-
|
|
40470
|
-
|
|
40579
|
+
}
|
|
40580
|
+
if (new RegExp(`\\b${falseLit}\\b`).test(snippet)) {
|
|
40581
|
+
const produced = snippet.replace(new RegExp(`\\b${falseLit}\\b`, "g"), trueLit);
|
|
40582
|
+
if (!seen.has(produced))
|
|
40583
|
+
results.push(produced);
|
|
40584
|
+
}
|
|
40585
|
+
return results;
|
|
40586
|
+
};
|
|
40587
|
+
}
|
|
40588
|
+
function makeOperators(prefix, trueLit, falseLit) {
|
|
40589
|
+
return [
|
|
40590
|
+
{ id: `${prefix}:cmp-flip`, apply: (snippet) => flipWithPairs(UNIVERSAL_COMPARISON_PAIRS, snippet) },
|
|
40591
|
+
{ id: `${prefix}:cmp-bracket-flip`, apply: applyComparisonBracketFlip },
|
|
40592
|
+
{ id: `${prefix}:bool-flip`, apply: makeBooleanFlip(trueLit, falseLit) },
|
|
40593
|
+
{ id: `${prefix}:arith-flip`, apply: (snippet) => flipWithPairs(ARITHMETIC_PAIRS, snippet) }
|
|
40594
|
+
];
|
|
40471
40595
|
}
|
|
40472
40596
|
function getOperatorsForLanguage(language) {
|
|
40473
40597
|
if (!language)
|
|
40474
40598
|
return [];
|
|
40475
40599
|
return SUPPORTED_LANGUAGES.get(language) ?? [];
|
|
40476
40600
|
}
|
|
40477
|
-
var TS_COMPARISON_PAIRS, COMPARISON_GT, COMPARISON_LT,
|
|
40601
|
+
var TS_COMPARISON_PAIRS, UNIVERSAL_COMPARISON_PAIRS, COMPARISON_GT, COMPARISON_LT, ARITHMETIC_PAIRS, TYPESCRIPT_OPERATORS, PYTHON_OPERATORS, GO_OPERATORS, RUST_OPERATORS, SUPPORTED_LANGUAGES;
|
|
40478
40602
|
var init_operators = __esm(() => {
|
|
40479
40603
|
TS_COMPARISON_PAIRS = [
|
|
40480
40604
|
[/==/g, "!="],
|
|
@@ -40484,27 +40608,35 @@ var init_operators = __esm(() => {
|
|
|
40484
40608
|
[/>=/g, "<="],
|
|
40485
40609
|
[/<=/g, ">="]
|
|
40486
40610
|
];
|
|
40611
|
+
UNIVERSAL_COMPARISON_PAIRS = [
|
|
40612
|
+
[/==/g, "!="],
|
|
40613
|
+
[/!=/g, "=="],
|
|
40614
|
+
[/>=/g, "<="],
|
|
40615
|
+
[/<=/g, ">="]
|
|
40616
|
+
];
|
|
40487
40617
|
COMPARISON_GT = /(?<=\s)>(?!=)(?=\s|$)/g;
|
|
40488
40618
|
COMPARISON_LT = /(?<=\s)<(?!=)(?=\s)/g;
|
|
40489
|
-
|
|
40619
|
+
ARITHMETIC_PAIRS = [
|
|
40490
40620
|
[/\+/g, "-"],
|
|
40491
40621
|
[/-/g, "+"],
|
|
40492
40622
|
[/\*/g, "/"],
|
|
40493
40623
|
[/\//g, "*"]
|
|
40494
40624
|
];
|
|
40495
40625
|
TYPESCRIPT_OPERATORS = [
|
|
40496
|
-
{ id:
|
|
40497
|
-
{ id:
|
|
40498
|
-
{ id:
|
|
40499
|
-
{ id:
|
|
40626
|
+
{ id: "ts:cmp-flip", apply: (snippet) => flipWithPairs(TS_COMPARISON_PAIRS, snippet) },
|
|
40627
|
+
{ id: "ts:cmp-bracket-flip", apply: applyComparisonBracketFlip },
|
|
40628
|
+
{ id: "ts:bool-flip", apply: makeBooleanFlip("true", "false") },
|
|
40629
|
+
{ id: "ts:arith-flip", apply: (snippet) => flipWithPairs(ARITHMETIC_PAIRS, snippet) }
|
|
40500
40630
|
];
|
|
40501
|
-
PYTHON_OPERATORS =
|
|
40502
|
-
GO_OPERATORS =
|
|
40631
|
+
PYTHON_OPERATORS = makeOperators("py", "True", "False");
|
|
40632
|
+
GO_OPERATORS = makeOperators("go", "true", "false");
|
|
40633
|
+
RUST_OPERATORS = makeOperators("rust", "true", "false");
|
|
40503
40634
|
SUPPORTED_LANGUAGES = new Map([
|
|
40504
40635
|
["typescript", TYPESCRIPT_OPERATORS],
|
|
40505
40636
|
["javascript", TYPESCRIPT_OPERATORS],
|
|
40506
40637
|
["python", PYTHON_OPERATORS],
|
|
40507
|
-
["go", GO_OPERATORS]
|
|
40638
|
+
["go", GO_OPERATORS],
|
|
40639
|
+
["rust", RUST_OPERATORS]
|
|
40508
40640
|
]);
|
|
40509
40641
|
});
|
|
40510
40642
|
|
|
@@ -40526,7 +40658,8 @@ function generateMutants(input) {
|
|
|
40526
40658
|
const line = lines[i];
|
|
40527
40659
|
const lineNumber = i + 1;
|
|
40528
40660
|
const trimmed = line.trim();
|
|
40529
|
-
|
|
40661
|
+
const commentPrefixes = language === "python" ? ["#"] : ["//", "/*", "*"];
|
|
40662
|
+
if (commentPrefixes.some((prefix) => trimmed.startsWith(prefix)))
|
|
40530
40663
|
continue;
|
|
40531
40664
|
for (const operator of operators) {
|
|
40532
40665
|
for (const replacement of applyOperator(operator, line)) {
|
|
@@ -41632,7 +41765,7 @@ var package_default;
|
|
|
41632
41765
|
var init_package = __esm(() => {
|
|
41633
41766
|
package_default = {
|
|
41634
41767
|
name: "@nathapp/nax",
|
|
41635
|
-
version: "0.73.
|
|
41768
|
+
version: "0.73.3",
|
|
41636
41769
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
41637
41770
|
type: "module",
|
|
41638
41771
|
bin: {
|
|
@@ -41733,8 +41866,8 @@ var init_version = __esm(() => {
|
|
|
41733
41866
|
NAX_VERSION = package_default.version;
|
|
41734
41867
|
NAX_COMMIT = (() => {
|
|
41735
41868
|
try {
|
|
41736
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
41737
|
-
return "
|
|
41869
|
+
if (/^[0-9a-f]{6,10}$/.test("a98a211e"))
|
|
41870
|
+
return "a98a211e";
|
|
41738
41871
|
} catch {}
|
|
41739
41872
|
try {
|
|
41740
41873
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -64582,44 +64715,210 @@ var init_crash_recovery = __esm(() => {
|
|
|
64582
64715
|
init_crash_heartbeat();
|
|
64583
64716
|
});
|
|
64584
64717
|
|
|
64585
|
-
// src/acceptance/
|
|
64586
|
-
|
|
64587
|
-
|
|
64588
|
-
|
|
64589
|
-
|
|
64590
|
-
|
|
64591
|
-
|
|
64718
|
+
// src/acceptance/import-resolution.ts
|
|
64719
|
+
import { resolve as resolve16, sep as sep5 } from "path";
|
|
64720
|
+
function languageFromExtension(testFilePath) {
|
|
64721
|
+
if (!testFilePath)
|
|
64722
|
+
return;
|
|
64723
|
+
const dot = testFilePath.lastIndexOf(".");
|
|
64724
|
+
if (dot < 0)
|
|
64725
|
+
return;
|
|
64726
|
+
return EXT_LANGUAGE.get(testFilePath.slice(dot).toLowerCase());
|
|
64727
|
+
}
|
|
64728
|
+
function isResolvedLanguage(lang) {
|
|
64729
|
+
return lang !== undefined && SUPPORTED.has(lang);
|
|
64730
|
+
}
|
|
64731
|
+
async function resolveLanguage(opts) {
|
|
64732
|
+
const explicit = opts.language ?? languageFromExtension(opts.testFilePath);
|
|
64733
|
+
if (isResolvedLanguage(explicit))
|
|
64734
|
+
return explicit;
|
|
64735
|
+
const detected = await detectLanguage(opts.packageDir);
|
|
64736
|
+
if (isResolvedLanguage(detected))
|
|
64737
|
+
return detected;
|
|
64738
|
+
return "typescript";
|
|
64739
|
+
}
|
|
64740
|
+
async function readCapped(relPath, packageDir) {
|
|
64741
|
+
const resolvedPackageDir = resolve16(packageDir);
|
|
64742
|
+
const fullPath = resolve16(resolvedPackageDir, relPath);
|
|
64743
|
+
if (fullPath !== resolvedPackageDir && !fullPath.startsWith(resolvedPackageDir + sep5)) {
|
|
64744
|
+
return null;
|
|
64745
|
+
}
|
|
64746
|
+
try {
|
|
64747
|
+
const text = await Bun.file(fullPath).text();
|
|
64748
|
+
const content = text.split(`
|
|
64749
|
+
`).slice(0, MAX_FILE_LINES2).join(`
|
|
64750
|
+
`);
|
|
64751
|
+
return { path: relPath, content };
|
|
64752
|
+
} catch {
|
|
64753
|
+
return null;
|
|
64592
64754
|
}
|
|
64593
|
-
return imports;
|
|
64594
64755
|
}
|
|
64595
|
-
function
|
|
64596
|
-
const
|
|
64597
|
-
for (const
|
|
64598
|
-
if (
|
|
64599
|
-
|
|
64600
|
-
|
|
64756
|
+
function parseTsImports(content) {
|
|
64757
|
+
const specs = [];
|
|
64758
|
+
for (const m of content.matchAll(TS_IMPORT_RE)) {
|
|
64759
|
+
if (m[1].startsWith("."))
|
|
64760
|
+
specs.push(m[1]);
|
|
64761
|
+
}
|
|
64762
|
+
return specs;
|
|
64763
|
+
}
|
|
64764
|
+
function tsCandidates(spec) {
|
|
64765
|
+
if (TS_EXTS.some((e) => spec.endsWith(e)))
|
|
64766
|
+
return [spec];
|
|
64767
|
+
const out = [];
|
|
64768
|
+
for (const e of TS_EXTS)
|
|
64769
|
+
out.push(`${spec}${e}`);
|
|
64770
|
+
for (const e of TS_EXTS)
|
|
64771
|
+
out.push(`${spec}/index${e}`);
|
|
64772
|
+
return out;
|
|
64773
|
+
}
|
|
64774
|
+
function parsePythonImports(content) {
|
|
64775
|
+
const modules = [];
|
|
64776
|
+
for (const m of content.matchAll(PY_IMPORT_LINE_RE)) {
|
|
64777
|
+
const fromModule = m[1];
|
|
64778
|
+
const importList = m[2];
|
|
64779
|
+
if (fromModule !== undefined) {
|
|
64780
|
+
if (fromModule)
|
|
64781
|
+
modules.push(fromModule);
|
|
64782
|
+
} else if (importList) {
|
|
64783
|
+
for (const part of importList.split(",")) {
|
|
64784
|
+
const mod = part.trim().split(/\s+as\s+/)[0].trim();
|
|
64785
|
+
if (mod)
|
|
64786
|
+
modules.push(mod);
|
|
64787
|
+
}
|
|
64788
|
+
}
|
|
64789
|
+
}
|
|
64790
|
+
return modules;
|
|
64791
|
+
}
|
|
64792
|
+
function pythonCandidates(module) {
|
|
64793
|
+
const base = module.replace(/\./g, "/");
|
|
64794
|
+
return [`${base}.py`, `${base}/__init__.py`];
|
|
64795
|
+
}
|
|
64796
|
+
function parseRustUses(content) {
|
|
64797
|
+
const paths = [];
|
|
64798
|
+
for (const m of content.matchAll(RUST_USE_RE))
|
|
64799
|
+
paths.push(m[1]);
|
|
64800
|
+
return paths;
|
|
64801
|
+
}
|
|
64802
|
+
function rustCandidates(usePath) {
|
|
64803
|
+
const rest = usePath.split("::").slice(1);
|
|
64804
|
+
if (rest.length === 0)
|
|
64805
|
+
return [];
|
|
64806
|
+
const base = `src/${rest.join("/")}`;
|
|
64807
|
+
const candidates = [`${base}.rs`, `${base}/mod.rs`];
|
|
64808
|
+
if (rest.length > 1) {
|
|
64809
|
+
const parent = `src/${rest.slice(0, -1).join("/")}`;
|
|
64810
|
+
candidates.push(`${parent}.rs`, `${parent}/mod.rs`);
|
|
64811
|
+
} else {
|
|
64812
|
+
candidates.push("src/lib.rs");
|
|
64601
64813
|
}
|
|
64602
|
-
return
|
|
64814
|
+
return candidates;
|
|
64603
64815
|
}
|
|
64604
|
-
|
|
64605
|
-
const
|
|
64606
|
-
const
|
|
64607
|
-
|
|
64608
|
-
|
|
64816
|
+
function parseGoImports(content) {
|
|
64817
|
+
const paths = [];
|
|
64818
|
+
for (const m of content.matchAll(GO_SINGLE_IMPORT_RE))
|
|
64819
|
+
paths.push(m[1]);
|
|
64820
|
+
for (const block of content.matchAll(GO_IMPORT_BLOCK_RE)) {
|
|
64821
|
+
for (const line of block[1].matchAll(GO_BLOCK_LINE_RE))
|
|
64822
|
+
paths.push(line[1]);
|
|
64823
|
+
}
|
|
64824
|
+
return paths;
|
|
64609
64825
|
}
|
|
64610
|
-
async function
|
|
64826
|
+
async function readGoModulePrefix(packageDir) {
|
|
64611
64827
|
try {
|
|
64612
|
-
const
|
|
64613
|
-
const
|
|
64614
|
-
|
|
64615
|
-
`).slice(0, MAX_FILE_LINES2);
|
|
64616
|
-
return { path: filePath, content: lines.join(`
|
|
64617
|
-
`) };
|
|
64828
|
+
const text = await Bun.file(`${packageDir}/go.mod`).text();
|
|
64829
|
+
const m = text.match(/^\s*module\s+(\S+)/m);
|
|
64830
|
+
return m ? m[1] : null;
|
|
64618
64831
|
} catch {
|
|
64619
64832
|
return null;
|
|
64620
64833
|
}
|
|
64621
64834
|
}
|
|
64622
|
-
|
|
64835
|
+
async function resolveGoCandidates(content, packageDir) {
|
|
64836
|
+
const prefix = await readGoModulePrefix(packageDir);
|
|
64837
|
+
if (!prefix)
|
|
64838
|
+
return [];
|
|
64839
|
+
const candidates = [];
|
|
64840
|
+
for (const imp of parseGoImports(content)) {
|
|
64841
|
+
if (imp !== prefix && !imp.startsWith(`${prefix}/`))
|
|
64842
|
+
continue;
|
|
64843
|
+
const relDir = imp === prefix ? "." : imp.slice(prefix.length + 1);
|
|
64844
|
+
try {
|
|
64845
|
+
for (const file3 of new Bun.Glob("*.go").scanSync({ cwd: `${packageDir}/${relDir}`, absolute: false })) {
|
|
64846
|
+
if (file3.endsWith("_test.go"))
|
|
64847
|
+
continue;
|
|
64848
|
+
candidates.push(relDir === "." ? file3 : `${relDir}/${file3}`);
|
|
64849
|
+
}
|
|
64850
|
+
} catch {}
|
|
64851
|
+
}
|
|
64852
|
+
return candidates;
|
|
64853
|
+
}
|
|
64854
|
+
async function collectCandidates(lang, opts) {
|
|
64855
|
+
switch (lang) {
|
|
64856
|
+
case "typescript":
|
|
64857
|
+
case "javascript":
|
|
64858
|
+
return parseTsImports(opts.testFileContent).flatMap(tsCandidates);
|
|
64859
|
+
case "python":
|
|
64860
|
+
return parsePythonImports(opts.testFileContent).flatMap(pythonCandidates);
|
|
64861
|
+
case "rust":
|
|
64862
|
+
return parseRustUses(opts.testFileContent).flatMap(rustCandidates);
|
|
64863
|
+
case "go":
|
|
64864
|
+
return resolveGoCandidates(opts.testFileContent, opts.packageDir);
|
|
64865
|
+
default:
|
|
64866
|
+
return [];
|
|
64867
|
+
}
|
|
64868
|
+
}
|
|
64869
|
+
async function readCandidates(candidates, packageDir) {
|
|
64870
|
+
const seen = new Set;
|
|
64871
|
+
const results = [];
|
|
64872
|
+
for (const rel of candidates) {
|
|
64873
|
+
if (results.length >= MAX_SOURCE_FILES)
|
|
64874
|
+
break;
|
|
64875
|
+
if (seen.has(rel))
|
|
64876
|
+
continue;
|
|
64877
|
+
seen.add(rel);
|
|
64878
|
+
const file3 = await readCapped(rel, packageDir);
|
|
64879
|
+
if (file3)
|
|
64880
|
+
results.push(file3);
|
|
64881
|
+
}
|
|
64882
|
+
return results;
|
|
64883
|
+
}
|
|
64884
|
+
async function resolveSourceFiles(opts) {
|
|
64885
|
+
const lang = await resolveLanguage(opts);
|
|
64886
|
+
const candidates = await collectCandidates(lang, opts);
|
|
64887
|
+
return readCandidates(candidates, opts.packageDir);
|
|
64888
|
+
}
|
|
64889
|
+
var MAX_SOURCE_FILES = 5, MAX_FILE_LINES2 = 500, SUPPORTED, EXT_LANGUAGE, TS_IMPORT_RE, TS_EXTS, PY_IMPORT_LINE_RE, RUST_USE_RE, GO_SINGLE_IMPORT_RE, GO_IMPORT_BLOCK_RE, GO_BLOCK_LINE_RE;
|
|
64890
|
+
var init_import_resolution = __esm(() => {
|
|
64891
|
+
init_project();
|
|
64892
|
+
SUPPORTED = new Set(["typescript", "javascript", "python", "go", "rust"]);
|
|
64893
|
+
EXT_LANGUAGE = new Map([
|
|
64894
|
+
[".ts", "typescript"],
|
|
64895
|
+
[".tsx", "typescript"],
|
|
64896
|
+
[".mts", "typescript"],
|
|
64897
|
+
[".cts", "typescript"],
|
|
64898
|
+
[".js", "javascript"],
|
|
64899
|
+
[".jsx", "javascript"],
|
|
64900
|
+
[".mjs", "javascript"],
|
|
64901
|
+
[".cjs", "javascript"],
|
|
64902
|
+
[".py", "python"],
|
|
64903
|
+
[".go", "go"],
|
|
64904
|
+
[".rs", "rust"]
|
|
64905
|
+
]);
|
|
64906
|
+
TS_IMPORT_RE = /import\s+(?:{[^}]+}|[^;'"]+)\s+from\s+["']([^"']+)["']/g;
|
|
64907
|
+
TS_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mts", ".cts", ".mjs", ".cjs"];
|
|
64908
|
+
PY_IMPORT_LINE_RE = /^\s*(?:from\s+\.*([\w.]*)\s+import\s+|import\s+([\w.]+(?:\s*,\s*[\w.]+)*))/gm;
|
|
64909
|
+
RUST_USE_RE = /^\s*use\s+(crate(?:::\w+)*|(?:super|self)(?:::\w+)?)/gm;
|
|
64910
|
+
GO_SINGLE_IMPORT_RE = /^\s*import\s+"([^"]+)"/gm;
|
|
64911
|
+
GO_IMPORT_BLOCK_RE = /import\s*\(([\s\S]*?)\)/g;
|
|
64912
|
+
GO_BLOCK_LINE_RE = /"([^"]+)"/g;
|
|
64913
|
+
});
|
|
64914
|
+
|
|
64915
|
+
// src/acceptance/fix-diagnosis.ts
|
|
64916
|
+
async function loadSourceFilesForDiagnosis(opts) {
|
|
64917
|
+
return resolveSourceFiles(opts);
|
|
64918
|
+
}
|
|
64919
|
+
var init_fix_diagnosis = __esm(() => {
|
|
64920
|
+
init_import_resolution();
|
|
64921
|
+
});
|
|
64623
64922
|
|
|
64624
64923
|
// src/execution/lifecycle/acceptance-helpers.ts
|
|
64625
64924
|
import path23 from "path";
|
|
@@ -64800,7 +65099,11 @@ async function resolveAcceptanceDiagnosis(opts) {
|
|
|
64800
65099
|
confidence: 0.9
|
|
64801
65100
|
};
|
|
64802
65101
|
}
|
|
64803
|
-
const sourceFiles = await loadSourceFilesForDiagnosis(
|
|
65102
|
+
const sourceFiles = await loadSourceFilesForDiagnosis({
|
|
65103
|
+
testFileContent: diagnosisOpts.testFileContent,
|
|
65104
|
+
packageDir: diagnosisOpts.workdir,
|
|
65105
|
+
testFilePath: diagnosisOpts.acceptanceTestPath
|
|
65106
|
+
});
|
|
64804
65107
|
return await _diagnosisDeps.callOp(fixCallCtx(ctx), acceptanceDiagnoseOp, {
|
|
64805
65108
|
testOutput: diagnosisOpts.testOutput,
|
|
64806
65109
|
testFileContent: diagnosisOpts.testFileContent,
|
|
@@ -64811,6 +65114,7 @@ async function resolveAcceptanceDiagnosis(opts) {
|
|
|
64811
65114
|
}
|
|
64812
65115
|
var _diagnosisDeps;
|
|
64813
65116
|
var init_acceptance_fix2 = __esm(() => {
|
|
65117
|
+
init_fix_diagnosis();
|
|
64814
65118
|
init_errors();
|
|
64815
65119
|
init_logger2();
|
|
64816
65120
|
init_operations();
|
|
@@ -69317,7 +69621,7 @@ var init_runner_execution = __esm(() => {
|
|
|
69317
69621
|
|
|
69318
69622
|
// src/execution/status-file.ts
|
|
69319
69623
|
import { rename as rename2, unlink as unlink3 } from "fs/promises";
|
|
69320
|
-
import { resolve as
|
|
69624
|
+
import { resolve as resolve17 } from "path";
|
|
69321
69625
|
function countProgress(prd) {
|
|
69322
69626
|
const stories = prd.userStories;
|
|
69323
69627
|
const passed = stories.filter((s) => s.status === "passed").length;
|
|
@@ -69362,7 +69666,7 @@ function buildStatusSnapshot(state) {
|
|
|
69362
69666
|
return snapshot;
|
|
69363
69667
|
}
|
|
69364
69668
|
async function writeStatusFile(filePath, status) {
|
|
69365
|
-
const resolvedPath =
|
|
69669
|
+
const resolvedPath = resolve17(filePath);
|
|
69366
69670
|
if (filePath.includes("../") || filePath.includes("..\\")) {
|
|
69367
69671
|
throw new Error("Invalid status file path: path traversal detected");
|
|
69368
69672
|
}
|
|
@@ -71300,14 +71604,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
71300
71604
|
prevActScopeDepth !== actScopeDepth - 1 && console.error("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ");
|
|
71301
71605
|
actScopeDepth = prevActScopeDepth;
|
|
71302
71606
|
}
|
|
71303
|
-
function recursivelyFlushAsyncActWork(returnValue,
|
|
71607
|
+
function recursivelyFlushAsyncActWork(returnValue, resolve18, reject) {
|
|
71304
71608
|
var queue = ReactSharedInternals.actQueue;
|
|
71305
71609
|
if (queue !== null)
|
|
71306
71610
|
if (queue.length !== 0)
|
|
71307
71611
|
try {
|
|
71308
71612
|
flushActQueue(queue);
|
|
71309
71613
|
enqueueTask(function() {
|
|
71310
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
71614
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve18, reject);
|
|
71311
71615
|
});
|
|
71312
71616
|
return;
|
|
71313
71617
|
} catch (error48) {
|
|
@@ -71315,7 +71619,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
71315
71619
|
}
|
|
71316
71620
|
else
|
|
71317
71621
|
ReactSharedInternals.actQueue = null;
|
|
71318
|
-
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) :
|
|
71622
|
+
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve18(returnValue);
|
|
71319
71623
|
}
|
|
71320
71624
|
function flushActQueue(queue) {
|
|
71321
71625
|
if (!isFlushing) {
|
|
@@ -71491,14 +71795,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
71491
71795
|
didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = true, console.error("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"));
|
|
71492
71796
|
});
|
|
71493
71797
|
return {
|
|
71494
|
-
then: function(
|
|
71798
|
+
then: function(resolve18, reject) {
|
|
71495
71799
|
didAwaitActCall = true;
|
|
71496
71800
|
thenable.then(function(returnValue) {
|
|
71497
71801
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
71498
71802
|
if (prevActScopeDepth === 0) {
|
|
71499
71803
|
try {
|
|
71500
71804
|
flushActQueue(queue), enqueueTask(function() {
|
|
71501
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
71805
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve18, reject);
|
|
71502
71806
|
});
|
|
71503
71807
|
} catch (error$0) {
|
|
71504
71808
|
ReactSharedInternals.thrownErrors.push(error$0);
|
|
@@ -71509,7 +71813,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
71509
71813
|
reject(_thrownError);
|
|
71510
71814
|
}
|
|
71511
71815
|
} else
|
|
71512
|
-
|
|
71816
|
+
resolve18(returnValue);
|
|
71513
71817
|
}, function(error48) {
|
|
71514
71818
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
71515
71819
|
0 < ReactSharedInternals.thrownErrors.length ? (error48 = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(error48)) : reject(error48);
|
|
@@ -71525,11 +71829,11 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
71525
71829
|
if (0 < ReactSharedInternals.thrownErrors.length)
|
|
71526
71830
|
throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
|
|
71527
71831
|
return {
|
|
71528
|
-
then: function(
|
|
71832
|
+
then: function(resolve18, reject) {
|
|
71529
71833
|
didAwaitActCall = true;
|
|
71530
71834
|
prevActScopeDepth === 0 ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
|
|
71531
|
-
return recursivelyFlushAsyncActWork(returnValue$jscomp$0,
|
|
71532
|
-
})) :
|
|
71835
|
+
return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve18, reject);
|
|
71836
|
+
})) : resolve18(returnValue$jscomp$0);
|
|
71533
71837
|
}
|
|
71534
71838
|
};
|
|
71535
71839
|
};
|
|
@@ -74371,8 +74675,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
74371
74675
|
currentEntangledActionThenable = {
|
|
74372
74676
|
status: "pending",
|
|
74373
74677
|
value: undefined,
|
|
74374
|
-
then: function(
|
|
74375
|
-
entangledListeners.push(
|
|
74678
|
+
then: function(resolve18) {
|
|
74679
|
+
entangledListeners.push(resolve18);
|
|
74376
74680
|
}
|
|
74377
74681
|
};
|
|
74378
74682
|
}
|
|
@@ -74396,8 +74700,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
74396
74700
|
status: "pending",
|
|
74397
74701
|
value: null,
|
|
74398
74702
|
reason: null,
|
|
74399
|
-
then: function(
|
|
74400
|
-
listeners.push(
|
|
74703
|
+
then: function(resolve18) {
|
|
74704
|
+
listeners.push(resolve18);
|
|
74401
74705
|
}
|
|
74402
74706
|
};
|
|
74403
74707
|
thenable.then(function() {
|
|
@@ -106460,7 +106764,7 @@ function ansiRegex({ onlyFirst = false } = {}) {
|
|
|
106460
106764
|
|
|
106461
106765
|
// node_modules/strip-ansi/index.js
|
|
106462
106766
|
var regex = ansiRegex();
|
|
106463
|
-
function
|
|
106767
|
+
function stripAnsi2(string4) {
|
|
106464
106768
|
if (typeof string4 !== "string") {
|
|
106465
106769
|
throw new TypeError(`Expected a \`string\`, got \`${typeof string4}\``);
|
|
106466
106770
|
}
|
|
@@ -106509,7 +106813,7 @@ function stringWidth(string4, options = {}) {
|
|
|
106509
106813
|
countAnsiEscapeCodes = false
|
|
106510
106814
|
} = options;
|
|
106511
106815
|
if (!countAnsiEscapeCodes) {
|
|
106512
|
-
string4 =
|
|
106816
|
+
string4 = stripAnsi2(string4);
|
|
106513
106817
|
}
|
|
106514
106818
|
if (string4.length === 0) {
|
|
106515
106819
|
return 0;
|
|
@@ -106740,7 +107044,7 @@ var wrapWord = (rows, word, columns) => {
|
|
|
106740
107044
|
const characters = [...word];
|
|
106741
107045
|
let isInsideEscape = false;
|
|
106742
107046
|
let isInsideLinkEscape = false;
|
|
106743
|
-
let visible = stringWidth(
|
|
107047
|
+
let visible = stringWidth(stripAnsi2(rows.at(-1)));
|
|
106744
107048
|
for (const [index, character] of characters.entries()) {
|
|
106745
107049
|
const characterLength = stringWidth(character);
|
|
106746
107050
|
if (visible + characterLength <= columns) {
|
|
@@ -107026,7 +107330,7 @@ function stringWidth2(input, options = {}) {
|
|
|
107026
107330
|
} = options;
|
|
107027
107331
|
let string4 = input;
|
|
107028
107332
|
if (!countAnsiEscapeCodes) {
|
|
107029
|
-
string4 =
|
|
107333
|
+
string4 = stripAnsi2(string4);
|
|
107030
107334
|
}
|
|
107031
107335
|
if (string4.length === 0) {
|
|
107032
107336
|
return 0;
|
|
@@ -109906,8 +110210,8 @@ class Ink {
|
|
|
109906
110210
|
}
|
|
109907
110211
|
}
|
|
109908
110212
|
async waitUntilExit() {
|
|
109909
|
-
this.exitPromise ||= new Promise((
|
|
109910
|
-
this.resolveExitPromise =
|
|
110213
|
+
this.exitPromise ||= new Promise((resolve18, reject2) => {
|
|
110214
|
+
this.resolveExitPromise = resolve18;
|
|
109911
110215
|
this.rejectExitPromise = reject2;
|
|
109912
110216
|
});
|
|
109913
110217
|
if (!this.beforeExitHandler) {
|
|
@@ -112161,7 +112465,7 @@ async function promptForConfirmation(question) {
|
|
|
112161
112465
|
if (!process.stdin.isTTY) {
|
|
112162
112466
|
return true;
|
|
112163
112467
|
}
|
|
112164
|
-
return new Promise((
|
|
112468
|
+
return new Promise((resolve18) => {
|
|
112165
112469
|
process.stdout.write(source_default.bold(`${question} [Y/n] `));
|
|
112166
112470
|
process.stdin.setRawMode(true);
|
|
112167
112471
|
process.stdin.resume();
|
|
@@ -112174,9 +112478,9 @@ async function promptForConfirmation(question) {
|
|
|
112174
112478
|
process.stdout.write(`
|
|
112175
112479
|
`);
|
|
112176
112480
|
if (answer === "n") {
|
|
112177
|
-
|
|
112481
|
+
resolve18(false);
|
|
112178
112482
|
} else {
|
|
112179
|
-
|
|
112483
|
+
resolve18(true);
|
|
112180
112484
|
}
|
|
112181
112485
|
};
|
|
112182
112486
|
process.stdin.on("data", handler);
|