@wrongstack/tools 0.273.1 → 0.274.0
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/builtin.js +166 -70
- package/dist/builtin.js.map +1 -1
- package/dist/codebase-index/index.js +24 -16
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/codebase-index/worker.js +24 -16
- package/dist/codebase-index/worker.js.map +1 -1
- package/dist/glob.js +61 -11
- package/dist/glob.js.map +1 -1
- package/dist/grep.js +92 -39
- package/dist/grep.js.map +1 -1
- package/dist/index.js +166 -70
- package/dist/index.js.map +1 -1
- package/dist/pack.js +166 -70
- package/dist/pack.js.map +1 -1
- package/package.json +2 -2
package/dist/pack.js
CHANGED
|
@@ -61,7 +61,7 @@ function createOutputSpool(opts) {
|
|
|
61
61
|
let filePath = null;
|
|
62
62
|
let failed = false;
|
|
63
63
|
let finalized = false;
|
|
64
|
-
const
|
|
64
|
+
const open2 = () => {
|
|
65
65
|
if (stream || failed) return;
|
|
66
66
|
try {
|
|
67
67
|
const dir = toolOutputDir();
|
|
@@ -94,7 +94,7 @@ function createOutputSpool(opts) {
|
|
|
94
94
|
return;
|
|
95
95
|
}
|
|
96
96
|
head += text;
|
|
97
|
-
|
|
97
|
+
open2();
|
|
98
98
|
head = "";
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
@@ -2654,6 +2654,8 @@ var IndexStore = class {
|
|
|
2654
2654
|
this.db.exec("CREATE INDEX IF NOT EXISTS idx_s_kind ON symbols(kind)");
|
|
2655
2655
|
this.db.exec("CREATE INDEX IF NOT EXISTS idx_s_lang ON symbols(lang)");
|
|
2656
2656
|
this.db.exec("CREATE INDEX IF NOT EXISTS idx_s_file ON symbols(file)");
|
|
2657
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS idx_s_lang_kind ON symbols(lang, kind)");
|
|
2658
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS idx_s_file_fk ON symbols(file_fk)");
|
|
2657
2659
|
this.db.exec(`
|
|
2658
2660
|
CREATE TABLE IF NOT EXISTS refs (
|
|
2659
2661
|
id INTEGER PRIMARY KEY,
|
|
@@ -3566,9 +3568,9 @@ async function syncGoParse(filePath, content, lang) {
|
|
|
3566
3568
|
}
|
|
3567
3569
|
}
|
|
3568
3570
|
async function parseSymbols3(opts) {
|
|
3569
|
-
const { file, lang } = opts;
|
|
3571
|
+
const { file, content, lang } = opts;
|
|
3570
3572
|
try {
|
|
3571
|
-
return await syncPyParse(file, lang);
|
|
3573
|
+
return await syncPyParse(file, content, lang);
|
|
3572
3574
|
} catch {
|
|
3573
3575
|
return { file, lang, symbols: [], mtimeMs: Date.now() };
|
|
3574
3576
|
}
|
|
@@ -3636,8 +3638,7 @@ syms = []
|
|
|
3636
3638
|
errors = []
|
|
3637
3639
|
|
|
3638
3640
|
try:
|
|
3639
|
-
|
|
3640
|
-
source = f.read()
|
|
3641
|
+
source = sys.stdin.read()
|
|
3641
3642
|
tree = ast.parse(source, filename=sys.argv[1])
|
|
3642
3643
|
except Exception as e:
|
|
3643
3644
|
errors.append(str(e))
|
|
@@ -3777,16 +3778,21 @@ visitor.visit(tree)
|
|
|
3777
3778
|
|
|
3778
3779
|
print(json.dumps([s.to_dict() for s in syms]))
|
|
3779
3780
|
`;
|
|
3780
|
-
|
|
3781
|
+
var _cachedScriptPath = null;
|
|
3782
|
+
async function syncPyParse(filePath, content, lang) {
|
|
3781
3783
|
try {
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3784
|
+
if (!_cachedScriptPath) {
|
|
3785
|
+
const tmpDir = path3.join(os2.tmpdir(), "ws-py-parse");
|
|
3786
|
+
await fs2.mkdir(tmpDir, { recursive: true });
|
|
3787
|
+
_cachedScriptPath = path3.join(tmpDir, "parse.py");
|
|
3788
|
+
await fs2.writeFile(_cachedScriptPath, PY_PARSE_SCRIPT, "utf8");
|
|
3789
|
+
}
|
|
3790
|
+
const proc = spawn("python", [_cachedScriptPath, filePath], {
|
|
3787
3791
|
stdio: ["pipe", "pipe", "pipe"],
|
|
3788
3792
|
windowsHide: true
|
|
3789
3793
|
});
|
|
3794
|
+
proc.stdin?.write(content);
|
|
3795
|
+
proc.stdin?.end();
|
|
3790
3796
|
let stdout = "";
|
|
3791
3797
|
proc.stdout?.on("data", (chunk) => {
|
|
3792
3798
|
stdout += chunk.toString();
|
|
@@ -4453,7 +4459,7 @@ async function parseFile(file, content, lang) {
|
|
|
4453
4459
|
case "go":
|
|
4454
4460
|
return parseSymbols2({ file, content, lang: "go" });
|
|
4455
4461
|
case "py":
|
|
4456
|
-
return parseSymbols3({ file, lang: "py" });
|
|
4462
|
+
return parseSymbols3({ file, content, lang: "py" });
|
|
4457
4463
|
case "rs":
|
|
4458
4464
|
return parseSymbols4({ file, content, lang: "rs" });
|
|
4459
4465
|
case "json":
|
|
@@ -4484,10 +4490,12 @@ async function runIndexerWithStore(store, opts) {
|
|
|
4484
4490
|
let symbolsIndexed = 0;
|
|
4485
4491
|
const isGitIgnored = await loadGitignoreMatcher(projectRoot);
|
|
4486
4492
|
let files;
|
|
4493
|
+
let discoveredFiles = null;
|
|
4487
4494
|
if (opts.files && opts.files.length > 0) {
|
|
4488
4495
|
files = opts.files.map((f) => path3.resolve(projectRoot, f)).filter((f) => !isGitIgnored(path3.relative(projectRoot, f).replace(/\\/g, "/"), false));
|
|
4489
4496
|
} else {
|
|
4490
4497
|
files = await findSourceFiles(projectRoot, ignore, isGitIgnored, signal);
|
|
4498
|
+
discoveredFiles = new Set(files);
|
|
4491
4499
|
}
|
|
4492
4500
|
if (langs && langs.length > 0) {
|
|
4493
4501
|
const langSet = new Set(langs);
|
|
@@ -4605,11 +4613,11 @@ async function runIndexerWithStore(store, opts) {
|
|
|
4605
4613
|
filesIndexed++;
|
|
4606
4614
|
}
|
|
4607
4615
|
}
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4616
|
+
if (discoveredFiles) {
|
|
4617
|
+
for (const [file_] of existingMeta) {
|
|
4618
|
+
if (!discoveredFiles.has(file_)) {
|
|
4619
|
+
store.deleteFile(file_);
|
|
4620
|
+
}
|
|
4613
4621
|
}
|
|
4614
4622
|
}
|
|
4615
4623
|
const durationMs = Date.now() - startMs;
|
|
@@ -6530,7 +6538,27 @@ function runGit2(args, cwd, signal) {
|
|
|
6530
6538
|
});
|
|
6531
6539
|
});
|
|
6532
6540
|
}
|
|
6541
|
+
|
|
6542
|
+
// src/_concurrency.ts
|
|
6543
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
6544
|
+
if (items.length === 0) return [];
|
|
6545
|
+
const effectiveLimit = Math.max(1, Math.min(limit | 0, items.length));
|
|
6546
|
+
const results = new Array(items.length);
|
|
6547
|
+
let nextIndex = 0;
|
|
6548
|
+
const worker2 = async () => {
|
|
6549
|
+
while (true) {
|
|
6550
|
+
const i = nextIndex++;
|
|
6551
|
+
if (i >= items.length) return;
|
|
6552
|
+
results[i] = await fn(items[i]);
|
|
6553
|
+
}
|
|
6554
|
+
};
|
|
6555
|
+
await Promise.all(Array.from({ length: effectiveLimit }, worker2));
|
|
6556
|
+
return results;
|
|
6557
|
+
}
|
|
6558
|
+
|
|
6559
|
+
// src/glob.ts
|
|
6533
6560
|
var DEFAULT_IGNORE2 = ["node_modules", ".git", "dist", "build", ".next", "coverage", ".turbo"];
|
|
6561
|
+
var WALK_CONCURRENCY = 16;
|
|
6534
6562
|
var globTool = {
|
|
6535
6563
|
name: "glob",
|
|
6536
6564
|
category: "Filesystem",
|
|
@@ -6568,6 +6596,22 @@ var globTool = {
|
|
|
6568
6596
|
const re = compileGlob(input.pattern);
|
|
6569
6597
|
const results = [];
|
|
6570
6598
|
let truncated = false;
|
|
6599
|
+
const pushResult = async (full) => {
|
|
6600
|
+
if (truncated || results.length >= limit) {
|
|
6601
|
+
truncated = true;
|
|
6602
|
+
return;
|
|
6603
|
+
}
|
|
6604
|
+
try {
|
|
6605
|
+
const st = await fs2.stat(full);
|
|
6606
|
+
if (truncated || results.length >= limit) {
|
|
6607
|
+
truncated = true;
|
|
6608
|
+
return;
|
|
6609
|
+
}
|
|
6610
|
+
results.push({ rel: full, mtime: st.mtimeMs });
|
|
6611
|
+
if (results.length >= limit) truncated = true;
|
|
6612
|
+
} catch {
|
|
6613
|
+
}
|
|
6614
|
+
};
|
|
6571
6615
|
const walk = async (dir, relPrefix) => {
|
|
6572
6616
|
if (results.length >= limit) {
|
|
6573
6617
|
truncated = true;
|
|
@@ -6579,6 +6623,8 @@ var globTool = {
|
|
|
6579
6623
|
} catch {
|
|
6580
6624
|
return;
|
|
6581
6625
|
}
|
|
6626
|
+
const subdirs = [];
|
|
6627
|
+
const matchedFiles = [];
|
|
6582
6628
|
for (const e of entries) {
|
|
6583
6629
|
const name = e.name;
|
|
6584
6630
|
if (DEFAULT_IGNORE2.includes(name)) continue;
|
|
@@ -6586,22 +6632,36 @@ var globTool = {
|
|
|
6586
6632
|
const rel = relPrefix ? `${relPrefix}/${name}` : name;
|
|
6587
6633
|
const full = path3.join(dir, name);
|
|
6588
6634
|
if (e.isDirectory()) {
|
|
6589
|
-
|
|
6590
|
-
if (truncated) return;
|
|
6635
|
+
subdirs.push({ full, rel });
|
|
6591
6636
|
} else if (e.isFile()) {
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6637
|
+
re.lastIndex = 0;
|
|
6638
|
+
const relMatch = re.test(rel);
|
|
6639
|
+
re.lastIndex = 0;
|
|
6640
|
+
const nameMatch = re.test(name);
|
|
6641
|
+
if (relMatch || nameMatch) {
|
|
6642
|
+
matchedFiles.push(full);
|
|
6643
|
+
}
|
|
6644
|
+
} else if (e.isSymbolicLink()) {
|
|
6645
|
+
try {
|
|
6646
|
+
const st = await fs2.stat(full);
|
|
6647
|
+
if (st.isDirectory()) {
|
|
6648
|
+
subdirs.push({ full, rel });
|
|
6649
|
+
} else if (st.isFile()) {
|
|
6650
|
+
re.lastIndex = 0;
|
|
6651
|
+
const relMatch = re.test(rel);
|
|
6652
|
+
re.lastIndex = 0;
|
|
6653
|
+
const nameMatch = re.test(name);
|
|
6654
|
+
if (relMatch || nameMatch) matchedFiles.push(full);
|
|
6601
6655
|
}
|
|
6656
|
+
} catch {
|
|
6602
6657
|
}
|
|
6603
6658
|
}
|
|
6659
|
+
if (truncated) return;
|
|
6604
6660
|
}
|
|
6661
|
+
await mapWithConcurrency(matchedFiles, WALK_CONCURRENCY, pushResult);
|
|
6662
|
+
if (truncated) return;
|
|
6663
|
+
const remainingSubdirs = truncated ? [] : subdirs;
|
|
6664
|
+
await mapWithConcurrency(remainingSubdirs, WALK_CONCURRENCY, ({ full, rel }) => walk(full, rel));
|
|
6605
6665
|
};
|
|
6606
6666
|
await walk(base, "");
|
|
6607
6667
|
results.sort((a, b) => b.mtime - a.mtime);
|
|
@@ -6665,6 +6725,8 @@ function capSubject(line) {
|
|
|
6665
6725
|
// src/grep.ts
|
|
6666
6726
|
var DEFAULT_IGNORE3 = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
|
|
6667
6727
|
var NATIVE_SCAN_CONCURRENCY = 32;
|
|
6728
|
+
var NATIVE_READ_CHUNK_BYTES = 64 * 1024;
|
|
6729
|
+
var NATIVE_MAX_FILE_BYTES = 1e6;
|
|
6668
6730
|
var grepTool = {
|
|
6669
6731
|
name: "grep",
|
|
6670
6732
|
category: "Search",
|
|
@@ -6889,7 +6951,8 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
6889
6951
|
const re = compiled.regex;
|
|
6890
6952
|
const globRe = input.glob ? compileGlob(input.glob) : null;
|
|
6891
6953
|
const matches = [];
|
|
6892
|
-
const
|
|
6954
|
+
const countOnlyFirstHit = mode === "count" && limit === 1;
|
|
6955
|
+
const maxBytes = mode === "content" ? NATIVE_MAX_FILE_BYTES : Math.min(NATIVE_MAX_FILE_BYTES, 256 * 1024);
|
|
6893
6956
|
let total = 0;
|
|
6894
6957
|
let stopped = false;
|
|
6895
6958
|
const scanFile = async (full, name) => {
|
|
@@ -6898,34 +6961,79 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
6898
6961
|
if (globRe) globRe.lastIndex = 0;
|
|
6899
6962
|
try {
|
|
6900
6963
|
const stat11 = await fs2.stat(full);
|
|
6901
|
-
if (stat11.size >
|
|
6902
|
-
const
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
const
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6964
|
+
if (!stat11.isFile() || stat11.size > maxBytes || stopped || signal.aborted) return;
|
|
6965
|
+
const file = await fs2.open(full, "r");
|
|
6966
|
+
try {
|
|
6967
|
+
let bytesReadTotal = 0;
|
|
6968
|
+
let lineNumber = 0;
|
|
6969
|
+
let fileHits = 0;
|
|
6970
|
+
let leftover = "";
|
|
6971
|
+
let binaryChecked = false;
|
|
6972
|
+
const buffer = Buffer.allocUnsafe(Math.min(NATIVE_READ_CHUNK_BYTES, maxBytes));
|
|
6973
|
+
while (!stopped && !signal.aborted && bytesReadTotal < maxBytes) {
|
|
6974
|
+
const remaining = maxBytes - bytesReadTotal;
|
|
6975
|
+
const { bytesRead } = await file.read(buffer, 0, Math.min(buffer.length, remaining), null);
|
|
6976
|
+
if (bytesRead === 0) break;
|
|
6977
|
+
const chunk = buffer.subarray(0, bytesRead);
|
|
6978
|
+
if (!binaryChecked) {
|
|
6979
|
+
binaryChecked = true;
|
|
6980
|
+
if (isBinaryBuffer(chunk)) return;
|
|
6981
|
+
}
|
|
6982
|
+
bytesReadTotal += bytesRead;
|
|
6983
|
+
const text = leftover + chunk.toString("utf8");
|
|
6984
|
+
const lines = text.split(/\r?\n/);
|
|
6985
|
+
leftover = lines.pop() ?? "";
|
|
6986
|
+
for (const rawLine of lines) {
|
|
6987
|
+
if (stopped || signal.aborted) break;
|
|
6988
|
+
lineNumber++;
|
|
6989
|
+
const ln = capSubject(rawLine);
|
|
6990
|
+
re.lastIndex = 0;
|
|
6991
|
+
if (!re.test(ln)) continue;
|
|
6992
|
+
fileHits++;
|
|
6993
|
+
total++;
|
|
6994
|
+
if (mode === "content") {
|
|
6995
|
+
if (matches.length < limit) matches.push(`${full}:${lineNumber}:${ln}`);
|
|
6996
|
+
} else if (mode === "files_with_matches") {
|
|
6997
|
+
if (fileHits === 1 && matches.length < limit) matches.push(full);
|
|
6998
|
+
break;
|
|
6999
|
+
} else if (fileHits === 1 && matches.length < limit) {
|
|
7000
|
+
matches.push(`${full}:${countOnlyFirstHit ? 1 : 0}`);
|
|
7001
|
+
}
|
|
7002
|
+
if (countOnlyFirstHit || mode !== "content" && matches.length >= limit) {
|
|
7003
|
+
stopped = true;
|
|
7004
|
+
break;
|
|
7005
|
+
}
|
|
6916
7006
|
}
|
|
7007
|
+
if (mode === "files_with_matches" && fileHits > 0) break;
|
|
6917
7008
|
}
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
7009
|
+
if (!stopped && !signal.aborted && leftover.length > 0) {
|
|
7010
|
+
lineNumber++;
|
|
7011
|
+
const ln = capSubject(leftover);
|
|
7012
|
+
re.lastIndex = 0;
|
|
7013
|
+
if (re.test(ln)) {
|
|
7014
|
+
fileHits++;
|
|
7015
|
+
total++;
|
|
7016
|
+
if (mode === "content") {
|
|
7017
|
+
if (matches.length < limit) matches.push(`${full}:${lineNumber}:${ln}`);
|
|
7018
|
+
} else if (mode === "files_with_matches") {
|
|
7019
|
+
if (matches.length < limit) matches.push(full);
|
|
7020
|
+
} else if (matches.length < limit) {
|
|
7021
|
+
matches.push(`${full}:${countOnlyFirstHit ? 1 : fileHits}`);
|
|
7022
|
+
}
|
|
7023
|
+
}
|
|
6923
7024
|
}
|
|
6924
|
-
if (
|
|
6925
|
-
|
|
7025
|
+
if (fileHits > 0) {
|
|
7026
|
+
if (mode === "count") {
|
|
7027
|
+
const idx = matches.findIndex((entry) => entry.startsWith(`${full}:`));
|
|
7028
|
+
if (idx !== -1) matches[idx] = `${full}:${fileHits}`;
|
|
7029
|
+
}
|
|
7030
|
+
if (mode === "files_with_matches" && matches.length >= limit) stopped = true;
|
|
6926
7031
|
}
|
|
7032
|
+
if (mode === "content" && matches.length >= limit) stopped = true;
|
|
7033
|
+
if (mode === "count" && matches.length >= limit && (countOnlyFirstHit || mode !== "count")) stopped = true;
|
|
7034
|
+
} finally {
|
|
7035
|
+
await file.close();
|
|
6927
7036
|
}
|
|
6928
|
-
if (matches.length >= limit) stopped = true;
|
|
6929
7037
|
} catch {
|
|
6930
7038
|
}
|
|
6931
7039
|
};
|
|
@@ -6938,18 +7046,20 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
6938
7046
|
return;
|
|
6939
7047
|
}
|
|
6940
7048
|
const files = [];
|
|
7049
|
+
const subdirs = [];
|
|
6941
7050
|
for (const e of entries) {
|
|
6942
7051
|
if (stopped) return;
|
|
6943
7052
|
if (DEFAULT_IGNORE3.includes(e.name)) continue;
|
|
6944
7053
|
if (e.isSymbolicLink()) continue;
|
|
6945
7054
|
const full = path3.join(dir, e.name);
|
|
6946
7055
|
if (e.isDirectory()) {
|
|
6947
|
-
|
|
7056
|
+
subdirs.push(full);
|
|
6948
7057
|
} else if (e.isFile()) {
|
|
6949
7058
|
files.push({ full, name: e.name });
|
|
6950
7059
|
}
|
|
6951
7060
|
}
|
|
6952
7061
|
await mapWithConcurrency(files, NATIVE_SCAN_CONCURRENCY, ({ full, name }) => scanFile(full, name));
|
|
7062
|
+
await mapWithConcurrency(subdirs, Math.min(16, NATIVE_SCAN_CONCURRENCY), walk);
|
|
6953
7063
|
};
|
|
6954
7064
|
await walk(base);
|
|
6955
7065
|
return {
|
|
@@ -6959,20 +7069,6 @@ async function runNative(input, base, mode, limit, signal) {
|
|
|
6959
7069
|
used: "native"
|
|
6960
7070
|
};
|
|
6961
7071
|
}
|
|
6962
|
-
async function mapWithConcurrency(items, concurrency, fn) {
|
|
6963
|
-
if (items.length === 0) return;
|
|
6964
|
-
let next = 0;
|
|
6965
|
-
const workerCount = Math.min(Math.max(1, concurrency), items.length);
|
|
6966
|
-
const workers = Array.from({ length: workerCount }, async () => {
|
|
6967
|
-
for (; ; ) {
|
|
6968
|
-
const idx = next++;
|
|
6969
|
-
if (idx >= items.length) return;
|
|
6970
|
-
const item = items[idx];
|
|
6971
|
-
if (item !== void 0) await fn(item);
|
|
6972
|
-
}
|
|
6973
|
-
});
|
|
6974
|
-
await Promise.all(workers);
|
|
6975
|
-
}
|
|
6976
7072
|
var installTool = {
|
|
6977
7073
|
name: "install",
|
|
6978
7074
|
category: "Package Management",
|
|
@@ -8017,13 +8113,13 @@ ${formatTaskList(taskFile.tasks)}`
|
|
|
8017
8113
|
}
|
|
8018
8114
|
};
|
|
8019
8115
|
function mkResult(plan, ok, message, todos) {
|
|
8020
|
-
const
|
|
8116
|
+
const open2 = plan.items.filter((i) => i.status !== "done").length;
|
|
8021
8117
|
const result = {
|
|
8022
8118
|
ok,
|
|
8023
8119
|
message,
|
|
8024
8120
|
plan: formatPlan(plan),
|
|
8025
8121
|
count: plan.items.length,
|
|
8026
|
-
open
|
|
8122
|
+
open: open2
|
|
8027
8123
|
};
|
|
8028
8124
|
if (todos !== void 0) result.todos = todos;
|
|
8029
8125
|
return result;
|