@wrongstack/tools 0.307.0 → 0.308.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 +564 -396
- package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +2 -0
- package/dist/codebase-index/index.js +134 -49
- package/dist/codebase-index/project-server.js +87 -43
- package/dist/codebase-index/worker.js +87 -43
- package/dist/codebase-index/writer-graph-helpers.d.ts +1 -1
- package/dist/codebase-index/writer-helpers.d.ts +12 -0
- package/dist/edit.js +87 -43
- package/dist/index.d.ts +1 -1
- package/dist/index.js +583 -412
- package/dist/pack.js +563 -396
- package/dist/patch.js +87 -43
- package/dist/read.js +91 -47
- package/dist/replace.js +87 -43
- package/dist/tool-tier.js +564 -396
- package/dist/write.js +87 -43
- package/package.json +4 -4
package/dist/write.js
CHANGED
|
@@ -4542,10 +4542,16 @@ function buildFileGraphNodeState(pkgSyms, localFiles, packageOf) {
|
|
|
4542
4542
|
}
|
|
4543
4543
|
return { fileNodes, symToFile, fileStats, ensureFileNode };
|
|
4544
4544
|
}
|
|
4545
|
-
function buildSymbolGraphNodes(symById, relatedIds,
|
|
4545
|
+
function buildSymbolGraphNodes(symById, relatedIds, localFiles, packageOf) {
|
|
4546
|
+
const local = new Set(
|
|
4547
|
+
[...typeof localFiles === "string" ? [localFiles] : localFiles].map(
|
|
4548
|
+
(file) => file.replace(/\\/g, "/")
|
|
4549
|
+
)
|
|
4550
|
+
);
|
|
4551
|
+
const isLocal = (file) => local.has(file.replace(/\\/g, "/"));
|
|
4546
4552
|
return [...relatedIds].map((id) => symById.get(id)).filter((symbol) => symbol !== void 0).sort((a, b) => {
|
|
4547
|
-
const aExternal = a.file
|
|
4548
|
-
const bExternal = b.file
|
|
4553
|
+
const aExternal = isLocal(a.file) ? 0 : 1;
|
|
4554
|
+
const bExternal = isLocal(b.file) ? 0 : 1;
|
|
4549
4555
|
return aExternal - bExternal || a.file.localeCompare(b.file) || a.line - b.line || a.id - b.id;
|
|
4550
4556
|
}).map((s) => ({
|
|
4551
4557
|
id: `sym:${s.id}`,
|
|
@@ -4559,7 +4565,7 @@ function buildSymbolGraphNodes(symById, relatedIds, fileFilter, packageOf) {
|
|
|
4559
4565
|
line: s.line,
|
|
4560
4566
|
signature: s.signature,
|
|
4561
4567
|
scope: s.scope,
|
|
4562
|
-
external: s.file
|
|
4568
|
+
external: !isLocal(s.file)
|
|
4563
4569
|
}));
|
|
4564
4570
|
}
|
|
4565
4571
|
function addWeightedEdge(edgeMap, source, target, callType, weight) {
|
|
@@ -4594,6 +4600,52 @@ function materializeWeightedEdges(edgeMap, idPrefix) {
|
|
|
4594
4600
|
return edges;
|
|
4595
4601
|
}
|
|
4596
4602
|
|
|
4603
|
+
// src/codebase-index/writer-helpers.ts
|
|
4604
|
+
import { resolveWstackPaths } from "@wrongstack/core/utils";
|
|
4605
|
+
function escapeLike(value) {
|
|
4606
|
+
return value.replace(/[\\%_]/g, (char) => `\\${char}`);
|
|
4607
|
+
}
|
|
4608
|
+
function posixIndexPath(file) {
|
|
4609
|
+
return file.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
4610
|
+
}
|
|
4611
|
+
function indexedFileMatchSql(column = "file") {
|
|
4612
|
+
return `(${column} = ? OR replace(${column}, '\\', '/') = ? OR replace(${column}, '\\', '/') LIKE ? ESCAPE '\\')`;
|
|
4613
|
+
}
|
|
4614
|
+
function indexedFileMatchArgs(file) {
|
|
4615
|
+
const posix4 = posixIndexPath(file.trim());
|
|
4616
|
+
return [file, posix4, `%/${escapeLike(posix4)}`];
|
|
4617
|
+
}
|
|
4618
|
+
function matchesIndexedPackageFilter(storedFile, packageLabel, filter) {
|
|
4619
|
+
if (packageLabel === filter) return true;
|
|
4620
|
+
const posixFile = posixIndexPath(storedFile);
|
|
4621
|
+
const posixFilter = posixIndexPath(filter.trim());
|
|
4622
|
+
if (!posixFilter) return false;
|
|
4623
|
+
return posixFile === posixFilter || posixFile.endsWith(`/${posixFilter}`) || posixFile.includes(`/${posixFilter}/`);
|
|
4624
|
+
}
|
|
4625
|
+
function assignRefsToSymbols(refs, symbols) {
|
|
4626
|
+
if (refs.length === 0 || symbols.length === 0) return [];
|
|
4627
|
+
const ordered = [...symbols].sort((a, b) => a.line - b.line || a.col - b.col || a.id - b.id);
|
|
4628
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4629
|
+
const assigned = [];
|
|
4630
|
+
for (const ref of refs) {
|
|
4631
|
+
let owner;
|
|
4632
|
+
for (const symbol of ordered) {
|
|
4633
|
+
if (symbol.line > ref.line) break;
|
|
4634
|
+
owner = symbol;
|
|
4635
|
+
}
|
|
4636
|
+
if (!owner && ref.callType === "import") owner = ordered[0];
|
|
4637
|
+
if (!owner || owner.id <= 0) continue;
|
|
4638
|
+
const key = `${owner.id}:${ref.toName}:${ref.callType}:${ref.module ?? ""}`;
|
|
4639
|
+
if (seen.has(key)) continue;
|
|
4640
|
+
seen.add(key);
|
|
4641
|
+
assigned.push({ ...ref, fromId: owner.id });
|
|
4642
|
+
}
|
|
4643
|
+
return assigned;
|
|
4644
|
+
}
|
|
4645
|
+
function resolveIndexDir(projectRoot, override) {
|
|
4646
|
+
return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;
|
|
4647
|
+
}
|
|
4648
|
+
|
|
4597
4649
|
// src/codebase-index/writer-ref-mapper.ts
|
|
4598
4650
|
function mapWriterRefRow(row) {
|
|
4599
4651
|
return {
|
|
@@ -4649,10 +4701,23 @@ function mapCallSiteRow(row) {
|
|
|
4649
4701
|
line: row.ref_line
|
|
4650
4702
|
};
|
|
4651
4703
|
}
|
|
4704
|
+
function resolveIndexedFiles(stmt, file) {
|
|
4705
|
+
const rows = stmt(
|
|
4706
|
+
`SELECT DISTINCT file FROM symbols WHERE ${indexedFileMatchSql("file")} ORDER BY length(file), file`
|
|
4707
|
+
).all(...indexedFileMatchArgs(file));
|
|
4708
|
+
return rows.map((row) => row.file);
|
|
4709
|
+
}
|
|
4652
4710
|
function resolveSymbolIds(stmt, symbolName, file) {
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4711
|
+
if (!file) {
|
|
4712
|
+
const rows2 = stmt("SELECT id FROM symbols WHERE name = ? ORDER BY id").all(symbolName);
|
|
4713
|
+
return rows2.map((r) => r.id);
|
|
4714
|
+
}
|
|
4715
|
+
const indexedFiles = resolveIndexedFiles(stmt, file);
|
|
4716
|
+
if (indexedFiles.length === 0) return [];
|
|
4717
|
+
const placeholders = indexedFiles.map(() => "?").join(",");
|
|
4718
|
+
const rows = stmt(
|
|
4719
|
+
`SELECT id FROM symbols WHERE name = ? AND file IN (${placeholders}) ORDER BY id`
|
|
4720
|
+
).all(symbolName, ...indexedFiles);
|
|
4656
4721
|
return rows.map((r) => r.id);
|
|
4657
4722
|
}
|
|
4658
4723
|
function findIncomingCallsByName(stmt, symbolName, file, limit) {
|
|
@@ -4974,7 +5039,7 @@ function getFileGraphWithStatement(stmt, packageFilter) {
|
|
|
4974
5039
|
const allFiles = stmt("SELECT DISTINCT file FROM symbols").all();
|
|
4975
5040
|
const packageOf = readPackageLabeller(stmt);
|
|
4976
5041
|
const langOf = (file) => detectLang(file) ?? "other";
|
|
4977
|
-
const pkgFilePaths = allFiles.filter((f) => packageOf(f.file)
|
|
5042
|
+
const pkgFilePaths = allFiles.filter((f) => matchesIndexedPackageFilter(f.file, packageOf(f.file), packageFilter)).map((f) => f.file);
|
|
4978
5043
|
const localFiles = new Set(pkgFilePaths);
|
|
4979
5044
|
if (localFiles.size === 0) return { nodes: [], edges: [] };
|
|
4980
5045
|
const filePlaceholders = [...localFiles].map(() => "?").join(",");
|
|
@@ -5050,9 +5115,12 @@ function getFileGraphWithStatement(stmt, packageFilter) {
|
|
|
5050
5115
|
return { nodes: [...fileNodes.values()], edges };
|
|
5051
5116
|
}
|
|
5052
5117
|
function getSymbolGraphWithStatement(stmt, fileFilter) {
|
|
5118
|
+
const indexedFiles = resolveIndexedFiles(stmt, fileFilter);
|
|
5119
|
+
if (indexedFiles.length === 0) return { nodes: [], edges: [] };
|
|
5120
|
+
const filePlaceholders = indexedFiles.map(() => "?").join(",");
|
|
5053
5121
|
const syms = stmt(
|
|
5054
|
-
|
|
5055
|
-
).all(
|
|
5122
|
+
`SELECT id, name, kind, lang, file, line, signature, scope FROM symbols WHERE file IN (${filePlaceholders}) ORDER BY line, id`
|
|
5123
|
+
).all(...indexedFiles);
|
|
5056
5124
|
if (syms.length === 0) return { nodes: [], edges: [] };
|
|
5057
5125
|
const symById = new Map(syms.map((symbol) => [symbol.id, symbol]));
|
|
5058
5126
|
const relatedIds = new Set(syms.map((symbol) => symbol.id));
|
|
@@ -5062,16 +5130,16 @@ function getSymbolGraphWithStatement(stmt, fileFilter) {
|
|
|
5062
5130
|
SELECT r.from_id, r.to_id, r.to_name, r.call_type, r.line
|
|
5063
5131
|
FROM refs r
|
|
5064
5132
|
JOIN symbols s ON s.id = r.from_id
|
|
5065
|
-
WHERE s.file
|
|
5133
|
+
WHERE s.file IN (${filePlaceholders})
|
|
5066
5134
|
UNION
|
|
5067
5135
|
SELECT r.from_id, r.to_id, r.to_name, r.call_type, r.line
|
|
5068
5136
|
FROM refs r
|
|
5069
5137
|
JOIN symbols s ON s.id = r.to_id
|
|
5070
|
-
WHERE s.file
|
|
5138
|
+
WHERE s.file IN (${filePlaceholders})
|
|
5071
5139
|
)
|
|
5072
5140
|
WHERE to_id IS NOT NULL
|
|
5073
5141
|
GROUP BY from_id, to_id, call_type`
|
|
5074
|
-
).all(
|
|
5142
|
+
).all(...indexedFiles, ...indexedFiles);
|
|
5075
5143
|
const edgeMap = /* @__PURE__ */ new Map();
|
|
5076
5144
|
for (const r of refRows) {
|
|
5077
5145
|
if (r.to_id == null) continue;
|
|
@@ -5090,39 +5158,15 @@ function getSymbolGraphWithStatement(stmt, fileFilter) {
|
|
|
5090
5158
|
).all(...missingIds);
|
|
5091
5159
|
for (const s of extras) symById.set(s.id, s);
|
|
5092
5160
|
}
|
|
5093
|
-
const nodes = buildSymbolGraphNodes(
|
|
5161
|
+
const nodes = buildSymbolGraphNodes(
|
|
5162
|
+
symById,
|
|
5163
|
+
relatedIds,
|
|
5164
|
+
new Set(syms.map((symbol) => symbol.file)),
|
|
5165
|
+
readPackageLabeller(stmt)
|
|
5166
|
+
);
|
|
5094
5167
|
return { nodes, edges };
|
|
5095
5168
|
}
|
|
5096
5169
|
|
|
5097
|
-
// src/codebase-index/writer-helpers.ts
|
|
5098
|
-
import { resolveWstackPaths } from "@wrongstack/core/utils";
|
|
5099
|
-
function escapeLike(value) {
|
|
5100
|
-
return value.replace(/[\\%_]/g, (char) => `\\${char}`);
|
|
5101
|
-
}
|
|
5102
|
-
function assignRefsToSymbols(refs, symbols) {
|
|
5103
|
-
if (refs.length === 0 || symbols.length === 0) return [];
|
|
5104
|
-
const ordered = [...symbols].sort((a, b) => a.line - b.line || a.col - b.col || a.id - b.id);
|
|
5105
|
-
const seen = /* @__PURE__ */ new Set();
|
|
5106
|
-
const assigned = [];
|
|
5107
|
-
for (const ref of refs) {
|
|
5108
|
-
let owner;
|
|
5109
|
-
for (const symbol of ordered) {
|
|
5110
|
-
if (symbol.line > ref.line) break;
|
|
5111
|
-
owner = symbol;
|
|
5112
|
-
}
|
|
5113
|
-
if (!owner && ref.callType === "import") owner = ordered[0];
|
|
5114
|
-
if (!owner || owner.id <= 0) continue;
|
|
5115
|
-
const key = `${owner.id}:${ref.toName}:${ref.callType}:${ref.module ?? ""}`;
|
|
5116
|
-
if (seen.has(key)) continue;
|
|
5117
|
-
seen.add(key);
|
|
5118
|
-
assigned.push({ ...ref, fromId: owner.id });
|
|
5119
|
-
}
|
|
5120
|
-
return assigned;
|
|
5121
|
-
}
|
|
5122
|
-
function resolveIndexDir(projectRoot, override) {
|
|
5123
|
-
return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;
|
|
5124
|
-
}
|
|
5125
|
-
|
|
5126
5170
|
// src/codebase-index/vector-search.ts
|
|
5127
5171
|
var RRF_K = 60;
|
|
5128
5172
|
var VECTOR_DIMENSIONS = 384;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.308.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack built-in tools: read/write/edit, bash/exec, grep/glob, git, fetch, test, lint, and more.",
|
|
6
6
|
"repository": {
|
|
@@ -253,9 +253,9 @@
|
|
|
253
253
|
"turndown": "^7.2.4",
|
|
254
254
|
"undici": "^8.10.0",
|
|
255
255
|
"web-tree-sitter": "0.26.12",
|
|
256
|
-
"@wrongstack/
|
|
257
|
-
"@wrongstack/
|
|
258
|
-
"@wrongstack/
|
|
256
|
+
"@wrongstack/core": "0.308.0",
|
|
257
|
+
"@wrongstack/kanban": "0.308.0",
|
|
258
|
+
"@wrongstack/persistence": "0.308.0"
|
|
259
259
|
},
|
|
260
260
|
"devDependencies": {
|
|
261
261
|
"@types/node": "^26.2.0",
|