@wrongstack/tools 0.319.0 → 0.320.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/_edit-match.d.ts +1 -3
- package/dist/_util.d.ts +7 -0
- package/dist/audit.js +8 -8
- package/dist/bash.js +6 -6
- package/dist/browser/index.js +1 -1
- package/dist/builtin.d.ts +10 -0
- package/dist/builtin.js +54 -52
- package/dist/{chunk-65EMYN5G.js → chunk-23EX5WDO.js} +6 -3
- package/dist/{chunk-2472NT76.js → chunk-2OXHS3KZ.js} +17 -5
- package/dist/{chunk-7WV3D4S3.js → chunk-34VLZ35Z.js} +75 -36
- package/dist/{chunk-MYRMD6PZ.js → chunk-3GIKYHLA.js} +32 -8
- package/dist/{chunk-X5K3U6GI.js → chunk-3M7LLN7W.js} +71 -7
- package/dist/{chunk-VALQFAY2.js → chunk-4BABEJC2.js} +158 -45
- package/dist/{chunk-42BHI7TN.js → chunk-4CQWNZ62.js} +2 -2
- package/dist/{chunk-WNUJR3H4.js → chunk-5UFVCIUB.js} +40 -16
- package/dist/{chunk-UMXVT7ST.js → chunk-6AAOT4PW.js} +58 -10
- package/dist/{chunk-H6AWAZ2Y.js → chunk-B4HTSV6Z.js} +57 -6
- package/dist/{chunk-5ZYEGP2P.js → chunk-BK732J7I.js} +72 -27
- package/dist/{chunk-KD5EHYA2.js → chunk-C2DQKVLO.js} +61 -28
- package/dist/{chunk-Z4VBTVUM.js → chunk-DFQDJT22.js} +99 -12
- package/dist/{chunk-6RNIFLG4.js → chunk-ELRRTWNP.js} +38 -6
- package/dist/{chunk-3PVYQFRQ.js → chunk-ESLPBT5A.js} +2 -1
- package/dist/{chunk-YZHK4TLF.js → chunk-FQNXYA6W.js} +45 -6
- package/dist/{chunk-OYVPBPCL.js → chunk-HR67OWEP.js} +72 -33
- package/dist/{chunk-ZDUGI5BC.js → chunk-I7FBZOEP.js} +2 -2
- package/dist/{chunk-HBM4QNXU.js → chunk-IU4DV2PA.js} +18 -8
- package/dist/{chunk-TFMVHYJI.js → chunk-J43O3BOX.js} +9 -15
- package/dist/{chunk-ODFVG54U.js → chunk-J74TMK4M.js} +37 -13
- package/dist/{chunk-COUNXG4X.js → chunk-JLYA4X7K.js} +75 -8
- package/dist/{chunk-FQZOHLG3.js → chunk-JSNSMG5R.js} +3 -2
- package/dist/{chunk-SYXW3Y5Z.js → chunk-JVRLTEO7.js} +2 -2
- package/dist/{chunk-V43EQ6VR.js → chunk-KE7A76VC.js} +3 -2
- package/dist/{chunk-ZKSBHXVB.js → chunk-KWXIKGE3.js} +64 -15
- package/dist/{chunk-RK47IWO3.js → chunk-LRDIRJJL.js} +62 -30
- package/dist/{chunk-UC3RKRIV.js → chunk-NDIT3SBZ.js} +3 -3
- package/dist/{chunk-C3W3V54D.js → chunk-NSPNFOJ7.js} +57 -27
- package/dist/{chunk-TX3R5NVV.js → chunk-NU2IZ72J.js} +7 -7
- package/dist/{chunk-WHIIIREL.js → chunk-NYRLWDT5.js} +7 -3
- package/dist/{chunk-PMHVSHMU.js → chunk-OTPTQBYE.js} +80 -19
- package/dist/{chunk-ZHH3BEWU.js → chunk-OYP27E3I.js} +4 -4
- package/dist/{chunk-W4GAAI3M.js → chunk-PV6HIZQD.js} +2 -2
- package/dist/{chunk-NKNOBUBU.js → chunk-QGF2C7TF.js} +2 -2
- package/dist/{chunk-PQTONQ4P.js → chunk-QPNYDH5B.js} +19 -5
- package/dist/{chunk-VFF3Q5Z3.js → chunk-QSNVDHOZ.js} +37 -9
- package/dist/{chunk-45JPRMC2.js → chunk-QWKSKFKZ.js} +7 -3
- package/dist/{chunk-2VSZC6QM.js → chunk-SCMRM6NL.js} +6 -4
- package/dist/{chunk-RJZQWEMS.js → chunk-T77XOX7E.js} +3 -2
- package/dist/{chunk-QZDOQRF7.js → chunk-UZFY3CKD.js} +35 -14
- package/dist/{chunk-D4CXUZIF.js → chunk-VD2LV5WO.js} +82 -13
- package/dist/{chunk-DPKTXJQS.js → chunk-VPALDFYM.js} +2 -2
- package/dist/{chunk-IIF5HIVF.js → chunk-VVZPQPTY.js} +2 -2
- package/dist/{chunk-HWDB2G7J.js → chunk-W232EFEM.js} +49 -36
- package/dist/{chunk-FJEQZHZN.js → chunk-W2CECGTG.js} +24 -14
- package/dist/{chunk-4Q7LFU4T.js → chunk-WAQASTXB.js} +20 -9
- package/dist/{chunk-CWALNI6K.js → chunk-X6KXNHUO.js} +1 -1
- package/dist/{chunk-OCUXN6Y3.js → chunk-XRNN44QY.js} +1 -1
- package/dist/{chunk-N5O3FK5Q.js → chunk-XSSFBS5I.js} +70 -29
- package/dist/{chunk-Y7QXSE7N.js → chunk-YTKSNTT4.js} +44 -10
- package/dist/{chunk-MRKWZCHZ.js → chunk-Z5Q3TXRY.js} +3 -3
- package/dist/{chunk-PRXZOIEW.js → chunk-Z6IHMJMC.js} +104 -59
- package/dist/{chunk-NWZ6XGBJ.js → chunk-ZBMANLYH.js} +5 -3
- package/dist/{chunk-OJ4FIBAN.js → chunk-ZMW6WJFT.js} +30 -23
- package/dist/{chunk-QLF74MSV.js → chunk-ZUFHAHTE.js} +12 -6
- package/dist/codebase-index/index.js +12 -12
- package/dist/codebase-index/parser-worker-script.js +3 -3
- package/dist/codebase-index/project-server.js +5 -5
- package/dist/codebase-index/worker.js +4 -4
- package/dist/design.d.ts +1 -1
- package/dist/design.js +1 -1
- package/dist/diff.js +3 -2
- package/dist/document.js +2 -2
- package/dist/e2e.js +2 -2
- package/dist/edit.js +9 -9
- package/dist/exec.js +6 -6
- package/dist/fetch.js +2 -2
- package/dist/format.js +8 -8
- package/dist/git.js +2 -2
- package/dist/glob.js +3 -3
- package/dist/{go-parser-IKHW67WE.js → go-parser-D7ELWQ7F.js} +2 -2
- package/dist/grep.d.ts +2 -0
- package/dist/grep.js +5 -3
- package/dist/index.js +56 -56
- package/dist/install.js +8 -8
- package/dist/{json-parser-2EOVP5MR.js → json-parser-34DHYCPW.js} +1 -18
- package/dist/json.js +2 -2
- package/dist/kanban-tool-types.d.ts +2 -0
- package/dist/kanban.js +2 -2
- package/dist/languages/index.js +6 -6
- package/dist/legacy-bridge-FOV5ODDI.js +18 -0
- package/dist/lint.js +8 -8
- package/dist/logs.js +2 -2
- package/dist/memory.js +1 -1
- package/dist/next-steps.d.ts +7 -0
- package/dist/next-steps.js +82 -38
- package/dist/outdated.js +5 -3
- package/dist/pack.js +53 -53
- package/dist/{parser-dispatch-3PDBKIQ7.js → parser-dispatch-BDVCJXTV.js} +4 -4
- package/dist/patch.js +8 -8
- package/dist/plan.js +4 -4
- package/dist/process-registry.js +1 -1
- package/dist/ps-slash.js +3 -3
- package/dist/{py-parser-RFWG2HYI.js → py-parser-QC6MR4GB.js} +3 -3
- package/dist/read.js +8 -8
- package/dist/replace.js +9 -8
- package/dist/scaffold.js +2 -2
- package/dist/search.js +1 -1
- package/dist/session-kanban.js +1 -1
- package/dist/task.js +4 -4
- package/dist/test.js +8 -8
- package/dist/todo.js +3 -3
- package/dist/tool-search.js +1 -1
- package/dist/tool-tier.js +54 -54
- package/dist/{tree-sitter-parser-FGKHJGSX.js → tree-sitter-parser-GILYQLS4.js} +2 -2
- package/dist/tree.js +2 -2
- package/dist/typecheck.js +8 -8
- package/dist/win32.js +1 -1
- package/dist/write.js +9 -9
- package/package.json +5 -5
- package/dist/legacy-bridge-EC7GM2IW.js +0 -18
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
} from "./chunk-Q5JPPCZC.js";
|
|
5
5
|
import {
|
|
6
6
|
mapWithConcurrency
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZBMANLYH.js";
|
|
8
8
|
import {
|
|
9
9
|
loadGitignoreMatcher
|
|
10
10
|
} from "./chunk-DTQ75VBC.js";
|
|
11
11
|
import {
|
|
12
12
|
isBinaryBuffer,
|
|
13
13
|
safeResolveReal
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
15
15
|
|
|
16
16
|
// src/grep.ts
|
|
17
17
|
import { spawn } from "node:child_process";
|
|
@@ -99,7 +99,8 @@ var grepTool = {
|
|
|
99
99
|
}
|
|
100
100
|
const base = input.path ? await safeResolveReal(input.path, ctx) : ctx.cwd;
|
|
101
101
|
const mode = input.output_mode ?? "content";
|
|
102
|
-
const
|
|
102
|
+
const rawLimit = typeof input.limit === "number" && Number.isFinite(input.limit) ? input.limit : 200;
|
|
103
|
+
const limit = Math.max(1, Math.min(Math.floor(rawLimit), 2e3));
|
|
103
104
|
const validation = compileUserRegex(input.pattern, input.case_insensitive ? "i" : "");
|
|
104
105
|
if (!validation.ok) {
|
|
105
106
|
throw new ToolValidationError({
|
|
@@ -125,6 +126,9 @@ var rgAvailabilityCache;
|
|
|
125
126
|
function __resetRgDetectionForTests() {
|
|
126
127
|
rgAvailabilityCache = void 0;
|
|
127
128
|
}
|
|
129
|
+
function __setRgAvailableForTests(available) {
|
|
130
|
+
rgAvailabilityCache = available !== void 0 ? Promise.resolve(available) : void 0;
|
|
131
|
+
}
|
|
128
132
|
function detectRg() {
|
|
129
133
|
rgAvailabilityCache ??= new Promise((resolve) => {
|
|
130
134
|
try {
|
|
@@ -143,7 +147,19 @@ function detectRg() {
|
|
|
143
147
|
return rgAvailabilityCache;
|
|
144
148
|
}
|
|
145
149
|
async function* runRgStream(input, base, mode, limit, signal) {
|
|
146
|
-
|
|
150
|
+
if (signal.aborted) {
|
|
151
|
+
yield {
|
|
152
|
+
type: "final",
|
|
153
|
+
output: {
|
|
154
|
+
matches: [],
|
|
155
|
+
count: 0,
|
|
156
|
+
truncated: false,
|
|
157
|
+
used: "rg"
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const args = ["--no-heading", "--with-filename"];
|
|
147
163
|
if (input.case_insensitive) args.push("-i");
|
|
148
164
|
if (mode === "files_with_matches") args.push("-l");
|
|
149
165
|
if (mode === "count") args.push("-c");
|
|
@@ -161,7 +177,14 @@ async function* runRgStream(input, base, mode, limit, signal) {
|
|
|
161
177
|
)) {
|
|
162
178
|
args.push("--ignore-file", gitignorePath);
|
|
163
179
|
}
|
|
164
|
-
if (input.glob)
|
|
180
|
+
if (input.glob) {
|
|
181
|
+
const g = input.glob.trim();
|
|
182
|
+
if (g.startsWith("!") || g.startsWith("**/") || g.startsWith("*")) {
|
|
183
|
+
args.push("--glob", g);
|
|
184
|
+
} else {
|
|
185
|
+
args.push("--glob", `**/${g}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
165
188
|
args.push("--", input.pattern, base);
|
|
166
189
|
const matches = [];
|
|
167
190
|
let buf = "";
|
|
@@ -319,11 +342,22 @@ async function* runRgStream(input, base, mode, limit, signal) {
|
|
|
319
342
|
}
|
|
320
343
|
function parseRgCountLine(line) {
|
|
321
344
|
const idx = line.lastIndexOf(":");
|
|
322
|
-
if (idx === -1)
|
|
345
|
+
if (idx === -1) {
|
|
346
|
+
const direct = Number.parseInt(line.trim(), 10);
|
|
347
|
+
return Number.isFinite(direct) ? direct : 0;
|
|
348
|
+
}
|
|
323
349
|
const n = Number.parseInt(line.slice(idx + 1), 10);
|
|
324
350
|
return Number.isFinite(n) ? n : 0;
|
|
325
351
|
}
|
|
326
352
|
async function runNative(input, base, mode, limit, signal) {
|
|
353
|
+
if (signal.aborted) {
|
|
354
|
+
return {
|
|
355
|
+
matches: [],
|
|
356
|
+
count: 0,
|
|
357
|
+
truncated: false,
|
|
358
|
+
used: "native"
|
|
359
|
+
};
|
|
360
|
+
}
|
|
327
361
|
const flags = input.case_insensitive ? "i" : "";
|
|
328
362
|
const compiled = compileUserRegex(input.pattern, flags);
|
|
329
363
|
if (!compiled.ok) {
|
|
@@ -337,13 +371,19 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
337
371
|
const isGitIgnored = await loadGitignoreMatcher(base);
|
|
338
372
|
const matches = [];
|
|
339
373
|
const countOnlyFirstHit = mode === "count" && limit === 1;
|
|
340
|
-
const maxBytes =
|
|
374
|
+
const maxBytes = NATIVE_MAX_FILE_BYTES;
|
|
341
375
|
let total = 0;
|
|
342
376
|
let stopped = false;
|
|
343
|
-
const scanFile = async (full, name) => {
|
|
377
|
+
const scanFile = async (full, name, rel) => {
|
|
344
378
|
if (stopped || signal.aborted) return;
|
|
345
|
-
if (globRe
|
|
346
|
-
|
|
379
|
+
if (globRe) {
|
|
380
|
+
globRe.lastIndex = 0;
|
|
381
|
+
const normRel = rel.replace(/\\/g, "/");
|
|
382
|
+
const normFull = full.replace(/\\/g, "/");
|
|
383
|
+
const matchesGlob = globRe.test(name) || globRe.test(normRel) || globRe.test(normFull);
|
|
384
|
+
globRe.lastIndex = 0;
|
|
385
|
+
if (!matchesGlob) return;
|
|
386
|
+
}
|
|
347
387
|
try {
|
|
348
388
|
const stat2 = await fs.stat(full);
|
|
349
389
|
if (!stat2.isFile() || stat2.size > maxBytes || stopped || signal.aborted) return;
|
|
@@ -376,8 +416,8 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
376
416
|
for (const rawLine of lines) {
|
|
377
417
|
if (stopped || signal.aborted) break;
|
|
378
418
|
lineNumber++;
|
|
379
|
-
const ln = capSubject(rawLine);
|
|
380
|
-
re.lastIndex = 0;
|
|
419
|
+
const ln = rawLine.length > 4096 ? capSubject(rawLine) : rawLine;
|
|
420
|
+
if (re.global || re.sticky) re.lastIndex = 0;
|
|
381
421
|
if (!re.test(ln)) continue;
|
|
382
422
|
fileHits++;
|
|
383
423
|
total++;
|
|
@@ -386,10 +426,8 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
386
426
|
} else if (mode === "files_with_matches") {
|
|
387
427
|
if (fileHits === 1 && matches.length < limit) matches.push(full);
|
|
388
428
|
break;
|
|
389
|
-
} else if (fileHits === 1 && matches.length < limit) {
|
|
390
|
-
matches.push(`${full}:${countOnlyFirstHit ? 1 : 0}`);
|
|
391
429
|
}
|
|
392
|
-
if (countOnlyFirstHit || mode
|
|
430
|
+
if (countOnlyFirstHit || mode === "content" && matches.length >= limit) {
|
|
393
431
|
stopped = true;
|
|
394
432
|
break;
|
|
395
433
|
}
|
|
@@ -398,8 +436,8 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
398
436
|
}
|
|
399
437
|
if (!stopped && !signal.aborted && leftover.length > 0) {
|
|
400
438
|
lineNumber++;
|
|
401
|
-
const ln = capSubject(leftover);
|
|
402
|
-
re.lastIndex = 0;
|
|
439
|
+
const ln = leftover.length > 4096 ? capSubject(leftover) : leftover;
|
|
440
|
+
if (re.global || re.sticky) re.lastIndex = 0;
|
|
403
441
|
if (re.test(ln)) {
|
|
404
442
|
fileHits++;
|
|
405
443
|
total++;
|
|
@@ -407,21 +445,17 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
407
445
|
if (matches.length < limit) matches.push(`${full}:${lineNumber}:${ln}`);
|
|
408
446
|
} else if (mode === "files_with_matches") {
|
|
409
447
|
if (matches.length < limit) matches.push(full);
|
|
410
|
-
} else if (matches.length < limit) {
|
|
411
|
-
matches.push(`${full}:${countOnlyFirstHit ? 1 : fileHits}`);
|
|
412
448
|
}
|
|
413
449
|
}
|
|
414
450
|
}
|
|
415
451
|
if (fileHits > 0) {
|
|
416
|
-
if (mode === "count") {
|
|
417
|
-
|
|
418
|
-
if (idx !== -1) matches[idx] = `${full}:${fileHits}`;
|
|
452
|
+
if (mode === "count" && matches.length < limit) {
|
|
453
|
+
matches.push(`${full}:${fileHits}`);
|
|
419
454
|
}
|
|
420
455
|
if (mode === "files_with_matches" && matches.length >= limit) stopped = true;
|
|
421
456
|
}
|
|
422
457
|
if (mode === "content" && matches.length >= limit) stopped = true;
|
|
423
|
-
if (mode === "count" && matches.length >= limit &&
|
|
424
|
-
stopped = true;
|
|
458
|
+
if (mode === "count" && matches.length >= limit && countOnlyFirstHit) stopped = true;
|
|
425
459
|
} finally {
|
|
426
460
|
await file.close();
|
|
427
461
|
}
|
|
@@ -449,13 +483,13 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
449
483
|
subdirs.push({ full, rel });
|
|
450
484
|
} else if (e.isFile()) {
|
|
451
485
|
if (isGitIgnored(rel, false)) continue;
|
|
452
|
-
files.push({ full, name: e.name });
|
|
486
|
+
files.push({ full, name: e.name, rel });
|
|
453
487
|
}
|
|
454
488
|
}
|
|
455
489
|
await mapWithConcurrency(
|
|
456
490
|
files,
|
|
457
491
|
NATIVE_SCAN_CONCURRENCY,
|
|
458
|
-
({ full, name }) => scanFile(full, name)
|
|
492
|
+
({ full, name, rel }) => scanFile(full, name, rel)
|
|
459
493
|
);
|
|
460
494
|
await mapWithConcurrency(
|
|
461
495
|
subdirs,
|
|
@@ -463,7 +497,13 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
463
497
|
({ full, rel }) => walk(full, rel)
|
|
464
498
|
);
|
|
465
499
|
};
|
|
466
|
-
await
|
|
500
|
+
const baseStat = await fs.stat(base).catch(() => null);
|
|
501
|
+
if (baseStat?.isFile()) {
|
|
502
|
+
const rel = input.path ? input.path.replace(/\\/g, "/") : path.basename(base);
|
|
503
|
+
await scanFile(base, path.basename(base), rel);
|
|
504
|
+
} else {
|
|
505
|
+
await walk(base, "");
|
|
506
|
+
}
|
|
467
507
|
return {
|
|
468
508
|
matches,
|
|
469
509
|
count: total,
|
|
@@ -474,6 +514,7 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
474
514
|
|
|
475
515
|
export {
|
|
476
516
|
grepTool,
|
|
477
|
-
__resetRgDetectionForTests
|
|
517
|
+
__resetRgDetectionForTests,
|
|
518
|
+
__setRgAvailableForTests
|
|
478
519
|
};
|
|
479
|
-
//# sourceMappingURL=chunk-
|
|
520
|
+
//# sourceMappingURL=chunk-XSSFBS5I.js.map
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
tryLegacyCodeOperation
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-I7FBZOEP.js";
|
|
4
4
|
import {
|
|
5
5
|
spawnStream
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OYP27E3I.js";
|
|
7
7
|
import {
|
|
8
8
|
normalizeCommandOutput,
|
|
9
9
|
safeResolveReal
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
11
11
|
|
|
12
12
|
// src/test.ts
|
|
13
13
|
import * as path from "node:path";
|
|
14
|
+
import { ToolValidationError } from "@wrongstack/core/types";
|
|
14
15
|
var testTool = {
|
|
15
16
|
name: "test",
|
|
16
17
|
category: "Code Quality",
|
|
@@ -57,6 +58,14 @@ var testTool = {
|
|
|
57
58
|
async *executeStream(input, ctx, opts) {
|
|
58
59
|
const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
|
|
59
60
|
const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
|
|
61
|
+
signal.throwIfAborted();
|
|
62
|
+
const VALID_RUNNERS = /* @__PURE__ */ new Set(["vitest", "jest", "mocha", "auto", "none"]);
|
|
63
|
+
if (input.runner !== void 0 && !VALID_RUNNERS.has(input.runner)) {
|
|
64
|
+
throw new ToolValidationError({
|
|
65
|
+
message: `test: unsupported runner "${input.runner}". Allowed runners: vitest, jest, mocha, auto, none`,
|
|
66
|
+
field: "runner"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
60
69
|
const runner = input.runner ?? "auto";
|
|
61
70
|
if (runner === "auto") {
|
|
62
71
|
const bridge = await tryLegacyCodeOperation("test", {
|
|
@@ -83,7 +92,7 @@ var testTool = {
|
|
|
83
92
|
}
|
|
84
93
|
}
|
|
85
94
|
const detected = runner === "auto" ? await detectRunner(cwd) : runner;
|
|
86
|
-
if (!detected) {
|
|
95
|
+
if (!detected || detected === "none") {
|
|
87
96
|
yield {
|
|
88
97
|
type: "final",
|
|
89
98
|
output: {
|
|
@@ -115,7 +124,21 @@ var testTool = {
|
|
|
115
124
|
};
|
|
116
125
|
async function detectRunner(cwd) {
|
|
117
126
|
const { stat } = await import("node:fs/promises");
|
|
118
|
-
const candidates = [
|
|
127
|
+
const candidates = [
|
|
128
|
+
"vitest.config.ts",
|
|
129
|
+
"vitest.config.js",
|
|
130
|
+
"vitest.config.mjs",
|
|
131
|
+
"vitest.config.mts",
|
|
132
|
+
"vitest.config.cjs",
|
|
133
|
+
"vitest.config.cts",
|
|
134
|
+
"jest.config.ts",
|
|
135
|
+
"jest.config.js",
|
|
136
|
+
"jest.config.mjs",
|
|
137
|
+
"jest.config.cjs",
|
|
138
|
+
".mocharc.json",
|
|
139
|
+
".mocharc.js",
|
|
140
|
+
".mocharc.cjs"
|
|
141
|
+
];
|
|
119
142
|
for (const f of candidates) {
|
|
120
143
|
try {
|
|
121
144
|
await stat(path.join(cwd, f));
|
|
@@ -129,7 +152,8 @@ async function detectRunner(cwd) {
|
|
|
129
152
|
}
|
|
130
153
|
function buildArgs(runner, input) {
|
|
131
154
|
const args = [];
|
|
132
|
-
const
|
|
155
|
+
const rawTimeout = typeof input.timeout === "number" && Number.isFinite(input.timeout) && input.timeout > 0 ? Math.floor(input.timeout) : 3e4;
|
|
156
|
+
const timeout = Math.max(100, rawTimeout);
|
|
133
157
|
switch (runner) {
|
|
134
158
|
case "vitest":
|
|
135
159
|
args.push(input.watch ? "watch" : "run");
|
|
@@ -152,8 +176,10 @@ function buildArgs(runner, input) {
|
|
|
152
176
|
break;
|
|
153
177
|
}
|
|
154
178
|
if (input.files) {
|
|
155
|
-
const files = Array.isArray(input.files) ? input.files : input.files.split(",");
|
|
156
|
-
|
|
179
|
+
const files = (Array.isArray(input.files) ? input.files : input.files.split(",")).map((f) => f.trim().replace(/\\/g, "/")).filter(Boolean);
|
|
180
|
+
if (files.length > 0) {
|
|
181
|
+
args.push("--", ...files);
|
|
182
|
+
}
|
|
157
183
|
}
|
|
158
184
|
return args;
|
|
159
185
|
}
|
|
@@ -175,7 +201,15 @@ function parseResult(runner, result, duration) {
|
|
|
175
201
|
tests_run = Number.parseInt(suitesMatch?.[1] ?? "0", 10);
|
|
176
202
|
passed = Number.parseInt(passedMatch?.[1] ?? "0", 10);
|
|
177
203
|
failed = Number.parseInt(failedMatch?.[1] ?? "0", 10);
|
|
204
|
+
} else if (runner === "mocha") {
|
|
205
|
+
const passedMatch = out.match(/(\d+)\s+passing/);
|
|
206
|
+
const failedMatch = out.match(/(\d+)\s+failing/);
|
|
207
|
+
if (passedMatch?.[1]) passed = Number.parseInt(passedMatch[1], 10);
|
|
208
|
+
if (failedMatch?.[1]) failed = Number.parseInt(failedMatch[1], 10);
|
|
209
|
+
tests_run = passed + failed;
|
|
178
210
|
}
|
|
211
|
+
const rawOutput = result.stdout && result.stderr ? `${result.stdout}
|
|
212
|
+
${result.stderr}` : result.stdout || result.stderr || result.error || "";
|
|
179
213
|
return {
|
|
180
214
|
runner,
|
|
181
215
|
exit_code: result.exitCode,
|
|
@@ -187,7 +221,7 @@ function parseResult(runner, result, duration) {
|
|
|
187
221
|
// already parsed above and the FULL log is on disk (spool marker rides
|
|
188
222
|
// the stdout tail). Failures keep the standard command-output cap so
|
|
189
223
|
// the agent sees the failure details inline.
|
|
190
|
-
output: normalizeCommandOutput(
|
|
224
|
+
output: normalizeCommandOutput(rawOutput, {
|
|
191
225
|
maxBytes: result.exitCode === 0 ? 4096 : void 0
|
|
192
226
|
}),
|
|
193
227
|
truncated: result.truncated
|
|
@@ -197,4 +231,4 @@ function parseResult(runner, result, duration) {
|
|
|
197
231
|
export {
|
|
198
232
|
testTool
|
|
199
233
|
};
|
|
200
|
-
//# sourceMappingURL=chunk-
|
|
234
|
+
//# sourceMappingURL=chunk-YTKSNTT4.js.map
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
projectIndexServerBuildId,
|
|
10
10
|
projectIndexServerEndpoint,
|
|
11
11
|
projectIndexServerMetadataPath
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PV6HIZQD.js";
|
|
13
13
|
import {
|
|
14
14
|
CircuitOpenError,
|
|
15
15
|
IndexTimeoutError,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
searchService,
|
|
25
25
|
statsService,
|
|
26
26
|
symbolGraphService
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-J43O3BOX.js";
|
|
28
28
|
import {
|
|
29
29
|
isIndexablePath
|
|
30
30
|
} from "./chunk-YOHO4DVT.js";
|
|
@@ -1269,4 +1269,4 @@ export {
|
|
|
1269
1269
|
checkCodebaseIndexServerHealth,
|
|
1270
1270
|
ensureCodebaseIndexServer
|
|
1271
1271
|
};
|
|
1272
|
-
//# sourceMappingURL=chunk-
|
|
1272
|
+
//# sourceMappingURL=chunk-Z5Q3TXRY.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
checkSyntax
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JSNSMG5R.js";
|
|
4
4
|
import {
|
|
5
5
|
enqueueReindex
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-Z5Q3TXRY.js";
|
|
7
7
|
import {
|
|
8
8
|
safeResolveReal,
|
|
9
9
|
sha256hex,
|
|
10
10
|
truncateDiffPayload
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
12
12
|
|
|
13
13
|
// src/edit.ts
|
|
14
14
|
import * as fs from "node:fs/promises";
|
|
@@ -39,45 +39,55 @@ var FUZZY_MIN_SIMILARITY = 0.9;
|
|
|
39
39
|
var FUZZY_AMBIGUITY_MARGIN = 0.05;
|
|
40
40
|
var FUZZY_MAX_INTERIOR_CHARS = 2e3;
|
|
41
41
|
function findLadderMatches(fileLf, oldLf) {
|
|
42
|
+
if (typeof fileLf !== "string" || typeof oldLf !== "string" || oldLf.length === 0) {
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
42
45
|
const exact = [];
|
|
43
46
|
let idx = fileLf.indexOf(oldLf);
|
|
47
|
+
let currentLine = 1;
|
|
48
|
+
let lastPos = 0;
|
|
44
49
|
while (idx !== -1) {
|
|
45
|
-
|
|
50
|
+
while (lastPos < idx) {
|
|
51
|
+
const nextNewline = fileLf.indexOf("\n", lastPos);
|
|
52
|
+
if (nextNewline === -1 || nextNewline >= idx) break;
|
|
53
|
+
currentLine++;
|
|
54
|
+
lastPos = nextNewline + 1;
|
|
55
|
+
}
|
|
56
|
+
exact.push({ start: idx, end: idx + oldLf.length, startLine: currentLine });
|
|
46
57
|
idx = fileLf.indexOf(oldLf, idx + 1);
|
|
47
58
|
}
|
|
48
59
|
if (exact.length > 0) return { tier: "exact", matches: exact };
|
|
49
60
|
const fileLines = fileLf.split("\n");
|
|
50
|
-
const
|
|
51
|
-
|
|
61
|
+
const needleEndsWithNewline = oldLf.endsWith("\n");
|
|
62
|
+
const rawNeedleLines = oldLf.split("\n");
|
|
63
|
+
const needleLines = needleEndsWithNewline && rawNeedleLines[rawNeedleLines.length - 1] === "" ? rawNeedleLines.slice(0, -1) : rawNeedleLines;
|
|
64
|
+
if (needleLines.length === 0 || needleLines.length > fileLines.length) return void 0;
|
|
52
65
|
const offsets = lineOffsets(fileLines);
|
|
53
66
|
const fileTrimEnd = fileLines.map((l) => l.trimEnd());
|
|
54
67
|
const needleTrimEnd = needleLines.map((l) => l.trimEnd());
|
|
55
|
-
const trailing = windowScan(
|
|
68
|
+
const trailing = windowScan(
|
|
69
|
+
fileTrimEnd,
|
|
70
|
+
needleTrimEnd,
|
|
71
|
+
offsets,
|
|
72
|
+
fileLines,
|
|
73
|
+
(a, b) => a === b,
|
|
74
|
+
needleEndsWithNewline
|
|
75
|
+
);
|
|
56
76
|
if (trailing.length > 0) return { tier: "trailing-whitespace", matches: trailing };
|
|
57
77
|
const normalizedLen = needleTrimEnd.reduce((n, l) => n + l.trimStart().length, 0);
|
|
58
78
|
if (normalizedLen < MIN_NORMALIZED_NEEDLE_CHARS) return void 0;
|
|
59
79
|
const fileTrimmed = fileTrimEnd.map((l) => l.trimStart());
|
|
60
80
|
const needleTrimmed = needleTrimEnd.map((l) => l.trimStart());
|
|
61
|
-
const normalized = windowScan(
|
|
81
|
+
const normalized = windowScan(
|
|
82
|
+
fileTrimmed,
|
|
83
|
+
needleTrimmed,
|
|
84
|
+
offsets,
|
|
85
|
+
fileLines,
|
|
86
|
+
(a, b) => a === b,
|
|
87
|
+
needleEndsWithNewline
|
|
88
|
+
);
|
|
62
89
|
if (normalized.length > 0) return { tier: "whitespace-normalized", matches: normalized };
|
|
63
|
-
return fuzzyScan(fileLines, needleLines, offsets);
|
|
64
|
-
}
|
|
65
|
-
function lineAt(text, pos) {
|
|
66
|
-
if (pos < 512) {
|
|
67
|
-
let line2 = 1;
|
|
68
|
-
for (let i = 0; i < pos; i++) {
|
|
69
|
-
if (text.charCodeAt(i) === 10) line2++;
|
|
70
|
-
}
|
|
71
|
-
return line2;
|
|
72
|
-
}
|
|
73
|
-
let line = 1;
|
|
74
|
-
let search = 0;
|
|
75
|
-
while (true) {
|
|
76
|
-
const idx = text.indexOf("\n", search);
|
|
77
|
-
if (idx === -1 || idx >= pos) return line;
|
|
78
|
-
search = idx + 1;
|
|
79
|
-
line++;
|
|
80
|
-
}
|
|
90
|
+
return fuzzyScan(fileLines, needleLines, offsets, needleEndsWithNewline);
|
|
81
91
|
}
|
|
82
92
|
function lineOffsets(lines) {
|
|
83
93
|
const out = new Array(lines.length);
|
|
@@ -88,15 +98,17 @@ function lineOffsets(lines) {
|
|
|
88
98
|
}
|
|
89
99
|
return out;
|
|
90
100
|
}
|
|
91
|
-
function windowToMatch(fileLines, offsets, start, windowLen) {
|
|
101
|
+
function windowToMatch(fileLines, offsets, start, windowLen, includeTrailingNewline = false) {
|
|
92
102
|
const lastLine = start + windowLen - 1;
|
|
103
|
+
const lineEnd = offsets[lastLine] + fileLines[lastLine].length;
|
|
104
|
+
const end = includeTrailingNewline && lastLine < fileLines.length - 1 ? lineEnd + 1 : lineEnd;
|
|
93
105
|
return {
|
|
94
106
|
start: offsets[start],
|
|
95
|
-
end
|
|
107
|
+
end,
|
|
96
108
|
startLine: start + 1
|
|
97
109
|
};
|
|
98
110
|
}
|
|
99
|
-
function windowScan(comparisonLines, needleLines, offsets, originalLines, eq) {
|
|
111
|
+
function windowScan(comparisonLines, needleLines, offsets, originalLines, eq, includeTrailingNewline = false) {
|
|
100
112
|
const n = needleLines.length;
|
|
101
113
|
const out = [];
|
|
102
114
|
for (let i = 0; i + n <= comparisonLines.length; i++) {
|
|
@@ -108,28 +120,32 @@ function windowScan(comparisonLines, needleLines, offsets, originalLines, eq) {
|
|
|
108
120
|
}
|
|
109
121
|
}
|
|
110
122
|
if (all) {
|
|
111
|
-
out.push(windowToMatch(originalLines, offsets, i, n));
|
|
123
|
+
out.push(windowToMatch(originalLines, offsets, i, n, includeTrailingNewline));
|
|
112
124
|
i += n - 1;
|
|
113
125
|
}
|
|
114
126
|
}
|
|
115
127
|
return out;
|
|
116
128
|
}
|
|
117
|
-
function fuzzyScan(fileLines, needleLines, offsets) {
|
|
129
|
+
function fuzzyScan(fileLines, needleLines, offsets, includeTrailingNewline = false) {
|
|
118
130
|
const n = needleLines.length;
|
|
119
131
|
if (n < 3) return void 0;
|
|
120
132
|
const firstNeedle = needleLines[0].trim();
|
|
121
133
|
const lastNeedle = needleLines[n - 1].trim();
|
|
122
134
|
const needleInterior = needleLines.slice(1, -1).map((l) => l.trim()).join("\n");
|
|
123
135
|
if (needleInterior.length > FUZZY_MAX_INTERIOR_CHARS) return void 0;
|
|
136
|
+
const fileTrimmed = fileLines.map((l) => l.trim());
|
|
124
137
|
const candidates = [];
|
|
125
138
|
for (let i = 0; i + n <= fileLines.length; i++) {
|
|
126
|
-
if (
|
|
127
|
-
if (
|
|
128
|
-
const windowInterior =
|
|
139
|
+
if (fileTrimmed[i] !== firstNeedle) continue;
|
|
140
|
+
if (fileTrimmed[i + n - 1] !== lastNeedle) continue;
|
|
141
|
+
const windowInterior = fileTrimmed.slice(i + 1, i + n - 1).join("\n");
|
|
129
142
|
if (windowInterior.length > FUZZY_MAX_INTERIOR_CHARS) continue;
|
|
130
143
|
const score = similarity(needleInterior, windowInterior);
|
|
131
144
|
if (score >= FUZZY_MIN_SIMILARITY) {
|
|
132
|
-
candidates.push({
|
|
145
|
+
candidates.push({
|
|
146
|
+
match: windowToMatch(fileLines, offsets, i, n, includeTrailingNewline),
|
|
147
|
+
score
|
|
148
|
+
});
|
|
133
149
|
}
|
|
134
150
|
}
|
|
135
151
|
if (candidates.length === 0) return void 0;
|
|
@@ -150,21 +166,29 @@ function similarity(a, b) {
|
|
|
150
166
|
if (a === b) return 1;
|
|
151
167
|
const max = Math.max(a.length, b.length);
|
|
152
168
|
if (max === 0) return 1;
|
|
153
|
-
|
|
154
|
-
|
|
169
|
+
const lenDiff = Math.abs(a.length - b.length);
|
|
170
|
+
if (lenDiff / max > 1 - FUZZY_MIN_SIMILARITY) {
|
|
171
|
+
return 1 - lenDiff / max;
|
|
155
172
|
}
|
|
156
173
|
return 1 - levenshtein(a, b) / max;
|
|
157
174
|
}
|
|
158
175
|
function levenshtein(a, b) {
|
|
159
176
|
if (a.length === 0) return b.length;
|
|
160
177
|
if (b.length === 0) return a.length;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
178
|
+
if (a.length < b.length) {
|
|
179
|
+
const tmp = a;
|
|
180
|
+
a = b;
|
|
181
|
+
b = tmp;
|
|
182
|
+
}
|
|
183
|
+
const bLen = b.length;
|
|
184
|
+
const aLen = a.length;
|
|
185
|
+
let prev = new Int32Array(bLen + 1);
|
|
186
|
+
let cur = new Int32Array(bLen + 1);
|
|
187
|
+
for (let j = 0; j <= bLen; j++) prev[j] = j;
|
|
188
|
+
for (let i = 1; i <= aLen; i++) {
|
|
165
189
|
cur[0] = i;
|
|
166
190
|
const ca = a.charCodeAt(i - 1);
|
|
167
|
-
for (let j = 1; j <=
|
|
191
|
+
for (let j = 1; j <= bLen; j++) {
|
|
168
192
|
const cost = ca === b.charCodeAt(j - 1) ? 0 : 1;
|
|
169
193
|
cur[j] = Math.min(
|
|
170
194
|
prev[j] + 1,
|
|
@@ -172,9 +196,11 @@ function levenshtein(a, b) {
|
|
|
172
196
|
prev[j - 1] + cost
|
|
173
197
|
);
|
|
174
198
|
}
|
|
175
|
-
|
|
199
|
+
const tmp = prev;
|
|
200
|
+
prev = cur;
|
|
201
|
+
cur = tmp;
|
|
176
202
|
}
|
|
177
|
-
return prev[
|
|
203
|
+
return prev[bLen];
|
|
178
204
|
}
|
|
179
205
|
function firstLineIndent(text) {
|
|
180
206
|
for (const line of text.split("\n")) {
|
|
@@ -189,14 +215,17 @@ function adjustIndent(newLf, fromIndent, toIndent) {
|
|
|
189
215
|
if (toIndent.startsWith(fromIndent)) {
|
|
190
216
|
const extra = toIndent.slice(fromIndent.length);
|
|
191
217
|
return {
|
|
192
|
-
text: lines.map((l) => l.trim() === "" ?
|
|
218
|
+
text: lines.map((l) => l.trim() === "" ? "" : extra + l).join("\n"),
|
|
193
219
|
adjusted: true
|
|
194
220
|
};
|
|
195
221
|
}
|
|
196
222
|
if (fromIndent.startsWith(toIndent)) {
|
|
197
223
|
const remove = fromIndent.slice(toIndent.length);
|
|
198
224
|
return {
|
|
199
|
-
text: lines.map((l) =>
|
|
225
|
+
text: lines.map((l) => {
|
|
226
|
+
if (l.trim() === "") return "";
|
|
227
|
+
return l.startsWith(remove) ? l.slice(remove.length) : l;
|
|
228
|
+
}).join("\n"),
|
|
200
229
|
adjusted: true
|
|
201
230
|
};
|
|
202
231
|
}
|
|
@@ -204,34 +233,50 @@ function adjustIndent(newLf, fromIndent, toIndent) {
|
|
|
204
233
|
}
|
|
205
234
|
function nearestMatchHint(fileLf, oldLf) {
|
|
206
235
|
const fileLines = fileLf.split("\n");
|
|
207
|
-
const
|
|
208
|
-
|
|
236
|
+
const rawNeedle = oldLf.split("\n");
|
|
237
|
+
const needleLines = oldLf.endsWith("\n") && rawNeedle[rawNeedle.length - 1] === "" ? rawNeedle.slice(0, -1) : rawNeedle;
|
|
238
|
+
const n = needleLines.length;
|
|
239
|
+
if (n === 0 || n > fileLines.length) return void 0;
|
|
209
240
|
const needleTrimmed = needleLines.map((l) => l.trim());
|
|
241
|
+
const fileTrimmed = fileLines.map((l) => l.trim());
|
|
210
242
|
let bestScore = 0;
|
|
211
243
|
let bestStart = -1;
|
|
212
|
-
|
|
244
|
+
const maxI = fileLines.length - n;
|
|
245
|
+
for (let i = 0; i <= maxI; i++) {
|
|
213
246
|
let sum = 0;
|
|
214
|
-
|
|
215
|
-
|
|
247
|
+
let possible = true;
|
|
248
|
+
for (let j = 0; j < n; j++) {
|
|
249
|
+
sum += lineSimilarity(needleTrimmed[j], fileTrimmed[i + j]);
|
|
250
|
+
if (sum + (n - 1 - j) <= bestScore * n) {
|
|
251
|
+
possible = false;
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
216
254
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
bestScore
|
|
220
|
-
|
|
255
|
+
if (possible) {
|
|
256
|
+
const score = sum / n;
|
|
257
|
+
if (score > bestScore) {
|
|
258
|
+
bestScore = score;
|
|
259
|
+
bestStart = i;
|
|
260
|
+
}
|
|
221
261
|
}
|
|
222
262
|
}
|
|
223
263
|
if (bestStart === -1 || bestScore < 0.5) return void 0;
|
|
224
|
-
const snippet = fileLines.slice(bestStart, bestStart + Math.min(3,
|
|
264
|
+
const snippet = fileLines.slice(bestStart, bestStart + Math.min(3, n)).map((l) => l.length > 120 ? `${l.slice(0, 120)}\u2026` : l).join("\n");
|
|
225
265
|
return { line: bestStart + 1, snippet };
|
|
226
266
|
}
|
|
227
|
-
function
|
|
267
|
+
function lineSimilarity(a, b) {
|
|
228
268
|
if (a === b) return 1;
|
|
229
269
|
const max = Math.max(a.length, b.length);
|
|
230
270
|
if (max === 0) return 1;
|
|
271
|
+
if (a.includes(b) || b.includes(a)) {
|
|
272
|
+
return Math.min(a.length, b.length) / max;
|
|
273
|
+
}
|
|
231
274
|
let p = 0;
|
|
232
275
|
const lim = Math.min(a.length, b.length);
|
|
233
276
|
while (p < lim && a.charCodeAt(p) === b.charCodeAt(p)) p++;
|
|
234
|
-
|
|
277
|
+
let s = 0;
|
|
278
|
+
while (s < lim - p && a.charCodeAt(a.length - 1 - s) === b.charCodeAt(b.length - 1 - s)) s++;
|
|
279
|
+
return (p + s) / max;
|
|
235
280
|
}
|
|
236
281
|
|
|
237
282
|
// src/edit.ts
|
|
@@ -473,4 +518,4 @@ Compare this against your old_string and retry with the file's actual text.` : "
|
|
|
473
518
|
export {
|
|
474
519
|
editTool
|
|
475
520
|
};
|
|
476
|
-
//# sourceMappingURL=chunk-
|
|
521
|
+
//# sourceMappingURL=chunk-Z6IHMJMC.js.map
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
// src/_concurrency.ts
|
|
2
2
|
async function mapWithConcurrency(items, limit, fn) {
|
|
3
|
-
if (items.length === 0) return [];
|
|
3
|
+
if (!Array.isArray(items) || items.length === 0) return [];
|
|
4
|
+
if (typeof fn !== "function") return [];
|
|
4
5
|
if (items.length === 1) return [await fn(items[0])];
|
|
5
|
-
const
|
|
6
|
+
const parsedLimit = Number.isFinite(limit) ? Math.floor(limit) : items.length;
|
|
7
|
+
const effectiveLimit = Math.max(1, Math.min(parsedLimit, items.length));
|
|
6
8
|
const results = new Array(items.length);
|
|
7
9
|
let nextIndex = 0;
|
|
8
10
|
const worker = async () => {
|
|
@@ -19,4 +21,4 @@ async function mapWithConcurrency(items, limit, fn) {
|
|
|
19
21
|
export {
|
|
20
22
|
mapWithConcurrency
|
|
21
23
|
};
|
|
22
|
-
//# sourceMappingURL=chunk-
|
|
24
|
+
//# sourceMappingURL=chunk-ZBMANLYH.js.map
|