@wrongstack/tools 0.307.0 → 0.307.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/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
|
@@ -54,7 +54,7 @@ export type WriterSymbolGraphRow = {
|
|
|
54
54
|
signature: string;
|
|
55
55
|
scope: string;
|
|
56
56
|
};
|
|
57
|
-
export declare function buildSymbolGraphNodes(symById: Map<number, WriterSymbolGraphRow>, relatedIds: Set<number>,
|
|
57
|
+
export declare function buildSymbolGraphNodes(symById: Map<number, WriterSymbolGraphRow>, relatedIds: Set<number>, localFiles: ReadonlySet<string> | string, packageOf: (file: string) => string): GraphNode[];
|
|
58
58
|
export type WeightedEdgeAccumulator = {
|
|
59
59
|
weight: number;
|
|
60
60
|
types: Map<string, number>;
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import type { Ref, Symbol as IndexSymbol } from './schema.js';
|
|
2
2
|
export declare function escapeLike(value: string): string;
|
|
3
|
+
/** Normalize an indexed or user-supplied file path for comparison. */
|
|
4
|
+
export declare function posixIndexPath(file: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* SQL predicate that matches a stored `file` column against a user-supplied
|
|
7
|
+
* path. Agents pass project-relative paths (`src/calc.ts`); the index stores
|
|
8
|
+
* absolute OS paths. Exact, slash-normalized, and suffix matches are accepted.
|
|
9
|
+
*/
|
|
10
|
+
export declare function indexedFileMatchSql(column?: string): string;
|
|
11
|
+
/** Bind values for {@link indexedFileMatchSql}: exact, posix, suffix-LIKE. */
|
|
12
|
+
export declare function indexedFileMatchArgs(file: string): [string, string, string];
|
|
13
|
+
/** True when a stored file path belongs to a package name or path fragment. */
|
|
14
|
+
export declare function matchesIndexedPackageFilter(storedFile: string, packageLabel: string, filter: string): boolean;
|
|
3
15
|
export declare function assignRefsToSymbols(refs: Ref[], symbols: IndexSymbol[]): Ref[];
|
|
4
16
|
/**
|
|
5
17
|
* Resolve the per-project index directory. By default it lives under the
|
package/dist/edit.js
CHANGED
|
@@ -4755,10 +4755,16 @@ function buildFileGraphNodeState(pkgSyms, localFiles, packageOf) {
|
|
|
4755
4755
|
}
|
|
4756
4756
|
return { fileNodes, symToFile, fileStats, ensureFileNode };
|
|
4757
4757
|
}
|
|
4758
|
-
function buildSymbolGraphNodes(symById, relatedIds,
|
|
4758
|
+
function buildSymbolGraphNodes(symById, relatedIds, localFiles, packageOf) {
|
|
4759
|
+
const local = new Set(
|
|
4760
|
+
[...typeof localFiles === "string" ? [localFiles] : localFiles].map(
|
|
4761
|
+
(file) => file.replace(/\\/g, "/")
|
|
4762
|
+
)
|
|
4763
|
+
);
|
|
4764
|
+
const isLocal = (file) => local.has(file.replace(/\\/g, "/"));
|
|
4759
4765
|
return [...relatedIds].map((id) => symById.get(id)).filter((symbol) => symbol !== void 0).sort((a, b) => {
|
|
4760
|
-
const aExternal = a.file
|
|
4761
|
-
const bExternal = b.file
|
|
4766
|
+
const aExternal = isLocal(a.file) ? 0 : 1;
|
|
4767
|
+
const bExternal = isLocal(b.file) ? 0 : 1;
|
|
4762
4768
|
return aExternal - bExternal || a.file.localeCompare(b.file) || a.line - b.line || a.id - b.id;
|
|
4763
4769
|
}).map((s) => ({
|
|
4764
4770
|
id: `sym:${s.id}`,
|
|
@@ -4772,7 +4778,7 @@ function buildSymbolGraphNodes(symById, relatedIds, fileFilter, packageOf) {
|
|
|
4772
4778
|
line: s.line,
|
|
4773
4779
|
signature: s.signature,
|
|
4774
4780
|
scope: s.scope,
|
|
4775
|
-
external: s.file
|
|
4781
|
+
external: !isLocal(s.file)
|
|
4776
4782
|
}));
|
|
4777
4783
|
}
|
|
4778
4784
|
function addWeightedEdge(edgeMap, source, target, callType, weight) {
|
|
@@ -4807,6 +4813,52 @@ function materializeWeightedEdges(edgeMap, idPrefix) {
|
|
|
4807
4813
|
return edges;
|
|
4808
4814
|
}
|
|
4809
4815
|
|
|
4816
|
+
// src/codebase-index/writer-helpers.ts
|
|
4817
|
+
import { resolveWstackPaths } from "@wrongstack/core/utils";
|
|
4818
|
+
function escapeLike(value) {
|
|
4819
|
+
return value.replace(/[\\%_]/g, (char) => `\\${char}`);
|
|
4820
|
+
}
|
|
4821
|
+
function posixIndexPath(file) {
|
|
4822
|
+
return file.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
4823
|
+
}
|
|
4824
|
+
function indexedFileMatchSql(column = "file") {
|
|
4825
|
+
return `(${column} = ? OR replace(${column}, '\\', '/') = ? OR replace(${column}, '\\', '/') LIKE ? ESCAPE '\\')`;
|
|
4826
|
+
}
|
|
4827
|
+
function indexedFileMatchArgs(file) {
|
|
4828
|
+
const posix4 = posixIndexPath(file.trim());
|
|
4829
|
+
return [file, posix4, `%/${escapeLike(posix4)}`];
|
|
4830
|
+
}
|
|
4831
|
+
function matchesIndexedPackageFilter(storedFile, packageLabel, filter) {
|
|
4832
|
+
if (packageLabel === filter) return true;
|
|
4833
|
+
const posixFile = posixIndexPath(storedFile);
|
|
4834
|
+
const posixFilter = posixIndexPath(filter.trim());
|
|
4835
|
+
if (!posixFilter) return false;
|
|
4836
|
+
return posixFile === posixFilter || posixFile.endsWith(`/${posixFilter}`) || posixFile.includes(`/${posixFilter}/`);
|
|
4837
|
+
}
|
|
4838
|
+
function assignRefsToSymbols(refs, symbols) {
|
|
4839
|
+
if (refs.length === 0 || symbols.length === 0) return [];
|
|
4840
|
+
const ordered = [...symbols].sort((a, b) => a.line - b.line || a.col - b.col || a.id - b.id);
|
|
4841
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4842
|
+
const assigned = [];
|
|
4843
|
+
for (const ref of refs) {
|
|
4844
|
+
let owner;
|
|
4845
|
+
for (const symbol of ordered) {
|
|
4846
|
+
if (symbol.line > ref.line) break;
|
|
4847
|
+
owner = symbol;
|
|
4848
|
+
}
|
|
4849
|
+
if (!owner && ref.callType === "import") owner = ordered[0];
|
|
4850
|
+
if (!owner || owner.id <= 0) continue;
|
|
4851
|
+
const key = `${owner.id}:${ref.toName}:${ref.callType}:${ref.module ?? ""}`;
|
|
4852
|
+
if (seen.has(key)) continue;
|
|
4853
|
+
seen.add(key);
|
|
4854
|
+
assigned.push({ ...ref, fromId: owner.id });
|
|
4855
|
+
}
|
|
4856
|
+
return assigned;
|
|
4857
|
+
}
|
|
4858
|
+
function resolveIndexDir(projectRoot, override) {
|
|
4859
|
+
return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;
|
|
4860
|
+
}
|
|
4861
|
+
|
|
4810
4862
|
// src/codebase-index/writer-ref-mapper.ts
|
|
4811
4863
|
function mapWriterRefRow(row) {
|
|
4812
4864
|
return {
|
|
@@ -4862,10 +4914,23 @@ function mapCallSiteRow(row) {
|
|
|
4862
4914
|
line: row.ref_line
|
|
4863
4915
|
};
|
|
4864
4916
|
}
|
|
4917
|
+
function resolveIndexedFiles(stmt, file) {
|
|
4918
|
+
const rows = stmt(
|
|
4919
|
+
`SELECT DISTINCT file FROM symbols WHERE ${indexedFileMatchSql("file")} ORDER BY length(file), file`
|
|
4920
|
+
).all(...indexedFileMatchArgs(file));
|
|
4921
|
+
return rows.map((row) => row.file);
|
|
4922
|
+
}
|
|
4865
4923
|
function resolveSymbolIds(stmt, symbolName, file) {
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4924
|
+
if (!file) {
|
|
4925
|
+
const rows2 = stmt("SELECT id FROM symbols WHERE name = ? ORDER BY id").all(symbolName);
|
|
4926
|
+
return rows2.map((r) => r.id);
|
|
4927
|
+
}
|
|
4928
|
+
const indexedFiles = resolveIndexedFiles(stmt, file);
|
|
4929
|
+
if (indexedFiles.length === 0) return [];
|
|
4930
|
+
const placeholders = indexedFiles.map(() => "?").join(",");
|
|
4931
|
+
const rows = stmt(
|
|
4932
|
+
`SELECT id FROM symbols WHERE name = ? AND file IN (${placeholders}) ORDER BY id`
|
|
4933
|
+
).all(symbolName, ...indexedFiles);
|
|
4869
4934
|
return rows.map((r) => r.id);
|
|
4870
4935
|
}
|
|
4871
4936
|
function findIncomingCallsByName(stmt, symbolName, file, limit) {
|
|
@@ -5187,7 +5252,7 @@ function getFileGraphWithStatement(stmt, packageFilter) {
|
|
|
5187
5252
|
const allFiles = stmt("SELECT DISTINCT file FROM symbols").all();
|
|
5188
5253
|
const packageOf = readPackageLabeller(stmt);
|
|
5189
5254
|
const langOf = (file) => detectLang(file) ?? "other";
|
|
5190
|
-
const pkgFilePaths = allFiles.filter((f) => packageOf(f.file)
|
|
5255
|
+
const pkgFilePaths = allFiles.filter((f) => matchesIndexedPackageFilter(f.file, packageOf(f.file), packageFilter)).map((f) => f.file);
|
|
5191
5256
|
const localFiles = new Set(pkgFilePaths);
|
|
5192
5257
|
if (localFiles.size === 0) return { nodes: [], edges: [] };
|
|
5193
5258
|
const filePlaceholders = [...localFiles].map(() => "?").join(",");
|
|
@@ -5263,9 +5328,12 @@ function getFileGraphWithStatement(stmt, packageFilter) {
|
|
|
5263
5328
|
return { nodes: [...fileNodes.values()], edges };
|
|
5264
5329
|
}
|
|
5265
5330
|
function getSymbolGraphWithStatement(stmt, fileFilter) {
|
|
5331
|
+
const indexedFiles = resolveIndexedFiles(stmt, fileFilter);
|
|
5332
|
+
if (indexedFiles.length === 0) return { nodes: [], edges: [] };
|
|
5333
|
+
const filePlaceholders = indexedFiles.map(() => "?").join(",");
|
|
5266
5334
|
const syms = stmt(
|
|
5267
|
-
|
|
5268
|
-
).all(
|
|
5335
|
+
`SELECT id, name, kind, lang, file, line, signature, scope FROM symbols WHERE file IN (${filePlaceholders}) ORDER BY line, id`
|
|
5336
|
+
).all(...indexedFiles);
|
|
5269
5337
|
if (syms.length === 0) return { nodes: [], edges: [] };
|
|
5270
5338
|
const symById = new Map(syms.map((symbol) => [symbol.id, symbol]));
|
|
5271
5339
|
const relatedIds = new Set(syms.map((symbol) => symbol.id));
|
|
@@ -5275,16 +5343,16 @@ function getSymbolGraphWithStatement(stmt, fileFilter) {
|
|
|
5275
5343
|
SELECT r.from_id, r.to_id, r.to_name, r.call_type, r.line
|
|
5276
5344
|
FROM refs r
|
|
5277
5345
|
JOIN symbols s ON s.id = r.from_id
|
|
5278
|
-
WHERE s.file
|
|
5346
|
+
WHERE s.file IN (${filePlaceholders})
|
|
5279
5347
|
UNION
|
|
5280
5348
|
SELECT r.from_id, r.to_id, r.to_name, r.call_type, r.line
|
|
5281
5349
|
FROM refs r
|
|
5282
5350
|
JOIN symbols s ON s.id = r.to_id
|
|
5283
|
-
WHERE s.file
|
|
5351
|
+
WHERE s.file IN (${filePlaceholders})
|
|
5284
5352
|
)
|
|
5285
5353
|
WHERE to_id IS NOT NULL
|
|
5286
5354
|
GROUP BY from_id, to_id, call_type`
|
|
5287
|
-
).all(
|
|
5355
|
+
).all(...indexedFiles, ...indexedFiles);
|
|
5288
5356
|
const edgeMap = /* @__PURE__ */ new Map();
|
|
5289
5357
|
for (const r of refRows) {
|
|
5290
5358
|
if (r.to_id == null) continue;
|
|
@@ -5303,39 +5371,15 @@ function getSymbolGraphWithStatement(stmt, fileFilter) {
|
|
|
5303
5371
|
).all(...missingIds);
|
|
5304
5372
|
for (const s of extras) symById.set(s.id, s);
|
|
5305
5373
|
}
|
|
5306
|
-
const nodes = buildSymbolGraphNodes(
|
|
5374
|
+
const nodes = buildSymbolGraphNodes(
|
|
5375
|
+
symById,
|
|
5376
|
+
relatedIds,
|
|
5377
|
+
new Set(syms.map((symbol) => symbol.file)),
|
|
5378
|
+
readPackageLabeller(stmt)
|
|
5379
|
+
);
|
|
5307
5380
|
return { nodes, edges };
|
|
5308
5381
|
}
|
|
5309
5382
|
|
|
5310
|
-
// src/codebase-index/writer-helpers.ts
|
|
5311
|
-
import { resolveWstackPaths } from "@wrongstack/core/utils";
|
|
5312
|
-
function escapeLike(value) {
|
|
5313
|
-
return value.replace(/[\\%_]/g, (char) => `\\${char}`);
|
|
5314
|
-
}
|
|
5315
|
-
function assignRefsToSymbols(refs, symbols) {
|
|
5316
|
-
if (refs.length === 0 || symbols.length === 0) return [];
|
|
5317
|
-
const ordered = [...symbols].sort((a, b) => a.line - b.line || a.col - b.col || a.id - b.id);
|
|
5318
|
-
const seen = /* @__PURE__ */ new Set();
|
|
5319
|
-
const assigned = [];
|
|
5320
|
-
for (const ref of refs) {
|
|
5321
|
-
let owner;
|
|
5322
|
-
for (const symbol of ordered) {
|
|
5323
|
-
if (symbol.line > ref.line) break;
|
|
5324
|
-
owner = symbol;
|
|
5325
|
-
}
|
|
5326
|
-
if (!owner && ref.callType === "import") owner = ordered[0];
|
|
5327
|
-
if (!owner || owner.id <= 0) continue;
|
|
5328
|
-
const key = `${owner.id}:${ref.toName}:${ref.callType}:${ref.module ?? ""}`;
|
|
5329
|
-
if (seen.has(key)) continue;
|
|
5330
|
-
seen.add(key);
|
|
5331
|
-
assigned.push({ ...ref, fromId: owner.id });
|
|
5332
|
-
}
|
|
5333
|
-
return assigned;
|
|
5334
|
-
}
|
|
5335
|
-
function resolveIndexDir(projectRoot, override) {
|
|
5336
|
-
return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;
|
|
5337
|
-
}
|
|
5338
|
-
|
|
5339
5383
|
// src/codebase-index/vector-search.ts
|
|
5340
5384
|
var RRF_K = 60;
|
|
5341
5385
|
var VECTOR_DIMENSIONS = 384;
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export { builtinTools, OFF_ONLY_TOOLS, OPTIONAL_TOOLS, TIER1_TOOLS, TIER2_TOOLS,
|
|
|
9
9
|
export { CircuitBreaker, type CircuitBreakerConfig, type CircuitBreakerSnapshot, } from './circuit-breaker.js';
|
|
10
10
|
export type { CircuitSnapshot, CircuitState, CodeMapGraph, DeadCodeScanInput, DeadCodeScanOutput, DeadFile, DeadPackage, DeadSymbol, GraphEdge, GraphNode, ProjectIndexDaemonAvailability, ProjectIndexServerActivity, ProjectIndexServerClientHealth, ProjectIndexServerConnectionState, ProjectIndexServerConnectionStatus, ProjectIndexServerHealth, } from './codebase-index/index.js';
|
|
11
11
|
export { clarifyTool, type ClarifyQuestionInput, type ClarifyOutput, } from './clarify.js';
|
|
12
|
-
export { CircuitOpenError, cancelPendingReindexes, checkCodebaseIndexServerHealth, codebaseAstReplaceTool, codebaseImpactAnalysisTool, codebaseIndexStats, codebaseIndexTool, codebaseRepoMapTool, codebaseSearchTool, codebaseSkeletonTool, codebaseStatsTool, codebaseTargetedTestTool, deadCodeScanTool, enqueueReindex, ensureCodebaseIndexServer, extractDirectorySkeleton, extractFileSkeleton, generateRepoMap, replaceSymbolInFile, type FileSkeletonResult, type MutateSymbolOptions, type MutateSymbolResult, type RepoMapOptions, type RepoMapResult, type SkeletonOptions, type SkeletonSymbolRange, fileGraphService, getIndexState, IndexCircuitBreaker, IndexTimeoutError, indexCircuitBreaker, isIndexableFile, isIndexing, isIndexReady, onIndexStateChange, packageGraphService, resetIndexCircuitBreaker, resolveProjectIndexDaemonAvailability, runDeadCodeScan, runStartupIndex, searchCodebaseIndex, shutdownCodebaseIndexHost, shutdownCodebaseIndexServer, symbolGraphService, } from './codebase-index/index.js';
|
|
12
|
+
export { CircuitOpenError, cancelPendingReindexes, checkCodebaseIndexServerHealth, codebaseAstReplaceTool, codebaseImpactAnalysisTool, codebaseIndexStats, codebaseIndexTool, codebaseInvariantCheckTool, codebaseRepoMapTool, codebaseSearchTool, codebaseSkeletonTool, codebaseStatsTool, codebaseTargetedTestTool, deadCodeScanTool, enqueueReindex, ensureCodebaseIndexServer, extractDirectorySkeleton, extractFileSkeleton, generateRepoMap, replaceSymbolInFile, type FileSkeletonResult, type MutateSymbolOptions, type MutateSymbolResult, type RepoMapOptions, type RepoMapResult, type SkeletonOptions, type SkeletonSymbolRange, fileGraphService, getIndexState, IndexCircuitBreaker, IndexTimeoutError, indexCircuitBreaker, isIndexableFile, isIndexing, isIndexReady, onIndexStateChange, packageGraphService, resetIndexCircuitBreaker, resolveProjectIndexDaemonAvailability, runDeadCodeScan, runStartupIndex, searchCodebaseIndex, shutdownCodebaseIndexHost, shutdownCodebaseIndexServer, symbolGraphService, } from './codebase-index/index.js';
|
|
13
13
|
export { designTool } from './design.js';
|
|
14
14
|
export { diffTool } from './diff.js';
|
|
15
15
|
export { documentTool } from './document.js';
|